@backstage/catalog-client
Advanced tools
+20
-0
| # @backstage/catalog-client | ||
| ## 1.14.0-next.1 | ||
| ### Minor Changes | ||
| - 972f686: Added support for the `query` field in `getEntitiesByRefs` requests, enabling predicate-based filtering with `$all`, `$any`, `$not`, `$exists`, `$in`, `$contains`, and `$hasPrefix` operators. | ||
| - 56c908e: Added support for the `query` field in `getEntityFacets` requests, enabling predicate-based filtering with `$all`, `$any`, `$not`, `$exists`, `$in`, `$contains`, and `$hasPrefix` operators. | ||
| - 0fbcf23: Migrated OpenAPI schemas to 3.1. | ||
| - 51e23eb: Added predicate-based entity filtering via POST /entities/by-query endpoint. | ||
| Supports `$all`, `$any`, `$not`, `$exists`, `$in`, `$hasPrefix`, and (partially) `$contains` operators for expressive entity queries. Integrated into the existing `queryEntities` flow with full cursor-based pagination, permission enforcement, and `totalItems` support. | ||
| The catalog client's `queryEntities()` method automatically routes to the POST endpoint when a `query` predicate is provided. | ||
| ### Patch Changes | ||
| - Updated dependencies | ||
| - @backstage/catalog-model@1.7.6 | ||
| - @backstage/errors@1.2.7 | ||
| - @backstage/filter-predicates@0.1.0 | ||
| ## 1.13.1-next.0 | ||
@@ -4,0 +24,0 @@ |
@@ -134,7 +134,25 @@ 'use strict'; | ||
| async getEntitiesByRefs(request, options) { | ||
| const { filter, query } = request; | ||
| let filterPredicate; | ||
| if (query !== void 0) { | ||
| if (typeof query !== "object" || query === null || Array.isArray(query)) { | ||
| throw new errors.InputError("Query must be an object"); | ||
| } | ||
| filterPredicate = query; | ||
| if (filter !== void 0) { | ||
| const converted = utils.convertFilterToPredicate(filter); | ||
| filterPredicate = { $all: [filterPredicate, converted] }; | ||
| } | ||
| } | ||
| const getOneChunk = async (refs) => { | ||
| const response = await this.apiClient.getEntitiesByRefs( | ||
| { | ||
| body: { entityRefs: refs, fields: request.fields }, | ||
| query: { filter: this.getFilterValue(request.filter) } | ||
| body: { | ||
| entityRefs: refs, | ||
| fields: request.fields, | ||
| ...filterPredicate && { | ||
| query: filterPredicate | ||
| } | ||
| }, | ||
| query: filterPredicate ? {} : { filter: this.getFilterValue(request.filter) } | ||
| }, | ||
@@ -164,4 +182,11 @@ options | ||
| async queryEntities(request = {}, options) { | ||
| const isInitialRequest = utils.isQueryEntitiesInitialRequest(request); | ||
| if (isInitialRequest && request.query) { | ||
| return this.queryEntitiesByPredicate(request, options); | ||
| } | ||
| if (!isInitialRequest && utils.cursorContainsQuery(request.cursor)) { | ||
| return this.queryEntitiesByPredicate(request, options); | ||
| } | ||
| const params = {}; | ||
| if (utils.isQueryEntitiesInitialRequest(request)) { | ||
| if (isInitialRequest) { | ||
| const { | ||
@@ -210,2 +235,65 @@ fields = [], | ||
| /** | ||
| * Query entities using predicate-based filters (POST endpoint). | ||
| * @internal | ||
| */ | ||
| async queryEntitiesByPredicate(request, options) { | ||
| const body = {}; | ||
| if (utils.isQueryEntitiesInitialRequest(request)) { | ||
| const { | ||
| filter, | ||
| query, | ||
| limit, | ||
| offset, | ||
| orderFields, | ||
| fullTextFilter, | ||
| fields | ||
| } = request; | ||
| let filterPredicate; | ||
| if (query !== void 0) { | ||
| if (typeof query !== "object" || query === null || Array.isArray(query)) { | ||
| throw new errors.InputError("Query must be an object"); | ||
| } | ||
| filterPredicate = query; | ||
| } | ||
| if (filter !== void 0) { | ||
| const converted = utils.convertFilterToPredicate(filter); | ||
| filterPredicate = filterPredicate ? { $all: [filterPredicate, converted] } : converted; | ||
| } | ||
| if (filterPredicate !== void 0) { | ||
| body.query = filterPredicate; | ||
| } | ||
| if (limit !== void 0) { | ||
| body.limit = limit; | ||
| } | ||
| if (offset !== void 0) { | ||
| body.offset = offset; | ||
| } | ||
| if (orderFields !== void 0) { | ||
| body.orderBy = [orderFields].flat(); | ||
| } | ||
| if (fullTextFilter) { | ||
| body.fullTextFilter = fullTextFilter; | ||
| } | ||
| if (fields?.length) { | ||
| body.fields = fields; | ||
| } | ||
| } else { | ||
| body.cursor = request.cursor; | ||
| if (request.limit !== void 0) { | ||
| body.limit = request.limit; | ||
| } | ||
| if (request.fields?.length) { | ||
| body.fields = request.fields; | ||
| } | ||
| } | ||
| const res = await this.requestRequired( | ||
| await this.apiClient.queryEntitiesByPredicate({ body }, options) | ||
| ); | ||
| return { | ||
| items: res.items, | ||
| totalItems: res.totalItems, | ||
| pageInfo: res.pageInfo | ||
| }; | ||
| } | ||
| /** | ||
| * {@inheritdoc CatalogApi.getEntityByRef} | ||
@@ -255,3 +343,6 @@ */ | ||
| async getEntityFacets(request, options) { | ||
| const { filter = [], facets } = request; | ||
| const { filter = [], query, facets } = request; | ||
| if (query) { | ||
| return this.getEntityFacetsByPredicate(request, options); | ||
| } | ||
| return await this.requestOptional( | ||
@@ -267,2 +358,33 @@ await this.apiClient.getEntityFacets( | ||
| /** | ||
| * Get entity facets using predicate-based filters (POST endpoint). | ||
| * @internal | ||
| */ | ||
| async getEntityFacetsByPredicate(request, options) { | ||
| const { filter, query, facets } = request; | ||
| let filterPredicate; | ||
| if (query !== void 0) { | ||
| if (typeof query !== "object" || query === null || Array.isArray(query)) { | ||
| throw new errors.InputError("Query must be an object"); | ||
| } | ||
| filterPredicate = query; | ||
| } | ||
| if (filter !== void 0) { | ||
| const converted = utils.convertFilterToPredicate(filter); | ||
| filterPredicate = filterPredicate ? { $all: [filterPredicate, converted] } : converted; | ||
| } | ||
| return await this.requestOptional( | ||
| await this.apiClient.queryEntityFacetsByPredicate( | ||
| { | ||
| body: { | ||
| facets, | ||
| ...filterPredicate && { | ||
| query: filterPredicate | ||
| } | ||
| } | ||
| }, | ||
| options | ||
| ) | ||
| ); | ||
| } | ||
| /** | ||
| * {@inheritdoc CatalogApi.addLocation} | ||
@@ -269,0 +391,0 @@ */ |
@@ -1,1 +0,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 // #region Private methods\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 // #endregion\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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"} | ||
| {"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 { InputError, ResponseError } from '@backstage/errors';\nimport { FilterPredicate } from '@backstage/filter-predicates';\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 {\n convertFilterToPredicate,\n isQueryEntitiesInitialRequest,\n splitRefsIntoChunks,\n cursorContainsQuery,\n} from './utils';\nimport {\n DefaultApiClient,\n GetEntitiesByQuery,\n GetLocationsByQueryRequest,\n QueryEntitiesByPredicateRequest,\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 { filter, query } = request;\n\n // Only convert and merge if both filter and query are provided, or if\n // query alone is provided. When only filter is given, preserve the old\n // query-parameter behavior for backward compatibility.\n let filterPredicate: FilterPredicate | undefined;\n if (query !== undefined) {\n if (typeof query !== 'object' || query === null || Array.isArray(query)) {\n throw new InputError('Query must be an object');\n }\n filterPredicate = query;\n if (filter !== undefined) {\n const converted = convertFilterToPredicate(filter);\n filterPredicate = { $all: [filterPredicate, converted] };\n }\n }\n\n const getOneChunk = async (refs: string[]) => {\n const response = await this.apiClient.getEntitiesByRefs(\n {\n body: {\n entityRefs: refs,\n fields: request.fields,\n ...(filterPredicate && {\n query: filterPredicate as unknown as { [key: string]: any },\n }),\n },\n query: filterPredicate\n ? {}\n : { 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 isInitialRequest = isQueryEntitiesInitialRequest(request);\n\n // Route to POST endpoint if query predicate is provided (initial request)\n if (isInitialRequest && request.query) {\n return this.queryEntitiesByPredicate(request, options);\n }\n\n // Route to POST endpoint if cursor contains a query predicate (pagination)\n // TODO(freben): It's costly and non-opaque to have to introspect the cursor\n // like this. It should be refactored in the future to not need this.\n // Suggestion: make the GET and POST endpoints understand the same cursor\n // format, and pick which one to call ONLY based on whether the cursor size\n // risks hitting url length limits\n if (!isInitialRequest && cursorContainsQuery(request.cursor)) {\n return this.queryEntitiesByPredicate(request, options);\n }\n\n const params: Partial<GetEntitiesByQuery['query']> = {};\n\n if (isInitialRequest) {\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 * Query entities using predicate-based filters (POST endpoint).\n * @internal\n */\n private async queryEntitiesByPredicate(\n request: QueryEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse> {\n const body: QueryEntitiesByPredicateRequest = {};\n\n if (isQueryEntitiesInitialRequest(request)) {\n const {\n filter,\n query,\n limit,\n offset,\n orderFields,\n fullTextFilter,\n fields,\n } = request;\n\n let filterPredicate: FilterPredicate | undefined;\n if (query !== undefined) {\n if (\n typeof query !== 'object' ||\n query === null ||\n Array.isArray(query)\n ) {\n throw new InputError('Query must be an object');\n }\n filterPredicate = query;\n }\n if (filter !== undefined) {\n const converted = convertFilterToPredicate(filter);\n filterPredicate = filterPredicate\n ? { $all: [filterPredicate, converted] }\n : converted;\n }\n if (filterPredicate !== undefined) {\n body.query = filterPredicate as unknown as { [key: string]: any };\n }\n\n if (limit !== undefined) {\n body.limit = limit;\n }\n if (offset !== undefined) {\n body.offset = offset;\n }\n if (orderFields !== undefined) {\n body.orderBy = [orderFields].flat();\n }\n if (fullTextFilter) {\n body.fullTextFilter = fullTextFilter;\n }\n if (fields?.length) {\n body.fields = fields;\n }\n } else {\n body.cursor = request.cursor;\n if (request.limit !== undefined) {\n body.limit = request.limit;\n }\n if (request.fields?.length) {\n body.fields = request.fields;\n }\n }\n\n const res = await this.requestRequired(\n await this.apiClient.queryEntitiesByPredicate({ body }, options),\n );\n\n return {\n items: res.items,\n totalItems: res.totalItems,\n pageInfo: res.pageInfo,\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 = [], query, facets } = request;\n\n // Route to POST endpoint if query predicate is provided\n if (query) {\n return this.getEntityFacetsByPredicate(request, options);\n }\n\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 * Get entity facets using predicate-based filters (POST endpoint).\n * @internal\n */\n private async getEntityFacetsByPredicate(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter, query, facets } = request;\n\n let filterPredicate: FilterPredicate | undefined;\n if (query !== undefined) {\n if (typeof query !== 'object' || query === null || Array.isArray(query)) {\n throw new InputError('Query must be an object');\n }\n filterPredicate = query;\n }\n if (filter !== undefined) {\n const converted = convertFilterToPredicate(filter);\n filterPredicate = filterPredicate\n ? { $all: [filterPredicate, converted] }\n : converted;\n }\n\n return await this.requestOptional(\n await this.apiClient.queryEntityFacetsByPredicate(\n {\n body: {\n facets,\n ...(filterPredicate && {\n query: filterPredicate as unknown as { [key: string]: any },\n }),\n },\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 // #region Private methods\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 // #endregion\n}\n"],"names":["DefaultApiClient","parseEntityRef","DEFAULT_STREAM_LOCATIONS_LIMIT","InputError","convertFilterToPredicate","ResponseError","splitRefsIntoChunks","isQueryEntitiesInitialRequest","cursorContainsQuery","stringifyLocationRef","errors","DEFAULT_STREAM_ENTITIES_LIMIT","CATALOG_FILTER_EXISTS"],"mappings":"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"} |
| import { parseEntityRef, stringifyLocationRef } from '@backstage/catalog-model'; | ||
| import { ResponseError } from '@backstage/errors'; | ||
| import { InputError, ResponseError } from '@backstage/errors'; | ||
| import { CATALOG_FILTER_EXISTS } from './types/api.esm.js'; | ||
| import { splitRefsIntoChunks, isQueryEntitiesInitialRequest } from './utils.esm.js'; | ||
| import { convertFilterToPredicate, splitRefsIntoChunks, isQueryEntitiesInitialRequest, cursorContainsQuery } from './utils.esm.js'; | ||
| import { DefaultApiClient } from './schema/openapi/generated/apis/Api.client.esm.js'; | ||
@@ -132,7 +132,25 @@ import { DEFAULT_STREAM_LOCATIONS_LIMIT, DEFAULT_STREAM_ENTITIES_LIMIT } from './constants.esm.js'; | ||
| async getEntitiesByRefs(request, options) { | ||
| const { filter, query } = request; | ||
| let filterPredicate; | ||
| if (query !== void 0) { | ||
| if (typeof query !== "object" || query === null || Array.isArray(query)) { | ||
| throw new InputError("Query must be an object"); | ||
| } | ||
| filterPredicate = query; | ||
| if (filter !== void 0) { | ||
| const converted = convertFilterToPredicate(filter); | ||
| filterPredicate = { $all: [filterPredicate, converted] }; | ||
| } | ||
| } | ||
| const getOneChunk = async (refs) => { | ||
| const response = await this.apiClient.getEntitiesByRefs( | ||
| { | ||
| body: { entityRefs: refs, fields: request.fields }, | ||
| query: { filter: this.getFilterValue(request.filter) } | ||
| body: { | ||
| entityRefs: refs, | ||
| fields: request.fields, | ||
| ...filterPredicate && { | ||
| query: filterPredicate | ||
| } | ||
| }, | ||
| query: filterPredicate ? {} : { filter: this.getFilterValue(request.filter) } | ||
| }, | ||
@@ -162,4 +180,11 @@ options | ||
| async queryEntities(request = {}, options) { | ||
| const isInitialRequest = isQueryEntitiesInitialRequest(request); | ||
| if (isInitialRequest && request.query) { | ||
| return this.queryEntitiesByPredicate(request, options); | ||
| } | ||
| if (!isInitialRequest && cursorContainsQuery(request.cursor)) { | ||
| return this.queryEntitiesByPredicate(request, options); | ||
| } | ||
| const params = {}; | ||
| if (isQueryEntitiesInitialRequest(request)) { | ||
| if (isInitialRequest) { | ||
| const { | ||
@@ -208,2 +233,65 @@ fields = [], | ||
| /** | ||
| * Query entities using predicate-based filters (POST endpoint). | ||
| * @internal | ||
| */ | ||
| async queryEntitiesByPredicate(request, options) { | ||
| const body = {}; | ||
| if (isQueryEntitiesInitialRequest(request)) { | ||
| const { | ||
| filter, | ||
| query, | ||
| limit, | ||
| offset, | ||
| orderFields, | ||
| fullTextFilter, | ||
| fields | ||
| } = request; | ||
| let filterPredicate; | ||
| if (query !== void 0) { | ||
| if (typeof query !== "object" || query === null || Array.isArray(query)) { | ||
| throw new InputError("Query must be an object"); | ||
| } | ||
| filterPredicate = query; | ||
| } | ||
| if (filter !== void 0) { | ||
| const converted = convertFilterToPredicate(filter); | ||
| filterPredicate = filterPredicate ? { $all: [filterPredicate, converted] } : converted; | ||
| } | ||
| if (filterPredicate !== void 0) { | ||
| body.query = filterPredicate; | ||
| } | ||
| if (limit !== void 0) { | ||
| body.limit = limit; | ||
| } | ||
| if (offset !== void 0) { | ||
| body.offset = offset; | ||
| } | ||
| if (orderFields !== void 0) { | ||
| body.orderBy = [orderFields].flat(); | ||
| } | ||
| if (fullTextFilter) { | ||
| body.fullTextFilter = fullTextFilter; | ||
| } | ||
| if (fields?.length) { | ||
| body.fields = fields; | ||
| } | ||
| } else { | ||
| body.cursor = request.cursor; | ||
| if (request.limit !== void 0) { | ||
| body.limit = request.limit; | ||
| } | ||
| if (request.fields?.length) { | ||
| body.fields = request.fields; | ||
| } | ||
| } | ||
| const res = await this.requestRequired( | ||
| await this.apiClient.queryEntitiesByPredicate({ body }, options) | ||
| ); | ||
| return { | ||
| items: res.items, | ||
| totalItems: res.totalItems, | ||
| pageInfo: res.pageInfo | ||
| }; | ||
| } | ||
| /** | ||
| * {@inheritdoc CatalogApi.getEntityByRef} | ||
@@ -253,3 +341,6 @@ */ | ||
| async getEntityFacets(request, options) { | ||
| const { filter = [], facets } = request; | ||
| const { filter = [], query, facets } = request; | ||
| if (query) { | ||
| return this.getEntityFacetsByPredicate(request, options); | ||
| } | ||
| return await this.requestOptional( | ||
@@ -265,2 +356,33 @@ await this.apiClient.getEntityFacets( | ||
| /** | ||
| * Get entity facets using predicate-based filters (POST endpoint). | ||
| * @internal | ||
| */ | ||
| async getEntityFacetsByPredicate(request, options) { | ||
| const { filter, query, facets } = request; | ||
| let filterPredicate; | ||
| if (query !== void 0) { | ||
| if (typeof query !== "object" || query === null || Array.isArray(query)) { | ||
| throw new InputError("Query must be an object"); | ||
| } | ||
| filterPredicate = query; | ||
| } | ||
| if (filter !== void 0) { | ||
| const converted = convertFilterToPredicate(filter); | ||
| filterPredicate = filterPredicate ? { $all: [filterPredicate, converted] } : converted; | ||
| } | ||
| return await this.requestOptional( | ||
| await this.apiClient.queryEntityFacetsByPredicate( | ||
| { | ||
| body: { | ||
| facets, | ||
| ...filterPredicate && { | ||
| query: filterPredicate | ||
| } | ||
| } | ||
| }, | ||
| options | ||
| ) | ||
| ); | ||
| } | ||
| /** | ||
| * {@inheritdoc CatalogApi.addLocation} | ||
@@ -267,0 +389,0 @@ */ |
@@ -1,1 +0,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 // #region Private methods\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 // #endregion\n}\n"],"names":[],"mappings":";;;;;;;AAqEO,MAAM,aAAA,CAAoC;AAAA,EAC9B,SAAA;AAAA,EAEjB,YAAY,OAAA,EAGT;AACD,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,gBAAA,CAAiB,OAAO,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBAAA,CACJ,OAAA,EACA,OAAA,EACqC;AACrC,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,KAAK,SAAA,CAAU,uBAAA;AAAA,QACnB,EAAE,IAAA,EAAM,cAAA,CAAe,OAAA,CAAQ,SAAS,CAAA,EAAE;AAAA,QAC1C;AAAA;AACF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YAAA,CACJ,OAAA,EACA,OAAA,EAC+B;AAC/B,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,eAAA;AAAA,MACrB,MAAM,IAAA,CAAK,SAAA,CAAU,aAAa,OAAA,IAAW,IAAI,OAAO;AAAA,KAC1D;AACA,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,GAAA,CAAI,GAAA,CAAI,CAAA,IAAA,KAAQ,KAAK,IAAI;AAAA,KAClC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAA,CACJ,OAAA,EACA,OAAA,EACiC;AACjC,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,eAAA;AAAA,MACrB,MAAM,KAAK,SAAA,CAAU,mBAAA;AAAA,QACnB,EAAE,IAAA,EAAO,OAAA,IAAW,EAAC,EAA4C;AAAA,QACjE;AAAA;AACF,KACF;AACA,IAAA,OAAO;AAAA,MACL,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,YAAY,GAAA,CAAI,UAAA;AAAA,MAChB,UAAU,GAAA,CAAI;AAAA,KAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,eAAA,CACL,OAAA,EACA,OAAA,EAC2B;AAC3B,IAAA,IAAI,QAAA,GAAW,MAAM,IAAA,CAAK,cAAA;AAAA,MACxB,EAAE,KAAA,EAAO,8BAAA,EAAgC,GAAG,OAAA,EAAQ;AAAA,MACpD;AAAA,KACF;AACA,IAAA,IAAI,QAAA,CAAS,MAAM,MAAA,EAAQ;AACzB,MAAA,MAAM,QAAA,CAAS,KAAA;AAAA,IACjB;AAEA,IAAA,OAAO,QAAA,CAAS,SAAS,UAAA,EAAY;AACnC,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,cAAA;AAAA,QACpB,EAAE,MAAA,EAAQ,QAAA,CAAS,QAAA,CAAS,UAAA,EAAW;AAAA,QACvC;AAAA,OACF;AACA,MAAA,IAAI,QAAA,CAAS,MAAM,MAAA,EAAQ;AACzB,QAAA,MAAM,QAAA,CAAS,KAAA;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAA,CACJ,EAAA,EACA,OAAA,EAC+B;AAC/B,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,IAAA,CAAK,SAAA,CAAU,WAAA,CAAY,EAAE,MAAM,EAAE,EAAA,EAAG,EAAE,EAAG,OAAO;AAAA,KAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAA,CACJ,SAAA,EACA,OAAA,EAC+B;AAC/B,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,KAAK,SAAA,CAAU,mBAAA;AAAA,QACnB,EAAE,IAAA,EAAM,cAAA,CAAe,SAAS,CAAA,EAAE;AAAA,QAClC;AAAA;AACF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAA,CACJ,OAAA,EACA,OAAA,EAC8B;AAC9B,IAAA,MAAM;AAAA,MACJ,SAAS,EAAC;AAAA,MACV,SAAS,EAAC;AAAA,MACV,KAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACF,GAAI,WAAW,EAAC;AAChB,IAAA,MAAM,eAAe,EAAC;AACtB,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,KAAA,MAAW,SAAA,IAAa,CAAC,KAAK,CAAA,CAAE,MAAK,EAAG;AACtC,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,YAAA,CAAa,KAAK,CAAA,EAAG,SAAA,CAAU,KAAK,CAAA,CAAA,EAAI,SAAA,CAAU,KAAK,CAAA,CAAE,CAAA;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,eAAA;AAAA,MAC1B,MAAM,KAAK,SAAA,CAAU,WAAA;AAAA,QACnB;AAAA,UACE,KAAA,EAAO;AAAA,YACL,MAAA;AAAA,YACA,KAAA;AAAA,YACA,MAAA,EAAQ,IAAA,CAAK,cAAA,CAAe,MAAM,CAAA;AAAA,YAClC,MAAA;AAAA,YACA,KAAA;AAAA,YACA,KAAA,EAAO,QAAQ,YAAA,GAAe;AAAA;AAChC,SACF;AAAA,QACA;AAAA;AACF,KACF;AACA,IAAA,OAAO,EAAE,OAAO,QAAA,EAAS;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAA,CACJ,OAAA,EACA,OAAA,EACoC;AACpC,IAAA,MAAM,WAAA,GAAc,OAAO,IAAA,KAAmB;AAC5C,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,iBAAA;AAAA,QACpC;AAAA,UACE,MAAM,EAAE,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,QAAQ,MAAA,EAAO;AAAA,UACjD,OAAO,EAAE,MAAA,EAAQ,KAAK,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA;AAAE,SACvD;AAAA,QACA;AAAA,OACF;AACA,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,MACjD;AACA,MAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAGlC,MAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAK,KAAK,MAAS,CAAA;AAAA,IAC3C,CAAA;AAEA,IAAA,IAAI,MAAA;AACJ,IAAA,KAAA,MAAW,IAAA,IAAQ,mBAAA,CAAoB,OAAA,CAAQ,UAAU,CAAA,EAAG;AAC1D,MAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,IAAI,CAAA;AACvC,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,MAAA,GAAS,QAAA;AAAA,MACX,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,IAAA,CAAK,GAAG,QAAQ,CAAA;AAAA,MACzB;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,KAAA,EAAO,MAAA,IAAU,EAAC,EAAE;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAA,CACJ,OAAA,GAAgC,IAChC,OAAA,EACgC;AAChC,IAAA,MAAM,SAEF,EAAC;AAEL,IAAA,IAAI,6BAAA,CAA8B,OAAO,CAAA,EAAG;AAC1C,MAAA,MAAM;AAAA,QACJ,SAAS,EAAC;AAAA,QACV,MAAA;AAAA,QACA,KAAA;AAAA,QACA,MAAA;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACF,GAAI,OAAA;AACJ,MAAA,MAAA,CAAO,MAAA,GAAS,IAAA,CAAK,cAAA,CAAe,MAAM,CAAA;AAE1C,MAAA,IAAI,UAAU,MAAA,EAAW;AACvB,QAAA,MAAA,CAAO,KAAA,GAAQ,KAAA;AAAA,MACjB;AACA,MAAA,IAAI,WAAW,MAAA,EAAW;AACxB,QAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAAA,MAClB;AACA,MAAA,IAAI,gBAAgB,MAAA,EAAW;AAC7B,QAAA,MAAA,CAAO,cACL,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,GAAI,WAAA,GAAc,CAAC,WAAW,CAAA,EACvD,IAAI,CAAC,EAAE,OAAO,KAAA,EAAM,KAAM,GAAG,KAAK,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,CAAA;AAAA,MACjD;AACA,MAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,QAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAAA,MAClB;AAEA,MAAA,MAAM,4BAAA,GAA+B,cAAA,EAAgB,IAAA,EAAM,IAAA,EAAK;AAChE,MAAA,IAAI,4BAAA,EAA8B;AAChC,QAAA,MAAA,CAAO,kBAAA,GAAqB,4BAAA;AAAA,MAC9B;AACA,MAAA,IAAI,cAAA,EAAgB,QAAQ,MAAA,EAAQ;AAClC,QAAA,MAAA,CAAO,uBAAuB,cAAA,CAAe,MAAA;AAAA,MAC/C;AAAA,IACF,CAAA,MAAO;AACL,MAAA,MAAM,EAAE,MAAA,GAAS,EAAC,EAAG,KAAA,EAAO,QAAO,GAAI,OAAA;AAEvC,MAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,MAAA,IAAI,UAAU,MAAA,EAAW;AACvB,QAAA,MAAA,CAAO,KAAA,GAAQ,KAAA;AAAA,MACjB;AACA,MAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,QAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAAA,MAClB;AAAA,IACF;AAEA,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,MACV,MAAM,KAAK,SAAA,CAAU,kBAAA,CAAmB,EAAE,KAAA,EAAO,MAAA,IAAU,OAAO;AAAA,KACpE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAA,CACJ,SAAA,EACA,OAAA,EAC6B;AAC7B,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,MACV,MAAM,KAAK,SAAA,CAAU,eAAA;AAAA,QACnB;AAAA,UACE,IAAA,EAAM,eAAe,SAAS;AAAA,SAChC;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAA,CACJ,YAAA,EACA,OAAA,EAC6B;AAC7B,IAAA,MAAM,EAAE,IAAA,EAAM,SAAA,GAAY,SAAA,EAAW,MAAK,GAAI,YAAA;AAC9C,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,MACV,MAAM,KAAK,SAAA,CAAU,eAAA;AAAA,QACnB,EAAE,IAAA,EAAM,EAAE,IAAA,EAAM,SAAA,EAAW,MAAK,EAAE;AAAA,QAClC;AAAA;AACF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAA,CAAc,SAAA,EAAmB,OAAA,EAAiC;AACtE,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,aAAA;AAAA,MACpC,EAAE,IAAA,EAAM,EAAE,SAAA,EAAU,EAAE;AAAA,MACtB;AAAA,KACF;AAEA,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAA,CACJ,OAAA,EACA,OAAA,EACkC;AAClC,IAAA,MAAM,EAAE,MAAA,GAAS,EAAC,EAAG,QAAO,GAAI,OAAA;AAChC,IAAA,OAAO,MAAM,IAAA,CAAK,eAAA;AAAA,MAChB,MAAM,KAAK,SAAA,CAAU,eAAA;AAAA,QACnB;AAAA,UACE,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAQ,IAAA,CAAK,cAAA,CAAe,MAAM,CAAA;AAAE,SAC9D;AAAA,QACA;AAAA;AACF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAA,CACJ,OAAA,EACA,OAAA,EAC8B;AAC9B,IAAA,MAAM,EAAE,IAAA,GAAO,KAAA,EAAO,MAAA,EAAQ,QAAO,GAAI,OAAA;AAEzC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,cAAA;AAAA,MACpC;AAAA,QACE,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAO;AAAA,QACrB,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAA,GAAS,SAAS,MAAA;AAAU,OAC/C;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,IACjD;AAEA,IAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAU,QAAO,GAAI,MAAM,SAAS,IAAA,EAAK;AAE3D,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,MAAM,CAAA,CAAE,CAAA;AAAA,IACpD;AAEA,IAAA,OAAO;AAAA,MACL,QAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,gBAAA,CACJ,WAAA,EACA,OAAA,EAC+B;AAC/B,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,eAAA;AAAA,MACrB,MAAM,IAAA,CAAK,SAAA,CAAU,YAAA,CAAa,IAAI,OAAO;AAAA,KAC/C;AACA,IAAA,OAAO,GAAA,CACJ,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAI,CAAA,CACf,IAAA,CAAK,CAAA,CAAA,KAAK,WAAA,KAAgB,oBAAA,CAAqB,CAAC,CAAC,CAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBAAA,CACJ,EAAA,EACA,OAAA,EACe;AACf,IAAA,MAAM,IAAA,CAAK,cAAA;AAAA,MACT,MAAM,IAAA,CAAK,SAAA,CAAU,cAAA,CAAe,EAAE,MAAM,EAAE,EAAA,EAAG,EAAE,EAAG,OAAO;AAAA,KAC/D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAA,CACJ,GAAA,EACA,OAAA,EACe;AACf,IAAA,MAAM,IAAA,CAAK,cAAA;AAAA,MACT,MAAM,IAAA,CAAK,SAAA,CAAU,iBAAA,CAAkB,EAAE,MAAM,EAAE,GAAA,EAAI,EAAE,EAAG,OAAO;AAAA,KACnE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAA,CACJ,MAAA,EACA,WAAA,EACA,OAAA,EACiC;AACjC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,cAAA;AAAA,MACpC,EAAE,IAAA,EAAM,EAAE,MAAA,EAAQ,QAAA,EAAU,aAAY,EAAE;AAAA,MAC1C;AAAA,KACF;AAEA,IAAA,IAAI,SAAS,EAAA,EAAI;AACf,MAAA,OAAO;AAAA,QACL,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAEA,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,IACjD;AAEA,IAAA,MAAM,EAAE,MAAA,GAAS,IAAG,GAAK,MAAM,SAAS,IAAA,EAAK;AAE7C,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,KAAA;AAAA,MACP;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eAAA,CACJ,OAAA,EACA,OAAA,EACkC;AAClC,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,eAAA;AAAA,MACpC;AAAA,QACE,IAAA,EAAM;AAAA,OACR;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,IACjD;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,cAAA,CACL,OAAA,EACA,OAAA,EACyB;AACzB,IAAA,IAAI,MAAA,GAA6B,MAAA;AACjC,IAAA,MAAM,KAAA,GAAQ,SAAS,QAAA,IAAY,6BAAA;AACnC,IAAA,GAAG;AACD,MAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,aAAA;AAAA,QACrB,MAAA,GAAS,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,OAAM,GAAI,EAAE,GAAG,OAAA,EAAS,KAAA,EAAM;AAAA,QAC7D;AAAA,OACF;AAEA,MAAA,MAAM,GAAA,CAAI,KAAA;AAEV,MAAA,MAAA,GAAS,IAAI,QAAA,CAAS,UAAA;AAAA,IACxB,CAAA,QAAS,MAAA;AAAA,EACX;AAAA;AAAA,EAIA,MAAc,eAAe,QAAA,EAAmC;AAC9D,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,MAAc,gBAAmB,QAAA,EAAwC;AACvE,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,IACjD;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AAAA,EAEA,MAAc,gBAAgB,QAAA,EAA8C;AAC1E,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,QAAA,OAAO,MAAA;AAAA,MACT;AACA,MAAA,MAAM,MAAM,aAAA,CAAc,YAAA,CAAa,QAAQ,CAAA;AAAA,IACjD;AAEA,IAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B;AAAA,EAEQ,cAAA,CAAe,MAAA,GAA4B,EAAC,EAAG;AACrD,IAAA,MAAM,UAAoB,EAAC;AAK3B,IAAA,KAAA,MAAW,UAAA,IAAc,CAAC,MAAM,CAAA,CAAE,MAAK,EAAG;AACxC,MAAA,MAAM,cAAwB,EAAC;AAC/B,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAAG;AACrD,QAAA,KAAA,MAAW,CAAA,IAAK,CAAC,KAAK,CAAA,CAAE,MAAK,EAAG;AAC9B,UAAA,IAAI,MAAM,qBAAA,EAAuB;AAC/B,YAAA,WAAA,CAAY,KAAK,GAAG,CAAA;AAAA,UACtB,CAAA,MAAA,IAAW,OAAO,CAAA,KAAM,QAAA,EAAU;AAChC,YAAA,WAAA,CAAY,IAAA,CAAK,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,CAAC,CAAA,CAAE,CAAA;AAAA,UAChC;AAAA,QACF;AAAA,MACF;AAEA,MAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,QAAA,OAAA,CAAQ,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,MACpC;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAGF;;;;"} | ||
| {"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 { InputError, ResponseError } from '@backstage/errors';\nimport { FilterPredicate } from '@backstage/filter-predicates';\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 {\n convertFilterToPredicate,\n isQueryEntitiesInitialRequest,\n splitRefsIntoChunks,\n cursorContainsQuery,\n} from './utils';\nimport {\n DefaultApiClient,\n GetEntitiesByQuery,\n GetLocationsByQueryRequest,\n QueryEntitiesByPredicateRequest,\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 { filter, query } = request;\n\n // Only convert and merge if both filter and query are provided, or if\n // query alone is provided. When only filter is given, preserve the old\n // query-parameter behavior for backward compatibility.\n let filterPredicate: FilterPredicate | undefined;\n if (query !== undefined) {\n if (typeof query !== 'object' || query === null || Array.isArray(query)) {\n throw new InputError('Query must be an object');\n }\n filterPredicate = query;\n if (filter !== undefined) {\n const converted = convertFilterToPredicate(filter);\n filterPredicate = { $all: [filterPredicate, converted] };\n }\n }\n\n const getOneChunk = async (refs: string[]) => {\n const response = await this.apiClient.getEntitiesByRefs(\n {\n body: {\n entityRefs: refs,\n fields: request.fields,\n ...(filterPredicate && {\n query: filterPredicate as unknown as { [key: string]: any },\n }),\n },\n query: filterPredicate\n ? {}\n : { 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 isInitialRequest = isQueryEntitiesInitialRequest(request);\n\n // Route to POST endpoint if query predicate is provided (initial request)\n if (isInitialRequest && request.query) {\n return this.queryEntitiesByPredicate(request, options);\n }\n\n // Route to POST endpoint if cursor contains a query predicate (pagination)\n // TODO(freben): It's costly and non-opaque to have to introspect the cursor\n // like this. It should be refactored in the future to not need this.\n // Suggestion: make the GET and POST endpoints understand the same cursor\n // format, and pick which one to call ONLY based on whether the cursor size\n // risks hitting url length limits\n if (!isInitialRequest && cursorContainsQuery(request.cursor)) {\n return this.queryEntitiesByPredicate(request, options);\n }\n\n const params: Partial<GetEntitiesByQuery['query']> = {};\n\n if (isInitialRequest) {\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 * Query entities using predicate-based filters (POST endpoint).\n * @internal\n */\n private async queryEntitiesByPredicate(\n request: QueryEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse> {\n const body: QueryEntitiesByPredicateRequest = {};\n\n if (isQueryEntitiesInitialRequest(request)) {\n const {\n filter,\n query,\n limit,\n offset,\n orderFields,\n fullTextFilter,\n fields,\n } = request;\n\n let filterPredicate: FilterPredicate | undefined;\n if (query !== undefined) {\n if (\n typeof query !== 'object' ||\n query === null ||\n Array.isArray(query)\n ) {\n throw new InputError('Query must be an object');\n }\n filterPredicate = query;\n }\n if (filter !== undefined) {\n const converted = convertFilterToPredicate(filter);\n filterPredicate = filterPredicate\n ? { $all: [filterPredicate, converted] }\n : converted;\n }\n if (filterPredicate !== undefined) {\n body.query = filterPredicate as unknown as { [key: string]: any };\n }\n\n if (limit !== undefined) {\n body.limit = limit;\n }\n if (offset !== undefined) {\n body.offset = offset;\n }\n if (orderFields !== undefined) {\n body.orderBy = [orderFields].flat();\n }\n if (fullTextFilter) {\n body.fullTextFilter = fullTextFilter;\n }\n if (fields?.length) {\n body.fields = fields;\n }\n } else {\n body.cursor = request.cursor;\n if (request.limit !== undefined) {\n body.limit = request.limit;\n }\n if (request.fields?.length) {\n body.fields = request.fields;\n }\n }\n\n const res = await this.requestRequired(\n await this.apiClient.queryEntitiesByPredicate({ body }, options),\n );\n\n return {\n items: res.items,\n totalItems: res.totalItems,\n pageInfo: res.pageInfo,\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 = [], query, facets } = request;\n\n // Route to POST endpoint if query predicate is provided\n if (query) {\n return this.getEntityFacetsByPredicate(request, options);\n }\n\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 * Get entity facets using predicate-based filters (POST endpoint).\n * @internal\n */\n private async getEntityFacetsByPredicate(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter, query, facets } = request;\n\n let filterPredicate: FilterPredicate | undefined;\n if (query !== undefined) {\n if (typeof query !== 'object' || query === null || Array.isArray(query)) {\n throw new InputError('Query must be an object');\n }\n filterPredicate = query;\n }\n if (filter !== undefined) {\n const converted = convertFilterToPredicate(filter);\n filterPredicate = filterPredicate\n ? { $all: [filterPredicate, converted] }\n : converted;\n }\n\n return await this.requestOptional(\n await this.apiClient.queryEntityFacetsByPredicate(\n {\n body: {\n facets,\n ...(filterPredicate && {\n query: filterPredicate as unknown as { [key: string]: any },\n }),\n },\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 // #region Private methods\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 // #endregion\n}\n"],"names":[],"mappings":"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"} |
+56
-4
@@ -183,2 +183,12 @@ import { Entity, CompoundEntityRef } from '@backstage/catalog-model'; | ||
| filter?: EntityFilterQuery; | ||
| /** | ||
| * If given, return only entities that match the given predicate query. | ||
| * | ||
| * @remarks | ||
| * | ||
| * Supports operators like `$all`, `$any`, `$not`, `$exists`, `$in`, | ||
| * `$contains`, and `$hasPrefix`. When both `filter` and `query` are | ||
| * provided, they are combined with `$all`. | ||
| */ | ||
| query?: FilterPredicate; | ||
| } | ||
@@ -266,2 +276,12 @@ /** | ||
| /** | ||
| * If given, return only entities that match the given predicate query. | ||
| * | ||
| * @remarks | ||
| * | ||
| * Supports operators like `$all`, `$any`, `$not`, `$exists`, `$in`, | ||
| * `$contains`, and `$hasPrefix`. When both `filter` and `query` are | ||
| * provided, they are combined with `$all`. | ||
| */ | ||
| query?: FilterPredicate; | ||
| /** | ||
| * Dot separated paths for the facets to extract from each entity. | ||
@@ -382,5 +402,11 @@ * | ||
| * | ||
| * The properties filter, sortField, query and sortFieldOrder, are going | ||
| * The properties filter, query, sortField and sortFieldOrder, are going | ||
| * to be immutable for the entire lifecycle of the following requests. | ||
| * | ||
| * @remarks | ||
| * | ||
| * Either `filter` or `query` can be provided, or even both: | ||
| * - `filter`: Uses the traditional key-value filter syntax (GET endpoint) | ||
| * - `query`: Uses the predicate-based filter syntax with logical operators (POST endpoint) | ||
| * | ||
| * @public | ||
@@ -392,3 +418,24 @@ */ | ||
| offset?: number; | ||
| /** | ||
| * Traditional key-value based filter. | ||
| */ | ||
| filter?: EntityFilterQuery; | ||
| /** | ||
| * Predicate-based filter with operators for logical expressions (`$all`, | ||
| * `$any`, and `$not`) and matching (`$exists`, `$in`, `$hasPrefix`, and | ||
| * (partially) `$contains`). | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * { | ||
| * query: { | ||
| * $all: [ | ||
| * { kind: 'component' }, | ||
| * { 'spec.type': { $in: ['service', 'website'] } } | ||
| * ] | ||
| * } | ||
| * } | ||
| * ``` | ||
| */ | ||
| query?: FilterPredicate; | ||
| orderFields?: EntityOrderQuery; | ||
@@ -508,2 +555,3 @@ fullTextFilter?: { | ||
| * limit: 20, | ||
| * fields: ['metadata', 'kind'], | ||
| * fullTextFilter: { | ||
@@ -525,7 +573,11 @@ * term: 'A', | ||
| * const secondBatchResponse = await catalogClient | ||
| * .queryEntities({ cursor: response.nextCursor }); | ||
| * .queryEntities({ | ||
| * cursor: response.nextCursor, | ||
| * limit: 20, | ||
| * fields: ['metadata', 'kind'], | ||
| * }); | ||
| * ``` | ||
| * | ||
| * secondBatchResponse will contain the next batch of (maximum) 20 entities, | ||
| * together with a prevCursor property, useful to fetch the previous batch. | ||
| * `secondBatchResponse` will contain the next batch of (maximum) 20 entities, | ||
| * together with a `prevCursor` property, useful to fetch the previous batch. | ||
| * | ||
@@ -532,0 +584,0 @@ * @public |
@@ -57,5 +57,5 @@ 'use strict'; | ||
| * Get all entities matching a given filter. | ||
| * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it'll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name` | ||
| * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it\'ll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name` | ||
| * @param limit - Number of records to return in the response. | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\'s look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param offset - Number of records to skip in the query page. | ||
@@ -81,8 +81,8 @@ * @param after - Pointer to the previous page of results. | ||
| * Search for entities by a given query. | ||
| * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it'll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name` | ||
| * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it\'ll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name` | ||
| * @param limit - Number of records to return in the response. | ||
| * @param offset - Number of records to skip in the query page. | ||
| * @param orderField - By default the entities are returned ordered by their internal uid. You can customize the `orderField` query parameters to affect that ordering. For example, to return entities by their name: `/entities/by-query?orderField=metadata.name,asc` Each parameter can be followed by `asc` for ascending lexicographical order or `desc` for descending (reverse) lexicographical order. | ||
| * @param cursor - You may pass the `cursor` query parameters to perform cursor based pagination through the set of entities. The value of `cursor` will be returned in the response, under the `pageInfo` property: ```json \"pageInfo\": { \"nextCursor\": \"a-cursor\", \"prevCursor\": \"another-cursor\" } ``` If `nextCursor` exists, it can be used to retrieve the next batch of entities. Following the same approach, if `prevCursor` exists, it can be used to retrieve the previous batch of entities. - [`filter`](#filtering), for selecting only a subset of all entities - [`fields`](#field-selection), for selecting only parts of the full data structure of each entity - `limit` for limiting the number of entities returned (20 is the default) - [`orderField`](#ordering), for deciding the order of the entities - `fullTextFilter` **NOTE**: [`filter`, `orderField`, `fullTextFilter`] and `cursor` are mutually exclusive. This means that, it isn't possible to change any of [`filter`, `orderField`, `fullTextFilter`] when passing `cursor` as query parameters, as changing any of these properties will affect pagination. If any of `filter`, `orderField`, `fullTextFilter` is specified together with `cursor`, only the latter is taken into consideration. | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param cursor - You may pass the `cursor` query parameters to perform cursor based pagination through the set of entities. The value of `cursor` will be returned in the response, under the `pageInfo` property: ```json \"pageInfo\": { \"nextCursor\": \"a-cursor\", \"prevCursor\": \"another-cursor\" } ``` If `nextCursor` exists, it can be used to retrieve the next batch of entities. Following the same approach, if `prevCursor` exists, it can be used to retrieve the previous batch of entities. - [`filter`](#filtering), for selecting only a subset of all entities - [`fields`](#field-selection), for selecting only parts of the full data structure of each entity - `limit` for limiting the number of entities returned (20 is the default) - [`orderField`](#ordering), for deciding the order of the entities - `fullTextFilter` **NOTE**: [`filter`, `orderField`, `fullTextFilter`] and `cursor` are mutually exclusive. This means that, it isn\'t possible to change any of [`filter`, `orderField`, `fullTextFilter`] when passing `cursor` as query parameters, as changing any of these properties will affect pagination. If any of `filter`, `orderField`, `fullTextFilter` is specified together with `cursor`, only the latter is taken into consideration. | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\'s look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param fullTextFilterTerm - Text search term. | ||
@@ -107,3 +107,3 @@ * @param fullTextFilterFields - A comma separated list of fields to sort returned results by. | ||
| * Get a batch set of entities given an array of entityRefs. | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\'s look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param getEntitiesByRefsRequest - | ||
@@ -127,3 +127,3 @@ */ | ||
| /** | ||
| * Get an entity's ancestry by entity ref. | ||
| * Get an entity\'s ancestry by entity ref. | ||
| * @param kind - | ||
@@ -192,3 +192,3 @@ * @param namespace - | ||
| * @param facet - | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\'s look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| */ | ||
@@ -210,2 +210,36 @@ async getEntityFacets(request, options) { | ||
| /** | ||
| * Query entities using predicate-based filters. | ||
| * @param queryEntitiesByPredicateRequest - | ||
| */ | ||
| async queryEntitiesByPredicate(request, options) { | ||
| const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId); | ||
| const uriTemplate = `/entities/by-query`; | ||
| const uri = parser__namespace.parse(uriTemplate).expand({}); | ||
| return await this.fetchApi.fetch(`${baseUrl}${uri}`, { | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| ...options?.token && { Authorization: `Bearer ${options?.token}` } | ||
| }, | ||
| method: "POST", | ||
| body: JSON.stringify(request.body) | ||
| }); | ||
| } | ||
| /** | ||
| * Get entity facets using predicate-based filters. | ||
| * @param queryEntityFacetsByPredicateRequest - | ||
| */ | ||
| async queryEntityFacetsByPredicate(request, options) { | ||
| const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId); | ||
| const uriTemplate = `/entity-facets`; | ||
| const uri = parser__namespace.parse(uriTemplate).expand({}); | ||
| return await this.fetchApi.fetch(`${baseUrl}${uri}`, { | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| ...options?.token && { Authorization: `Bearer ${options?.token}` } | ||
| }, | ||
| method: "POST", | ||
| body: JSON.stringify(request.body) | ||
| }); | ||
| } | ||
| /** | ||
| * Refresh the entity related to entityRef. | ||
@@ -212,0 +246,0 @@ * @param refreshEntityRequest - |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"Api.client.cjs.js","sources":["../../../../../src/schema/openapi/generated/apis/Api.client.ts"],"sourcesContent":["/*\n * Copyright 2026 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// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *\n// ******************************************************************\n\nimport { DiscoveryApi } from '../types/discovery';\nimport { FetchApi } from '../types/fetch';\nimport crossFetch from 'cross-fetch';\nimport { pluginId } from '../pluginId';\nimport * as parser from 'uri-template';\nimport { EntitiesBatchResponse } from '../models/EntitiesBatchResponse.model';\nimport { EntitiesQueryResponse } from '../models/EntitiesQueryResponse.model';\nimport { Entity } from '../models/Entity.model';\nimport { EntityAncestryResponse } from '../models/EntityAncestryResponse.model';\nimport { EntityFacetsResponse } from '../models/EntityFacetsResponse.model';\nimport { GetEntitiesByRefsRequest } from '../models/GetEntitiesByRefsRequest.model';\nimport { RefreshEntityRequest } from '../models/RefreshEntityRequest.model';\nimport { ValidateEntityRequest } from '../models/ValidateEntityRequest.model';\nimport { AnalyzeLocationRequest } from '../models/AnalyzeLocationRequest.model';\nimport { AnalyzeLocationResponse } from '../models/AnalyzeLocationResponse.model';\nimport { CreateLocation201Response } from '../models/CreateLocation201Response.model';\nimport { CreateLocationRequest } from '../models/CreateLocationRequest.model';\nimport { GetLocations200ResponseInner } from '../models/GetLocations200ResponseInner.model';\nimport { GetLocationsByQueryRequest } from '../models/GetLocationsByQueryRequest.model';\nimport { Location } from '../models/Location.model';\nimport { LocationsQueryResponse } from '../models/LocationsQueryResponse.model';\n\n/**\n * Wraps the Response type to convey a type on the json call.\n *\n * @public\n */\nexport type TypedResponse<T> = Omit<Response, 'json'> & {\n json: () => Promise<T>;\n};\n\n/**\n * Options you can pass into a request for additional information.\n *\n * @public\n */\nexport interface RequestOptions {\n token?: string;\n}\n/**\n * @public\n */\nexport type DeleteEntityByUid = {\n path: {\n uid: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntities = {\n query: {\n fields?: Array<string>;\n limit?: number;\n filter?: Array<string>;\n offset?: number;\n after?: string;\n order?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntitiesByQuery = {\n query: {\n fields?: Array<string>;\n limit?: number;\n offset?: number;\n orderField?: Array<string>;\n cursor?: string;\n filter?: Array<string>;\n fullTextFilterTerm?: string;\n fullTextFilterFields?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntitiesByRefs = {\n body: GetEntitiesByRefsRequest;\n query: {\n filter?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntityAncestryByName = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityByName = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityByUid = {\n path: {\n uid: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityFacets = {\n query: {\n facet: Array<string>;\n filter?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type RefreshEntity = {\n body: RefreshEntityRequest;\n};\n/**\n * @public\n */\nexport type ValidateEntity = {\n body: ValidateEntityRequest;\n};\n/**\n * @public\n */\nexport type AnalyzeLocation = {\n body: AnalyzeLocationRequest;\n};\n/**\n * @public\n */\nexport type CreateLocation = {\n body: CreateLocationRequest;\n query: {\n dryRun?: string;\n };\n};\n/**\n * @public\n */\nexport type DeleteLocation = {\n path: {\n id: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocation = {\n path: {\n id: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocationByEntity = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocations = {};\n/**\n * @public\n */\nexport type GetLocationsByQuery = {\n body: GetLocationsByQueryRequest;\n};\n\n/**\n * @public\n */\nexport class DefaultApiClient {\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 * Delete a single entity by UID.\n * @param uid -\n */\n public async deleteEntityByUid(\n // @ts-ignore\n request: DeleteEntityByUid,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-uid/{uid}`;\n\n const uri = parser.parse(uriTemplate).expand({\n uid: request.path.uid,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'DELETE',\n });\n }\n\n /**\n * Get all entities matching a given filter.\n * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it'll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name`\n * @param limit - Number of records to return in the response.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param offset - Number of records to skip in the query page.\n * @param after - Pointer to the previous page of results.\n * @param order -\n */\n public async getEntities(\n // @ts-ignore\n request: GetEntities,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<Entity>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities{?fields,limit,filter*,offset,after,order*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Search for entities by a given query.\n * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it'll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name`\n * @param limit - Number of records to return in the response.\n * @param offset - Number of records to skip in the query page.\n * @param orderField - By default the entities are returned ordered by their internal uid. You can customize the `orderField` query parameters to affect that ordering. For example, to return entities by their name: `/entities/by-query?orderField=metadata.name,asc` Each parameter can be followed by `asc` for ascending lexicographical order or `desc` for descending (reverse) lexicographical order.\n * @param cursor - You may pass the `cursor` query parameters to perform cursor based pagination through the set of entities. The value of `cursor` will be returned in the response, under the `pageInfo` property: ```json \\"pageInfo\\": { \\"nextCursor\\": \\"a-cursor\\", \\"prevCursor\\": \\"another-cursor\\" } ``` If `nextCursor` exists, it can be used to retrieve the next batch of entities. Following the same approach, if `prevCursor` exists, it can be used to retrieve the previous batch of entities. - [`filter`](#filtering), for selecting only a subset of all entities - [`fields`](#field-selection), for selecting only parts of the full data structure of each entity - `limit` for limiting the number of entities returned (20 is the default) - [`orderField`](#ordering), for deciding the order of the entities - `fullTextFilter` **NOTE**: [`filter`, `orderField`, `fullTextFilter`] and `cursor` are mutually exclusive. This means that, it isn't possible to change any of [`filter`, `orderField`, `fullTextFilter`] when passing `cursor` as query parameters, as changing any of these properties will affect pagination. If any of `filter`, `orderField`, `fullTextFilter` is specified together with `cursor`, only the latter is taken into consideration.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param fullTextFilterTerm - Text search term.\n * @param fullTextFilterFields - A comma separated list of fields to sort returned results by.\n */\n public async getEntitiesByQuery(\n // @ts-ignore\n request: GetEntitiesByQuery,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-query{?fields,limit,offset,orderField*,cursor,filter*,fullTextFilterTerm,fullTextFilterFields}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a batch set of entities given an array of entityRefs.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param getEntitiesByRefsRequest -\n */\n public async getEntitiesByRefs(\n // @ts-ignore\n request: GetEntitiesByRefs,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesBatchResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-refs{?filter*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Get an entity's ancestry by entity ref.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getEntityAncestryByName(\n // @ts-ignore\n request: GetEntityAncestryByName,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityAncestryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-name/{kind}/{namespace}/{name}/ancestry`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get an entity by an entity ref.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getEntityByName(\n // @ts-ignore\n request: GetEntityByName,\n options?: RequestOptions,\n ): Promise<TypedResponse<Entity>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-name/{kind}/{namespace}/{name}`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a single entity by the UID.\n * @param uid -\n */\n public async getEntityByUid(\n // @ts-ignore\n request: GetEntityByUid,\n options?: RequestOptions,\n ): Promise<TypedResponse<Entity>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-uid/{uid}`;\n\n const uri = parser.parse(uriTemplate).expand({\n uid: request.path.uid,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get all entity facets that match the given filters.\n * @param facet -\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n */\n public async getEntityFacets(\n // @ts-ignore\n request: GetEntityFacets,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityFacetsResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entity-facets{?facet*,filter*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Refresh the entity related to entityRef.\n * @param refreshEntityRequest -\n */\n public async refreshEntity(\n // @ts-ignore\n request: RefreshEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/refresh`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Validate that a passed in entity has no errors in schema.\n * @param validateEntityRequest -\n */\n public async validateEntity(\n // @ts-ignore\n request: ValidateEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/validate-entity`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Validate a given location.\n * @param analyzeLocationRequest -\n */\n public async analyzeLocation(\n // @ts-ignore\n request: AnalyzeLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<AnalyzeLocationResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/analyze-location`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Create a location for a given target.\n * @param createLocationRequest -\n * @param dryRun -\n */\n public async createLocation(\n // @ts-ignore\n request: CreateLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<CreateLocation201Response>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations{?dryRun}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Delete a location by id.\n * @param id -\n */\n public async deleteLocation(\n // @ts-ignore\n request: DeleteLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/{id}`;\n\n const uri = parser.parse(uriTemplate).expand({\n id: request.path.id,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'DELETE',\n });\n }\n\n /**\n * Get a location by id.\n * @param id -\n */\n public async getLocation(\n // @ts-ignore\n request: GetLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<Location>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/{id}`;\n\n const uri = parser.parse(uriTemplate).expand({\n id: request.path.id,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a location for entity.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getLocationByEntity(\n // @ts-ignore\n request: GetLocationByEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<Location>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/by-entity/{kind}/{namespace}/{name}`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get all locations\n */\n public async getLocations(\n // @ts-ignore\n request: GetLocations,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<GetLocations200ResponseInner>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Query for locations\n * @param getLocationsByQueryRequest -\n */\n public async getLocationsByQuery(\n // @ts-ignore\n request: GetLocationsByQuery,\n options?: RequestOptions,\n ): Promise<TypedResponse<LocationsQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/by-query`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n}\n"],"names":["crossFetch","pluginId","parser"],"mappings":"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"} | ||
| {"version":3,"file":"Api.client.cjs.js","sources":["../../../../../src/schema/openapi/generated/apis/Api.client.ts"],"sourcesContent":["/*\n * Copyright 2026 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// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *\n// ******************************************************************\n\nimport { DiscoveryApi } from '../types/discovery';\nimport { FetchApi } from '../types/fetch';\nimport crossFetch from 'cross-fetch';\nimport { pluginId } from '../pluginId';\nimport * as parser from 'uri-template';\nimport { EntitiesBatchResponse } from '../models/EntitiesBatchResponse.model';\nimport { EntitiesQueryResponse } from '../models/EntitiesQueryResponse.model';\nimport { Entity } from '../models/Entity.model';\nimport { EntityAncestryResponse } from '../models/EntityAncestryResponse.model';\nimport { EntityFacetsResponse } from '../models/EntityFacetsResponse.model';\nimport { GetEntitiesByRefsRequest } from '../models/GetEntitiesByRefsRequest.model';\nimport { QueryEntitiesByPredicateRequest } from '../models/QueryEntitiesByPredicateRequest.model';\nimport { QueryEntityFacetsByPredicateRequest } from '../models/QueryEntityFacetsByPredicateRequest.model';\nimport { RefreshEntityRequest } from '../models/RefreshEntityRequest.model';\nimport { ValidateEntityRequest } from '../models/ValidateEntityRequest.model';\nimport { AnalyzeLocationRequest } from '../models/AnalyzeLocationRequest.model';\nimport { AnalyzeLocationResponse } from '../models/AnalyzeLocationResponse.model';\nimport { CreateLocation201Response } from '../models/CreateLocation201Response.model';\nimport { CreateLocationRequest } from '../models/CreateLocationRequest.model';\nimport { GetLocations200ResponseInner } from '../models/GetLocations200ResponseInner.model';\nimport { GetLocationsByQueryRequest } from '../models/GetLocationsByQueryRequest.model';\nimport { Location } from '../models/Location.model';\nimport { LocationsQueryResponse } from '../models/LocationsQueryResponse.model';\n\n/**\n * Wraps the Response type to convey a type on the json call.\n *\n * @public\n */\nexport type TypedResponse<T> = Omit<Response, 'json'> & {\n json: () => Promise<T>;\n};\n\n/**\n * Options you can pass into a request for additional information.\n *\n * @public\n */\nexport interface RequestOptions {\n token?: string;\n}\n/**\n * @public\n */\nexport type DeleteEntityByUid = {\n path: {\n uid: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntities = {\n query: {\n fields?: Array<string>;\n limit?: number;\n filter?: Array<string>;\n offset?: number;\n after?: string;\n order?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntitiesByQuery = {\n query: {\n fields?: Array<string>;\n limit?: number;\n offset?: number;\n orderField?: Array<string>;\n cursor?: string;\n filter?: Array<string>;\n fullTextFilterTerm?: string;\n fullTextFilterFields?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntitiesByRefs = {\n body: GetEntitiesByRefsRequest;\n query: {\n filter?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntityAncestryByName = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityByName = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityByUid = {\n path: {\n uid: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityFacets = {\n query: {\n facet: Array<string>;\n filter?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type QueryEntitiesByPredicate = {\n body: QueryEntitiesByPredicateRequest;\n};\n/**\n * @public\n */\nexport type QueryEntityFacetsByPredicate = {\n body: QueryEntityFacetsByPredicateRequest;\n};\n/**\n * @public\n */\nexport type RefreshEntity = {\n body: RefreshEntityRequest;\n};\n/**\n * @public\n */\nexport type ValidateEntity = {\n body: ValidateEntityRequest;\n};\n/**\n * @public\n */\nexport type AnalyzeLocation = {\n body: AnalyzeLocationRequest;\n};\n/**\n * @public\n */\nexport type CreateLocation = {\n body: CreateLocationRequest;\n query: {\n dryRun?: string;\n };\n};\n/**\n * @public\n */\nexport type DeleteLocation = {\n path: {\n id: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocation = {\n path: {\n id: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocationByEntity = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocations = {};\n/**\n * @public\n */\nexport type GetLocationsByQuery = {\n body: GetLocationsByQueryRequest;\n};\n\n/**\n * @public\n */\nexport class DefaultApiClient {\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 * Delete a single entity by UID.\n * @param uid -\n */\n public async deleteEntityByUid(\n // @ts-ignore\n request: DeleteEntityByUid,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-uid/{uid}`;\n\n const uri = parser.parse(uriTemplate).expand({\n uid: request.path.uid,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'DELETE',\n });\n }\n\n /**\n * Get all entities matching a given filter.\n * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it\\'ll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name`\n * @param limit - Number of records to return in the response.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\\'s look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param offset - Number of records to skip in the query page.\n * @param after - Pointer to the previous page of results.\n * @param order -\n */\n public async getEntities(\n // @ts-ignore\n request: GetEntities,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<Entity>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities{?fields,limit,filter*,offset,after,order*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Search for entities by a given query.\n * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it\\'ll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name`\n * @param limit - Number of records to return in the response.\n * @param offset - Number of records to skip in the query page.\n * @param orderField - By default the entities are returned ordered by their internal uid. You can customize the `orderField` query parameters to affect that ordering. For example, to return entities by their name: `/entities/by-query?orderField=metadata.name,asc` Each parameter can be followed by `asc` for ascending lexicographical order or `desc` for descending (reverse) lexicographical order.\n * @param cursor - You may pass the `cursor` query parameters to perform cursor based pagination through the set of entities. The value of `cursor` will be returned in the response, under the `pageInfo` property: ```json \\"pageInfo\\": { \\"nextCursor\\": \\"a-cursor\\", \\"prevCursor\\": \\"another-cursor\\" } ``` If `nextCursor` exists, it can be used to retrieve the next batch of entities. Following the same approach, if `prevCursor` exists, it can be used to retrieve the previous batch of entities. - [`filter`](#filtering), for selecting only a subset of all entities - [`fields`](#field-selection), for selecting only parts of the full data structure of each entity - `limit` for limiting the number of entities returned (20 is the default) - [`orderField`](#ordering), for deciding the order of the entities - `fullTextFilter` **NOTE**: [`filter`, `orderField`, `fullTextFilter`] and `cursor` are mutually exclusive. This means that, it isn\\'t possible to change any of [`filter`, `orderField`, `fullTextFilter`] when passing `cursor` as query parameters, as changing any of these properties will affect pagination. If any of `filter`, `orderField`, `fullTextFilter` is specified together with `cursor`, only the latter is taken into consideration.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\\'s look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param fullTextFilterTerm - Text search term.\n * @param fullTextFilterFields - A comma separated list of fields to sort returned results by.\n */\n public async getEntitiesByQuery(\n // @ts-ignore\n request: GetEntitiesByQuery,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-query{?fields,limit,offset,orderField*,cursor,filter*,fullTextFilterTerm,fullTextFilterFields}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a batch set of entities given an array of entityRefs.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\\'s look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param getEntitiesByRefsRequest -\n */\n public async getEntitiesByRefs(\n // @ts-ignore\n request: GetEntitiesByRefs,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesBatchResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-refs{?filter*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Get an entity\\'s ancestry by entity ref.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getEntityAncestryByName(\n // @ts-ignore\n request: GetEntityAncestryByName,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityAncestryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-name/{kind}/{namespace}/{name}/ancestry`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get an entity by an entity ref.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getEntityByName(\n // @ts-ignore\n request: GetEntityByName,\n options?: RequestOptions,\n ): Promise<TypedResponse<Entity>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-name/{kind}/{namespace}/{name}`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a single entity by the UID.\n * @param uid -\n */\n public async getEntityByUid(\n // @ts-ignore\n request: GetEntityByUid,\n options?: RequestOptions,\n ): Promise<TypedResponse<Entity>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-uid/{uid}`;\n\n const uri = parser.parse(uriTemplate).expand({\n uid: request.path.uid,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get all entity facets that match the given filters.\n * @param facet -\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\\'s look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n */\n public async getEntityFacets(\n // @ts-ignore\n request: GetEntityFacets,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityFacetsResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entity-facets{?facet*,filter*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Query entities using predicate-based filters.\n * @param queryEntitiesByPredicateRequest -\n */\n public async queryEntitiesByPredicate(\n // @ts-ignore\n request: QueryEntitiesByPredicate,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-query`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Get entity facets using predicate-based filters.\n * @param queryEntityFacetsByPredicateRequest -\n */\n public async queryEntityFacetsByPredicate(\n // @ts-ignore\n request: QueryEntityFacetsByPredicate,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityFacetsResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entity-facets`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Refresh the entity related to entityRef.\n * @param refreshEntityRequest -\n */\n public async refreshEntity(\n // @ts-ignore\n request: RefreshEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/refresh`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Validate that a passed in entity has no errors in schema.\n * @param validateEntityRequest -\n */\n public async validateEntity(\n // @ts-ignore\n request: ValidateEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/validate-entity`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Validate a given location.\n * @param analyzeLocationRequest -\n */\n public async analyzeLocation(\n // @ts-ignore\n request: AnalyzeLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<AnalyzeLocationResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/analyze-location`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Create a location for a given target.\n * @param createLocationRequest -\n * @param dryRun -\n */\n public async createLocation(\n // @ts-ignore\n request: CreateLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<CreateLocation201Response>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations{?dryRun}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Delete a location by id.\n * @param id -\n */\n public async deleteLocation(\n // @ts-ignore\n request: DeleteLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/{id}`;\n\n const uri = parser.parse(uriTemplate).expand({\n id: request.path.id,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'DELETE',\n });\n }\n\n /**\n * Get a location by id.\n * @param id -\n */\n public async getLocation(\n // @ts-ignore\n request: GetLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<Location>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/{id}`;\n\n const uri = parser.parse(uriTemplate).expand({\n id: request.path.id,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a location for entity.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getLocationByEntity(\n // @ts-ignore\n request: GetLocationByEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<Location>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/by-entity/{kind}/{namespace}/{name}`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get all locations\n */\n public async getLocations(\n // @ts-ignore\n request: GetLocations,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<GetLocations200ResponseInner>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Query for locations\n * @param getLocationsByQueryRequest -\n */\n public async getLocationsByQuery(\n // @ts-ignore\n request: GetLocationsByQuery,\n options?: RequestOptions,\n ): Promise<TypedResponse<LocationsQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/by-query`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n}\n"],"names":["crossFetch","pluginId","parser"],"mappings":"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"} |
@@ -32,5 +32,5 @@ import crossFetch from 'cross-fetch'; | ||
| * Get all entities matching a given filter. | ||
| * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it'll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name` | ||
| * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it\'ll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name` | ||
| * @param limit - Number of records to return in the response. | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\'s look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param offset - Number of records to skip in the query page. | ||
@@ -56,8 +56,8 @@ * @param after - Pointer to the previous page of results. | ||
| * Search for entities by a given query. | ||
| * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it'll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name` | ||
| * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it\'ll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name` | ||
| * @param limit - Number of records to return in the response. | ||
| * @param offset - Number of records to skip in the query page. | ||
| * @param orderField - By default the entities are returned ordered by their internal uid. You can customize the `orderField` query parameters to affect that ordering. For example, to return entities by their name: `/entities/by-query?orderField=metadata.name,asc` Each parameter can be followed by `asc` for ascending lexicographical order or `desc` for descending (reverse) lexicographical order. | ||
| * @param cursor - You may pass the `cursor` query parameters to perform cursor based pagination through the set of entities. The value of `cursor` will be returned in the response, under the `pageInfo` property: ```json \"pageInfo\": { \"nextCursor\": \"a-cursor\", \"prevCursor\": \"another-cursor\" } ``` If `nextCursor` exists, it can be used to retrieve the next batch of entities. Following the same approach, if `prevCursor` exists, it can be used to retrieve the previous batch of entities. - [`filter`](#filtering), for selecting only a subset of all entities - [`fields`](#field-selection), for selecting only parts of the full data structure of each entity - `limit` for limiting the number of entities returned (20 is the default) - [`orderField`](#ordering), for deciding the order of the entities - `fullTextFilter` **NOTE**: [`filter`, `orderField`, `fullTextFilter`] and `cursor` are mutually exclusive. This means that, it isn't possible to change any of [`filter`, `orderField`, `fullTextFilter`] when passing `cursor` as query parameters, as changing any of these properties will affect pagination. If any of `filter`, `orderField`, `fullTextFilter` is specified together with `cursor`, only the latter is taken into consideration. | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param cursor - You may pass the `cursor` query parameters to perform cursor based pagination through the set of entities. The value of `cursor` will be returned in the response, under the `pageInfo` property: ```json \"pageInfo\": { \"nextCursor\": \"a-cursor\", \"prevCursor\": \"another-cursor\" } ``` If `nextCursor` exists, it can be used to retrieve the next batch of entities. Following the same approach, if `prevCursor` exists, it can be used to retrieve the previous batch of entities. - [`filter`](#filtering), for selecting only a subset of all entities - [`fields`](#field-selection), for selecting only parts of the full data structure of each entity - `limit` for limiting the number of entities returned (20 is the default) - [`orderField`](#ordering), for deciding the order of the entities - `fullTextFilter` **NOTE**: [`filter`, `orderField`, `fullTextFilter`] and `cursor` are mutually exclusive. This means that, it isn\'t possible to change any of [`filter`, `orderField`, `fullTextFilter`] when passing `cursor` as query parameters, as changing any of these properties will affect pagination. If any of `filter`, `orderField`, `fullTextFilter` is specified together with `cursor`, only the latter is taken into consideration. | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\'s look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param fullTextFilterTerm - Text search term. | ||
@@ -82,3 +82,3 @@ * @param fullTextFilterFields - A comma separated list of fields to sort returned results by. | ||
| * Get a batch set of entities given an array of entityRefs. | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\'s look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param getEntitiesByRefsRequest - | ||
@@ -102,3 +102,3 @@ */ | ||
| /** | ||
| * Get an entity's ancestry by entity ref. | ||
| * Get an entity\'s ancestry by entity ref. | ||
| * @param kind - | ||
@@ -167,3 +167,3 @@ * @param namespace - | ||
| * @param facet - | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\'s look at a simplified example to illustrate the concept: ```json { \"a\": { \"b\": [\"c\", { \"d\": 1 }], \"e\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops` | ||
| */ | ||
@@ -185,2 +185,36 @@ async getEntityFacets(request, options) { | ||
| /** | ||
| * Query entities using predicate-based filters. | ||
| * @param queryEntitiesByPredicateRequest - | ||
| */ | ||
| async queryEntitiesByPredicate(request, options) { | ||
| const baseUrl = await this.discoveryApi.getBaseUrl(pluginId); | ||
| const uriTemplate = `/entities/by-query`; | ||
| const uri = parser.parse(uriTemplate).expand({}); | ||
| return await this.fetchApi.fetch(`${baseUrl}${uri}`, { | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| ...options?.token && { Authorization: `Bearer ${options?.token}` } | ||
| }, | ||
| method: "POST", | ||
| body: JSON.stringify(request.body) | ||
| }); | ||
| } | ||
| /** | ||
| * Get entity facets using predicate-based filters. | ||
| * @param queryEntityFacetsByPredicateRequest - | ||
| */ | ||
| async queryEntityFacetsByPredicate(request, options) { | ||
| const baseUrl = await this.discoveryApi.getBaseUrl(pluginId); | ||
| const uriTemplate = `/entity-facets`; | ||
| const uri = parser.parse(uriTemplate).expand({}); | ||
| return await this.fetchApi.fetch(`${baseUrl}${uri}`, { | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| ...options?.token && { Authorization: `Bearer ${options?.token}` } | ||
| }, | ||
| method: "POST", | ||
| body: JSON.stringify(request.body) | ||
| }); | ||
| } | ||
| /** | ||
| * Refresh the entity related to entityRef. | ||
@@ -187,0 +221,0 @@ * @param refreshEntityRequest - |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"Api.client.esm.js","sources":["../../../../../src/schema/openapi/generated/apis/Api.client.ts"],"sourcesContent":["/*\n * Copyright 2026 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// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *\n// ******************************************************************\n\nimport { DiscoveryApi } from '../types/discovery';\nimport { FetchApi } from '../types/fetch';\nimport crossFetch from 'cross-fetch';\nimport { pluginId } from '../pluginId';\nimport * as parser from 'uri-template';\nimport { EntitiesBatchResponse } from '../models/EntitiesBatchResponse.model';\nimport { EntitiesQueryResponse } from '../models/EntitiesQueryResponse.model';\nimport { Entity } from '../models/Entity.model';\nimport { EntityAncestryResponse } from '../models/EntityAncestryResponse.model';\nimport { EntityFacetsResponse } from '../models/EntityFacetsResponse.model';\nimport { GetEntitiesByRefsRequest } from '../models/GetEntitiesByRefsRequest.model';\nimport { RefreshEntityRequest } from '../models/RefreshEntityRequest.model';\nimport { ValidateEntityRequest } from '../models/ValidateEntityRequest.model';\nimport { AnalyzeLocationRequest } from '../models/AnalyzeLocationRequest.model';\nimport { AnalyzeLocationResponse } from '../models/AnalyzeLocationResponse.model';\nimport { CreateLocation201Response } from '../models/CreateLocation201Response.model';\nimport { CreateLocationRequest } from '../models/CreateLocationRequest.model';\nimport { GetLocations200ResponseInner } from '../models/GetLocations200ResponseInner.model';\nimport { GetLocationsByQueryRequest } from '../models/GetLocationsByQueryRequest.model';\nimport { Location } from '../models/Location.model';\nimport { LocationsQueryResponse } from '../models/LocationsQueryResponse.model';\n\n/**\n * Wraps the Response type to convey a type on the json call.\n *\n * @public\n */\nexport type TypedResponse<T> = Omit<Response, 'json'> & {\n json: () => Promise<T>;\n};\n\n/**\n * Options you can pass into a request for additional information.\n *\n * @public\n */\nexport interface RequestOptions {\n token?: string;\n}\n/**\n * @public\n */\nexport type DeleteEntityByUid = {\n path: {\n uid: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntities = {\n query: {\n fields?: Array<string>;\n limit?: number;\n filter?: Array<string>;\n offset?: number;\n after?: string;\n order?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntitiesByQuery = {\n query: {\n fields?: Array<string>;\n limit?: number;\n offset?: number;\n orderField?: Array<string>;\n cursor?: string;\n filter?: Array<string>;\n fullTextFilterTerm?: string;\n fullTextFilterFields?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntitiesByRefs = {\n body: GetEntitiesByRefsRequest;\n query: {\n filter?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntityAncestryByName = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityByName = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityByUid = {\n path: {\n uid: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityFacets = {\n query: {\n facet: Array<string>;\n filter?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type RefreshEntity = {\n body: RefreshEntityRequest;\n};\n/**\n * @public\n */\nexport type ValidateEntity = {\n body: ValidateEntityRequest;\n};\n/**\n * @public\n */\nexport type AnalyzeLocation = {\n body: AnalyzeLocationRequest;\n};\n/**\n * @public\n */\nexport type CreateLocation = {\n body: CreateLocationRequest;\n query: {\n dryRun?: string;\n };\n};\n/**\n * @public\n */\nexport type DeleteLocation = {\n path: {\n id: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocation = {\n path: {\n id: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocationByEntity = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocations = {};\n/**\n * @public\n */\nexport type GetLocationsByQuery = {\n body: GetLocationsByQueryRequest;\n};\n\n/**\n * @public\n */\nexport class DefaultApiClient {\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 * Delete a single entity by UID.\n * @param uid -\n */\n public async deleteEntityByUid(\n // @ts-ignore\n request: DeleteEntityByUid,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-uid/{uid}`;\n\n const uri = parser.parse(uriTemplate).expand({\n uid: request.path.uid,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'DELETE',\n });\n }\n\n /**\n * Get all entities matching a given filter.\n * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it'll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name`\n * @param limit - Number of records to return in the response.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param offset - Number of records to skip in the query page.\n * @param after - Pointer to the previous page of results.\n * @param order -\n */\n public async getEntities(\n // @ts-ignore\n request: GetEntities,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<Entity>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities{?fields,limit,filter*,offset,after,order*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Search for entities by a given query.\n * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it'll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name`\n * @param limit - Number of records to return in the response.\n * @param offset - Number of records to skip in the query page.\n * @param orderField - By default the entities are returned ordered by their internal uid. You can customize the `orderField` query parameters to affect that ordering. For example, to return entities by their name: `/entities/by-query?orderField=metadata.name,asc` Each parameter can be followed by `asc` for ascending lexicographical order or `desc` for descending (reverse) lexicographical order.\n * @param cursor - You may pass the `cursor` query parameters to perform cursor based pagination through the set of entities. The value of `cursor` will be returned in the response, under the `pageInfo` property: ```json \\"pageInfo\\": { \\"nextCursor\\": \\"a-cursor\\", \\"prevCursor\\": \\"another-cursor\\" } ``` If `nextCursor` exists, it can be used to retrieve the next batch of entities. Following the same approach, if `prevCursor` exists, it can be used to retrieve the previous batch of entities. - [`filter`](#filtering), for selecting only a subset of all entities - [`fields`](#field-selection), for selecting only parts of the full data structure of each entity - `limit` for limiting the number of entities returned (20 is the default) - [`orderField`](#ordering), for deciding the order of the entities - `fullTextFilter` **NOTE**: [`filter`, `orderField`, `fullTextFilter`] and `cursor` are mutually exclusive. This means that, it isn't possible to change any of [`filter`, `orderField`, `fullTextFilter`] when passing `cursor` as query parameters, as changing any of these properties will affect pagination. If any of `filter`, `orderField`, `fullTextFilter` is specified together with `cursor`, only the latter is taken into consideration.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param fullTextFilterTerm - Text search term.\n * @param fullTextFilterFields - A comma separated list of fields to sort returned results by.\n */\n public async getEntitiesByQuery(\n // @ts-ignore\n request: GetEntitiesByQuery,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-query{?fields,limit,offset,orderField*,cursor,filter*,fullTextFilterTerm,fullTextFilterFields}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a batch set of entities given an array of entityRefs.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param getEntitiesByRefsRequest -\n */\n public async getEntitiesByRefs(\n // @ts-ignore\n request: GetEntitiesByRefs,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesBatchResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-refs{?filter*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Get an entity's ancestry by entity ref.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getEntityAncestryByName(\n // @ts-ignore\n request: GetEntityAncestryByName,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityAncestryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-name/{kind}/{namespace}/{name}/ancestry`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get an entity by an entity ref.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getEntityByName(\n // @ts-ignore\n request: GetEntityByName,\n options?: RequestOptions,\n ): Promise<TypedResponse<Entity>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-name/{kind}/{namespace}/{name}`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a single entity by the UID.\n * @param uid -\n */\n public async getEntityByUid(\n // @ts-ignore\n request: GetEntityByUid,\n options?: RequestOptions,\n ): Promise<TypedResponse<Entity>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-uid/{uid}`;\n\n const uri = parser.parse(uriTemplate).expand({\n uid: request.path.uid,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get all entity facets that match the given filters.\n * @param facet -\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let's look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n */\n public async getEntityFacets(\n // @ts-ignore\n request: GetEntityFacets,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityFacetsResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entity-facets{?facet*,filter*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Refresh the entity related to entityRef.\n * @param refreshEntityRequest -\n */\n public async refreshEntity(\n // @ts-ignore\n request: RefreshEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/refresh`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Validate that a passed in entity has no errors in schema.\n * @param validateEntityRequest -\n */\n public async validateEntity(\n // @ts-ignore\n request: ValidateEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/validate-entity`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Validate a given location.\n * @param analyzeLocationRequest -\n */\n public async analyzeLocation(\n // @ts-ignore\n request: AnalyzeLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<AnalyzeLocationResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/analyze-location`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Create a location for a given target.\n * @param createLocationRequest -\n * @param dryRun -\n */\n public async createLocation(\n // @ts-ignore\n request: CreateLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<CreateLocation201Response>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations{?dryRun}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Delete a location by id.\n * @param id -\n */\n public async deleteLocation(\n // @ts-ignore\n request: DeleteLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/{id}`;\n\n const uri = parser.parse(uriTemplate).expand({\n id: request.path.id,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'DELETE',\n });\n }\n\n /**\n * Get a location by id.\n * @param id -\n */\n public async getLocation(\n // @ts-ignore\n request: GetLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<Location>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/{id}`;\n\n const uri = parser.parse(uriTemplate).expand({\n id: request.path.id,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a location for entity.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getLocationByEntity(\n // @ts-ignore\n request: GetLocationByEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<Location>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/by-entity/{kind}/{namespace}/{name}`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get all locations\n */\n public async getLocations(\n // @ts-ignore\n request: GetLocations,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<GetLocations200ResponseInner>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Query for locations\n * @param getLocationsByQueryRequest -\n */\n public async getLocationsByQuery(\n // @ts-ignore\n request: GetLocationsByQuery,\n options?: RequestOptions,\n ): Promise<TypedResponse<LocationsQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/by-query`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n}\n"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"Api.client.esm.js","sources":["../../../../../src/schema/openapi/generated/apis/Api.client.ts"],"sourcesContent":["/*\n * Copyright 2026 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// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *\n// ******************************************************************\n\nimport { DiscoveryApi } from '../types/discovery';\nimport { FetchApi } from '../types/fetch';\nimport crossFetch from 'cross-fetch';\nimport { pluginId } from '../pluginId';\nimport * as parser from 'uri-template';\nimport { EntitiesBatchResponse } from '../models/EntitiesBatchResponse.model';\nimport { EntitiesQueryResponse } from '../models/EntitiesQueryResponse.model';\nimport { Entity } from '../models/Entity.model';\nimport { EntityAncestryResponse } from '../models/EntityAncestryResponse.model';\nimport { EntityFacetsResponse } from '../models/EntityFacetsResponse.model';\nimport { GetEntitiesByRefsRequest } from '../models/GetEntitiesByRefsRequest.model';\nimport { QueryEntitiesByPredicateRequest } from '../models/QueryEntitiesByPredicateRequest.model';\nimport { QueryEntityFacetsByPredicateRequest } from '../models/QueryEntityFacetsByPredicateRequest.model';\nimport { RefreshEntityRequest } from '../models/RefreshEntityRequest.model';\nimport { ValidateEntityRequest } from '../models/ValidateEntityRequest.model';\nimport { AnalyzeLocationRequest } from '../models/AnalyzeLocationRequest.model';\nimport { AnalyzeLocationResponse } from '../models/AnalyzeLocationResponse.model';\nimport { CreateLocation201Response } from '../models/CreateLocation201Response.model';\nimport { CreateLocationRequest } from '../models/CreateLocationRequest.model';\nimport { GetLocations200ResponseInner } from '../models/GetLocations200ResponseInner.model';\nimport { GetLocationsByQueryRequest } from '../models/GetLocationsByQueryRequest.model';\nimport { Location } from '../models/Location.model';\nimport { LocationsQueryResponse } from '../models/LocationsQueryResponse.model';\n\n/**\n * Wraps the Response type to convey a type on the json call.\n *\n * @public\n */\nexport type TypedResponse<T> = Omit<Response, 'json'> & {\n json: () => Promise<T>;\n};\n\n/**\n * Options you can pass into a request for additional information.\n *\n * @public\n */\nexport interface RequestOptions {\n token?: string;\n}\n/**\n * @public\n */\nexport type DeleteEntityByUid = {\n path: {\n uid: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntities = {\n query: {\n fields?: Array<string>;\n limit?: number;\n filter?: Array<string>;\n offset?: number;\n after?: string;\n order?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntitiesByQuery = {\n query: {\n fields?: Array<string>;\n limit?: number;\n offset?: number;\n orderField?: Array<string>;\n cursor?: string;\n filter?: Array<string>;\n fullTextFilterTerm?: string;\n fullTextFilterFields?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntitiesByRefs = {\n body: GetEntitiesByRefsRequest;\n query: {\n filter?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type GetEntityAncestryByName = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityByName = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityByUid = {\n path: {\n uid: string;\n };\n};\n/**\n * @public\n */\nexport type GetEntityFacets = {\n query: {\n facet: Array<string>;\n filter?: Array<string>;\n };\n};\n/**\n * @public\n */\nexport type QueryEntitiesByPredicate = {\n body: QueryEntitiesByPredicateRequest;\n};\n/**\n * @public\n */\nexport type QueryEntityFacetsByPredicate = {\n body: QueryEntityFacetsByPredicateRequest;\n};\n/**\n * @public\n */\nexport type RefreshEntity = {\n body: RefreshEntityRequest;\n};\n/**\n * @public\n */\nexport type ValidateEntity = {\n body: ValidateEntityRequest;\n};\n/**\n * @public\n */\nexport type AnalyzeLocation = {\n body: AnalyzeLocationRequest;\n};\n/**\n * @public\n */\nexport type CreateLocation = {\n body: CreateLocationRequest;\n query: {\n dryRun?: string;\n };\n};\n/**\n * @public\n */\nexport type DeleteLocation = {\n path: {\n id: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocation = {\n path: {\n id: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocationByEntity = {\n path: {\n kind: string;\n namespace: string;\n name: string;\n };\n};\n/**\n * @public\n */\nexport type GetLocations = {};\n/**\n * @public\n */\nexport type GetLocationsByQuery = {\n body: GetLocationsByQueryRequest;\n};\n\n/**\n * @public\n */\nexport class DefaultApiClient {\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 * Delete a single entity by UID.\n * @param uid -\n */\n public async deleteEntityByUid(\n // @ts-ignore\n request: DeleteEntityByUid,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-uid/{uid}`;\n\n const uri = parser.parse(uriTemplate).expand({\n uid: request.path.uid,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'DELETE',\n });\n }\n\n /**\n * Get all entities matching a given filter.\n * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it\\'ll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name`\n * @param limit - Number of records to return in the response.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\\'s look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param offset - Number of records to skip in the query page.\n * @param after - Pointer to the previous page of results.\n * @param order -\n */\n public async getEntities(\n // @ts-ignore\n request: GetEntities,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<Entity>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities{?fields,limit,filter*,offset,after,order*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Search for entities by a given query.\n * @param fields - By default the full entities are returned, but you can pass in a `fields` query parameter which selects what parts of the entity data to retain. This makes the response smaller and faster to transfer, and may allow the catalog to perform more efficient queries. The query parameter value is a comma separated list of simplified JSON paths like above. Each path corresponds to the key of either a value, or of a subtree root that you want to keep in the output. The rest is pruned away. For example, specifying `?fields=metadata.name,metadata.annotations,spec` retains only the `name` and `annotations` fields of the `metadata` of each entity (it\\'ll be an object with at most two keys), keeps the entire `spec` unchanged, and cuts out all other roots such as `relations`. Some more real world usable examples: - Return only enough data to form the full ref of each entity: `/entities/by-query?fields=kind,metadata.namespace,metadata.name`\n * @param limit - Number of records to return in the response.\n * @param offset - Number of records to skip in the query page.\n * @param orderField - By default the entities are returned ordered by their internal uid. You can customize the `orderField` query parameters to affect that ordering. For example, to return entities by their name: `/entities/by-query?orderField=metadata.name,asc` Each parameter can be followed by `asc` for ascending lexicographical order or `desc` for descending (reverse) lexicographical order.\n * @param cursor - You may pass the `cursor` query parameters to perform cursor based pagination through the set of entities. The value of `cursor` will be returned in the response, under the `pageInfo` property: ```json \\"pageInfo\\": { \\"nextCursor\\": \\"a-cursor\\", \\"prevCursor\\": \\"another-cursor\\" } ``` If `nextCursor` exists, it can be used to retrieve the next batch of entities. Following the same approach, if `prevCursor` exists, it can be used to retrieve the previous batch of entities. - [`filter`](#filtering), for selecting only a subset of all entities - [`fields`](#field-selection), for selecting only parts of the full data structure of each entity - `limit` for limiting the number of entities returned (20 is the default) - [`orderField`](#ordering), for deciding the order of the entities - `fullTextFilter` **NOTE**: [`filter`, `orderField`, `fullTextFilter`] and `cursor` are mutually exclusive. This means that, it isn\\'t possible to change any of [`filter`, `orderField`, `fullTextFilter`] when passing `cursor` as query parameters, as changing any of these properties will affect pagination. If any of `filter`, `orderField`, `fullTextFilter` is specified together with `cursor`, only the latter is taken into consideration.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\\'s look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param fullTextFilterTerm - Text search term.\n * @param fullTextFilterFields - A comma separated list of fields to sort returned results by.\n */\n public async getEntitiesByQuery(\n // @ts-ignore\n request: GetEntitiesByQuery,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-query{?fields,limit,offset,orderField*,cursor,filter*,fullTextFilterTerm,fullTextFilterFields}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a batch set of entities given an array of entityRefs.\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\\'s look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n * @param getEntitiesByRefsRequest -\n */\n public async getEntitiesByRefs(\n // @ts-ignore\n request: GetEntitiesByRefs,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesBatchResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-refs{?filter*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Get an entity\\'s ancestry by entity ref.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getEntityAncestryByName(\n // @ts-ignore\n request: GetEntityAncestryByName,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityAncestryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-name/{kind}/{namespace}/{name}/ancestry`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get an entity by an entity ref.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getEntityByName(\n // @ts-ignore\n request: GetEntityByName,\n options?: RequestOptions,\n ): Promise<TypedResponse<Entity>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-name/{kind}/{namespace}/{name}`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a single entity by the UID.\n * @param uid -\n */\n public async getEntityByUid(\n // @ts-ignore\n request: GetEntityByUid,\n options?: RequestOptions,\n ): Promise<TypedResponse<Entity>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-uid/{uid}`;\n\n const uri = parser.parse(uriTemplate).expand({\n uid: request.path.uid,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get all entity facets that match the given filters.\n * @param facet -\n * @param filter - You can pass in one or more filter sets that get matched against each entity. Each filter set is a number of conditions that all have to match for the condition to be true (conditions effectively have an AND between them). At least one filter set has to be true for the entity to be part of the result set (filter sets effectively have an OR between them). Example: ```text /entities/by-query?filter=kind=user,metadata.namespace=default&filter=kind=group,spec.type Return entities that match Filter set 1: Condition 1: kind = user AND Condition 2: metadata.namespace = default OR Filter set 2: Condition 1: kind = group AND Condition 2: spec.type exists ``` Each condition is either on the form `<key>`, or on the form `<key>=<value>`. The first form asserts on the existence of a certain key (with any value), and the second asserts that the key exists and has a certain value. All checks are always case _insensitive_. In all cases, the key is a simplified JSON path in a given piece of entity data. Each part of the path is a key of an object, and the traversal also descends through arrays. There are two special forms: - Array items that are simple value types (such as strings) match on a key-value pair where the key is the item as a string, and the value is the string `true` - Relations can be matched on a `relations.<type>=<targetRef>` form Let\\'s look at a simplified example to illustrate the concept: ```json { \\"a\\": { \\"b\\": [\\"c\\", { \\"d\\": 1 }], \\"e\\": 7 } } ``` This would match any one of the following conditions: - `a` - `a.b` - `a.b.c` - `a.b.c=true` - `a.b.d` - `a.b.d=1` - `a.e` - `a.e=7` Some more real world usable examples: - Return all orphaned entities: `/entities/by-query?filter=metadata.annotations.backstage.io/orphan=true` - Return all users and groups: `/entities/by-query?filter=kind=user&filter=kind=group` - Return all service components: `/entities/by-query?filter=kind=component,spec.type=service` - Return all entities with the `java` tag: `/entities/by-query?filter=metadata.tags.java` - Return all users who are members of the `ops` group (note that the full [reference](references.md) of the group is used): `/entities/by-query?filter=kind=user,relations.memberof=group:default/ops`\n */\n public async getEntityFacets(\n // @ts-ignore\n request: GetEntityFacets,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityFacetsResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entity-facets{?facet*,filter*}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Query entities using predicate-based filters.\n * @param queryEntitiesByPredicateRequest -\n */\n public async queryEntitiesByPredicate(\n // @ts-ignore\n request: QueryEntitiesByPredicate,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntitiesQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entities/by-query`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Get entity facets using predicate-based filters.\n * @param queryEntityFacetsByPredicateRequest -\n */\n public async queryEntityFacetsByPredicate(\n // @ts-ignore\n request: QueryEntityFacetsByPredicate,\n options?: RequestOptions,\n ): Promise<TypedResponse<EntityFacetsResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/entity-facets`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Refresh the entity related to entityRef.\n * @param refreshEntityRequest -\n */\n public async refreshEntity(\n // @ts-ignore\n request: RefreshEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/refresh`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Validate that a passed in entity has no errors in schema.\n * @param validateEntityRequest -\n */\n public async validateEntity(\n // @ts-ignore\n request: ValidateEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/validate-entity`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Validate a given location.\n * @param analyzeLocationRequest -\n */\n public async analyzeLocation(\n // @ts-ignore\n request: AnalyzeLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<AnalyzeLocationResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/analyze-location`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Create a location for a given target.\n * @param createLocationRequest -\n * @param dryRun -\n */\n public async createLocation(\n // @ts-ignore\n request: CreateLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<CreateLocation201Response>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations{?dryRun}`;\n\n const uri = parser.parse(uriTemplate).expand({\n ...request.query,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n\n /**\n * Delete a location by id.\n * @param id -\n */\n public async deleteLocation(\n // @ts-ignore\n request: DeleteLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<void>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/{id}`;\n\n const uri = parser.parse(uriTemplate).expand({\n id: request.path.id,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'DELETE',\n });\n }\n\n /**\n * Get a location by id.\n * @param id -\n */\n public async getLocation(\n // @ts-ignore\n request: GetLocation,\n options?: RequestOptions,\n ): Promise<TypedResponse<Location>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/{id}`;\n\n const uri = parser.parse(uriTemplate).expand({\n id: request.path.id,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get a location for entity.\n * @param kind -\n * @param namespace -\n * @param name -\n */\n public async getLocationByEntity(\n // @ts-ignore\n request: GetLocationByEntity,\n options?: RequestOptions,\n ): Promise<TypedResponse<Location>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/by-entity/{kind}/{namespace}/{name}`;\n\n const uri = parser.parse(uriTemplate).expand({\n kind: request.path.kind,\n namespace: request.path.namespace,\n name: request.path.name,\n });\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Get all locations\n */\n public async getLocations(\n // @ts-ignore\n request: GetLocations,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<GetLocations200ResponseInner>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n\n /**\n * Query for locations\n * @param getLocationsByQueryRequest -\n */\n public async getLocationsByQuery(\n // @ts-ignore\n request: GetLocationsByQuery,\n options?: RequestOptions,\n ): Promise<TypedResponse<LocationsQueryResponse>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/locations/by-query`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify(request.body),\n });\n }\n}\n"],"names":[],"mappings":"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"} |
@@ -6,2 +6,3 @@ 'use strict'; | ||
| var errors = require('@backstage/errors'); | ||
| var filterPredicates = require('@backstage/filter-predicates'); | ||
| var lodash = require('lodash'); | ||
@@ -232,4 +233,7 @@ var buildEntitySearch$1 = require('../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.cjs.js'); | ||
| const filter = createFilter(request.filter); | ||
| const queryFilter = request.query ? filterPredicates.filterPredicateToFilterFunction(request.query) : void 0; | ||
| const refMap = this.#createEntityRefMap(); | ||
| const items = request.entityRefs.map((ref) => refMap.get(ref)).map((e) => e && filter(e) ? e : void 0); | ||
| const items = request.entityRefs.map((ref) => refMap.get(ref)).map( | ||
| (e) => e && filter(e) && (!queryFilter || queryFilter(e)) ? e : void 0 | ||
| ); | ||
| return { | ||
@@ -241,2 +245,3 @@ items: request.fields ? items.map((e) => e ? applyFieldsFilter(e, request.fields) : void 0) : items | ||
| let filter; | ||
| let query; | ||
| let orderFields; | ||
@@ -254,2 +259,3 @@ let fullTextFilter; | ||
| filter = deserializeFilter(c.filter); | ||
| query = c.query; | ||
| orderFields = c.orderFields; | ||
@@ -261,2 +267,3 @@ fullTextFilter = c.fullTextFilter; | ||
| filter = request?.filter; | ||
| query = request?.query; | ||
| orderFields = request?.orderFields; | ||
@@ -268,2 +275,5 @@ fullTextFilter = request?.fullTextFilter; | ||
| let items = this.#entities.filter(createFilter(filter)); | ||
| if (query) { | ||
| items = items.filter(filterPredicates.filterPredicateToFilterFunction(query)); | ||
| } | ||
| if (fullTextFilter) { | ||
@@ -291,2 +301,3 @@ const orderFieldsList = orderFields ? [orderFields].flat() : []; | ||
| filter: serializeFilter(filter), | ||
| query, | ||
| orderFields, | ||
@@ -340,3 +351,8 @@ fullTextFilter, | ||
| const filter = createFilter(request.filter); | ||
| const filteredEntities = this.#entities.filter(filter); | ||
| let filteredEntities = this.#entities.filter(filter); | ||
| if (request.query) { | ||
| filteredEntities = filteredEntities.filter( | ||
| filterPredicates.filterPredicateToFilterFunction(request.query) | ||
| ); | ||
| } | ||
| const facets = Object.fromEntries( | ||
@@ -343,0 +359,0 @@ request.facets.map((facet) => { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"InMemoryCatalogClient.cjs.js","sources":["../../src/testUtils/InMemoryCatalogClient.ts"],"sourcesContent":["/*\n * Copyright 2024 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 AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n EntityFilterQuery,\n EntityOrderQuery,\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 '@backstage/catalog-client';\nimport {\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n InputError,\n NotFoundError,\n NotImplementedError,\n} from '@backstage/errors';\nimport lodash from 'lodash';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { traverse } from '../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport { DEFAULT_STREAM_ENTITIES_LIMIT } from '../constants.ts';\n\nfunction makeCursor(data: Record<string, unknown>): string {\n return btoa(JSON.stringify(data));\n}\n\nfunction parseCursor(cursor: string): Record<string, unknown> {\n return JSON.parse(atob(cursor));\n}\n\n// CATALOG_FILTER_EXISTS is a Symbol that doesn't survive JSON serialization,\n// so we swap it with a sentinel string when encoding/decoding cursors.\nconst FILTER_EXISTS_SENTINEL = '\\0CATALOG_FILTER_EXISTS';\n\nfunction serializeFilterValue(v: unknown): unknown {\n if (v === CATALOG_FILTER_EXISTS) return FILTER_EXISTS_SENTINEL;\n if (Array.isArray(v)) {\n return v.map(x =>\n x === CATALOG_FILTER_EXISTS ? FILTER_EXISTS_SENTINEL : x,\n );\n }\n return v;\n}\n\nfunction deserializeFilterValue(v: unknown): unknown {\n if (v === FILTER_EXISTS_SENTINEL) return CATALOG_FILTER_EXISTS;\n if (Array.isArray(v)) {\n return v.map(x =>\n x === FILTER_EXISTS_SENTINEL ? CATALOG_FILTER_EXISTS : x,\n );\n }\n return v;\n}\n\nfunction serializeFilter(filter?: EntityFilterQuery): any[] | undefined {\n if (!filter) return undefined;\n return [filter]\n .flat()\n .map(f =>\n Object.fromEntries(\n Object.entries(f).map(([k, v]) => [k, serializeFilterValue(v)]),\n ),\n );\n}\n\nfunction deserializeFilter(filter?: any[]): EntityFilterQuery | undefined {\n if (!filter) return undefined;\n return filter.map(\n f =>\n Object.fromEntries(\n Object.entries(f).map(([k, v]: [string, any]) => [\n k,\n deserializeFilterValue(v),\n ]),\n ) as Record<string, string | symbol | (string | symbol)[]>,\n );\n}\n\nfunction buildEntitySearch(entity: Entity) {\n const rows = traverse(entity);\n\n if (entity.metadata?.name) {\n rows.push({\n key: 'metadata.name',\n value: entity.metadata.name.toLocaleLowerCase('en-US'),\n });\n }\n if (entity.metadata?.namespace) {\n rows.push({\n key: 'metadata.namespace',\n value: entity.metadata.namespace.toLocaleLowerCase('en-US'),\n });\n }\n if (entity.metadata?.uid) {\n rows.push({\n key: 'metadata.uid',\n value: entity.metadata.uid.toLocaleLowerCase('en-US'),\n });\n }\n\n if (!entity.metadata.namespace) {\n rows.push({ key: 'metadata.namespace', value: DEFAULT_NAMESPACE });\n }\n\n // Visit relations\n for (const relation of entity.relations ?? []) {\n rows.push({\n key: `relations.${relation.type.toLocaleLowerCase('en-US')}`,\n value: relation.targetRef.toLocaleLowerCase('en-US'),\n });\n }\n\n return rows;\n}\n\nfunction createFilter(\n filterOrFilters?: EntityFilterQuery,\n): (entity: Entity) => boolean {\n if (!filterOrFilters) {\n return () => true;\n }\n\n const filters = [filterOrFilters].flat();\n\n return entity => {\n const rows = buildEntitySearch(entity);\n\n return filters.some(filter => {\n for (const [key, expectedValue] of Object.entries(filter)) {\n const searchValues = rows\n .filter(row => row.key === key.toLocaleLowerCase('en-US'))\n .map(row => row.value?.toString().toLocaleLowerCase('en-US'));\n\n if (searchValues.length === 0) {\n return false;\n }\n if (expectedValue === CATALOG_FILTER_EXISTS) {\n continue;\n }\n if (Array.isArray(expectedValue)) {\n return expectedValue.some(value =>\n searchValues?.includes(String(value).toLocaleLowerCase('en-US')),\n );\n }\n if (\n !searchValues?.includes(\n String(expectedValue).toLocaleLowerCase('en-US'),\n )\n ) {\n return false;\n }\n }\n return true;\n });\n };\n}\n\n// Resolves a dot-separated field path against an entity, handling keys that\n// themselves contain dots (e.g. annotation keys like \"backstage.io/orphan\").\n// This matches the backend's parseEntityTransformParams implementation.\nfunction getPathArrayAndValue(\n input: Entity,\n field: string,\n): [string[], unknown] {\n return field.split('.').reduce(\n ([pathArray, inputSubset], pathPart, index, fieldParts) => {\n if (lodash.hasIn(inputSubset, pathPart)) {\n return [pathArray.concat(pathPart), (inputSubset as any)[pathPart]];\n } else if (fieldParts[index + 1] !== undefined) {\n fieldParts[index + 1] = `${pathPart}.${fieldParts[index + 1]}`;\n return [pathArray, inputSubset];\n }\n return [pathArray, undefined];\n },\n [[] as string[], input as unknown],\n );\n}\n\nfunction applyFieldsFilter(entity: Entity, fields?: string[]): Entity {\n if (!fields?.length) {\n return entity;\n }\n const output: Record<string, any> = {};\n for (const field of fields) {\n const [pathArray, value] = getPathArrayAndValue(entity, field);\n if (value !== undefined) {\n lodash.set(output, pathArray, value);\n }\n }\n return output as Entity;\n}\n\nfunction applyOrdering(entities: Entity[], order?: EntityOrderQuery): Entity[] {\n if (!order) {\n return entities;\n }\n const orders = [order].flat();\n if (orders.length === 0) {\n return entities;\n }\n\n const searchMap = new Map<Entity, Array<{ key: string; value: unknown }>>();\n for (const entity of entities) {\n searchMap.set(entity, buildEntitySearch(entity));\n }\n\n return [...entities].sort((a, b) => {\n const aRows = searchMap.get(a)!;\n const bRows = searchMap.get(b)!;\n\n for (const { field, order: dir } of orders) {\n const key = field.toLocaleLowerCase('en-US');\n const aRow = aRows.find(r => r.key.toLocaleLowerCase('en-US') === key);\n const bRow = bRows.find(r => r.key.toLocaleLowerCase('en-US') === key);\n const aValue =\n aRow?.value !== null && aRow?.value !== undefined\n ? String(aRow.value).toLocaleLowerCase('en-US')\n : null;\n const bValue =\n bRow?.value !== null && bRow?.value !== undefined\n ? String(bRow.value).toLocaleLowerCase('en-US')\n : null;\n\n if (aValue === null && bValue === null) continue;\n if (aValue === null) return 1;\n if (bValue === null) return -1;\n\n if (aValue < bValue) return dir === 'asc' ? -1 : 1;\n if (aValue > bValue) return dir === 'asc' ? 1 : -1;\n }\n\n // Stable tie-breaker by entity ref, matching backend behavior\n const aRef = stringifyEntityRef(a);\n const bRef = stringifyEntityRef(b);\n if (aRef < bRef) return -1;\n if (aRef > bRef) return 1;\n return 0;\n });\n}\n\nfunction applyFullTextFilter(\n entities: Entity[],\n fullTextFilter?: { term: string; fields?: string[] },\n): Entity[] {\n if (!fullTextFilter?.term?.trim()) {\n return entities;\n }\n const term = fullTextFilter.term.trim().toLocaleLowerCase('en-US');\n const fields = fullTextFilter.fields?.map(f => f.toLocaleLowerCase('en-US'));\n\n return entities.filter(entity => {\n const rows = buildEntitySearch(entity);\n return rows.some(row => {\n if (\n fields?.length &&\n !fields.includes(row.key.toLocaleLowerCase('en-US'))\n ) {\n return false;\n }\n if (row.value === null || row.value === undefined) return false;\n const value = String(row.value).toLocaleLowerCase('en-US');\n return value.includes(term);\n });\n });\n}\n\n/**\n * Implements a fake catalog client that stores entities in memory.\n * Supports filtering, ordering, pagination, full-text search, and field\n * projection for entity query methods. Location and validation methods\n * throw {@link @backstage/errors#NotImplementedError}.\n *\n * @public\n */\nexport class InMemoryCatalogClient implements CatalogApi {\n #entities: Entity[];\n\n constructor(options?: { entities?: Entity[] }) {\n this.#entities = options?.entities?.slice() ?? [];\n }\n\n async getEntities(\n request?: GetEntitiesRequest,\n ): Promise<GetEntitiesResponse> {\n const filter = createFilter(request?.filter);\n let items = this.#entities.filter(filter);\n items = applyOrdering(items, request?.order);\n\n let offset = request?.offset ?? 0;\n let limit = request?.limit;\n\n if (request?.after) {\n try {\n const cursor = parseCursor(request.after);\n if (cursor.offset !== undefined) offset = cursor.offset as number;\n if (cursor.limit !== undefined) limit = cursor.limit as number;\n } catch {\n throw new InputError('Invalid cursor');\n }\n }\n\n if (offset > 0) {\n items = items.slice(offset);\n }\n if (limit !== undefined) {\n items = items.slice(0, limit);\n }\n\n return {\n items: request?.fields\n ? items.map(e => applyFieldsFilter(e, request.fields))\n : items,\n };\n }\n\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n ): Promise<GetEntitiesByRefsResponse> {\n const filter = createFilter(request.filter);\n const refMap = this.#createEntityRefMap();\n const items = request.entityRefs\n .map(ref => refMap.get(ref))\n .map(e => (e && filter(e) ? e : undefined));\n return {\n items: request.fields\n ? items.map(e => (e ? applyFieldsFilter(e, request.fields) : undefined))\n : items,\n };\n }\n\n async queryEntities(\n request?: QueryEntitiesRequest,\n ): Promise<QueryEntitiesResponse> {\n // Decode query parameters from cursor or from the request directly\n let filter: EntityFilterQuery | undefined;\n let orderFields: EntityOrderQuery | undefined;\n let fullTextFilter: { term: string; fields?: string[] } | undefined;\n let offset: number;\n let limit: number | undefined;\n\n if (request && 'cursor' in request) {\n let c: Record<string, unknown>;\n try {\n c = parseCursor(request.cursor);\n } catch {\n throw new InputError('Invalid cursor');\n }\n filter = deserializeFilter(c.filter as any[]);\n orderFields = c.orderFields as EntityOrderQuery | undefined;\n fullTextFilter = c.fullTextFilter as typeof fullTextFilter;\n offset = c.offset as number;\n limit = request.limit;\n } else {\n filter = request?.filter;\n orderFields = request?.orderFields;\n fullTextFilter = request?.fullTextFilter;\n offset = request?.offset ?? 0;\n limit = request?.limit;\n }\n\n // Apply filter\n let items = this.#entities.filter(createFilter(filter));\n\n // Apply full-text filter, defaulting to the sort field or metadata.uid\n if (fullTextFilter) {\n const orderFieldsList = orderFields ? [orderFields].flat() : [];\n items = applyFullTextFilter(items, {\n ...fullTextFilter,\n fields: fullTextFilter.fields ?? [\n orderFieldsList[0]?.field ?? 'metadata.uid',\n ],\n });\n }\n\n items = applyOrdering(items, orderFields);\n\n const totalItems = items.length;\n\n // No pagination requested, return all items\n if (limit === undefined && offset === 0) {\n return {\n items: request?.fields\n ? items.map(e => applyFieldsFilter(e, request?.fields))\n : items,\n pageInfo: {},\n totalItems,\n };\n }\n\n const effectiveLimit = limit ?? totalItems;\n const pageItems = items.slice(offset, offset + effectiveLimit);\n\n const cursorBase = {\n filter: serializeFilter(filter),\n orderFields,\n fullTextFilter,\n totalItems,\n };\n const pageInfo: QueryEntitiesResponse['pageInfo'] = {};\n if (offset + effectiveLimit < totalItems) {\n pageInfo.nextCursor = makeCursor({\n ...cursorBase,\n offset: offset + effectiveLimit,\n });\n }\n if (offset > 0) {\n pageInfo.prevCursor = makeCursor({\n ...cursorBase,\n offset: Math.max(0, offset - effectiveLimit),\n });\n }\n\n return {\n items: request?.fields\n ? pageItems.map(e => applyFieldsFilter(e, request?.fields))\n : pageItems,\n totalItems,\n pageInfo,\n };\n }\n\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n ): Promise<GetEntityAncestorsResponse> {\n const entity = this.#createEntityRefMap().get(request.entityRef);\n if (!entity) {\n throw new NotFoundError(`Entity with ref ${request.entityRef} not found`);\n }\n return {\n items: [{ entity, parentEntityRefs: [] }],\n rootEntityRef: request.entityRef,\n };\n }\n\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n ): Promise<Entity | undefined> {\n return this.#createEntityRefMap().get(\n stringifyEntityRef(parseEntityRef(entityRef)),\n );\n }\n\n async removeEntityByUid(uid: string): Promise<void> {\n const index = this.#entities.findIndex(e => e.metadata.uid === uid);\n if (index !== -1) {\n this.#entities.splice(index, 1);\n }\n }\n\n async refreshEntity(_entityRef: string): Promise<void> {}\n\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n ): Promise<GetEntityFacetsResponse> {\n const filter = createFilter(request.filter);\n const filteredEntities = this.#entities.filter(filter);\n const facets = Object.fromEntries(\n request.facets.map(facet => {\n const facetValues = new Map<string, number>();\n for (const entity of filteredEntities) {\n const rows = buildEntitySearch(entity);\n // Use a Set to count each distinct value once per entity,\n // matching the backend's count(DISTINCT entity_id) behavior\n const uniqueValues = new Set(\n rows\n .filter(\n row =>\n row.key.toLocaleLowerCase('en-US') ===\n facet.toLocaleLowerCase('en-US'),\n )\n .map(row => row.value)\n .filter(v => v !== null && v !== undefined)\n .map(v => String(v)),\n );\n for (const value of uniqueValues) {\n facetValues.set(value, (facetValues.get(value) ?? 0) + 1);\n }\n }\n const counts = Array.from(facetValues.entries()).map(\n ([value, count]) => ({ value, count }),\n );\n return [facet, counts];\n }),\n );\n return {\n facets,\n };\n }\n\n async getLocations(_request?: {}): Promise<GetLocationsResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async queryLocations(\n _request?: QueryLocationsRequest,\n ): Promise<QueryLocationsResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async *streamLocations(\n _request?: QueryLocationsInitialRequest,\n ): AsyncIterable<Location[]> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationById(_id: string): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationByRef(_locationRef: string): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async addLocation(\n _location: AddLocationRequest,\n ): Promise<AddLocationResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async removeLocationById(_id: string): Promise<void> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationByEntity(\n _entityRef: string | CompoundEntityRef,\n ): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async validateEntity(\n _entity: Entity,\n _locationRef: string,\n ): Promise<ValidateEntityResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async analyzeLocation(\n _location: AnalyzeLocationRequest,\n ): Promise<AnalyzeLocationResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async *streamEntities(\n request?: StreamEntitiesRequest,\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, limit, cursor } : { ...request, limit },\n );\n\n yield res.items;\n\n cursor = res.pageInfo.nextCursor;\n } while (cursor);\n }\n\n #createEntityRefMap() {\n return new Map(this.#entities.map(e => [stringifyEntityRef(e), e]));\n }\n}\n"],"names":["CATALOG_FILTER_EXISTS","traverse","DEFAULT_NAMESPACE","lodash","stringifyEntityRef","InputError","NotFoundError","parseEntityRef","NotImplementedError","DEFAULT_STREAM_ENTITIES_LIMIT"],"mappings":";;;;;;;;;;;;;AA8DA,SAAS,WAAW,IAAA,EAAuC;AACzD,EAAA,OAAO,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,IAAI,CAAC,CAAA;AAClC;AAEA,SAAS,YAAY,MAAA,EAAyC;AAC5D,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAM,CAAC,CAAA;AAChC;AAIA,MAAM,sBAAA,GAAyB,yBAAA;AAE/B,SAAS,qBAAqB,CAAA,EAAqB;AACjD,EAAA,IAAI,CAAA,KAAMA,qCAAuB,OAAO,sBAAA;AACxC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AACpB,IAAA,OAAO,CAAA,CAAE,GAAA;AAAA,MAAI,CAAA,CAAA,KACX,CAAA,KAAMA,mCAAA,GAAwB,sBAAA,GAAyB;AAAA,KACzD;AAAA,EACF;AACA,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,uBAAuB,CAAA,EAAqB;AACnD,EAAA,IAAI,CAAA,KAAM,wBAAwB,OAAOA,mCAAA;AACzC,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AACpB,IAAA,OAAO,CAAA,CAAE,GAAA;AAAA,MAAI,CAAA,CAAA,KACX,CAAA,KAAM,sBAAA,GAAyBA,mCAAA,GAAwB;AAAA,KACzD;AAAA,EACF;AACA,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,gBAAgB,MAAA,EAA+C;AACtE,EAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AACpB,EAAA,OAAO,CAAC,MAAM,CAAA,CACX,IAAA,EAAK,CACL,GAAA;AAAA,IAAI,OACH,MAAA,CAAO,WAAA;AAAA,MACL,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,CAAE,IAAI,CAAC,CAAC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA,EAAG,oBAAA,CAAqB,CAAC,CAAC,CAAC;AAAA;AAChE,GACF;AACJ;AAEA,SAAS,kBAAkB,MAAA,EAA+C;AACxE,EAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AACpB,EAAA,OAAO,MAAA,CAAO,GAAA;AAAA,IACZ,OACE,MAAA,CAAO,WAAA;AAAA,MACL,MAAA,CAAO,QAAQ,CAAC,CAAA,CAAE,IAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAqB;AAAA,QAC/C,CAAA;AAAA,QACA,uBAAuB,CAAC;AAAA,OACzB;AAAA;AACH,GACJ;AACF;AAEA,SAAS,kBAAkB,MAAA,EAAgB;AACzC,EAAA,MAAM,IAAA,GAAOC,6BAAS,MAAM,CAAA;AAE5B,EAAA,IAAI,MAAA,CAAO,UAAU,IAAA,EAAM;AACzB,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,GAAA,EAAK,eAAA;AAAA,MACL,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,kBAAkB,OAAO;AAAA,KACtD,CAAA;AAAA,EACH;AACA,EAAA,IAAI,MAAA,CAAO,UAAU,SAAA,EAAW;AAC9B,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,GAAA,EAAK,oBAAA;AAAA,MACL,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,SAAA,CAAU,kBAAkB,OAAO;AAAA,KAC3D,CAAA;AAAA,EACH;AACA,EAAA,IAAI,MAAA,CAAO,UAAU,GAAA,EAAK;AACxB,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,GAAA,EAAK,cAAA;AAAA,MACL,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,kBAAkB,OAAO;AAAA,KACrD,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,SAAA,EAAW;AAC9B,IAAA,IAAA,CAAK,KAAK,EAAE,GAAA,EAAK,oBAAA,EAAsB,KAAA,EAAOC,gCAAmB,CAAA;AAAA,EACnE;AAGA,EAAA,KAAA,MAAW,QAAA,IAAY,MAAA,CAAO,SAAA,IAAa,EAAC,EAAG;AAC7C,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,KAAK,CAAA,UAAA,EAAa,QAAA,CAAS,IAAA,CAAK,iBAAA,CAAkB,OAAO,CAAC,CAAA,CAAA;AAAA,MAC1D,KAAA,EAAO,QAAA,CAAS,SAAA,CAAU,iBAAA,CAAkB,OAAO;AAAA,KACpD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,aACP,eAAA,EAC6B;AAC7B,EAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,IAAA,OAAO,MAAM,IAAA;AAAA,EACf;AAEA,EAAA,MAAM,OAAA,GAAU,CAAC,eAAe,CAAA,CAAE,IAAA,EAAK;AAEvC,EAAA,OAAO,CAAA,MAAA,KAAU;AACf,IAAA,MAAM,IAAA,GAAO,kBAAkB,MAAM,CAAA;AAErC,IAAA,OAAO,OAAA,CAAQ,KAAK,CAAA,MAAA,KAAU;AAC5B,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,aAAa,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AACzD,QAAA,MAAM,eAAe,IAAA,CAClB,MAAA,CAAO,SAAO,GAAA,CAAI,GAAA,KAAQ,IAAI,iBAAA,CAAkB,OAAO,CAAC,CAAA,CACxD,GAAA,CAAI,SAAO,GAAA,CAAI,KAAA,EAAO,UAAS,CAAE,iBAAA,CAAkB,OAAO,CAAC,CAAA;AAE9D,QAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAC7B,UAAA,OAAO,KAAA;AAAA,QACT;AACA,QAAA,IAAI,kBAAkBF,mCAAA,EAAuB;AAC3C,UAAA;AAAA,QACF;AACA,QAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,aAAa,CAAA,EAAG;AAChC,UAAA,OAAO,aAAA,CAAc,IAAA;AAAA,YAAK,CAAA,KAAA,KACxB,cAAc,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA,CAAE,iBAAA,CAAkB,OAAO,CAAC;AAAA,WACjE;AAAA,QACF;AACA,QAAA,IACE,CAAC,YAAA,EAAc,QAAA;AAAA,UACb,MAAA,CAAO,aAAa,CAAA,CAAE,iBAAA,CAAkB,OAAO;AAAA,SACjD,EACA;AACA,UAAA,OAAO,KAAA;AAAA,QACT;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,IACT,CAAC,CAAA;AAAA,EACH,CAAA;AACF;AAKA,SAAS,oBAAA,CACP,OACA,KAAA,EACqB;AACrB,EAAA,OAAO,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA;AAAA,IACtB,CAAC,CAAC,SAAA,EAAW,WAAW,CAAA,EAAG,QAAA,EAAU,OAAO,UAAA,KAAe;AACzD,MAAA,IAAIG,uBAAA,CAAO,KAAA,CAAM,WAAA,EAAa,QAAQ,CAAA,EAAG;AACvC,QAAA,OAAO,CAAC,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA,EAAI,WAAA,CAAoB,QAAQ,CAAC,CAAA;AAAA,MACpE,CAAA,MAAA,IAAW,UAAA,CAAW,KAAA,GAAQ,CAAC,MAAM,MAAA,EAAW;AAC9C,QAAA,UAAA,CAAW,KAAA,GAAQ,CAAC,CAAA,GAAI,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,UAAA,CAAW,KAAA,GAAQ,CAAC,CAAC,CAAA,CAAA;AAC5D,QAAA,OAAO,CAAC,WAAW,WAAW,CAAA;AAAA,MAChC;AACA,MAAA,OAAO,CAAC,WAAW,MAAS,CAAA;AAAA,IAC9B,CAAA;AAAA,IACA,CAAC,EAAC,EAAe,KAAgB;AAAA,GACnC;AACF;AAEA,SAAS,iBAAA,CAAkB,QAAgB,MAAA,EAA2B;AACpE,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,SAA8B,EAAC;AACrC,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,CAAC,SAAA,EAAW,KAAK,CAAA,GAAI,oBAAA,CAAqB,QAAQ,KAAK,CAAA;AAC7D,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAAA,uBAAA,CAAO,GAAA,CAAI,MAAA,EAAQ,SAAA,EAAW,KAAK,CAAA;AAAA,IACrC;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,aAAA,CAAc,UAAoB,KAAA,EAAoC;AAC7E,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,MAAM,MAAA,GAAS,CAAC,KAAK,CAAA,CAAE,IAAA,EAAK;AAC5B,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoD;AAC1E,EAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,IAAA,SAAA,CAAU,GAAA,CAAI,MAAA,EAAQ,iBAAA,CAAkB,MAAM,CAAC,CAAA;AAAA,EACjD;AAEA,EAAA,OAAO,CAAC,GAAG,QAAQ,EAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AAClC,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA;AAC7B,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA;AAE7B,IAAA,KAAA,MAAW,EAAE,KAAA,EAAO,KAAA,EAAO,GAAA,MAAS,MAAA,EAAQ;AAC1C,MAAA,MAAM,GAAA,GAAM,KAAA,CAAM,iBAAA,CAAkB,OAAO,CAAA;AAC3C,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,GAAA,CAAI,iBAAA,CAAkB,OAAO,CAAA,KAAM,GAAG,CAAA;AACrE,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,GAAA,CAAI,iBAAA,CAAkB,OAAO,CAAA,KAAM,GAAG,CAAA;AACrE,MAAA,MAAM,MAAA,GACJ,IAAA,EAAM,KAAA,KAAU,IAAA,IAAQ,IAAA,EAAM,KAAA,KAAU,MAAA,GACpC,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,iBAAA,CAAkB,OAAO,CAAA,GAC5C,IAAA;AACN,MAAA,MAAM,MAAA,GACJ,IAAA,EAAM,KAAA,KAAU,IAAA,IAAQ,IAAA,EAAM,KAAA,KAAU,MAAA,GACpC,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,iBAAA,CAAkB,OAAO,CAAA,GAC5C,IAAA;AAEN,MAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,MAAA,KAAW,IAAA,EAAM;AACxC,MAAA,IAAI,MAAA,KAAW,MAAM,OAAO,CAAA;AAC5B,MAAA,IAAI,MAAA,KAAW,MAAM,OAAO,EAAA;AAE5B,MAAA,IAAI,MAAA,GAAS,MAAA,EAAQ,OAAO,GAAA,KAAQ,QAAQ,EAAA,GAAK,CAAA;AACjD,MAAA,IAAI,MAAA,GAAS,MAAA,EAAQ,OAAO,GAAA,KAAQ,QAAQ,CAAA,GAAI,EAAA;AAAA,IAClD;AAGA,IAAA,MAAM,IAAA,GAAOC,gCAAmB,CAAC,CAAA;AACjC,IAAA,MAAM,IAAA,GAAOA,gCAAmB,CAAC,CAAA;AACjC,IAAA,IAAI,IAAA,GAAO,MAAM,OAAO,EAAA;AACxB,IAAA,IAAI,IAAA,GAAO,MAAM,OAAO,CAAA;AACxB,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AACH;AAEA,SAAS,mBAAA,CACP,UACA,cAAA,EACU;AACV,EAAA,IAAI,CAAC,cAAA,EAAgB,IAAA,EAAM,IAAA,EAAK,EAAG;AACjC,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAO,cAAA,CAAe,IAAA,CAAK,IAAA,EAAK,CAAE,kBAAkB,OAAO,CAAA;AACjE,EAAA,MAAM,MAAA,GAAS,eAAe,MAAA,EAAQ,GAAA,CAAI,OAAK,CAAA,CAAE,iBAAA,CAAkB,OAAO,CAAC,CAAA;AAE3E,EAAA,OAAO,QAAA,CAAS,OAAO,CAAA,MAAA,KAAU;AAC/B,IAAA,MAAM,IAAA,GAAO,kBAAkB,MAAM,CAAA;AACrC,IAAA,OAAO,IAAA,CAAK,KAAK,CAAA,GAAA,KAAO;AACtB,MAAA,IACE,MAAA,EAAQ,MAAA,IACR,CAAC,MAAA,CAAO,QAAA,CAAS,IAAI,GAAA,CAAI,iBAAA,CAAkB,OAAO,CAAC,CAAA,EACnD;AACA,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,IAAI,IAAI,KAAA,KAAU,IAAA,IAAQ,GAAA,CAAI,KAAA,KAAU,QAAW,OAAO,KAAA;AAC1D,MAAA,MAAM,QAAQ,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA,CAAE,kBAAkB,OAAO,CAAA;AACzD,MAAA,OAAO,KAAA,CAAM,SAAS,IAAI,CAAA;AAAA,IAC5B,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;AAUO,MAAM,qBAAA,CAA4C;AAAA,EACvD,SAAA;AAAA,EAEA,YAAY,OAAA,EAAmC;AAC7C,IAAA,IAAA,CAAK,SAAA,GAAY,OAAA,EAAS,QAAA,EAAU,KAAA,MAAW,EAAC;AAAA,EAClD;AAAA,EAEA,MAAM,YACJ,OAAA,EAC8B;AAC9B,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,OAAA,EAAS,MAAM,CAAA;AAC3C,IAAA,IAAI,KAAA,GAAQ,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,MAAM,CAAA;AACxC,IAAA,KAAA,GAAQ,aAAA,CAAc,KAAA,EAAO,OAAA,EAAS,KAAK,CAAA;AAE3C,IAAA,IAAI,MAAA,GAAS,SAAS,MAAA,IAAU,CAAA;AAChC,IAAA,IAAI,QAAQ,OAAA,EAAS,KAAA;AAErB,IAAA,IAAI,SAAS,KAAA,EAAO;AAClB,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,WAAA,CAAY,OAAA,CAAQ,KAAK,CAAA;AACxC,QAAA,IAAI,MAAA,CAAO,MAAA,KAAW,KAAA,CAAA,EAAW,MAAA,GAAS,MAAA,CAAO,MAAA;AACjD,QAAA,IAAI,MAAA,CAAO,KAAA,KAAU,KAAA,CAAA,EAAW,KAAA,GAAQ,MAAA,CAAO,KAAA;AAAA,MACjD,CAAA,CAAA,MAAQ;AACN,QAAA,MAAM,IAAIC,kBAAW,gBAAgB,CAAA;AAAA,MACvC;AAAA,IACF;AAEA,IAAA,IAAI,SAAS,CAAA,EAAG;AACd,MAAA,KAAA,GAAQ,KAAA,CAAM,MAAM,MAAM,CAAA;AAAA,IAC5B;AACA,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAAA,IAC9B;AAEA,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,OAAA,EAAS,MAAA,GACZ,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAK,iBAAA,CAAkB,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAC,CAAA,GACnD;AAAA,KACN;AAAA,EACF;AAAA,EAEA,MAAM,kBACJ,OAAA,EACoC;AACpC,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,OAAA,CAAQ,MAAM,CAAA;AAC1C,IAAA,MAAM,MAAA,GAAS,KAAK,mBAAA,EAAoB;AACxC,IAAA,MAAM,QAAQ,OAAA,CAAQ,UAAA,CACnB,GAAA,CAAI,CAAA,GAAA,KAAO,OAAO,GAAA,CAAI,GAAG,CAAC,CAAA,CAC1B,IAAI,CAAA,CAAA,KAAM,CAAA,IAAK,OAAO,CAAC,CAAA,GAAI,IAAI,MAAU,CAAA;AAC5C,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,OAAA,CAAQ,MAAA,GACX,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAM,CAAA,GAAI,iBAAA,CAAkB,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA,GAAI,MAAU,CAAA,GACrE;AAAA,KACN;AAAA,EACF;AAAA,EAEA,MAAM,cACJ,OAAA,EACgC;AAEhC,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,WAAA;AACJ,IAAA,IAAI,cAAA;AACJ,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,KAAA;AAEJ,IAAA,IAAI,OAAA,IAAW,YAAY,OAAA,EAAS;AAClC,MAAA,IAAI,CAAA;AACJ,MAAA,IAAI;AACF,QAAA,CAAA,GAAI,WAAA,CAAY,QAAQ,MAAM,CAAA;AAAA,MAChC,CAAA,CAAA,MAAQ;AACN,QAAA,MAAM,IAAIA,kBAAW,gBAAgB,CAAA;AAAA,MACvC;AACA,MAAA,MAAA,GAAS,iBAAA,CAAkB,EAAE,MAAe,CAAA;AAC5C,MAAA,WAAA,GAAc,CAAA,CAAE,WAAA;AAChB,MAAA,cAAA,GAAiB,CAAA,CAAE,cAAA;AACnB,MAAA,MAAA,GAAS,CAAA,CAAE,MAAA;AACX,MAAA,KAAA,GAAQ,OAAA,CAAQ,KAAA;AAAA,IAClB,CAAA,MAAO;AACL,MAAA,MAAA,GAAS,OAAA,EAAS,MAAA;AAClB,MAAA,WAAA,GAAc,OAAA,EAAS,WAAA;AACvB,MAAA,cAAA,GAAiB,OAAA,EAAS,cAAA;AAC1B,MAAA,MAAA,GAAS,SAAS,MAAA,IAAU,CAAA;AAC5B,MAAA,KAAA,GAAQ,OAAA,EAAS,KAAA;AAAA,IACnB;AAGA,IAAA,IAAI,QAAQ,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,YAAA,CAAa,MAAM,CAAC,CAAA;AAGtD,IAAA,IAAI,cAAA,EAAgB;AAClB,MAAA,MAAM,kBAAkB,WAAA,GAAc,CAAC,WAAW,CAAA,CAAE,IAAA,KAAS,EAAC;AAC9D,MAAA,KAAA,GAAQ,oBAAoB,KAAA,EAAO;AAAA,QACjC,GAAG,cAAA;AAAA,QACH,MAAA,EAAQ,eAAe,MAAA,IAAU;AAAA,UAC/B,eAAA,CAAgB,CAAC,CAAA,EAAG,KAAA,IAAS;AAAA;AAC/B,OACD,CAAA;AAAA,IACH;AAEA,IAAA,KAAA,GAAQ,aAAA,CAAc,OAAO,WAAW,CAAA;AAExC,IAAA,MAAM,aAAa,KAAA,CAAM,MAAA;AAGzB,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,MAAA,KAAW,CAAA,EAAG;AACvC,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,OAAA,EAAS,MAAA,GACZ,KAAA,CAAM,GAAA,CAAI,CAAA,CAAA,KAAK,iBAAA,CAAkB,CAAA,EAAG,OAAA,EAAS,MAAM,CAAC,CAAA,GACpD,KAAA;AAAA,QACJ,UAAU,EAAC;AAAA,QACX;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,iBAAiB,KAAA,IAAS,UAAA;AAChC,IAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,CAAM,MAAA,EAAQ,SAAS,cAAc,CAAA;AAE7D,IAAA,MAAM,UAAA,GAAa;AAAA,MACjB,MAAA,EAAQ,gBAAgB,MAAM,CAAA;AAAA,MAC9B,WAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,MAAM,WAA8C,EAAC;AACrD,IAAA,IAAI,MAAA,GAAS,iBAAiB,UAAA,EAAY;AACxC,MAAA,QAAA,CAAS,aAAa,UAAA,CAAW;AAAA,QAC/B,GAAG,UAAA;AAAA,QACH,QAAQ,MAAA,GAAS;AAAA,OAClB,CAAA;AAAA,IACH;AACA,IAAA,IAAI,SAAS,CAAA,EAAG;AACd,MAAA,QAAA,CAAS,aAAa,UAAA,CAAW;AAAA,QAC/B,GAAG,UAAA;AAAA,QACH,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,SAAS,cAAc;AAAA,OAC5C,CAAA;AAAA,IACH;AAEA,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,OAAA,EAAS,MAAA,GACZ,SAAA,CAAU,GAAA,CAAI,CAAA,CAAA,KAAK,iBAAA,CAAkB,CAAA,EAAG,OAAA,EAAS,MAAM,CAAC,CAAA,GACxD,SAAA;AAAA,MACJ,UAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA,EAEA,MAAM,mBACJ,OAAA,EACqC;AACrC,IAAA,MAAM,SAAS,IAAA,CAAK,mBAAA,EAAoB,CAAE,GAAA,CAAI,QAAQ,SAAS,CAAA;AAC/D,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAIC,oBAAA,CAAc,CAAA,gBAAA,EAAmB,OAAA,CAAQ,SAAS,CAAA,UAAA,CAAY,CAAA;AAAA,IAC1E;AACA,IAAA,OAAO;AAAA,MACL,OAAO,CAAC,EAAE,QAAQ,gBAAA,EAAkB,IAAI,CAAA;AAAA,MACxC,eAAe,OAAA,CAAQ;AAAA,KACzB;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,SAAA,EAC6B;AAC7B,IAAA,OAAO,IAAA,CAAK,qBAAoB,CAAE,GAAA;AAAA,MAChCF,+BAAA,CAAmBG,2BAAA,CAAe,SAAS,CAAC;AAAA,KAC9C;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,GAAA,EAA4B;AAClD,IAAA,MAAM,KAAA,GAAQ,KAAK,SAAA,CAAU,SAAA,CAAU,OAAK,CAAA,CAAE,QAAA,CAAS,QAAQ,GAAG,CAAA;AAClE,IAAA,IAAI,UAAU,EAAA,EAAI;AAChB,MAAA,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,KAAA,EAAO,CAAC,CAAA;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,UAAA,EAAmC;AAAA,EAAC;AAAA,EAExD,MAAM,gBACJ,OAAA,EACkC;AAClC,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,OAAA,CAAQ,MAAM,CAAA;AAC1C,IAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,MAAM,CAAA;AACrD,IAAA,MAAM,SAAS,MAAA,CAAO,WAAA;AAAA,MACpB,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,KAAA,KAAS;AAC1B,QAAA,MAAM,WAAA,uBAAkB,GAAA,EAAoB;AAC5C,QAAA,KAAA,MAAW,UAAU,gBAAA,EAAkB;AACrC,UAAA,MAAM,IAAA,GAAO,kBAAkB,MAAM,CAAA;AAGrC,UAAA,MAAM,eAAe,IAAI,GAAA;AAAA,YACvB,IAAA,CACG,MAAA;AAAA,cACC,CAAA,GAAA,KACE,IAAI,GAAA,CAAI,iBAAA,CAAkB,OAAO,CAAA,KACjC,KAAA,CAAM,kBAAkB,OAAO;AAAA,cAElC,GAAA,CAAI,CAAA,GAAA,KAAO,GAAA,CAAI,KAAK,EACpB,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,KAAM,IAAA,IAAQ,MAAM,MAAS,CAAA,CACzC,IAAI,CAAA,CAAA,KAAK,MAAA,CAAO,CAAC,CAAC;AAAA,WACvB;AACA,UAAA,KAAA,MAAW,SAAS,YAAA,EAAc;AAChC,YAAA,WAAA,CAAY,IAAI,KAAA,EAAA,CAAQ,WAAA,CAAY,IAAI,KAAK,CAAA,IAAK,KAAK,CAAC,CAAA;AAAA,UAC1D;AAAA,QACF;AACA,QAAA,MAAM,SAAS,KAAA,CAAM,IAAA,CAAK,WAAA,CAAY,OAAA,EAAS,CAAA,CAAE,GAAA;AAAA,UAC/C,CAAC,CAAC,KAAA,EAAO,KAAK,CAAA,MAAO,EAAE,OAAO,KAAA,EAAM;AAAA,SACtC;AACA,QAAA,OAAO,CAAC,OAAO,MAAM,CAAA;AAAA,MACvB,CAAC;AAAA,KACH;AACA,IAAA,OAAO;AAAA,MACL;AAAA,KACF;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,QAAA,EAA8C;AAC/D,IAAA,MAAM,IAAIC,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,MAAM,eACJ,QAAA,EACiC;AACjC,IAAA,MAAM,IAAIA,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,OAAO,gBACL,QAAA,EAC2B;AAC3B,IAAA,MAAM,IAAIA,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,MAAM,gBAAgB,GAAA,EAA4C;AAChE,IAAA,MAAM,IAAIA,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,MAAM,iBAAiB,YAAA,EAAqD;AAC1E,IAAA,MAAM,IAAIA,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,MAAM,YACJ,SAAA,EAC8B;AAC9B,IAAA,MAAM,IAAIA,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,MAAM,mBAAmB,GAAA,EAA4B;AACnD,IAAA,MAAM,IAAIA,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,MAAM,oBACJ,UAAA,EAC+B;AAC/B,IAAA,MAAM,IAAIA,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,MAAM,cAAA,CACJ,OAAA,EACA,YAAA,EACiC;AACjC,IAAA,MAAM,IAAIA,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,MAAM,gBACJ,SAAA,EACkC;AAClC,IAAA,MAAM,IAAIA,2BAAoB,yBAAyB,CAAA;AAAA,EACzD;AAAA,EAEA,OAAO,eACL,OAAA,EACyB;AACzB,IAAA,IAAI,MAAA,GAA6B,MAAA;AACjC,IAAA,MAAM,KAAA,GAAQ,SAAS,QAAA,IAAYC,uCAAA;AACnC,IAAA,GAAG;AACD,MAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,aAAA;AAAA,QACrB,MAAA,GAAS,EAAE,GAAG,OAAA,EAAS,KAAA,EAAO,QAAO,GAAI,EAAE,GAAG,OAAA,EAAS,KAAA;AAAM,OAC/D;AAEA,MAAA,MAAM,GAAA,CAAI,KAAA;AAEV,MAAA,MAAA,GAAS,IAAI,QAAA,CAAS,UAAA;AAAA,IACxB,CAAA,QAAS,MAAA;AAAA,EACX;AAAA,EAEA,mBAAA,GAAsB;AACpB,IAAA,OAAO,IAAI,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,CAAA,CAAA,KAAK,CAACL,+BAAA,CAAmB,CAAC,CAAA,EAAG,CAAC,CAAC,CAAC,CAAA;AAAA,EACpE;AACF;;;;"} | ||
| {"version":3,"file":"InMemoryCatalogClient.cjs.js","sources":["../../src/testUtils/InMemoryCatalogClient.ts"],"sourcesContent":["/*\n * Copyright 2024 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 AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n EntityFilterQuery,\n EntityOrderQuery,\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 '@backstage/catalog-client';\nimport {\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n InputError,\n NotFoundError,\n NotImplementedError,\n} from '@backstage/errors';\nimport {\n FilterPredicate,\n filterPredicateToFilterFunction,\n} from '@backstage/filter-predicates';\nimport lodash from 'lodash';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { traverse } from '../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport { DEFAULT_STREAM_ENTITIES_LIMIT } from '../constants.ts';\n\nfunction makeCursor(data: Record<string, unknown>): string {\n return btoa(JSON.stringify(data));\n}\n\nfunction parseCursor(cursor: string): Record<string, unknown> {\n return JSON.parse(atob(cursor));\n}\n\n// CATALOG_FILTER_EXISTS is a Symbol that doesn't survive JSON serialization,\n// so we swap it with a sentinel string when encoding/decoding cursors.\nconst FILTER_EXISTS_SENTINEL = '\\0CATALOG_FILTER_EXISTS';\n\nfunction serializeFilterValue(v: unknown): unknown {\n if (v === CATALOG_FILTER_EXISTS) return FILTER_EXISTS_SENTINEL;\n if (Array.isArray(v)) {\n return v.map(x =>\n x === CATALOG_FILTER_EXISTS ? FILTER_EXISTS_SENTINEL : x,\n );\n }\n return v;\n}\n\nfunction deserializeFilterValue(v: unknown): unknown {\n if (v === FILTER_EXISTS_SENTINEL) return CATALOG_FILTER_EXISTS;\n if (Array.isArray(v)) {\n return v.map(x =>\n x === FILTER_EXISTS_SENTINEL ? CATALOG_FILTER_EXISTS : x,\n );\n }\n return v;\n}\n\nfunction serializeFilter(filter?: EntityFilterQuery): any[] | undefined {\n if (!filter) return undefined;\n return [filter]\n .flat()\n .map(f =>\n Object.fromEntries(\n Object.entries(f).map(([k, v]) => [k, serializeFilterValue(v)]),\n ),\n );\n}\n\nfunction deserializeFilter(filter?: any[]): EntityFilterQuery | undefined {\n if (!filter) return undefined;\n return filter.map(\n f =>\n Object.fromEntries(\n Object.entries(f).map(([k, v]: [string, any]) => [\n k,\n deserializeFilterValue(v),\n ]),\n ) as Record<string, string | symbol | (string | symbol)[]>,\n );\n}\n\nfunction buildEntitySearch(entity: Entity) {\n const rows = traverse(entity);\n\n if (entity.metadata?.name) {\n rows.push({\n key: 'metadata.name',\n value: entity.metadata.name.toLocaleLowerCase('en-US'),\n });\n }\n if (entity.metadata?.namespace) {\n rows.push({\n key: 'metadata.namespace',\n value: entity.metadata.namespace.toLocaleLowerCase('en-US'),\n });\n }\n if (entity.metadata?.uid) {\n rows.push({\n key: 'metadata.uid',\n value: entity.metadata.uid.toLocaleLowerCase('en-US'),\n });\n }\n\n if (!entity.metadata.namespace) {\n rows.push({ key: 'metadata.namespace', value: DEFAULT_NAMESPACE });\n }\n\n // Visit relations\n for (const relation of entity.relations ?? []) {\n rows.push({\n key: `relations.${relation.type.toLocaleLowerCase('en-US')}`,\n value: relation.targetRef.toLocaleLowerCase('en-US'),\n });\n }\n\n return rows;\n}\n\nfunction createFilter(\n filterOrFilters?: EntityFilterQuery,\n): (entity: Entity) => boolean {\n if (!filterOrFilters) {\n return () => true;\n }\n\n const filters = [filterOrFilters].flat();\n\n return entity => {\n const rows = buildEntitySearch(entity);\n\n return filters.some(filter => {\n for (const [key, expectedValue] of Object.entries(filter)) {\n const searchValues = rows\n .filter(row => row.key === key.toLocaleLowerCase('en-US'))\n .map(row => row.value?.toString().toLocaleLowerCase('en-US'));\n\n if (searchValues.length === 0) {\n return false;\n }\n if (expectedValue === CATALOG_FILTER_EXISTS) {\n continue;\n }\n if (Array.isArray(expectedValue)) {\n return expectedValue.some(value =>\n searchValues?.includes(String(value).toLocaleLowerCase('en-US')),\n );\n }\n if (\n !searchValues?.includes(\n String(expectedValue).toLocaleLowerCase('en-US'),\n )\n ) {\n return false;\n }\n }\n return true;\n });\n };\n}\n\n// Resolves a dot-separated field path against an entity, handling keys that\n// themselves contain dots (e.g. annotation keys like \"backstage.io/orphan\").\n// This matches the backend's parseEntityTransformParams implementation.\nfunction getPathArrayAndValue(\n input: Entity,\n field: string,\n): [string[], unknown] {\n return field.split('.').reduce(\n ([pathArray, inputSubset], pathPart, index, fieldParts) => {\n if (lodash.hasIn(inputSubset, pathPart)) {\n return [pathArray.concat(pathPart), (inputSubset as any)[pathPart]];\n } else if (fieldParts[index + 1] !== undefined) {\n fieldParts[index + 1] = `${pathPart}.${fieldParts[index + 1]}`;\n return [pathArray, inputSubset];\n }\n return [pathArray, undefined];\n },\n [[] as string[], input as unknown],\n );\n}\n\nfunction applyFieldsFilter(entity: Entity, fields?: string[]): Entity {\n if (!fields?.length) {\n return entity;\n }\n const output: Record<string, any> = {};\n for (const field of fields) {\n const [pathArray, value] = getPathArrayAndValue(entity, field);\n if (value !== undefined) {\n lodash.set(output, pathArray, value);\n }\n }\n return output as Entity;\n}\n\nfunction applyOrdering(entities: Entity[], order?: EntityOrderQuery): Entity[] {\n if (!order) {\n return entities;\n }\n const orders = [order].flat();\n if (orders.length === 0) {\n return entities;\n }\n\n const searchMap = new Map<Entity, Array<{ key: string; value: unknown }>>();\n for (const entity of entities) {\n searchMap.set(entity, buildEntitySearch(entity));\n }\n\n return [...entities].sort((a, b) => {\n const aRows = searchMap.get(a)!;\n const bRows = searchMap.get(b)!;\n\n for (const { field, order: dir } of orders) {\n const key = field.toLocaleLowerCase('en-US');\n const aRow = aRows.find(r => r.key.toLocaleLowerCase('en-US') === key);\n const bRow = bRows.find(r => r.key.toLocaleLowerCase('en-US') === key);\n const aValue =\n aRow?.value !== null && aRow?.value !== undefined\n ? String(aRow.value).toLocaleLowerCase('en-US')\n : null;\n const bValue =\n bRow?.value !== null && bRow?.value !== undefined\n ? String(bRow.value).toLocaleLowerCase('en-US')\n : null;\n\n if (aValue === null && bValue === null) continue;\n if (aValue === null) return 1;\n if (bValue === null) return -1;\n\n if (aValue < bValue) return dir === 'asc' ? -1 : 1;\n if (aValue > bValue) return dir === 'asc' ? 1 : -1;\n }\n\n // Stable tie-breaker by entity ref, matching backend behavior\n const aRef = stringifyEntityRef(a);\n const bRef = stringifyEntityRef(b);\n if (aRef < bRef) return -1;\n if (aRef > bRef) return 1;\n return 0;\n });\n}\n\nfunction applyFullTextFilter(\n entities: Entity[],\n fullTextFilter?: { term: string; fields?: string[] },\n): Entity[] {\n if (!fullTextFilter?.term?.trim()) {\n return entities;\n }\n const term = fullTextFilter.term.trim().toLocaleLowerCase('en-US');\n const fields = fullTextFilter.fields?.map(f => f.toLocaleLowerCase('en-US'));\n\n return entities.filter(entity => {\n const rows = buildEntitySearch(entity);\n return rows.some(row => {\n if (\n fields?.length &&\n !fields.includes(row.key.toLocaleLowerCase('en-US'))\n ) {\n return false;\n }\n if (row.value === null || row.value === undefined) return false;\n const value = String(row.value).toLocaleLowerCase('en-US');\n return value.includes(term);\n });\n });\n}\n\n/**\n * Implements a fake catalog client that stores entities in memory.\n * Supports filtering, ordering, pagination, full-text search, and field\n * projection for entity query methods. Location and validation methods\n * throw {@link @backstage/errors#NotImplementedError}.\n *\n * @public\n */\nexport class InMemoryCatalogClient implements CatalogApi {\n #entities: Entity[];\n\n constructor(options?: { entities?: Entity[] }) {\n this.#entities = options?.entities?.slice() ?? [];\n }\n\n async getEntities(\n request?: GetEntitiesRequest,\n ): Promise<GetEntitiesResponse> {\n const filter = createFilter(request?.filter);\n let items = this.#entities.filter(filter);\n items = applyOrdering(items, request?.order);\n\n let offset = request?.offset ?? 0;\n let limit = request?.limit;\n\n if (request?.after) {\n try {\n const cursor = parseCursor(request.after);\n if (cursor.offset !== undefined) offset = cursor.offset as number;\n if (cursor.limit !== undefined) limit = cursor.limit as number;\n } catch {\n throw new InputError('Invalid cursor');\n }\n }\n\n if (offset > 0) {\n items = items.slice(offset);\n }\n if (limit !== undefined) {\n items = items.slice(0, limit);\n }\n\n return {\n items: request?.fields\n ? items.map(e => applyFieldsFilter(e, request.fields))\n : items,\n };\n }\n\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n ): Promise<GetEntitiesByRefsResponse> {\n const filter = createFilter(request.filter);\n const queryFilter = request.query\n ? filterPredicateToFilterFunction(request.query)\n : undefined;\n const refMap = this.#createEntityRefMap();\n const items = request.entityRefs\n .map(ref => refMap.get(ref))\n .map(e =>\n e && filter(e) && (!queryFilter || queryFilter(e)) ? e : undefined,\n );\n return {\n items: request.fields\n ? items.map(e => (e ? applyFieldsFilter(e, request.fields) : undefined))\n : items,\n };\n }\n\n async queryEntities(\n request?: QueryEntitiesRequest,\n ): Promise<QueryEntitiesResponse> {\n // Decode query parameters from cursor or from the request directly\n let filter: EntityFilterQuery | undefined;\n let query: FilterPredicate | undefined;\n let orderFields: EntityOrderQuery | undefined;\n let fullTextFilter: { term: string; fields?: string[] } | undefined;\n let offset: number;\n let limit: number | undefined;\n\n if (request && 'cursor' in request) {\n let c: Record<string, unknown>;\n try {\n c = parseCursor(request.cursor);\n } catch {\n throw new InputError('Invalid cursor');\n }\n filter = deserializeFilter(c.filter as any[]);\n query = c.query as FilterPredicate | undefined;\n orderFields = c.orderFields as EntityOrderQuery | undefined;\n fullTextFilter = c.fullTextFilter as typeof fullTextFilter;\n offset = c.offset as number;\n limit = request.limit;\n } else {\n filter = request?.filter;\n query = request?.query;\n orderFields = request?.orderFields;\n fullTextFilter = request?.fullTextFilter;\n offset = request?.offset ?? 0;\n limit = request?.limit;\n }\n\n // Apply filter\n let items = this.#entities.filter(createFilter(filter));\n\n // Apply predicate-based query filter\n if (query) {\n items = items.filter(filterPredicateToFilterFunction(query));\n }\n\n // Apply full-text filter, defaulting to the sort field or metadata.uid\n if (fullTextFilter) {\n const orderFieldsList = orderFields ? [orderFields].flat() : [];\n items = applyFullTextFilter(items, {\n ...fullTextFilter,\n fields: fullTextFilter.fields ?? [\n orderFieldsList[0]?.field ?? 'metadata.uid',\n ],\n });\n }\n\n items = applyOrdering(items, orderFields);\n\n const totalItems = items.length;\n\n // No pagination requested, return all items\n if (limit === undefined && offset === 0) {\n return {\n items: request?.fields\n ? items.map(e => applyFieldsFilter(e, request?.fields))\n : items,\n pageInfo: {},\n totalItems,\n };\n }\n\n const effectiveLimit = limit ?? totalItems;\n const pageItems = items.slice(offset, offset + effectiveLimit);\n\n const cursorBase = {\n filter: serializeFilter(filter),\n query,\n orderFields,\n fullTextFilter,\n totalItems,\n };\n const pageInfo: QueryEntitiesResponse['pageInfo'] = {};\n if (offset + effectiveLimit < totalItems) {\n pageInfo.nextCursor = makeCursor({\n ...cursorBase,\n offset: offset + effectiveLimit,\n });\n }\n if (offset > 0) {\n pageInfo.prevCursor = makeCursor({\n ...cursorBase,\n offset: Math.max(0, offset - effectiveLimit),\n });\n }\n\n return {\n items: request?.fields\n ? pageItems.map(e => applyFieldsFilter(e, request?.fields))\n : pageItems,\n totalItems,\n pageInfo,\n };\n }\n\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n ): Promise<GetEntityAncestorsResponse> {\n const entity = this.#createEntityRefMap().get(request.entityRef);\n if (!entity) {\n throw new NotFoundError(`Entity with ref ${request.entityRef} not found`);\n }\n return {\n items: [{ entity, parentEntityRefs: [] }],\n rootEntityRef: request.entityRef,\n };\n }\n\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n ): Promise<Entity | undefined> {\n return this.#createEntityRefMap().get(\n stringifyEntityRef(parseEntityRef(entityRef)),\n );\n }\n\n async removeEntityByUid(uid: string): Promise<void> {\n const index = this.#entities.findIndex(e => e.metadata.uid === uid);\n if (index !== -1) {\n this.#entities.splice(index, 1);\n }\n }\n\n async refreshEntity(_entityRef: string): Promise<void> {}\n\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n ): Promise<GetEntityFacetsResponse> {\n const filter = createFilter(request.filter);\n let filteredEntities = this.#entities.filter(filter);\n if (request.query) {\n filteredEntities = filteredEntities.filter(\n filterPredicateToFilterFunction(request.query),\n );\n }\n const facets = Object.fromEntries(\n request.facets.map(facet => {\n const facetValues = new Map<string, number>();\n for (const entity of filteredEntities) {\n const rows = buildEntitySearch(entity);\n // Use a Set to count each distinct value once per entity,\n // matching the backend's count(DISTINCT entity_id) behavior\n const uniqueValues = new Set(\n rows\n .filter(\n row =>\n row.key.toLocaleLowerCase('en-US') ===\n facet.toLocaleLowerCase('en-US'),\n )\n .map(row => row.value)\n .filter(v => v !== null && v !== undefined)\n .map(v => String(v)),\n );\n for (const value of uniqueValues) {\n facetValues.set(value, (facetValues.get(value) ?? 0) + 1);\n }\n }\n const counts = Array.from(facetValues.entries()).map(\n ([value, count]) => ({ value, count }),\n );\n return [facet, counts];\n }),\n );\n return {\n facets,\n };\n }\n\n async getLocations(_request?: {}): Promise<GetLocationsResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async queryLocations(\n _request?: QueryLocationsRequest,\n ): Promise<QueryLocationsResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async *streamLocations(\n _request?: QueryLocationsInitialRequest,\n ): AsyncIterable<Location[]> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationById(_id: string): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationByRef(_locationRef: string): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async addLocation(\n _location: AddLocationRequest,\n ): Promise<AddLocationResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async removeLocationById(_id: string): Promise<void> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationByEntity(\n _entityRef: string | CompoundEntityRef,\n ): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async validateEntity(\n _entity: Entity,\n _locationRef: string,\n ): Promise<ValidateEntityResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async analyzeLocation(\n _location: AnalyzeLocationRequest,\n ): Promise<AnalyzeLocationResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async *streamEntities(\n request?: StreamEntitiesRequest,\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, limit, cursor } : { ...request, limit },\n );\n\n yield res.items;\n\n cursor = res.pageInfo.nextCursor;\n } while (cursor);\n }\n\n #createEntityRefMap() {\n return new Map(this.#entities.map(e => [stringifyEntityRef(e), e]));\n }\n}\n"],"names":["CATALOG_FILTER_EXISTS","traverse","DEFAULT_NAMESPACE","lodash","stringifyEntityRef","InputError","filterPredicateToFilterFunction","NotFoundError","parseEntityRef","NotImplementedError","DEFAULT_STREAM_ENTITIES_LIMIT"],"mappings":"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"} |
| import { CATALOG_FILTER_EXISTS } from '@backstage/catalog-client'; | ||
| import { stringifyEntityRef, parseEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model'; | ||
| import { InputError, NotFoundError, NotImplementedError } from '@backstage/errors'; | ||
| import { filterPredicateToFilterFunction } from '@backstage/filter-predicates'; | ||
| import lodash from 'lodash'; | ||
@@ -225,4 +226,7 @@ import { traverse } from '../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.esm.js'; | ||
| const filter = createFilter(request.filter); | ||
| const queryFilter = request.query ? filterPredicateToFilterFunction(request.query) : void 0; | ||
| const refMap = this.#createEntityRefMap(); | ||
| const items = request.entityRefs.map((ref) => refMap.get(ref)).map((e) => e && filter(e) ? e : void 0); | ||
| const items = request.entityRefs.map((ref) => refMap.get(ref)).map( | ||
| (e) => e && filter(e) && (!queryFilter || queryFilter(e)) ? e : void 0 | ||
| ); | ||
| return { | ||
@@ -234,2 +238,3 @@ items: request.fields ? items.map((e) => e ? applyFieldsFilter(e, request.fields) : void 0) : items | ||
| let filter; | ||
| let query; | ||
| let orderFields; | ||
@@ -247,2 +252,3 @@ let fullTextFilter; | ||
| filter = deserializeFilter(c.filter); | ||
| query = c.query; | ||
| orderFields = c.orderFields; | ||
@@ -254,2 +260,3 @@ fullTextFilter = c.fullTextFilter; | ||
| filter = request?.filter; | ||
| query = request?.query; | ||
| orderFields = request?.orderFields; | ||
@@ -261,2 +268,5 @@ fullTextFilter = request?.fullTextFilter; | ||
| let items = this.#entities.filter(createFilter(filter)); | ||
| if (query) { | ||
| items = items.filter(filterPredicateToFilterFunction(query)); | ||
| } | ||
| if (fullTextFilter) { | ||
@@ -284,2 +294,3 @@ const orderFieldsList = orderFields ? [orderFields].flat() : []; | ||
| filter: serializeFilter(filter), | ||
| query, | ||
| orderFields, | ||
@@ -333,3 +344,8 @@ fullTextFilter, | ||
| const filter = createFilter(request.filter); | ||
| const filteredEntities = this.#entities.filter(filter); | ||
| let filteredEntities = this.#entities.filter(filter); | ||
| if (request.query) { | ||
| filteredEntities = filteredEntities.filter( | ||
| filterPredicateToFilterFunction(request.query) | ||
| ); | ||
| } | ||
| const facets = Object.fromEntries( | ||
@@ -336,0 +352,0 @@ request.facets.map((facet) => { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"InMemoryCatalogClient.esm.js","sources":["../../src/testUtils/InMemoryCatalogClient.ts"],"sourcesContent":["/*\n * Copyright 2024 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 AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n EntityFilterQuery,\n EntityOrderQuery,\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 '@backstage/catalog-client';\nimport {\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n InputError,\n NotFoundError,\n NotImplementedError,\n} from '@backstage/errors';\nimport lodash from 'lodash';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { traverse } from '../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport { DEFAULT_STREAM_ENTITIES_LIMIT } from '../constants.ts';\n\nfunction makeCursor(data: Record<string, unknown>): string {\n return btoa(JSON.stringify(data));\n}\n\nfunction parseCursor(cursor: string): Record<string, unknown> {\n return JSON.parse(atob(cursor));\n}\n\n// CATALOG_FILTER_EXISTS is a Symbol that doesn't survive JSON serialization,\n// so we swap it with a sentinel string when encoding/decoding cursors.\nconst FILTER_EXISTS_SENTINEL = '\\0CATALOG_FILTER_EXISTS';\n\nfunction serializeFilterValue(v: unknown): unknown {\n if (v === CATALOG_FILTER_EXISTS) return FILTER_EXISTS_SENTINEL;\n if (Array.isArray(v)) {\n return v.map(x =>\n x === CATALOG_FILTER_EXISTS ? FILTER_EXISTS_SENTINEL : x,\n );\n }\n return v;\n}\n\nfunction deserializeFilterValue(v: unknown): unknown {\n if (v === FILTER_EXISTS_SENTINEL) return CATALOG_FILTER_EXISTS;\n if (Array.isArray(v)) {\n return v.map(x =>\n x === FILTER_EXISTS_SENTINEL ? CATALOG_FILTER_EXISTS : x,\n );\n }\n return v;\n}\n\nfunction serializeFilter(filter?: EntityFilterQuery): any[] | undefined {\n if (!filter) return undefined;\n return [filter]\n .flat()\n .map(f =>\n Object.fromEntries(\n Object.entries(f).map(([k, v]) => [k, serializeFilterValue(v)]),\n ),\n );\n}\n\nfunction deserializeFilter(filter?: any[]): EntityFilterQuery | undefined {\n if (!filter) return undefined;\n return filter.map(\n f =>\n Object.fromEntries(\n Object.entries(f).map(([k, v]: [string, any]) => [\n k,\n deserializeFilterValue(v),\n ]),\n ) as Record<string, string | symbol | (string | symbol)[]>,\n );\n}\n\nfunction buildEntitySearch(entity: Entity) {\n const rows = traverse(entity);\n\n if (entity.metadata?.name) {\n rows.push({\n key: 'metadata.name',\n value: entity.metadata.name.toLocaleLowerCase('en-US'),\n });\n }\n if (entity.metadata?.namespace) {\n rows.push({\n key: 'metadata.namespace',\n value: entity.metadata.namespace.toLocaleLowerCase('en-US'),\n });\n }\n if (entity.metadata?.uid) {\n rows.push({\n key: 'metadata.uid',\n value: entity.metadata.uid.toLocaleLowerCase('en-US'),\n });\n }\n\n if (!entity.metadata.namespace) {\n rows.push({ key: 'metadata.namespace', value: DEFAULT_NAMESPACE });\n }\n\n // Visit relations\n for (const relation of entity.relations ?? []) {\n rows.push({\n key: `relations.${relation.type.toLocaleLowerCase('en-US')}`,\n value: relation.targetRef.toLocaleLowerCase('en-US'),\n });\n }\n\n return rows;\n}\n\nfunction createFilter(\n filterOrFilters?: EntityFilterQuery,\n): (entity: Entity) => boolean {\n if (!filterOrFilters) {\n return () => true;\n }\n\n const filters = [filterOrFilters].flat();\n\n return entity => {\n const rows = buildEntitySearch(entity);\n\n return filters.some(filter => {\n for (const [key, expectedValue] of Object.entries(filter)) {\n const searchValues = rows\n .filter(row => row.key === key.toLocaleLowerCase('en-US'))\n .map(row => row.value?.toString().toLocaleLowerCase('en-US'));\n\n if (searchValues.length === 0) {\n return false;\n }\n if (expectedValue === CATALOG_FILTER_EXISTS) {\n continue;\n }\n if (Array.isArray(expectedValue)) {\n return expectedValue.some(value =>\n searchValues?.includes(String(value).toLocaleLowerCase('en-US')),\n );\n }\n if (\n !searchValues?.includes(\n String(expectedValue).toLocaleLowerCase('en-US'),\n )\n ) {\n return false;\n }\n }\n return true;\n });\n };\n}\n\n// Resolves a dot-separated field path against an entity, handling keys that\n// themselves contain dots (e.g. annotation keys like \"backstage.io/orphan\").\n// This matches the backend's parseEntityTransformParams implementation.\nfunction getPathArrayAndValue(\n input: Entity,\n field: string,\n): [string[], unknown] {\n return field.split('.').reduce(\n ([pathArray, inputSubset], pathPart, index, fieldParts) => {\n if (lodash.hasIn(inputSubset, pathPart)) {\n return [pathArray.concat(pathPart), (inputSubset as any)[pathPart]];\n } else if (fieldParts[index + 1] !== undefined) {\n fieldParts[index + 1] = `${pathPart}.${fieldParts[index + 1]}`;\n return [pathArray, inputSubset];\n }\n return [pathArray, undefined];\n },\n [[] as string[], input as unknown],\n );\n}\n\nfunction applyFieldsFilter(entity: Entity, fields?: string[]): Entity {\n if (!fields?.length) {\n return entity;\n }\n const output: Record<string, any> = {};\n for (const field of fields) {\n const [pathArray, value] = getPathArrayAndValue(entity, field);\n if (value !== undefined) {\n lodash.set(output, pathArray, value);\n }\n }\n return output as Entity;\n}\n\nfunction applyOrdering(entities: Entity[], order?: EntityOrderQuery): Entity[] {\n if (!order) {\n return entities;\n }\n const orders = [order].flat();\n if (orders.length === 0) {\n return entities;\n }\n\n const searchMap = new Map<Entity, Array<{ key: string; value: unknown }>>();\n for (const entity of entities) {\n searchMap.set(entity, buildEntitySearch(entity));\n }\n\n return [...entities].sort((a, b) => {\n const aRows = searchMap.get(a)!;\n const bRows = searchMap.get(b)!;\n\n for (const { field, order: dir } of orders) {\n const key = field.toLocaleLowerCase('en-US');\n const aRow = aRows.find(r => r.key.toLocaleLowerCase('en-US') === key);\n const bRow = bRows.find(r => r.key.toLocaleLowerCase('en-US') === key);\n const aValue =\n aRow?.value !== null && aRow?.value !== undefined\n ? String(aRow.value).toLocaleLowerCase('en-US')\n : null;\n const bValue =\n bRow?.value !== null && bRow?.value !== undefined\n ? String(bRow.value).toLocaleLowerCase('en-US')\n : null;\n\n if (aValue === null && bValue === null) continue;\n if (aValue === null) return 1;\n if (bValue === null) return -1;\n\n if (aValue < bValue) return dir === 'asc' ? -1 : 1;\n if (aValue > bValue) return dir === 'asc' ? 1 : -1;\n }\n\n // Stable tie-breaker by entity ref, matching backend behavior\n const aRef = stringifyEntityRef(a);\n const bRef = stringifyEntityRef(b);\n if (aRef < bRef) return -1;\n if (aRef > bRef) return 1;\n return 0;\n });\n}\n\nfunction applyFullTextFilter(\n entities: Entity[],\n fullTextFilter?: { term: string; fields?: string[] },\n): Entity[] {\n if (!fullTextFilter?.term?.trim()) {\n return entities;\n }\n const term = fullTextFilter.term.trim().toLocaleLowerCase('en-US');\n const fields = fullTextFilter.fields?.map(f => f.toLocaleLowerCase('en-US'));\n\n return entities.filter(entity => {\n const rows = buildEntitySearch(entity);\n return rows.some(row => {\n if (\n fields?.length &&\n !fields.includes(row.key.toLocaleLowerCase('en-US'))\n ) {\n return false;\n }\n if (row.value === null || row.value === undefined) return false;\n const value = String(row.value).toLocaleLowerCase('en-US');\n return value.includes(term);\n });\n });\n}\n\n/**\n * Implements a fake catalog client that stores entities in memory.\n * Supports filtering, ordering, pagination, full-text search, and field\n * projection for entity query methods. Location and validation methods\n * throw {@link @backstage/errors#NotImplementedError}.\n *\n * @public\n */\nexport class InMemoryCatalogClient implements CatalogApi {\n #entities: Entity[];\n\n constructor(options?: { entities?: Entity[] }) {\n this.#entities = options?.entities?.slice() ?? [];\n }\n\n async getEntities(\n request?: GetEntitiesRequest,\n ): Promise<GetEntitiesResponse> {\n const filter = createFilter(request?.filter);\n let items = this.#entities.filter(filter);\n items = applyOrdering(items, request?.order);\n\n let offset = request?.offset ?? 0;\n let limit = request?.limit;\n\n if (request?.after) {\n try {\n const cursor = parseCursor(request.after);\n if (cursor.offset !== undefined) offset = cursor.offset as number;\n if (cursor.limit !== undefined) limit = cursor.limit as number;\n } catch {\n throw new InputError('Invalid cursor');\n }\n }\n\n if (offset > 0) {\n items = items.slice(offset);\n }\n if (limit !== undefined) {\n items = items.slice(0, limit);\n }\n\n return {\n items: request?.fields\n ? items.map(e => applyFieldsFilter(e, request.fields))\n : items,\n };\n }\n\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n ): Promise<GetEntitiesByRefsResponse> {\n const filter = createFilter(request.filter);\n const refMap = this.#createEntityRefMap();\n const items = request.entityRefs\n .map(ref => refMap.get(ref))\n .map(e => (e && filter(e) ? e : undefined));\n return {\n items: request.fields\n ? items.map(e => (e ? applyFieldsFilter(e, request.fields) : undefined))\n : items,\n };\n }\n\n async queryEntities(\n request?: QueryEntitiesRequest,\n ): Promise<QueryEntitiesResponse> {\n // Decode query parameters from cursor or from the request directly\n let filter: EntityFilterQuery | undefined;\n let orderFields: EntityOrderQuery | undefined;\n let fullTextFilter: { term: string; fields?: string[] } | undefined;\n let offset: number;\n let limit: number | undefined;\n\n if (request && 'cursor' in request) {\n let c: Record<string, unknown>;\n try {\n c = parseCursor(request.cursor);\n } catch {\n throw new InputError('Invalid cursor');\n }\n filter = deserializeFilter(c.filter as any[]);\n orderFields = c.orderFields as EntityOrderQuery | undefined;\n fullTextFilter = c.fullTextFilter as typeof fullTextFilter;\n offset = c.offset as number;\n limit = request.limit;\n } else {\n filter = request?.filter;\n orderFields = request?.orderFields;\n fullTextFilter = request?.fullTextFilter;\n offset = request?.offset ?? 0;\n limit = request?.limit;\n }\n\n // Apply filter\n let items = this.#entities.filter(createFilter(filter));\n\n // Apply full-text filter, defaulting to the sort field or metadata.uid\n if (fullTextFilter) {\n const orderFieldsList = orderFields ? [orderFields].flat() : [];\n items = applyFullTextFilter(items, {\n ...fullTextFilter,\n fields: fullTextFilter.fields ?? [\n orderFieldsList[0]?.field ?? 'metadata.uid',\n ],\n });\n }\n\n items = applyOrdering(items, orderFields);\n\n const totalItems = items.length;\n\n // No pagination requested, return all items\n if (limit === undefined && offset === 0) {\n return {\n items: request?.fields\n ? items.map(e => applyFieldsFilter(e, request?.fields))\n : items,\n pageInfo: {},\n totalItems,\n };\n }\n\n const effectiveLimit = limit ?? totalItems;\n const pageItems = items.slice(offset, offset + effectiveLimit);\n\n const cursorBase = {\n filter: serializeFilter(filter),\n orderFields,\n fullTextFilter,\n totalItems,\n };\n const pageInfo: QueryEntitiesResponse['pageInfo'] = {};\n if (offset + effectiveLimit < totalItems) {\n pageInfo.nextCursor = makeCursor({\n ...cursorBase,\n offset: offset + effectiveLimit,\n });\n }\n if (offset > 0) {\n pageInfo.prevCursor = makeCursor({\n ...cursorBase,\n offset: Math.max(0, offset - effectiveLimit),\n });\n }\n\n return {\n items: request?.fields\n ? pageItems.map(e => applyFieldsFilter(e, request?.fields))\n : pageItems,\n totalItems,\n pageInfo,\n };\n }\n\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n ): Promise<GetEntityAncestorsResponse> {\n const entity = this.#createEntityRefMap().get(request.entityRef);\n if (!entity) {\n throw new NotFoundError(`Entity with ref ${request.entityRef} not found`);\n }\n return {\n items: [{ entity, parentEntityRefs: [] }],\n rootEntityRef: request.entityRef,\n };\n }\n\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n ): Promise<Entity | undefined> {\n return this.#createEntityRefMap().get(\n stringifyEntityRef(parseEntityRef(entityRef)),\n );\n }\n\n async removeEntityByUid(uid: string): Promise<void> {\n const index = this.#entities.findIndex(e => e.metadata.uid === uid);\n if (index !== -1) {\n this.#entities.splice(index, 1);\n }\n }\n\n async refreshEntity(_entityRef: string): Promise<void> {}\n\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n ): Promise<GetEntityFacetsResponse> {\n const filter = createFilter(request.filter);\n const filteredEntities = this.#entities.filter(filter);\n const facets = Object.fromEntries(\n request.facets.map(facet => {\n const facetValues = new Map<string, number>();\n for (const entity of filteredEntities) {\n const rows = buildEntitySearch(entity);\n // Use a Set to count each distinct value once per entity,\n // matching the backend's count(DISTINCT entity_id) behavior\n const uniqueValues = new Set(\n rows\n .filter(\n row =>\n row.key.toLocaleLowerCase('en-US') ===\n facet.toLocaleLowerCase('en-US'),\n )\n .map(row => row.value)\n .filter(v => v !== null && v !== undefined)\n .map(v => String(v)),\n );\n for (const value of uniqueValues) {\n facetValues.set(value, (facetValues.get(value) ?? 0) + 1);\n }\n }\n const counts = Array.from(facetValues.entries()).map(\n ([value, count]) => ({ value, count }),\n );\n return [facet, counts];\n }),\n );\n return {\n facets,\n };\n }\n\n async getLocations(_request?: {}): Promise<GetLocationsResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async queryLocations(\n _request?: QueryLocationsRequest,\n ): Promise<QueryLocationsResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async *streamLocations(\n _request?: QueryLocationsInitialRequest,\n ): AsyncIterable<Location[]> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationById(_id: string): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationByRef(_locationRef: string): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async addLocation(\n _location: AddLocationRequest,\n ): Promise<AddLocationResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async removeLocationById(_id: string): Promise<void> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationByEntity(\n _entityRef: string | CompoundEntityRef,\n ): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async validateEntity(\n _entity: Entity,\n _locationRef: string,\n ): Promise<ValidateEntityResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async analyzeLocation(\n _location: AnalyzeLocationRequest,\n ): Promise<AnalyzeLocationResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async *streamEntities(\n request?: StreamEntitiesRequest,\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, limit, cursor } : { ...request, limit },\n );\n\n yield res.items;\n\n cursor = res.pageInfo.nextCursor;\n } while (cursor);\n }\n\n #createEntityRefMap() {\n return new Map(this.#entities.map(e => [stringifyEntityRef(e), e]));\n }\n}\n"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"InMemoryCatalogClient.esm.js","sources":["../../src/testUtils/InMemoryCatalogClient.ts"],"sourcesContent":["/*\n * Copyright 2024 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 AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n EntityFilterQuery,\n EntityOrderQuery,\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 '@backstage/catalog-client';\nimport {\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n InputError,\n NotFoundError,\n NotImplementedError,\n} from '@backstage/errors';\nimport {\n FilterPredicate,\n filterPredicateToFilterFunction,\n} from '@backstage/filter-predicates';\nimport lodash from 'lodash';\n// eslint-disable-next-line @backstage/no-relative-monorepo-imports\nimport { traverse } from '../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport { DEFAULT_STREAM_ENTITIES_LIMIT } from '../constants.ts';\n\nfunction makeCursor(data: Record<string, unknown>): string {\n return btoa(JSON.stringify(data));\n}\n\nfunction parseCursor(cursor: string): Record<string, unknown> {\n return JSON.parse(atob(cursor));\n}\n\n// CATALOG_FILTER_EXISTS is a Symbol that doesn't survive JSON serialization,\n// so we swap it with a sentinel string when encoding/decoding cursors.\nconst FILTER_EXISTS_SENTINEL = '\\0CATALOG_FILTER_EXISTS';\n\nfunction serializeFilterValue(v: unknown): unknown {\n if (v === CATALOG_FILTER_EXISTS) return FILTER_EXISTS_SENTINEL;\n if (Array.isArray(v)) {\n return v.map(x =>\n x === CATALOG_FILTER_EXISTS ? FILTER_EXISTS_SENTINEL : x,\n );\n }\n return v;\n}\n\nfunction deserializeFilterValue(v: unknown): unknown {\n if (v === FILTER_EXISTS_SENTINEL) return CATALOG_FILTER_EXISTS;\n if (Array.isArray(v)) {\n return v.map(x =>\n x === FILTER_EXISTS_SENTINEL ? CATALOG_FILTER_EXISTS : x,\n );\n }\n return v;\n}\n\nfunction serializeFilter(filter?: EntityFilterQuery): any[] | undefined {\n if (!filter) return undefined;\n return [filter]\n .flat()\n .map(f =>\n Object.fromEntries(\n Object.entries(f).map(([k, v]) => [k, serializeFilterValue(v)]),\n ),\n );\n}\n\nfunction deserializeFilter(filter?: any[]): EntityFilterQuery | undefined {\n if (!filter) return undefined;\n return filter.map(\n f =>\n Object.fromEntries(\n Object.entries(f).map(([k, v]: [string, any]) => [\n k,\n deserializeFilterValue(v),\n ]),\n ) as Record<string, string | symbol | (string | symbol)[]>,\n );\n}\n\nfunction buildEntitySearch(entity: Entity) {\n const rows = traverse(entity);\n\n if (entity.metadata?.name) {\n rows.push({\n key: 'metadata.name',\n value: entity.metadata.name.toLocaleLowerCase('en-US'),\n });\n }\n if (entity.metadata?.namespace) {\n rows.push({\n key: 'metadata.namespace',\n value: entity.metadata.namespace.toLocaleLowerCase('en-US'),\n });\n }\n if (entity.metadata?.uid) {\n rows.push({\n key: 'metadata.uid',\n value: entity.metadata.uid.toLocaleLowerCase('en-US'),\n });\n }\n\n if (!entity.metadata.namespace) {\n rows.push({ key: 'metadata.namespace', value: DEFAULT_NAMESPACE });\n }\n\n // Visit relations\n for (const relation of entity.relations ?? []) {\n rows.push({\n key: `relations.${relation.type.toLocaleLowerCase('en-US')}`,\n value: relation.targetRef.toLocaleLowerCase('en-US'),\n });\n }\n\n return rows;\n}\n\nfunction createFilter(\n filterOrFilters?: EntityFilterQuery,\n): (entity: Entity) => boolean {\n if (!filterOrFilters) {\n return () => true;\n }\n\n const filters = [filterOrFilters].flat();\n\n return entity => {\n const rows = buildEntitySearch(entity);\n\n return filters.some(filter => {\n for (const [key, expectedValue] of Object.entries(filter)) {\n const searchValues = rows\n .filter(row => row.key === key.toLocaleLowerCase('en-US'))\n .map(row => row.value?.toString().toLocaleLowerCase('en-US'));\n\n if (searchValues.length === 0) {\n return false;\n }\n if (expectedValue === CATALOG_FILTER_EXISTS) {\n continue;\n }\n if (Array.isArray(expectedValue)) {\n return expectedValue.some(value =>\n searchValues?.includes(String(value).toLocaleLowerCase('en-US')),\n );\n }\n if (\n !searchValues?.includes(\n String(expectedValue).toLocaleLowerCase('en-US'),\n )\n ) {\n return false;\n }\n }\n return true;\n });\n };\n}\n\n// Resolves a dot-separated field path against an entity, handling keys that\n// themselves contain dots (e.g. annotation keys like \"backstage.io/orphan\").\n// This matches the backend's parseEntityTransformParams implementation.\nfunction getPathArrayAndValue(\n input: Entity,\n field: string,\n): [string[], unknown] {\n return field.split('.').reduce(\n ([pathArray, inputSubset], pathPart, index, fieldParts) => {\n if (lodash.hasIn(inputSubset, pathPart)) {\n return [pathArray.concat(pathPart), (inputSubset as any)[pathPart]];\n } else if (fieldParts[index + 1] !== undefined) {\n fieldParts[index + 1] = `${pathPart}.${fieldParts[index + 1]}`;\n return [pathArray, inputSubset];\n }\n return [pathArray, undefined];\n },\n [[] as string[], input as unknown],\n );\n}\n\nfunction applyFieldsFilter(entity: Entity, fields?: string[]): Entity {\n if (!fields?.length) {\n return entity;\n }\n const output: Record<string, any> = {};\n for (const field of fields) {\n const [pathArray, value] = getPathArrayAndValue(entity, field);\n if (value !== undefined) {\n lodash.set(output, pathArray, value);\n }\n }\n return output as Entity;\n}\n\nfunction applyOrdering(entities: Entity[], order?: EntityOrderQuery): Entity[] {\n if (!order) {\n return entities;\n }\n const orders = [order].flat();\n if (orders.length === 0) {\n return entities;\n }\n\n const searchMap = new Map<Entity, Array<{ key: string; value: unknown }>>();\n for (const entity of entities) {\n searchMap.set(entity, buildEntitySearch(entity));\n }\n\n return [...entities].sort((a, b) => {\n const aRows = searchMap.get(a)!;\n const bRows = searchMap.get(b)!;\n\n for (const { field, order: dir } of orders) {\n const key = field.toLocaleLowerCase('en-US');\n const aRow = aRows.find(r => r.key.toLocaleLowerCase('en-US') === key);\n const bRow = bRows.find(r => r.key.toLocaleLowerCase('en-US') === key);\n const aValue =\n aRow?.value !== null && aRow?.value !== undefined\n ? String(aRow.value).toLocaleLowerCase('en-US')\n : null;\n const bValue =\n bRow?.value !== null && bRow?.value !== undefined\n ? String(bRow.value).toLocaleLowerCase('en-US')\n : null;\n\n if (aValue === null && bValue === null) continue;\n if (aValue === null) return 1;\n if (bValue === null) return -1;\n\n if (aValue < bValue) return dir === 'asc' ? -1 : 1;\n if (aValue > bValue) return dir === 'asc' ? 1 : -1;\n }\n\n // Stable tie-breaker by entity ref, matching backend behavior\n const aRef = stringifyEntityRef(a);\n const bRef = stringifyEntityRef(b);\n if (aRef < bRef) return -1;\n if (aRef > bRef) return 1;\n return 0;\n });\n}\n\nfunction applyFullTextFilter(\n entities: Entity[],\n fullTextFilter?: { term: string; fields?: string[] },\n): Entity[] {\n if (!fullTextFilter?.term?.trim()) {\n return entities;\n }\n const term = fullTextFilter.term.trim().toLocaleLowerCase('en-US');\n const fields = fullTextFilter.fields?.map(f => f.toLocaleLowerCase('en-US'));\n\n return entities.filter(entity => {\n const rows = buildEntitySearch(entity);\n return rows.some(row => {\n if (\n fields?.length &&\n !fields.includes(row.key.toLocaleLowerCase('en-US'))\n ) {\n return false;\n }\n if (row.value === null || row.value === undefined) return false;\n const value = String(row.value).toLocaleLowerCase('en-US');\n return value.includes(term);\n });\n });\n}\n\n/**\n * Implements a fake catalog client that stores entities in memory.\n * Supports filtering, ordering, pagination, full-text search, and field\n * projection for entity query methods. Location and validation methods\n * throw {@link @backstage/errors#NotImplementedError}.\n *\n * @public\n */\nexport class InMemoryCatalogClient implements CatalogApi {\n #entities: Entity[];\n\n constructor(options?: { entities?: Entity[] }) {\n this.#entities = options?.entities?.slice() ?? [];\n }\n\n async getEntities(\n request?: GetEntitiesRequest,\n ): Promise<GetEntitiesResponse> {\n const filter = createFilter(request?.filter);\n let items = this.#entities.filter(filter);\n items = applyOrdering(items, request?.order);\n\n let offset = request?.offset ?? 0;\n let limit = request?.limit;\n\n if (request?.after) {\n try {\n const cursor = parseCursor(request.after);\n if (cursor.offset !== undefined) offset = cursor.offset as number;\n if (cursor.limit !== undefined) limit = cursor.limit as number;\n } catch {\n throw new InputError('Invalid cursor');\n }\n }\n\n if (offset > 0) {\n items = items.slice(offset);\n }\n if (limit !== undefined) {\n items = items.slice(0, limit);\n }\n\n return {\n items: request?.fields\n ? items.map(e => applyFieldsFilter(e, request.fields))\n : items,\n };\n }\n\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n ): Promise<GetEntitiesByRefsResponse> {\n const filter = createFilter(request.filter);\n const queryFilter = request.query\n ? filterPredicateToFilterFunction(request.query)\n : undefined;\n const refMap = this.#createEntityRefMap();\n const items = request.entityRefs\n .map(ref => refMap.get(ref))\n .map(e =>\n e && filter(e) && (!queryFilter || queryFilter(e)) ? e : undefined,\n );\n return {\n items: request.fields\n ? items.map(e => (e ? applyFieldsFilter(e, request.fields) : undefined))\n : items,\n };\n }\n\n async queryEntities(\n request?: QueryEntitiesRequest,\n ): Promise<QueryEntitiesResponse> {\n // Decode query parameters from cursor or from the request directly\n let filter: EntityFilterQuery | undefined;\n let query: FilterPredicate | undefined;\n let orderFields: EntityOrderQuery | undefined;\n let fullTextFilter: { term: string; fields?: string[] } | undefined;\n let offset: number;\n let limit: number | undefined;\n\n if (request && 'cursor' in request) {\n let c: Record<string, unknown>;\n try {\n c = parseCursor(request.cursor);\n } catch {\n throw new InputError('Invalid cursor');\n }\n filter = deserializeFilter(c.filter as any[]);\n query = c.query as FilterPredicate | undefined;\n orderFields = c.orderFields as EntityOrderQuery | undefined;\n fullTextFilter = c.fullTextFilter as typeof fullTextFilter;\n offset = c.offset as number;\n limit = request.limit;\n } else {\n filter = request?.filter;\n query = request?.query;\n orderFields = request?.orderFields;\n fullTextFilter = request?.fullTextFilter;\n offset = request?.offset ?? 0;\n limit = request?.limit;\n }\n\n // Apply filter\n let items = this.#entities.filter(createFilter(filter));\n\n // Apply predicate-based query filter\n if (query) {\n items = items.filter(filterPredicateToFilterFunction(query));\n }\n\n // Apply full-text filter, defaulting to the sort field or metadata.uid\n if (fullTextFilter) {\n const orderFieldsList = orderFields ? [orderFields].flat() : [];\n items = applyFullTextFilter(items, {\n ...fullTextFilter,\n fields: fullTextFilter.fields ?? [\n orderFieldsList[0]?.field ?? 'metadata.uid',\n ],\n });\n }\n\n items = applyOrdering(items, orderFields);\n\n const totalItems = items.length;\n\n // No pagination requested, return all items\n if (limit === undefined && offset === 0) {\n return {\n items: request?.fields\n ? items.map(e => applyFieldsFilter(e, request?.fields))\n : items,\n pageInfo: {},\n totalItems,\n };\n }\n\n const effectiveLimit = limit ?? totalItems;\n const pageItems = items.slice(offset, offset + effectiveLimit);\n\n const cursorBase = {\n filter: serializeFilter(filter),\n query,\n orderFields,\n fullTextFilter,\n totalItems,\n };\n const pageInfo: QueryEntitiesResponse['pageInfo'] = {};\n if (offset + effectiveLimit < totalItems) {\n pageInfo.nextCursor = makeCursor({\n ...cursorBase,\n offset: offset + effectiveLimit,\n });\n }\n if (offset > 0) {\n pageInfo.prevCursor = makeCursor({\n ...cursorBase,\n offset: Math.max(0, offset - effectiveLimit),\n });\n }\n\n return {\n items: request?.fields\n ? pageItems.map(e => applyFieldsFilter(e, request?.fields))\n : pageItems,\n totalItems,\n pageInfo,\n };\n }\n\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n ): Promise<GetEntityAncestorsResponse> {\n const entity = this.#createEntityRefMap().get(request.entityRef);\n if (!entity) {\n throw new NotFoundError(`Entity with ref ${request.entityRef} not found`);\n }\n return {\n items: [{ entity, parentEntityRefs: [] }],\n rootEntityRef: request.entityRef,\n };\n }\n\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n ): Promise<Entity | undefined> {\n return this.#createEntityRefMap().get(\n stringifyEntityRef(parseEntityRef(entityRef)),\n );\n }\n\n async removeEntityByUid(uid: string): Promise<void> {\n const index = this.#entities.findIndex(e => e.metadata.uid === uid);\n if (index !== -1) {\n this.#entities.splice(index, 1);\n }\n }\n\n async refreshEntity(_entityRef: string): Promise<void> {}\n\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n ): Promise<GetEntityFacetsResponse> {\n const filter = createFilter(request.filter);\n let filteredEntities = this.#entities.filter(filter);\n if (request.query) {\n filteredEntities = filteredEntities.filter(\n filterPredicateToFilterFunction(request.query),\n );\n }\n const facets = Object.fromEntries(\n request.facets.map(facet => {\n const facetValues = new Map<string, number>();\n for (const entity of filteredEntities) {\n const rows = buildEntitySearch(entity);\n // Use a Set to count each distinct value once per entity,\n // matching the backend's count(DISTINCT entity_id) behavior\n const uniqueValues = new Set(\n rows\n .filter(\n row =>\n row.key.toLocaleLowerCase('en-US') ===\n facet.toLocaleLowerCase('en-US'),\n )\n .map(row => row.value)\n .filter(v => v !== null && v !== undefined)\n .map(v => String(v)),\n );\n for (const value of uniqueValues) {\n facetValues.set(value, (facetValues.get(value) ?? 0) + 1);\n }\n }\n const counts = Array.from(facetValues.entries()).map(\n ([value, count]) => ({ value, count }),\n );\n return [facet, counts];\n }),\n );\n return {\n facets,\n };\n }\n\n async getLocations(_request?: {}): Promise<GetLocationsResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async queryLocations(\n _request?: QueryLocationsRequest,\n ): Promise<QueryLocationsResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async *streamLocations(\n _request?: QueryLocationsInitialRequest,\n ): AsyncIterable<Location[]> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationById(_id: string): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationByRef(_locationRef: string): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async addLocation(\n _location: AddLocationRequest,\n ): Promise<AddLocationResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async removeLocationById(_id: string): Promise<void> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async getLocationByEntity(\n _entityRef: string | CompoundEntityRef,\n ): Promise<Location | undefined> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async validateEntity(\n _entity: Entity,\n _locationRef: string,\n ): Promise<ValidateEntityResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async analyzeLocation(\n _location: AnalyzeLocationRequest,\n ): Promise<AnalyzeLocationResponse> {\n throw new NotImplementedError('Method not implemented.');\n }\n\n async *streamEntities(\n request?: StreamEntitiesRequest,\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, limit, cursor } : { ...request, limit },\n );\n\n yield res.items;\n\n cursor = res.pageInfo.nextCursor;\n } while (cursor);\n }\n\n #createEntityRefMap() {\n return new Map(this.#entities.map(e => [stringifyEntityRef(e), e]));\n }\n}\n"],"names":[],"mappings":"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"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"api.cjs.js","sources":["../../src/types/api.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';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport { FilterPredicate } from '@backstage/filter-predicates';\n\n/**\n * This symbol can be used in place of a value when passed to filters in e.g.\n * {@link CatalogApi.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 * Dot-separated field based ordering directives, controlling the sort order of\n * the output entities.\n *\n * @remarks\n *\n * Each field is a dot-separated path into an entity's keys. The order is either\n * ascending (`asc`, lexicographical order) or descending (`desc`, reverse\n * lexicographical order). The ordering is case insensitive.\n *\n * If more than one order directive is given, later directives have lower\n * precedence (they are applied only when directives of higher precedence have\n * equal values).\n *\n * Example:\n *\n * ```\n * [\n * { field: 'kind', order: 'asc' },\n * { field: 'metadata.name', order: 'desc' },\n * ]\n * ```\n *\n * This will order the output first by kind ascending, and then within each kind\n * (if there's more than one of a given kind) by their name descending.\n *\n * When given a field that does NOT exist on all entities in the result set,\n * those entities that do not have the field will always be sorted last in that\n * particular order step, no matter what the desired order was.\n *\n * @public\n */\nexport type EntityOrderQuery =\n | {\n field: string;\n order: 'asc' | 'desc';\n }\n | Array<{\n field: string;\n order: 'asc' | 'desc';\n }>;\n\n/**\n * The request type for {@link CatalogApi.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, order the result set by those directives.\n */\n order?: EntityOrderQuery;\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 CatalogApi.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesResponse {\n items: Entity[];\n}\n\n/**\n * The request type for {@link CatalogApi.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 * undefined 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 * If given, return only entities that match the given filter.\n */\n filter?: EntityFilterQuery;\n}\n\n/**\n * The response type for {@link CatalogApi.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 * undefined 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 CatalogApi.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsRequest {\n entityRef: string;\n}\n\n/**\n * The response type for {@link CatalogApi.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 CatalogApi.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?: EntityFilterQuery;\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 CatalogApi.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 response type for {@link CatalogApi.getLocations}\n *\n * @public\n */\nexport interface GetLocationsResponse {\n items: Location[];\n}\n\n/**\n * The request type for {@link CatalogApi.addLocation}.\n *\n * @public\n */\nexport type AddLocationRequest = {\n type?: string;\n target: string;\n /**\n * If set to true, the location will not be added, but the response will\n * contain the entities that match the given location.\n */\n dryRun?: boolean;\n};\n\n/**\n * The response type for {@link CatalogApi.addLocation}.\n *\n * @public\n */\nexport type AddLocationResponse = {\n location: Location;\n /**\n * The entities matching this location. Will only be filled in dryRun mode\n */\n entities: Entity[];\n /**\n * True, if the location exists. Will only be filled in dryRun mode\n */\n exists?: boolean;\n};\n\n/**\n * The response type for {@link CatalogApi.validateEntity}\n *\n * @public\n */\nexport type ValidateEntityResponse =\n | { valid: true }\n | { valid: false; errors: SerializedError[] };\n\n/**\n * The request type for {@link CatalogApi.queryEntities}.\n *\n * @public\n */\nexport type QueryEntitiesRequest =\n | QueryEntitiesInitialRequest\n | QueryEntitiesCursorRequest;\n\n/**\n * A request type for {@link CatalogApi.queryEntities}.\n * The method takes this type in an initial pagination request,\n * when requesting the first batch of entities.\n *\n * The properties filter, sortField, query and sortFieldOrder, are going\n * to be immutable for the entire lifecycle of the following requests.\n *\n * @public\n */\nexport type QueryEntitiesInitialRequest = {\n fields?: string[];\n limit?: number;\n offset?: number;\n filter?: EntityFilterQuery;\n orderFields?: EntityOrderQuery;\n fullTextFilter?: {\n term: string;\n fields?: string[];\n };\n};\n\n/**\n * A request type for {@link CatalogApi.queryEntities}.\n * The method takes this type in a pagination request, following\n * the initial request.\n *\n * @public\n */\nexport type QueryEntitiesCursorRequest = {\n fields?: string[];\n limit?: number;\n cursor: string;\n};\n\n/**\n * The response type for {@link CatalogApi.queryEntities}.\n *\n * @public\n */\nexport type QueryEntitiesResponse = {\n /* The list of entities for the current request */\n items: Entity[];\n /* The number of entities among all the requests */\n totalItems: number;\n pageInfo: {\n /* The cursor for the next batch of entities */\n nextCursor?: string;\n /* The cursor for the previous batch of entities */\n prevCursor?: string;\n };\n};\n\n/**\n * Stream entities request for {@link CatalogApi.streamEntities}.\n *\n * @public\n */\nexport type StreamEntitiesRequest = Omit<\n QueryEntitiesInitialRequest,\n 'limit' | 'offset'\n> & {\n /**\n * The number of entities to fetch in each page. Defaults to 500.\n */\n pageSize?: number;\n};\n\n/**\n * The request type for {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport type QueryLocationsRequest =\n | QueryLocationsInitialRequest\n | QueryLocationsCursorRequest;\n\n/**\n * The request type for initial requests to {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsInitialRequest {\n limit?: number;\n query?: FilterPredicate;\n}\n\n/**\n * The request type for cursor requests to {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsCursorRequest {\n cursor: string;\n}\n\n/**\n * The response type for {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsResponse {\n items: Location[];\n totalItems: number;\n pageInfo: {\n nextCursor?: string;\n };\n}\n\n/**\n * A client for interacting with the Backstage software catalog through its API.\n *\n * @public\n */\nexport interface CatalogApi {\n /**\n * Lists catalog entities.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse>;\n\n /**\n * Gets 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 undefined.\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 paginated entities from the catalog.\n *\n * @remarks\n *\n * @example\n *\n * ```\n * const response = await catalogClient.queryEntities({\n * filter: [{ kind: 'group' }],\n * limit: 20,\n * fullTextFilter: {\n * term: 'A',\n * },\n * orderFields: { field: 'metadata.name', order: 'asc' },\n * });\n * ```\n *\n * this will match all entities of type group having a name starting\n * with 'A', ordered by name ascending.\n *\n * The response will contain a maximum of 20 entities. In case\n * more than 20 entities exist, the response will contain a nextCursor\n * property that can be used to fetch the next batch of entities.\n *\n * ```\n * const secondBatchResponse = await catalogClient\n * .queryEntities({ cursor: response.nextCursor });\n * ```\n *\n * secondBatchResponse will contain the next batch of (maximum) 20 entities,\n * together with a prevCursor property, useful to fetch the previous batch.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n queryEntities(\n request?: QueryEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse>;\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 * List locations\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getLocations(\n request?: {},\n options?: CatalogRequestOptions,\n ): Promise<GetLocationsResponse>;\n\n /**\n * Gets paginated locations from the catalog.\n *\n * @remarks\n *\n * @example\n *\n * ```\n * const response = await catalogClient.queryLocations({\n * limit: 20,\n * query: {\n * type: 'url',\n * target: { $hasPrefix: 'https://github.com/backstage/backstage' },\n * },\n * });\n * ```\n *\n * This will match all locations of type `url` having a target starting\n * with `https://github.com/backstage/backstage`.\n *\n * The response will contain a maximum of 20 locations. In case\n * more than 20 locations exist, the response will contain a `nextCursor`\n * property that can be used to fetch the next batch of locations.\n *\n * ```\n * const secondBatchResponse = await catalogClient\n * .queryLocations({ cursor: response.pageInfo.nextCursor });\n * ```\n *\n * `secondBatchResponse` will contain the next batch of (maximum) 20 locations,\n * again together with a `nextCursor` property if there is more data to fetch.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n queryLocations(\n request?: QueryLocationsRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryLocationsResponse>;\n\n /**\n * Asynchronously streams locations from the catalog. Uses `queryLocations`\n * to fetch locations in batches, and yields them one page at a time.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n streamLocations(\n request?: QueryLocationsInitialRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Location[]>;\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 * Gets a location associated with an entity.\n *\n * @param entityRef - A complete entity ref, either on string or compound form\n * @param options - Additional options\n */\n getLocationByEntity(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\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 * @param options - Additional options\n */\n validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse>;\n\n /**\n * Validate a given location.\n *\n * @param location - Request parameters\n * @param options - Additional options\n */\n analyzeLocation(\n location: AnalyzeLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AnalyzeLocationResponse>;\n\n /**\n * Asynchronously streams entities from the catalog. Uses `queryEntities`\n * to fetch entities in batches, and yields them one page at a time.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n streamEntities(\n request?: StreamEntitiesRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Entity[]>;\n}\n"],"names":[],"mappings":";;AA+BO,MAAM,wCAAwB,MAAA,CAAO,GAAA;AAAA;AAAA,EAE1C;AACF;;;;"} | ||
| {"version":3,"file":"api.cjs.js","sources":["../../src/types/api.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 type { CompoundEntityRef, Entity } from '@backstage/catalog-model';\nimport type { SerializedError } from '@backstage/errors';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport type { FilterPredicate } from '@backstage/filter-predicates';\n\n/**\n * This symbol can be used in place of a value when passed to filters in e.g.\n * {@link CatalogApi.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 * Dot-separated field based ordering directives, controlling the sort order of\n * the output entities.\n *\n * @remarks\n *\n * Each field is a dot-separated path into an entity's keys. The order is either\n * ascending (`asc`, lexicographical order) or descending (`desc`, reverse\n * lexicographical order). The ordering is case insensitive.\n *\n * If more than one order directive is given, later directives have lower\n * precedence (they are applied only when directives of higher precedence have\n * equal values).\n *\n * Example:\n *\n * ```\n * [\n * { field: 'kind', order: 'asc' },\n * { field: 'metadata.name', order: 'desc' },\n * ]\n * ```\n *\n * This will order the output first by kind ascending, and then within each kind\n * (if there's more than one of a given kind) by their name descending.\n *\n * When given a field that does NOT exist on all entities in the result set,\n * those entities that do not have the field will always be sorted last in that\n * particular order step, no matter what the desired order was.\n *\n * @public\n */\nexport type EntityOrderQuery =\n | {\n field: string;\n order: 'asc' | 'desc';\n }\n | Array<{\n field: string;\n order: 'asc' | 'desc';\n }>;\n\n/**\n * The request type for {@link CatalogApi.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, order the result set by those directives.\n */\n order?: EntityOrderQuery;\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 CatalogApi.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesResponse {\n items: Entity[];\n}\n\n/**\n * The request type for {@link CatalogApi.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 * undefined 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 * If given, return only entities that match the given filter.\n */\n filter?: EntityFilterQuery;\n /**\n * If given, return only entities that match the given predicate query.\n *\n * @remarks\n *\n * Supports operators like `$all`, `$any`, `$not`, `$exists`, `$in`,\n * `$contains`, and `$hasPrefix`. When both `filter` and `query` are\n * provided, they are combined with `$all`.\n */\n query?: FilterPredicate;\n}\n\n/**\n * The response type for {@link CatalogApi.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 * undefined 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 CatalogApi.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsRequest {\n entityRef: string;\n}\n\n/**\n * The response type for {@link CatalogApi.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 CatalogApi.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?: EntityFilterQuery;\n /**\n * If given, return only entities that match the given predicate query.\n *\n * @remarks\n *\n * Supports operators like `$all`, `$any`, `$not`, `$exists`, `$in`,\n * `$contains`, and `$hasPrefix`. When both `filter` and `query` are\n * provided, they are combined with `$all`.\n */\n query?: FilterPredicate;\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 CatalogApi.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 response type for {@link CatalogApi.getLocations}\n *\n * @public\n */\nexport interface GetLocationsResponse {\n items: Location[];\n}\n\n/**\n * The request type for {@link CatalogApi.addLocation}.\n *\n * @public\n */\nexport type AddLocationRequest = {\n type?: string;\n target: string;\n /**\n * If set to true, the location will not be added, but the response will\n * contain the entities that match the given location.\n */\n dryRun?: boolean;\n};\n\n/**\n * The response type for {@link CatalogApi.addLocation}.\n *\n * @public\n */\nexport type AddLocationResponse = {\n location: Location;\n /**\n * The entities matching this location. Will only be filled in dryRun mode\n */\n entities: Entity[];\n /**\n * True, if the location exists. Will only be filled in dryRun mode\n */\n exists?: boolean;\n};\n\n/**\n * The response type for {@link CatalogApi.validateEntity}\n *\n * @public\n */\nexport type ValidateEntityResponse =\n | { valid: true }\n | { valid: false; errors: SerializedError[] };\n\n/**\n * The request type for {@link CatalogApi.queryEntities}.\n *\n * @public\n */\nexport type QueryEntitiesRequest =\n | QueryEntitiesInitialRequest\n | QueryEntitiesCursorRequest;\n\n/**\n * A request type for {@link CatalogApi.queryEntities}.\n * The method takes this type in an initial pagination request,\n * when requesting the first batch of entities.\n *\n * The properties filter, query, sortField and sortFieldOrder, are going\n * to be immutable for the entire lifecycle of the following requests.\n *\n * @remarks\n *\n * Either `filter` or `query` can be provided, or even both:\n * - `filter`: Uses the traditional key-value filter syntax (GET endpoint)\n * - `query`: Uses the predicate-based filter syntax with logical operators (POST endpoint)\n *\n * @public\n */\nexport type QueryEntitiesInitialRequest = {\n fields?: string[];\n limit?: number;\n offset?: number;\n /**\n * Traditional key-value based filter.\n */\n filter?: EntityFilterQuery;\n /**\n * Predicate-based filter with operators for logical expressions (`$all`,\n * `$any`, and `$not`) and matching (`$exists`, `$in`, `$hasPrefix`, and\n * (partially) `$contains`).\n *\n * @example\n * ```typescript\n * {\n * query: {\n * $all: [\n * { kind: 'component' },\n * { 'spec.type': { $in: ['service', 'website'] } }\n * ]\n * }\n * }\n * ```\n */\n query?: FilterPredicate;\n orderFields?: EntityOrderQuery;\n fullTextFilter?: {\n term: string;\n fields?: string[];\n };\n};\n\n/**\n * A request type for {@link CatalogApi.queryEntities}.\n * The method takes this type in a pagination request, following\n * the initial request.\n *\n * @public\n */\nexport type QueryEntitiesCursorRequest = {\n fields?: string[];\n limit?: number;\n cursor: string;\n};\n\n/**\n * The response type for {@link CatalogApi.queryEntities}.\n *\n * @public\n */\nexport type QueryEntitiesResponse = {\n /* The list of entities for the current request */\n items: Entity[];\n /* The number of entities among all the requests */\n totalItems: number;\n pageInfo: {\n /* The cursor for the next batch of entities */\n nextCursor?: string;\n /* The cursor for the previous batch of entities */\n prevCursor?: string;\n };\n};\n\n/**\n * Stream entities request for {@link CatalogApi.streamEntities}.\n *\n * @public\n */\nexport type StreamEntitiesRequest = Omit<\n QueryEntitiesInitialRequest,\n 'limit' | 'offset'\n> & {\n /**\n * The number of entities to fetch in each page. Defaults to 500.\n */\n pageSize?: number;\n};\n\n/**\n * The request type for {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport type QueryLocationsRequest =\n | QueryLocationsInitialRequest\n | QueryLocationsCursorRequest;\n\n/**\n * The request type for initial requests to {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsInitialRequest {\n limit?: number;\n query?: FilterPredicate;\n}\n\n/**\n * The request type for cursor requests to {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsCursorRequest {\n cursor: string;\n}\n\n/**\n * The response type for {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsResponse {\n items: Location[];\n totalItems: number;\n pageInfo: {\n nextCursor?: string;\n };\n}\n\n/**\n * A client for interacting with the Backstage software catalog through its API.\n *\n * @public\n */\nexport interface CatalogApi {\n /**\n * Lists catalog entities.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse>;\n\n /**\n * Gets 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 undefined.\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 paginated entities from the catalog.\n *\n * @remarks\n *\n * @example\n *\n * ```\n * const response = await catalogClient.queryEntities({\n * filter: [{ kind: 'group' }],\n * limit: 20,\n * fields: ['metadata', 'kind'],\n * fullTextFilter: {\n * term: 'A',\n * },\n * orderFields: { field: 'metadata.name', order: 'asc' },\n * });\n * ```\n *\n * this will match all entities of type group having a name starting\n * with 'A', ordered by name ascending.\n *\n * The response will contain a maximum of 20 entities. In case\n * more than 20 entities exist, the response will contain a nextCursor\n * property that can be used to fetch the next batch of entities.\n *\n * ```\n * const secondBatchResponse = await catalogClient\n * .queryEntities({\n * cursor: response.nextCursor,\n * limit: 20,\n * fields: ['metadata', 'kind'],\n * });\n * ```\n *\n * `secondBatchResponse` will contain the next batch of (maximum) 20 entities,\n * together with a `prevCursor` property, useful to fetch the previous batch.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n queryEntities(\n request?: QueryEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse>;\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 * List locations\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getLocations(\n request?: {},\n options?: CatalogRequestOptions,\n ): Promise<GetLocationsResponse>;\n\n /**\n * Gets paginated locations from the catalog.\n *\n * @remarks\n *\n * @example\n *\n * ```\n * const response = await catalogClient.queryLocations({\n * limit: 20,\n * query: {\n * type: 'url',\n * target: { $hasPrefix: 'https://github.com/backstage/backstage' },\n * },\n * });\n * ```\n *\n * This will match all locations of type `url` having a target starting\n * with `https://github.com/backstage/backstage`.\n *\n * The response will contain a maximum of 20 locations. In case\n * more than 20 locations exist, the response will contain a `nextCursor`\n * property that can be used to fetch the next batch of locations.\n *\n * ```\n * const secondBatchResponse = await catalogClient\n * .queryLocations({ cursor: response.pageInfo.nextCursor });\n * ```\n *\n * `secondBatchResponse` will contain the next batch of (maximum) 20 locations,\n * again together with a `nextCursor` property if there is more data to fetch.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n queryLocations(\n request?: QueryLocationsRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryLocationsResponse>;\n\n /**\n * Asynchronously streams locations from the catalog. Uses `queryLocations`\n * to fetch locations in batches, and yields them one page at a time.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n streamLocations(\n request?: QueryLocationsInitialRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Location[]>;\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 * Gets a location associated with an entity.\n *\n * @param entityRef - A complete entity ref, either on string or compound form\n * @param options - Additional options\n */\n getLocationByEntity(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\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 * @param options - Additional options\n */\n validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse>;\n\n /**\n * Validate a given location.\n *\n * @param location - Request parameters\n * @param options - Additional options\n */\n analyzeLocation(\n location: AnalyzeLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AnalyzeLocationResponse>;\n\n /**\n * Asynchronously streams entities from the catalog. Uses `queryEntities`\n * to fetch entities in batches, and yields them one page at a time.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n streamEntities(\n request?: StreamEntitiesRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Entity[]>;\n}\n"],"names":[],"mappings":";;AA+BO,MAAM,wCAAwB,MAAA,CAAO,GAAA;AAAA;AAAA,EAE1C;AACF;;;;"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"api.esm.js","sources":["../../src/types/api.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';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport { FilterPredicate } from '@backstage/filter-predicates';\n\n/**\n * This symbol can be used in place of a value when passed to filters in e.g.\n * {@link CatalogApi.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 * Dot-separated field based ordering directives, controlling the sort order of\n * the output entities.\n *\n * @remarks\n *\n * Each field is a dot-separated path into an entity's keys. The order is either\n * ascending (`asc`, lexicographical order) or descending (`desc`, reverse\n * lexicographical order). The ordering is case insensitive.\n *\n * If more than one order directive is given, later directives have lower\n * precedence (they are applied only when directives of higher precedence have\n * equal values).\n *\n * Example:\n *\n * ```\n * [\n * { field: 'kind', order: 'asc' },\n * { field: 'metadata.name', order: 'desc' },\n * ]\n * ```\n *\n * This will order the output first by kind ascending, and then within each kind\n * (if there's more than one of a given kind) by their name descending.\n *\n * When given a field that does NOT exist on all entities in the result set,\n * those entities that do not have the field will always be sorted last in that\n * particular order step, no matter what the desired order was.\n *\n * @public\n */\nexport type EntityOrderQuery =\n | {\n field: string;\n order: 'asc' | 'desc';\n }\n | Array<{\n field: string;\n order: 'asc' | 'desc';\n }>;\n\n/**\n * The request type for {@link CatalogApi.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, order the result set by those directives.\n */\n order?: EntityOrderQuery;\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 CatalogApi.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesResponse {\n items: Entity[];\n}\n\n/**\n * The request type for {@link CatalogApi.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 * undefined 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 * If given, return only entities that match the given filter.\n */\n filter?: EntityFilterQuery;\n}\n\n/**\n * The response type for {@link CatalogApi.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 * undefined 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 CatalogApi.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsRequest {\n entityRef: string;\n}\n\n/**\n * The response type for {@link CatalogApi.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 CatalogApi.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?: EntityFilterQuery;\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 CatalogApi.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 response type for {@link CatalogApi.getLocations}\n *\n * @public\n */\nexport interface GetLocationsResponse {\n items: Location[];\n}\n\n/**\n * The request type for {@link CatalogApi.addLocation}.\n *\n * @public\n */\nexport type AddLocationRequest = {\n type?: string;\n target: string;\n /**\n * If set to true, the location will not be added, but the response will\n * contain the entities that match the given location.\n */\n dryRun?: boolean;\n};\n\n/**\n * The response type for {@link CatalogApi.addLocation}.\n *\n * @public\n */\nexport type AddLocationResponse = {\n location: Location;\n /**\n * The entities matching this location. Will only be filled in dryRun mode\n */\n entities: Entity[];\n /**\n * True, if the location exists. Will only be filled in dryRun mode\n */\n exists?: boolean;\n};\n\n/**\n * The response type for {@link CatalogApi.validateEntity}\n *\n * @public\n */\nexport type ValidateEntityResponse =\n | { valid: true }\n | { valid: false; errors: SerializedError[] };\n\n/**\n * The request type for {@link CatalogApi.queryEntities}.\n *\n * @public\n */\nexport type QueryEntitiesRequest =\n | QueryEntitiesInitialRequest\n | QueryEntitiesCursorRequest;\n\n/**\n * A request type for {@link CatalogApi.queryEntities}.\n * The method takes this type in an initial pagination request,\n * when requesting the first batch of entities.\n *\n * The properties filter, sortField, query and sortFieldOrder, are going\n * to be immutable for the entire lifecycle of the following requests.\n *\n * @public\n */\nexport type QueryEntitiesInitialRequest = {\n fields?: string[];\n limit?: number;\n offset?: number;\n filter?: EntityFilterQuery;\n orderFields?: EntityOrderQuery;\n fullTextFilter?: {\n term: string;\n fields?: string[];\n };\n};\n\n/**\n * A request type for {@link CatalogApi.queryEntities}.\n * The method takes this type in a pagination request, following\n * the initial request.\n *\n * @public\n */\nexport type QueryEntitiesCursorRequest = {\n fields?: string[];\n limit?: number;\n cursor: string;\n};\n\n/**\n * The response type for {@link CatalogApi.queryEntities}.\n *\n * @public\n */\nexport type QueryEntitiesResponse = {\n /* The list of entities for the current request */\n items: Entity[];\n /* The number of entities among all the requests */\n totalItems: number;\n pageInfo: {\n /* The cursor for the next batch of entities */\n nextCursor?: string;\n /* The cursor for the previous batch of entities */\n prevCursor?: string;\n };\n};\n\n/**\n * Stream entities request for {@link CatalogApi.streamEntities}.\n *\n * @public\n */\nexport type StreamEntitiesRequest = Omit<\n QueryEntitiesInitialRequest,\n 'limit' | 'offset'\n> & {\n /**\n * The number of entities to fetch in each page. Defaults to 500.\n */\n pageSize?: number;\n};\n\n/**\n * The request type for {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport type QueryLocationsRequest =\n | QueryLocationsInitialRequest\n | QueryLocationsCursorRequest;\n\n/**\n * The request type for initial requests to {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsInitialRequest {\n limit?: number;\n query?: FilterPredicate;\n}\n\n/**\n * The request type for cursor requests to {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsCursorRequest {\n cursor: string;\n}\n\n/**\n * The response type for {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsResponse {\n items: Location[];\n totalItems: number;\n pageInfo: {\n nextCursor?: string;\n };\n}\n\n/**\n * A client for interacting with the Backstage software catalog through its API.\n *\n * @public\n */\nexport interface CatalogApi {\n /**\n * Lists catalog entities.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse>;\n\n /**\n * Gets 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 undefined.\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 paginated entities from the catalog.\n *\n * @remarks\n *\n * @example\n *\n * ```\n * const response = await catalogClient.queryEntities({\n * filter: [{ kind: 'group' }],\n * limit: 20,\n * fullTextFilter: {\n * term: 'A',\n * },\n * orderFields: { field: 'metadata.name', order: 'asc' },\n * });\n * ```\n *\n * this will match all entities of type group having a name starting\n * with 'A', ordered by name ascending.\n *\n * The response will contain a maximum of 20 entities. In case\n * more than 20 entities exist, the response will contain a nextCursor\n * property that can be used to fetch the next batch of entities.\n *\n * ```\n * const secondBatchResponse = await catalogClient\n * .queryEntities({ cursor: response.nextCursor });\n * ```\n *\n * secondBatchResponse will contain the next batch of (maximum) 20 entities,\n * together with a prevCursor property, useful to fetch the previous batch.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n queryEntities(\n request?: QueryEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse>;\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 * List locations\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getLocations(\n request?: {},\n options?: CatalogRequestOptions,\n ): Promise<GetLocationsResponse>;\n\n /**\n * Gets paginated locations from the catalog.\n *\n * @remarks\n *\n * @example\n *\n * ```\n * const response = await catalogClient.queryLocations({\n * limit: 20,\n * query: {\n * type: 'url',\n * target: { $hasPrefix: 'https://github.com/backstage/backstage' },\n * },\n * });\n * ```\n *\n * This will match all locations of type `url` having a target starting\n * with `https://github.com/backstage/backstage`.\n *\n * The response will contain a maximum of 20 locations. In case\n * more than 20 locations exist, the response will contain a `nextCursor`\n * property that can be used to fetch the next batch of locations.\n *\n * ```\n * const secondBatchResponse = await catalogClient\n * .queryLocations({ cursor: response.pageInfo.nextCursor });\n * ```\n *\n * `secondBatchResponse` will contain the next batch of (maximum) 20 locations,\n * again together with a `nextCursor` property if there is more data to fetch.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n queryLocations(\n request?: QueryLocationsRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryLocationsResponse>;\n\n /**\n * Asynchronously streams locations from the catalog. Uses `queryLocations`\n * to fetch locations in batches, and yields them one page at a time.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n streamLocations(\n request?: QueryLocationsInitialRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Location[]>;\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 * Gets a location associated with an entity.\n *\n * @param entityRef - A complete entity ref, either on string or compound form\n * @param options - Additional options\n */\n getLocationByEntity(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\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 * @param options - Additional options\n */\n validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse>;\n\n /**\n * Validate a given location.\n *\n * @param location - Request parameters\n * @param options - Additional options\n */\n analyzeLocation(\n location: AnalyzeLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AnalyzeLocationResponse>;\n\n /**\n * Asynchronously streams entities from the catalog. Uses `queryEntities`\n * to fetch entities in batches, and yields them one page at a time.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n streamEntities(\n request?: StreamEntitiesRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Entity[]>;\n}\n"],"names":[],"mappings":"AA+BO,MAAM,wCAAwB,MAAA,CAAO,GAAA;AAAA;AAAA,EAE1C;AACF;;;;"} | ||
| {"version":3,"file":"api.esm.js","sources":["../../src/types/api.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 type { CompoundEntityRef, Entity } from '@backstage/catalog-model';\nimport type { SerializedError } from '@backstage/errors';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport type { FilterPredicate } from '@backstage/filter-predicates';\n\n/**\n * This symbol can be used in place of a value when passed to filters in e.g.\n * {@link CatalogApi.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 * Dot-separated field based ordering directives, controlling the sort order of\n * the output entities.\n *\n * @remarks\n *\n * Each field is a dot-separated path into an entity's keys. The order is either\n * ascending (`asc`, lexicographical order) or descending (`desc`, reverse\n * lexicographical order). The ordering is case insensitive.\n *\n * If more than one order directive is given, later directives have lower\n * precedence (they are applied only when directives of higher precedence have\n * equal values).\n *\n * Example:\n *\n * ```\n * [\n * { field: 'kind', order: 'asc' },\n * { field: 'metadata.name', order: 'desc' },\n * ]\n * ```\n *\n * This will order the output first by kind ascending, and then within each kind\n * (if there's more than one of a given kind) by their name descending.\n *\n * When given a field that does NOT exist on all entities in the result set,\n * those entities that do not have the field will always be sorted last in that\n * particular order step, no matter what the desired order was.\n *\n * @public\n */\nexport type EntityOrderQuery =\n | {\n field: string;\n order: 'asc' | 'desc';\n }\n | Array<{\n field: string;\n order: 'asc' | 'desc';\n }>;\n\n/**\n * The request type for {@link CatalogApi.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, order the result set by those directives.\n */\n order?: EntityOrderQuery;\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 CatalogApi.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesResponse {\n items: Entity[];\n}\n\n/**\n * The request type for {@link CatalogApi.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 * undefined 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 * If given, return only entities that match the given filter.\n */\n filter?: EntityFilterQuery;\n /**\n * If given, return only entities that match the given predicate query.\n *\n * @remarks\n *\n * Supports operators like `$all`, `$any`, `$not`, `$exists`, `$in`,\n * `$contains`, and `$hasPrefix`. When both `filter` and `query` are\n * provided, they are combined with `$all`.\n */\n query?: FilterPredicate;\n}\n\n/**\n * The response type for {@link CatalogApi.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 * undefined 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 CatalogApi.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsRequest {\n entityRef: string;\n}\n\n/**\n * The response type for {@link CatalogApi.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 CatalogApi.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?: EntityFilterQuery;\n /**\n * If given, return only entities that match the given predicate query.\n *\n * @remarks\n *\n * Supports operators like `$all`, `$any`, `$not`, `$exists`, `$in`,\n * `$contains`, and `$hasPrefix`. When both `filter` and `query` are\n * provided, they are combined with `$all`.\n */\n query?: FilterPredicate;\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 CatalogApi.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 response type for {@link CatalogApi.getLocations}\n *\n * @public\n */\nexport interface GetLocationsResponse {\n items: Location[];\n}\n\n/**\n * The request type for {@link CatalogApi.addLocation}.\n *\n * @public\n */\nexport type AddLocationRequest = {\n type?: string;\n target: string;\n /**\n * If set to true, the location will not be added, but the response will\n * contain the entities that match the given location.\n */\n dryRun?: boolean;\n};\n\n/**\n * The response type for {@link CatalogApi.addLocation}.\n *\n * @public\n */\nexport type AddLocationResponse = {\n location: Location;\n /**\n * The entities matching this location. Will only be filled in dryRun mode\n */\n entities: Entity[];\n /**\n * True, if the location exists. Will only be filled in dryRun mode\n */\n exists?: boolean;\n};\n\n/**\n * The response type for {@link CatalogApi.validateEntity}\n *\n * @public\n */\nexport type ValidateEntityResponse =\n | { valid: true }\n | { valid: false; errors: SerializedError[] };\n\n/**\n * The request type for {@link CatalogApi.queryEntities}.\n *\n * @public\n */\nexport type QueryEntitiesRequest =\n | QueryEntitiesInitialRequest\n | QueryEntitiesCursorRequest;\n\n/**\n * A request type for {@link CatalogApi.queryEntities}.\n * The method takes this type in an initial pagination request,\n * when requesting the first batch of entities.\n *\n * The properties filter, query, sortField and sortFieldOrder, are going\n * to be immutable for the entire lifecycle of the following requests.\n *\n * @remarks\n *\n * Either `filter` or `query` can be provided, or even both:\n * - `filter`: Uses the traditional key-value filter syntax (GET endpoint)\n * - `query`: Uses the predicate-based filter syntax with logical operators (POST endpoint)\n *\n * @public\n */\nexport type QueryEntitiesInitialRequest = {\n fields?: string[];\n limit?: number;\n offset?: number;\n /**\n * Traditional key-value based filter.\n */\n filter?: EntityFilterQuery;\n /**\n * Predicate-based filter with operators for logical expressions (`$all`,\n * `$any`, and `$not`) and matching (`$exists`, `$in`, `$hasPrefix`, and\n * (partially) `$contains`).\n *\n * @example\n * ```typescript\n * {\n * query: {\n * $all: [\n * { kind: 'component' },\n * { 'spec.type': { $in: ['service', 'website'] } }\n * ]\n * }\n * }\n * ```\n */\n query?: FilterPredicate;\n orderFields?: EntityOrderQuery;\n fullTextFilter?: {\n term: string;\n fields?: string[];\n };\n};\n\n/**\n * A request type for {@link CatalogApi.queryEntities}.\n * The method takes this type in a pagination request, following\n * the initial request.\n *\n * @public\n */\nexport type QueryEntitiesCursorRequest = {\n fields?: string[];\n limit?: number;\n cursor: string;\n};\n\n/**\n * The response type for {@link CatalogApi.queryEntities}.\n *\n * @public\n */\nexport type QueryEntitiesResponse = {\n /* The list of entities for the current request */\n items: Entity[];\n /* The number of entities among all the requests */\n totalItems: number;\n pageInfo: {\n /* The cursor for the next batch of entities */\n nextCursor?: string;\n /* The cursor for the previous batch of entities */\n prevCursor?: string;\n };\n};\n\n/**\n * Stream entities request for {@link CatalogApi.streamEntities}.\n *\n * @public\n */\nexport type StreamEntitiesRequest = Omit<\n QueryEntitiesInitialRequest,\n 'limit' | 'offset'\n> & {\n /**\n * The number of entities to fetch in each page. Defaults to 500.\n */\n pageSize?: number;\n};\n\n/**\n * The request type for {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport type QueryLocationsRequest =\n | QueryLocationsInitialRequest\n | QueryLocationsCursorRequest;\n\n/**\n * The request type for initial requests to {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsInitialRequest {\n limit?: number;\n query?: FilterPredicate;\n}\n\n/**\n * The request type for cursor requests to {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsCursorRequest {\n cursor: string;\n}\n\n/**\n * The response type for {@link CatalogApi.queryLocations}.\n *\n * @public\n */\nexport interface QueryLocationsResponse {\n items: Location[];\n totalItems: number;\n pageInfo: {\n nextCursor?: string;\n };\n}\n\n/**\n * A client for interacting with the Backstage software catalog through its API.\n *\n * @public\n */\nexport interface CatalogApi {\n /**\n * Lists catalog entities.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse>;\n\n /**\n * Gets 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 undefined.\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 paginated entities from the catalog.\n *\n * @remarks\n *\n * @example\n *\n * ```\n * const response = await catalogClient.queryEntities({\n * filter: [{ kind: 'group' }],\n * limit: 20,\n * fields: ['metadata', 'kind'],\n * fullTextFilter: {\n * term: 'A',\n * },\n * orderFields: { field: 'metadata.name', order: 'asc' },\n * });\n * ```\n *\n * this will match all entities of type group having a name starting\n * with 'A', ordered by name ascending.\n *\n * The response will contain a maximum of 20 entities. In case\n * more than 20 entities exist, the response will contain a nextCursor\n * property that can be used to fetch the next batch of entities.\n *\n * ```\n * const secondBatchResponse = await catalogClient\n * .queryEntities({\n * cursor: response.nextCursor,\n * limit: 20,\n * fields: ['metadata', 'kind'],\n * });\n * ```\n *\n * `secondBatchResponse` will contain the next batch of (maximum) 20 entities,\n * together with a `prevCursor` property, useful to fetch the previous batch.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n queryEntities(\n request?: QueryEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse>;\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 * List locations\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getLocations(\n request?: {},\n options?: CatalogRequestOptions,\n ): Promise<GetLocationsResponse>;\n\n /**\n * Gets paginated locations from the catalog.\n *\n * @remarks\n *\n * @example\n *\n * ```\n * const response = await catalogClient.queryLocations({\n * limit: 20,\n * query: {\n * type: 'url',\n * target: { $hasPrefix: 'https://github.com/backstage/backstage' },\n * },\n * });\n * ```\n *\n * This will match all locations of type `url` having a target starting\n * with `https://github.com/backstage/backstage`.\n *\n * The response will contain a maximum of 20 locations. In case\n * more than 20 locations exist, the response will contain a `nextCursor`\n * property that can be used to fetch the next batch of locations.\n *\n * ```\n * const secondBatchResponse = await catalogClient\n * .queryLocations({ cursor: response.pageInfo.nextCursor });\n * ```\n *\n * `secondBatchResponse` will contain the next batch of (maximum) 20 locations,\n * again together with a `nextCursor` property if there is more data to fetch.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n queryLocations(\n request?: QueryLocationsRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryLocationsResponse>;\n\n /**\n * Asynchronously streams locations from the catalog. Uses `queryLocations`\n * to fetch locations in batches, and yields them one page at a time.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n streamLocations(\n request?: QueryLocationsInitialRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Location[]>;\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 * Gets a location associated with an entity.\n *\n * @param entityRef - A complete entity ref, either on string or compound form\n * @param options - Additional options\n */\n getLocationByEntity(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\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 * @param options - Additional options\n */\n validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse>;\n\n /**\n * Validate a given location.\n *\n * @param location - Request parameters\n * @param options - Additional options\n */\n analyzeLocation(\n location: AnalyzeLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AnalyzeLocationResponse>;\n\n /**\n * Asynchronously streams entities from the catalog. Uses `queryEntities`\n * to fetch entities in batches, and yields them one page at a time.\n *\n * @public\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n streamEntities(\n request?: StreamEntitiesRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Entity[]>;\n}\n"],"names":[],"mappings":"AA+BO,MAAM,wCAAwB,MAAA,CAAO,GAAA;AAAA;AAAA,EAE1C;AACF;;;;"} |
+32
-0
| 'use strict'; | ||
| var api = require('./types/api.cjs.js'); | ||
| function isQueryEntitiesInitialRequest(request) { | ||
| return !request.cursor; | ||
| } | ||
| function cursorContainsQuery(cursor) { | ||
| try { | ||
| const decoded = JSON.parse(atob(cursor)); | ||
| return "query" in decoded; | ||
| } catch { | ||
| return false; | ||
| } | ||
| } | ||
| function convertFilterToPredicate(filter) { | ||
| const records = [filter].flat(); | ||
| const clauses = records.map((record) => { | ||
| const parts = []; | ||
| for (const [key, value] of Object.entries(record)) { | ||
| const values = [value].flat(); | ||
| const strings = values.filter((v) => typeof v === "string"); | ||
| const hasExists = values.some((v) => v === api.CATALOG_FILTER_EXISTS); | ||
| if (hasExists) { | ||
| parts.push({ [key]: { $exists: true } }); | ||
| } else if (strings.length === 1) { | ||
| parts.push({ [key]: strings[0] }); | ||
| } else if (strings.length > 1) { | ||
| parts.push({ [key]: { $in: strings } }); | ||
| } | ||
| } | ||
| return parts.length === 1 ? parts[0] : { $all: parts }; | ||
| }); | ||
| return clauses.length === 1 ? clauses[0] : { $any: clauses }; | ||
| } | ||
| function splitRefsIntoChunks(refs, options) { | ||
@@ -36,4 +66,6 @@ if (!refs.length) { | ||
| exports.convertFilterToPredicate = convertFilterToPredicate; | ||
| exports.cursorContainsQuery = cursorContainsQuery; | ||
| exports.isQueryEntitiesInitialRequest = isQueryEntitiesInitialRequest; | ||
| exports.splitRefsIntoChunks = splitRefsIntoChunks; | ||
| //# sourceMappingURL=utils.cjs.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"utils.cjs.js","sources":["../src/utils.ts"],"sourcesContent":["/*\n * Copyright 2022 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 QueryEntitiesCursorRequest,\n QueryEntitiesInitialRequest,\n QueryEntitiesRequest,\n} from './types/api';\n\nexport function isQueryEntitiesInitialRequest(\n request: QueryEntitiesRequest,\n): request is QueryEntitiesInitialRequest {\n return !(request as QueryEntitiesCursorRequest).cursor;\n}\n\n/**\n * Takes a set of entity refs, and splits them into chunks (groups) such that\n * the total string length in each chunk does not exceed the default Express.js\n * request body limit of 100 kB (with some margin) when JSON encoded as an\n * array.\n */\nexport function splitRefsIntoChunks(\n refs: string[],\n options?: {\n // No chunk has more than this many refs, no matter what\n maxCountPerChunk?: number;\n // The total string length (taking the extraStringLengthPerRef into account)\n // of each chunk never exceeds this many characters, no matter what\n maxStringLengthPerChunk?: number;\n // Add this many characters to the length of each ref when calculating\n // (default is 3, since eacn array entry is surrounded by quotes and a\n // comma)\n extraStringLengthPerRef?: number;\n },\n): string[][] {\n if (!refs.length) {\n return [];\n }\n\n const {\n maxCountPerChunk = 1000,\n maxStringLengthPerChunk = 90 * 2 ** 10,\n extraStringLengthPerRef = 3,\n } = options ?? {};\n\n const chunks: string[][] = [];\n\n let currentChunkStart = 0;\n let currentChunkStringLength = 0;\n let currentChunkSize = 0;\n\n for (let i = 0; i < refs.length; ++i) {\n const refLength = refs[i].length + extraStringLengthPerRef;\n\n // always allow at least one element per chunk even in abnormal situations\n if (currentChunkSize > 0) {\n // emit chunk and start over if either the string length or the count\n // limit would be reached\n if (\n currentChunkStringLength + refLength > maxStringLengthPerChunk ||\n currentChunkSize + 1 > maxCountPerChunk\n ) {\n chunks.push(refs.slice(currentChunkStart, i));\n currentChunkStart = i;\n currentChunkStringLength = 0;\n currentChunkSize = 0;\n }\n }\n\n currentChunkStringLength += refLength;\n currentChunkSize += 1;\n }\n\n // emit whatever is left as the last chunk\n chunks.push(refs.slice(currentChunkStart, refs.length));\n\n return chunks;\n}\n"],"names":[],"mappings":";;AAsBO,SAAS,8BACd,OAAA,EACwC;AACxC,EAAA,OAAO,CAAE,OAAA,CAAuC,MAAA;AAClD;AAQO,SAAS,mBAAA,CACd,MACA,OAAA,EAWY;AACZ,EAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM;AAAA,IACJ,gBAAA,GAAmB,GAAA;AAAA,IACnB,uBAAA,GAA0B,KAAK,CAAA,IAAK,EAAA;AAAA,IACpC,uBAAA,GAA0B;AAAA,GAC5B,GAAe,EAAC;AAEhB,EAAA,MAAM,SAAqB,EAAC;AAE5B,EAAA,IAAI,iBAAA,GAAoB,CAAA;AACxB,EAAA,IAAI,wBAAA,GAA2B,CAAA;AAC/B,EAAA,IAAI,gBAAA,GAAmB,CAAA;AAEvB,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,EAAQ,EAAE,CAAA,EAAG;AACpC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,CAAC,CAAA,CAAE,MAAA,GAAS,uBAAA;AAGnC,IAAA,IAAI,mBAAmB,CAAA,EAAG;AAGxB,MAAA,IACE,wBAAA,GAA2B,SAAA,GAAY,uBAAA,IACvC,gBAAA,GAAmB,IAAI,gBAAA,EACvB;AACA,QAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,iBAAA,EAAmB,CAAC,CAAC,CAAA;AAC5C,QAAA,iBAAA,GAAoB,CAAA;AACpB,QAAA,wBAAA,GAA2B,CAAA;AAC3B,QAAA,gBAAA,GAAmB,CAAA;AAAA,MACrB;AAAA,IACF;AAEA,IAAA,wBAAA,IAA4B,SAAA;AAC5B,IAAA,gBAAA,IAAoB,CAAA;AAAA,EACtB;AAGA,EAAA,MAAA,CAAO,KAAK,IAAA,CAAK,KAAA,CAAM,iBAAA,EAAmB,IAAA,CAAK,MAAM,CAAC,CAAA;AAEtD,EAAA,OAAO,MAAA;AACT;;;;;"} | ||
| {"version":3,"file":"utils.cjs.js","sources":["../src/utils.ts"],"sourcesContent":["/*\n * Copyright 2022 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 type {\n FilterPredicate,\n FilterPredicateExpression,\n} from '@backstage/filter-predicates';\nimport {\n CATALOG_FILTER_EXISTS,\n EntityFilterQuery,\n QueryEntitiesCursorRequest,\n QueryEntitiesInitialRequest,\n QueryEntitiesRequest,\n} from './types/api';\n\nexport function isQueryEntitiesInitialRequest(\n request: QueryEntitiesRequest,\n): request is QueryEntitiesInitialRequest {\n return !(request as QueryEntitiesCursorRequest).cursor;\n}\n\n/**\n * Check if a cursor contains a predicate query by attempting to decode it.\n * @internal\n */\nexport function cursorContainsQuery(cursor: string): boolean {\n try {\n const decoded = JSON.parse(atob(cursor));\n return 'query' in decoded;\n } catch {\n return false;\n }\n}\n\n/**\n * Converts an {@link EntityFilterQuery} into a predicate query object.\n * @internal\n */\nexport function convertFilterToPredicate(filter: EntityFilterQuery):\n | FilterPredicateExpression\n | {\n $all: FilterPredicate[];\n }\n | {\n $any: FilterPredicate[];\n } {\n const records = [filter].flat();\n\n const clauses = records.map(record => {\n const parts: FilterPredicateExpression[] = [];\n\n for (const [key, value] of Object.entries(record)) {\n const values = [value].flat();\n const strings = values.filter((v): v is string => typeof v === 'string');\n const hasExists = values.some(v => v === CATALOG_FILTER_EXISTS);\n\n if (hasExists) {\n // Ignore whether there ALSO were some strings - that would boil down to\n // just existence anyway since there's effectively an OR between them\n parts.push({ [key]: { $exists: true } } as FilterPredicateExpression);\n } else if (strings.length === 1) {\n parts.push({ [key]: strings[0] } as FilterPredicateExpression);\n } else if (strings.length > 1) {\n parts.push({ [key]: { $in: strings } } as FilterPredicateExpression);\n }\n }\n\n return parts.length === 1 ? parts[0] : { $all: parts };\n });\n\n return clauses.length === 1 ? clauses[0] : { $any: clauses };\n}\n\n/**\n * Takes a set of entity refs, and splits them into chunks (groups) such that\n * the total string length in each chunk does not exceed the default Express.js\n * request body limit of 100 kB (with some margin) when JSON encoded as an\n * array.\n */\nexport function splitRefsIntoChunks(\n refs: string[],\n options?: {\n // No chunk has more than this many refs, no matter what\n maxCountPerChunk?: number;\n // The total string length (taking the extraStringLengthPerRef into account)\n // of each chunk never exceeds this many characters, no matter what\n maxStringLengthPerChunk?: number;\n // Add this many characters to the length of each ref when calculating\n // (default is 3, since eacn array entry is surrounded by quotes and a\n // comma)\n extraStringLengthPerRef?: number;\n },\n): string[][] {\n if (!refs.length) {\n return [];\n }\n\n const {\n maxCountPerChunk = 1000,\n maxStringLengthPerChunk = 90 * 2 ** 10,\n extraStringLengthPerRef = 3,\n } = options ?? {};\n\n const chunks: string[][] = [];\n\n let currentChunkStart = 0;\n let currentChunkStringLength = 0;\n let currentChunkSize = 0;\n\n for (let i = 0; i < refs.length; ++i) {\n const refLength = refs[i].length + extraStringLengthPerRef;\n\n // always allow at least one element per chunk even in abnormal situations\n if (currentChunkSize > 0) {\n // emit chunk and start over if either the string length or the count\n // limit would be reached\n if (\n currentChunkStringLength + refLength > maxStringLengthPerChunk ||\n currentChunkSize + 1 > maxCountPerChunk\n ) {\n chunks.push(refs.slice(currentChunkStart, i));\n currentChunkStart = i;\n currentChunkStringLength = 0;\n currentChunkSize = 0;\n }\n }\n\n currentChunkStringLength += refLength;\n currentChunkSize += 1;\n }\n\n // emit whatever is left as the last chunk\n chunks.push(refs.slice(currentChunkStart, refs.length));\n\n return chunks;\n}\n"],"names":["CATALOG_FILTER_EXISTS"],"mappings":"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"} |
+31
-1
@@ -0,4 +1,34 @@ | ||
| import { CATALOG_FILTER_EXISTS } from './types/api.esm.js'; | ||
| function isQueryEntitiesInitialRequest(request) { | ||
| return !request.cursor; | ||
| } | ||
| function cursorContainsQuery(cursor) { | ||
| try { | ||
| const decoded = JSON.parse(atob(cursor)); | ||
| return "query" in decoded; | ||
| } catch { | ||
| return false; | ||
| } | ||
| } | ||
| function convertFilterToPredicate(filter) { | ||
| const records = [filter].flat(); | ||
| const clauses = records.map((record) => { | ||
| const parts = []; | ||
| for (const [key, value] of Object.entries(record)) { | ||
| const values = [value].flat(); | ||
| const strings = values.filter((v) => typeof v === "string"); | ||
| const hasExists = values.some((v) => v === CATALOG_FILTER_EXISTS); | ||
| if (hasExists) { | ||
| parts.push({ [key]: { $exists: true } }); | ||
| } else if (strings.length === 1) { | ||
| parts.push({ [key]: strings[0] }); | ||
| } else if (strings.length > 1) { | ||
| parts.push({ [key]: { $in: strings } }); | ||
| } | ||
| } | ||
| return parts.length === 1 ? parts[0] : { $all: parts }; | ||
| }); | ||
| return clauses.length === 1 ? clauses[0] : { $any: clauses }; | ||
| } | ||
| function splitRefsIntoChunks(refs, options) { | ||
@@ -34,3 +64,3 @@ if (!refs.length) { | ||
| export { isQueryEntitiesInitialRequest, splitRefsIntoChunks }; | ||
| export { convertFilterToPredicate, cursorContainsQuery, isQueryEntitiesInitialRequest, splitRefsIntoChunks }; | ||
| //# sourceMappingURL=utils.esm.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"utils.esm.js","sources":["../src/utils.ts"],"sourcesContent":["/*\n * Copyright 2022 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 QueryEntitiesCursorRequest,\n QueryEntitiesInitialRequest,\n QueryEntitiesRequest,\n} from './types/api';\n\nexport function isQueryEntitiesInitialRequest(\n request: QueryEntitiesRequest,\n): request is QueryEntitiesInitialRequest {\n return !(request as QueryEntitiesCursorRequest).cursor;\n}\n\n/**\n * Takes a set of entity refs, and splits them into chunks (groups) such that\n * the total string length in each chunk does not exceed the default Express.js\n * request body limit of 100 kB (with some margin) when JSON encoded as an\n * array.\n */\nexport function splitRefsIntoChunks(\n refs: string[],\n options?: {\n // No chunk has more than this many refs, no matter what\n maxCountPerChunk?: number;\n // The total string length (taking the extraStringLengthPerRef into account)\n // of each chunk never exceeds this many characters, no matter what\n maxStringLengthPerChunk?: number;\n // Add this many characters to the length of each ref when calculating\n // (default is 3, since eacn array entry is surrounded by quotes and a\n // comma)\n extraStringLengthPerRef?: number;\n },\n): string[][] {\n if (!refs.length) {\n return [];\n }\n\n const {\n maxCountPerChunk = 1000,\n maxStringLengthPerChunk = 90 * 2 ** 10,\n extraStringLengthPerRef = 3,\n } = options ?? {};\n\n const chunks: string[][] = [];\n\n let currentChunkStart = 0;\n let currentChunkStringLength = 0;\n let currentChunkSize = 0;\n\n for (let i = 0; i < refs.length; ++i) {\n const refLength = refs[i].length + extraStringLengthPerRef;\n\n // always allow at least one element per chunk even in abnormal situations\n if (currentChunkSize > 0) {\n // emit chunk and start over if either the string length or the count\n // limit would be reached\n if (\n currentChunkStringLength + refLength > maxStringLengthPerChunk ||\n currentChunkSize + 1 > maxCountPerChunk\n ) {\n chunks.push(refs.slice(currentChunkStart, i));\n currentChunkStart = i;\n currentChunkStringLength = 0;\n currentChunkSize = 0;\n }\n }\n\n currentChunkStringLength += refLength;\n currentChunkSize += 1;\n }\n\n // emit whatever is left as the last chunk\n chunks.push(refs.slice(currentChunkStart, refs.length));\n\n return chunks;\n}\n"],"names":[],"mappings":"AAsBO,SAAS,8BACd,OAAA,EACwC;AACxC,EAAA,OAAO,CAAE,OAAA,CAAuC,MAAA;AAClD;AAQO,SAAS,mBAAA,CACd,MACA,OAAA,EAWY;AACZ,EAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AAChB,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM;AAAA,IACJ,gBAAA,GAAmB,GAAA;AAAA,IACnB,uBAAA,GAA0B,KAAK,CAAA,IAAK,EAAA;AAAA,IACpC,uBAAA,GAA0B;AAAA,GAC5B,GAAe,EAAC;AAEhB,EAAA,MAAM,SAAqB,EAAC;AAE5B,EAAA,IAAI,iBAAA,GAAoB,CAAA;AACxB,EAAA,IAAI,wBAAA,GAA2B,CAAA;AAC/B,EAAA,IAAI,gBAAA,GAAmB,CAAA;AAEvB,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,EAAQ,EAAE,CAAA,EAAG;AACpC,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,CAAC,CAAA,CAAE,MAAA,GAAS,uBAAA;AAGnC,IAAA,IAAI,mBAAmB,CAAA,EAAG;AAGxB,MAAA,IACE,wBAAA,GAA2B,SAAA,GAAY,uBAAA,IACvC,gBAAA,GAAmB,IAAI,gBAAA,EACvB;AACA,QAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,KAAA,CAAM,iBAAA,EAAmB,CAAC,CAAC,CAAA;AAC5C,QAAA,iBAAA,GAAoB,CAAA;AACpB,QAAA,wBAAA,GAA2B,CAAA;AAC3B,QAAA,gBAAA,GAAmB,CAAA;AAAA,MACrB;AAAA,IACF;AAEA,IAAA,wBAAA,IAA4B,SAAA;AAC5B,IAAA,gBAAA,IAAoB,CAAA;AAAA,EACtB;AAGA,EAAA,MAAA,CAAO,KAAK,IAAA,CAAK,KAAA,CAAM,iBAAA,EAAmB,IAAA,CAAK,MAAM,CAAC,CAAA;AAEtD,EAAA,OAAO,MAAA;AACT;;;;"} | ||
| {"version":3,"file":"utils.esm.js","sources":["../src/utils.ts"],"sourcesContent":["/*\n * Copyright 2022 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 type {\n FilterPredicate,\n FilterPredicateExpression,\n} from '@backstage/filter-predicates';\nimport {\n CATALOG_FILTER_EXISTS,\n EntityFilterQuery,\n QueryEntitiesCursorRequest,\n QueryEntitiesInitialRequest,\n QueryEntitiesRequest,\n} from './types/api';\n\nexport function isQueryEntitiesInitialRequest(\n request: QueryEntitiesRequest,\n): request is QueryEntitiesInitialRequest {\n return !(request as QueryEntitiesCursorRequest).cursor;\n}\n\n/**\n * Check if a cursor contains a predicate query by attempting to decode it.\n * @internal\n */\nexport function cursorContainsQuery(cursor: string): boolean {\n try {\n const decoded = JSON.parse(atob(cursor));\n return 'query' in decoded;\n } catch {\n return false;\n }\n}\n\n/**\n * Converts an {@link EntityFilterQuery} into a predicate query object.\n * @internal\n */\nexport function convertFilterToPredicate(filter: EntityFilterQuery):\n | FilterPredicateExpression\n | {\n $all: FilterPredicate[];\n }\n | {\n $any: FilterPredicate[];\n } {\n const records = [filter].flat();\n\n const clauses = records.map(record => {\n const parts: FilterPredicateExpression[] = [];\n\n for (const [key, value] of Object.entries(record)) {\n const values = [value].flat();\n const strings = values.filter((v): v is string => typeof v === 'string');\n const hasExists = values.some(v => v === CATALOG_FILTER_EXISTS);\n\n if (hasExists) {\n // Ignore whether there ALSO were some strings - that would boil down to\n // just existence anyway since there's effectively an OR between them\n parts.push({ [key]: { $exists: true } } as FilterPredicateExpression);\n } else if (strings.length === 1) {\n parts.push({ [key]: strings[0] } as FilterPredicateExpression);\n } else if (strings.length > 1) {\n parts.push({ [key]: { $in: strings } } as FilterPredicateExpression);\n }\n }\n\n return parts.length === 1 ? parts[0] : { $all: parts };\n });\n\n return clauses.length === 1 ? clauses[0] : { $any: clauses };\n}\n\n/**\n * Takes a set of entity refs, and splits them into chunks (groups) such that\n * the total string length in each chunk does not exceed the default Express.js\n * request body limit of 100 kB (with some margin) when JSON encoded as an\n * array.\n */\nexport function splitRefsIntoChunks(\n refs: string[],\n options?: {\n // No chunk has more than this many refs, no matter what\n maxCountPerChunk?: number;\n // The total string length (taking the extraStringLengthPerRef into account)\n // of each chunk never exceeds this many characters, no matter what\n maxStringLengthPerChunk?: number;\n // Add this many characters to the length of each ref when calculating\n // (default is 3, since eacn array entry is surrounded by quotes and a\n // comma)\n extraStringLengthPerRef?: number;\n },\n): string[][] {\n if (!refs.length) {\n return [];\n }\n\n const {\n maxCountPerChunk = 1000,\n maxStringLengthPerChunk = 90 * 2 ** 10,\n extraStringLengthPerRef = 3,\n } = options ?? {};\n\n const chunks: string[][] = [];\n\n let currentChunkStart = 0;\n let currentChunkStringLength = 0;\n let currentChunkSize = 0;\n\n for (let i = 0; i < refs.length; ++i) {\n const refLength = refs[i].length + extraStringLengthPerRef;\n\n // always allow at least one element per chunk even in abnormal situations\n if (currentChunkSize > 0) {\n // emit chunk and start over if either the string length or the count\n // limit would be reached\n if (\n currentChunkStringLength + refLength > maxStringLengthPerChunk ||\n currentChunkSize + 1 > maxCountPerChunk\n ) {\n chunks.push(refs.slice(currentChunkStart, i));\n currentChunkStart = i;\n currentChunkStringLength = 0;\n currentChunkSize = 0;\n }\n }\n\n currentChunkStringLength += refLength;\n currentChunkSize += 1;\n }\n\n // emit whatever is left as the last chunk\n chunks.push(refs.slice(currentChunkStart, refs.length));\n\n return chunks;\n}\n"],"names":[],"mappings":"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"} |
+2
-2
| { | ||
| "name": "@backstage/catalog-client", | ||
| "version": "1.13.1-next.0", | ||
| "version": "1.14.0-next.1", | ||
| "description": "An isomorphic client for the catalog backend", | ||
@@ -69,3 +69,3 @@ "backstage": { | ||
| "devDependencies": { | ||
| "@backstage/cli": "0.35.5-next.0", | ||
| "@backstage/cli": "0.36.0-next.1", | ||
| "@backstage/plugin-catalog-common": "1.1.8", | ||
@@ -72,0 +72,0 @@ "@types/lodash": "^4.14.151", |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
503322
11.28%3918
13.17%52
8.33%