@backstage/catalog-client 1.8.0-next.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/CatalogClient.cjs.js +1 -1
  3. package/dist/CatalogClient.cjs.js.map +1 -1
  4. package/dist/CatalogClient.esm.js +1 -1
  5. package/dist/CatalogClient.esm.js.map +1 -1
  6. package/dist/plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.cjs.js.map +1 -1
  7. package/dist/plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.esm.js.map +1 -1
  8. package/dist/{generated → schema/openapi/generated}/apis/DefaultApi.client.cjs.js +40 -36
  9. package/dist/schema/openapi/generated/apis/DefaultApi.client.cjs.js.map +1 -0
  10. package/dist/{generated → schema/openapi/generated}/apis/DefaultApi.client.esm.js +40 -36
  11. package/dist/schema/openapi/generated/apis/DefaultApi.client.esm.js.map +1 -0
  12. package/dist/schema/openapi/generated/pluginId.cjs.js.map +1 -0
  13. package/dist/schema/openapi/generated/pluginId.esm.js.map +1 -0
  14. package/dist/testUtils/InMemoryCatalogClient.cjs.js.map +1 -1
  15. package/dist/testUtils/InMemoryCatalogClient.esm.js +1 -1
  16. package/dist/testUtils/InMemoryCatalogClient.esm.js.map +1 -1
  17. package/dist/types/api.cjs.js.map +1 -1
  18. package/dist/types/api.esm.js.map +1 -1
  19. package/dist/utils.cjs.js.map +1 -1
  20. package/dist/utils.esm.js.map +1 -1
  21. package/package.json +15 -6
  22. package/dist/generated/apis/DefaultApi.client.cjs.js.map +0 -1
  23. package/dist/generated/apis/DefaultApi.client.esm.js.map +0 -1
  24. package/dist/generated/pluginId.cjs.js.map +0 -1
  25. package/dist/generated/pluginId.esm.js.map +0 -1
  26. package/testUtils/package.json +0 -7
  27. /package/dist/{generated → schema/openapi/generated}/pluginId.cjs.js +0 -0
  28. /package/dist/{generated → schema/openapi/generated}/pluginId.esm.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @backstage/catalog-client
2
2
 
3
+ ## 1.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 656d1ef: Internal update to use the updated generated code from `backstage-cli package schema openapi generate --client-package ...`.
8
+ - 31c4fe0: The client now automatically splits up very large `getEntitiesByRefs` calls into several smaller requests behind the scenes when needed. This ensures that each individual request does not exceed common Express.js request body limits or overload the server.
9
+
10
+ ### Patch Changes
11
+
12
+ - 873f89a: Fix for certain filter fields in the `catalogApiMock` being case sensitive.
13
+ - Updated dependencies
14
+ - @backstage/catalog-model@1.7.1
15
+ - @backstage/errors@1.2.5
16
+
17
+ ## 1.8.0-next.1
18
+
19
+ ### Minor Changes
20
+
21
+ - 656d1ef: Internal update to use the updated generated code from `backstage-cli package schema openapi generate --client-package ...`.
22
+
23
+ ### Patch Changes
24
+
25
+ - Updated dependencies
26
+ - @backstage/catalog-model@1.7.0
27
+ - @backstage/errors@1.2.4
28
+
3
29
  ## 1.8.0-next.0
4
30
 
5
31
  ### Minor Changes
@@ -4,7 +4,7 @@ var catalogModel = require('@backstage/catalog-model');
4
4
  var errors = require('@backstage/errors');
5
5
  var api = require('./types/api.cjs.js');
6
6
  var utils = require('./utils.cjs.js');
7
- var DefaultApi_client = require('./generated/apis/DefaultApi.client.cjs.js');
7
+ var DefaultApi_client = require('./schema/openapi/generated/apis/DefaultApi.client.cjs.js');
8
8
 
9
9
  class CatalogClient {
10
10
  apiClient;
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogClient.cjs.js","sources":["../src/CatalogClient.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n CatalogRequestOptions,\n EntityFilterQuery,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\n GetEntitiesRequest,\n GetEntitiesResponse,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n Location,\n QueryEntitiesRequest,\n QueryEntitiesResponse,\n ValidateEntityResponse,\n} from './types/api';\nimport { isQueryEntitiesInitialRequest, splitRefsIntoChunks } from './utils';\nimport { DefaultApiClient, TypedResponse } from './generated';\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.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.apiClient\n .getEntitiesByQuery({ query: params }, options)\n .then(r => r.json());\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 new Error(await response.text());\n }\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityFacets}\n */\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter = [], facets } = request;\n 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 new Error(await response.text());\n }\n\n const { location, entities, exists } = await response.json();\n\n if (!location) {\n throw new Error(`Location wasn't added: ${target}`);\n }\n\n return {\n location,\n entities,\n exists,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByRef}\n */\n async getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const all = 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 // Private methods\n //\n\n private async requestIgnored(response: Response): Promise<void> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private async requestOptional(response: Response): Promise<any | undefined> {\n if (!response.ok) {\n if (response.status === 404) {\n return undefined;\n }\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n private getFilterValue(filter: EntityFilterQuery = []) {\n const filters: string[] = [];\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(key);\n } else if (typeof v === 'string') {\n filterParts.push(`${key}=${v}`);\n }\n }\n }\n\n if (filterParts.length) {\n filters.push(filterParts.join(','));\n }\n }\n return filters;\n }\n}\n"],"names":["DefaultApiClient","parseEntityRef","ResponseError","splitRefsIntoChunks","isQueryEntitiesInitialRequest","stringifyLocationRef","errors","CATALOG_FILTER_EXISTS"],"mappings":"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"}
1
+ {"version":3,"file":"CatalogClient.cjs.js","sources":["../src/CatalogClient.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n CatalogRequestOptions,\n EntityFilterQuery,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\n GetEntitiesRequest,\n GetEntitiesResponse,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n Location,\n QueryEntitiesRequest,\n QueryEntitiesResponse,\n ValidateEntityResponse,\n} from './types/api';\nimport { isQueryEntitiesInitialRequest, splitRefsIntoChunks } from './utils';\nimport { DefaultApiClient, TypedResponse } from './schema/openapi';\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.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.apiClient\n .getEntitiesByQuery({ query: params }, options)\n .then(r => r.json());\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 new Error(await response.text());\n }\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityFacets}\n */\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter = [], facets } = request;\n 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 new Error(await response.text());\n }\n\n const { location, entities, exists } = await response.json();\n\n if (!location) {\n throw new Error(`Location wasn't added: ${target}`);\n }\n\n return {\n location,\n entities,\n exists,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByRef}\n */\n async getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const all = 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 // Private methods\n //\n\n private async requestIgnored(response: Response): Promise<void> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private async requestOptional(response: Response): Promise<any | undefined> {\n if (!response.ok) {\n if (response.status === 404) {\n return undefined;\n }\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n private getFilterValue(filter: EntityFilterQuery = []) {\n const filters: string[] = [];\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(key);\n } else if (typeof v === 'string') {\n filterParts.push(`${key}=${v}`);\n }\n }\n }\n\n if (filterParts.length) {\n filters.push(filterParts.join(','));\n }\n }\n return filters;\n }\n}\n"],"names":["DefaultApiClient","parseEntityRef","ResponseError","splitRefsIntoChunks","isQueryEntitiesInitialRequest","stringifyLocationRef","errors","CATALOG_FILTER_EXISTS"],"mappings":";;;;;;;;AAoDO,MAAM,aAAoC,CAAA;AAAA,EAC9B,SAAA;AAAA,EAEjB,YAAY,OAGT,EAAA;AACD,IAAK,IAAA,CAAA,SAAA,GAAY,IAAIA,kCAAA,CAAiB,OAAO,CAAA;AAAA;AAC/C;AAAA;AAAA;AAAA,EAKA,MAAM,kBACJ,CAAA,OAAA,EACA,OACqC,EAAA;AACrC,IAAA,OAAO,MAAM,IAAK,CAAA,eAAA;AAAA,MAChB,MAAM,KAAK,SAAU,CAAA,uBAAA;AAAA,QACnB,EAAE,IAAA,EAAMC,2BAAe,CAAA,OAAA,CAAQ,SAAS,CAAE,EAAA;AAAA,QAC1C;AAAA;AACF,KACF;AAAA;AACF;AAAA;AAAA;AAAA,EAKA,MAAM,eACJ,CAAA,EAAA,EACA,OAC+B,EAAA;AAC/B,IAAA,OAAO,MAAM,IAAK,CAAA,eAAA;AAAA,MAChB,MAAM,IAAK,CAAA,SAAA,CAAU,WAAY,CAAA,EAAE,MAAM,EAAE,EAAA,EAAK,EAAA,EAAG,OAAO;AAAA,KAC5D;AAAA;AACF;AAAA;AAAA;AAAA,EAKA,MAAM,mBACJ,CAAA,SAAA,EACA,OAC+B,EAAA;AAC/B,IAAA,OAAO,MAAM,IAAK,CAAA,eAAA;AAAA,MAChB,MAAM,KAAK,SAAU,CAAA,mBAAA;AAAA,QACnB,EAAE,IAAA,EAAMA,2BAAe,CAAA,SAAS,CAAE,EAAA;AAAA,QAClC;AAAA;AACF,KACF;AAAA;AACF;AAAA;AAAA;AAAA,EAKA,MAAM,WACJ,CAAA,OAAA,EACA,OAC8B,EAAA;AAC9B,IAAM,MAAA;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,KAAO,EAAA;AACT,MAAA,KAAA,MAAW,SAAa,IAAA,CAAC,KAAK,CAAA,CAAE,MAAQ,EAAA;AACtC,QAAA,IAAI,SAAW,EAAA;AACb,UAAA,YAAA,CAAa,KAAK,CAAG,EAAA,SAAA,CAAU,KAAK,CAAI,CAAA,EAAA,SAAA,CAAU,KAAK,CAAE,CAAA,CAAA;AAAA;AAC3D;AACF;AAGF,IAAM,MAAA,QAAA,GAAW,MAAM,IAAK,CAAA,eAAA;AAAA,MAC1B,MAAM,KAAK,SAAU,CAAA,WAAA;AAAA,QACnB;AAAA,UACE,KAAO,EAAA;AAAA,YACL,MAAA;AAAA,YACA,KAAA;AAAA,YACA,MAAA,EAAQ,IAAK,CAAA,cAAA,CAAe,MAAM,CAAA;AAAA,YAClC,MAAA;AAAA,YACA,KAAA;AAAA,YACA,KAAA,EAAO,QAAQ,YAAe,GAAA,KAAA;AAAA;AAChC,SACF;AAAA,QACA;AAAA;AACF,KACF;AACA,IAAO,OAAA,EAAE,OAAO,QAAS,EAAA;AAAA;AAC3B;AAAA;AAAA;AAAA,EAKA,MAAM,iBACJ,CAAA,OAAA,EACA,OACoC,EAAA;AACpC,IAAM,MAAA,WAAA,GAAc,OAAO,IAAmB,KAAA;AAC5C,MAAM,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,SAAU,CAAA,iBAAA;AAAA,QACpC;AAAA,UACE,MAAM,EAAE,UAAA,EAAY,IAAM,EAAA,MAAA,EAAQ,QAAQ,MAAO,EAAA;AAAA,UACjD,OAAO,EAAE,MAAA,EAAQ,KAAK,cAAe,CAAA,OAAA,CAAQ,MAAM,CAAE;AAAA,SACvD;AAAA,QACA;AAAA,OACF;AACA,MAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,QAAM,MAAA,MAAMC,oBAAc,CAAA,YAAA,CAAa,QAAQ,CAAA;AAAA;AAEjD,MAAM,MAAA,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAK,EAAA;AAGlC,MAAA,OAAO,IAAK,CAAA,KAAA,CAAM,GAAI,CAAA,CAAA,CAAA,KAAK,KAAK,KAAS,CAAA,CAAA;AAAA,KAC3C;AAEA,IAAI,IAAA,MAAA;AACJ,IAAA,KAAA,MAAW,IAAQ,IAAAC,yBAAA,CAAoB,OAAQ,CAAA,UAAU,CAAG,EAAA;AAC1D,MAAM,MAAA,QAAA,GAAW,MAAM,WAAA,CAAY,IAAI,CAAA;AACvC,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAS,MAAA,GAAA,QAAA;AAAA,OACJ,MAAA;AACL,QAAO,MAAA,CAAA,IAAA,CAAK,GAAG,QAAQ,CAAA;AAAA;AACzB;AAGF,IAAA,OAAO,EAAE,KAAA,EAAO,MAAU,IAAA,EAAG,EAAA;AAAA;AAC/B;AAAA;AAAA;AAAA,EAKA,MAAM,aAAA,CACJ,OAAgC,GAAA,IAChC,OACgC,EAAA;AAChC,IAAA,MAAM,SAEF,EAAC;AAEL,IAAI,IAAAC,mCAAA,CAA8B,OAAO,CAAG,EAAA;AAC1C,MAAM,MAAA;AAAA,QACJ,SAAS,EAAC;AAAA,QACV,MAAA;AAAA,QACA,KAAA;AAAA,QACA,MAAA;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACE,GAAA,OAAA;AACJ,MAAO,MAAA,CAAA,MAAA,GAAS,IAAK,CAAA,cAAA,CAAe,MAAM,CAAA;AAE1C,MAAA,IAAI,UAAU,KAAW,CAAA,EAAA;AACvB,QAAA,MAAA,CAAO,KAAQ,GAAA,KAAA;AAAA;AAEjB,MAAA,IAAI,WAAW,KAAW,CAAA,EAAA;AACxB,QAAA,MAAA,CAAO,MAAS,GAAA,MAAA;AAAA;AAElB,MAAA,IAAI,gBAAgB,KAAW,CAAA,EAAA;AAC7B,QAAA,MAAA,CAAO,cACL,KAAM,CAAA,OAAA,CAAQ,WAAW,CAAI,GAAA,WAAA,GAAc,CAAC,WAAW,CAAA,EACvD,IAAI,CAAC,EAAE,OAAO,KAAM,EAAA,KAAM,GAAG,KAAK,CAAA,CAAA,EAAI,KAAK,CAAE,CAAA,CAAA;AAAA;AAEjD,MAAA,IAAI,OAAO,MAAQ,EAAA;AACjB,QAAA,MAAA,CAAO,MAAS,GAAA,MAAA;AAAA;AAGlB,MAAM,MAAA,4BAAA,GAA+B,cAAgB,EAAA,IAAA,EAAM,IAAK,EAAA;AAChE,MAAA,IAAI,4BAA8B,EAAA;AAChC,QAAA,MAAA,CAAO,kBAAqB,GAAA,4BAAA;AAAA;AAE9B,MAAI,IAAA,cAAA,EAAgB,QAAQ,MAAQ,EAAA;AAClC,QAAA,MAAA,CAAO,uBAAuB,cAAe,CAAA,MAAA;AAAA;AAC/C,KACK,MAAA;AACL,MAAA,MAAM,EAAE,MAAS,GAAA,EAAI,EAAA,KAAA,EAAO,QAAW,GAAA,OAAA;AAEvC,MAAA,MAAA,CAAO,MAAS,GAAA,MAAA;AAChB,MAAA,IAAI,UAAU,KAAW,CAAA,EAAA;AACvB,QAAA,MAAA,CAAO,KAAQ,GAAA,KAAA;AAAA;AAEjB,MAAA,IAAI,OAAO,MAAQ,EAAA;AACjB,QAAA,MAAA,CAAO,MAAS,GAAA,MAAA;AAAA;AAClB;AAGF,IAAA,OAAO,IAAK,CAAA,SAAA,CACT,kBAAmB,CAAA,EAAE,KAAO,EAAA,MAAA,EAAU,EAAA,OAAO,CAC7C,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,MAAM,CAAA;AAAA;AACvB;AAAA;AAAA;AAAA,EAKA,MAAM,cACJ,CAAA,SAAA,EACA,OAC6B,EAAA;AAC7B,IAAA,OAAO,IAAK,CAAA,eAAA;AAAA,MACV,MAAM,KAAK,SAAU,CAAA,eAAA;AAAA,QACnB;AAAA,UACE,IAAA,EAAMH,4BAAe,SAAS;AAAA,SAChC;AAAA,QACA;AAAA;AACF,KACF;AAAA;AACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eACJ,CAAA,YAAA,EACA,OAC6B,EAAA;AAC7B,IAAA,MAAM,EAAE,IAAA,EAAM,SAAY,GAAA,SAAA,EAAW,MAAS,GAAA,YAAA;AAC9C,IAAA,OAAO,IAAK,CAAA,eAAA;AAAA,MACV,MAAM,KAAK,SAAU,CAAA,eAAA;AAAA,QACnB,EAAE,IAAM,EAAA,EAAE,IAAM,EAAA,SAAA,EAAW,MAAO,EAAA;AAAA,QAClC;AAAA;AACF,KACF;AAAA;AACF;AAAA;AAAA;AAAA,EAKA,MAAM,aAAc,CAAA,SAAA,EAAmB,OAAiC,EAAA;AACtE,IAAM,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,SAAU,CAAA,aAAA;AAAA,MACpC,EAAE,IAAA,EAAM,EAAE,SAAA,EAAY,EAAA;AAAA,MACtB;AAAA,KACF;AAEA,IAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,MAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA;AACvC;AACF;AAAA;AAAA;AAAA,EAKA,MAAM,eACJ,CAAA,OAAA,EACA,OACkC,EAAA;AAClC,IAAA,MAAM,EAAE,MAAA,GAAS,EAAC,EAAG,QAAW,GAAA,OAAA;AAChC,IAAA,OAAO,MAAM,IAAK,CAAA,eAAA;AAAA,MAChB,MAAM,KAAK,SAAU,CAAA,eAAA;AAAA,QACnB;AAAA,UACE,KAAA,EAAO,EAAE,KAAO,EAAA,MAAA,EAAQ,QAAQ,IAAK,CAAA,cAAA,CAAe,MAAM,CAAE;AAAA,SAC9D;AAAA,QACA;AAAA;AACF,KACF;AAAA;AACF;AAAA;AAAA;AAAA,EAKA,MAAM,WACJ,CAAA,OAAA,EACA,OAC8B,EAAA;AAC9B,IAAA,MAAM,EAAE,IAAA,GAAO,KAAO,EAAA,MAAA,EAAQ,QAAW,GAAA,OAAA;AAEzC,IAAM,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,SAAU,CAAA,cAAA;AAAA,MACpC;AAAA,QACE,IAAA,EAAM,EAAE,IAAA,EAAM,MAAO,EAAA;AAAA,QACrB,KAAO,EAAA,EAAE,MAAQ,EAAA,MAAA,GAAS,SAAS,KAAU,CAAA;AAAA,OAC/C;AAAA,MACA;AAAA,KACF;AAEA,IAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,MAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA;AAAA;AAGvC,IAAA,MAAM,EAAE,QAAU,EAAA,QAAA,EAAU,QAAW,GAAA,MAAM,SAAS,IAAK,EAAA;AAE3D,IAAA,IAAI,CAAC,QAAU,EAAA;AACb,MAAA,MAAM,IAAI,KAAA,CAAM,CAA0B,uBAAA,EAAA,MAAM,CAAE,CAAA,CAAA;AAAA;AAGpD,IAAO,OAAA;AAAA,MACL,QAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF;AAAA;AACF;AAAA;AAAA;AAAA,EAKA,MAAM,gBACJ,CAAA,WAAA,EACA,OAC+B,EAAA;AAC/B,IAAM,MAAA,GAAA,GAAM,MAAM,IAAK,CAAA,eAAA;AAAA,MACrB,MAAM,IAAK,CAAA,SAAA,CAAU,YAAa,CAAA,IAAI,OAAO;AAAA,KAC/C;AACA,IAAO,OAAA,GAAA,CACJ,GAAI,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,IAAI,CACf,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,WAAA,KAAgBI,iCAAqB,CAAA,CAAC,CAAC,CAAA;AAAA;AACtD;AAAA;AAAA;AAAA,EAKA,MAAM,kBACJ,CAAA,EAAA,EACA,OACe,EAAA;AACf,IAAA,MAAM,IAAK,CAAA,cAAA;AAAA,MACT,MAAM,IAAK,CAAA,SAAA,CAAU,cAAe,CAAA,EAAE,MAAM,EAAE,EAAA,EAAK,EAAA,EAAG,OAAO;AAAA,KAC/D;AAAA;AACF;AAAA;AAAA;AAAA,EAKA,MAAM,iBACJ,CAAA,GAAA,EACA,OACe,EAAA;AACf,IAAA,MAAM,IAAK,CAAA,cAAA;AAAA,MACT,MAAM,IAAK,CAAA,SAAA,CAAU,iBAAkB,CAAA,EAAE,MAAM,EAAE,GAAA,EAAM,EAAA,EAAG,OAAO;AAAA,KACnE;AAAA;AACF;AAAA;AAAA;AAAA,EAKA,MAAM,cAAA,CACJ,MACA,EAAA,WAAA,EACA,OACiC,EAAA;AACjC,IAAM,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,SAAU,CAAA,cAAA;AAAA,MACpC,EAAE,IAAM,EAAA,EAAE,MAAQ,EAAA,QAAA,EAAU,aAAc,EAAA;AAAA,MAC1C;AAAA,KACF;AAEA,IAAA,IAAI,SAAS,EAAI,EAAA;AACf,MAAO,OAAA;AAAA,QACL,KAAO,EAAA;AAAA,OACT;AAAA;AAGF,IAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,MAAM,MAAA,MAAMH,oBAAc,CAAA,YAAA,CAAa,QAAQ,CAAA;AAAA;AAGjD,IAAA,MAAM,UAAEI,QAAS,GAAA,IAAQ,GAAA,MAAM,SAAS,IAAK,EAAA;AAE7C,IAAO,OAAA;AAAA,MACL,KAAO,EAAA,KAAA;AAAA,cACPA;AAAA,KACF;AAAA;AACF;AAAA;AAAA;AAAA,EAMA,MAAc,eAAe,QAAmC,EAAA;AAC9D,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAM,MAAA,MAAMJ,oBAAc,CAAA,YAAA,CAAa,QAAQ,CAAA;AAAA;AACjD;AACF,EAEA,MAAc,gBAAmB,QAAwC,EAAA;AACvE,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAM,MAAA,MAAMA,oBAAc,CAAA,YAAA,CAAa,QAAQ,CAAA;AAAA;AAGjD,IAAA,OAAO,SAAS,IAAK,EAAA;AAAA;AACvB,EAEA,MAAc,gBAAgB,QAA8C,EAAA;AAC1E,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,QAAO,OAAA,KAAA,CAAA;AAAA;AAET,MAAM,MAAA,MAAMA,oBAAc,CAAA,YAAA,CAAa,QAAQ,CAAA;AAAA;AAGjD,IAAO,OAAA,MAAM,SAAS,IAAK,EAAA;AAAA;AAC7B,EAEQ,cAAA,CAAe,MAA4B,GAAA,EAAI,EAAA;AACrD,IAAA,MAAM,UAAoB,EAAC;AAK3B,IAAA,KAAA,MAAW,UAAc,IAAA,CAAC,MAAM,CAAA,CAAE,MAAQ,EAAA;AACxC,MAAA,MAAM,cAAwB,EAAC;AAC/B,MAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,UAAU,CAAG,EAAA;AACrD,QAAA,KAAA,MAAW,CAAK,IAAA,CAAC,KAAK,CAAA,CAAE,MAAQ,EAAA;AAC9B,UAAA,IAAI,MAAMK,yBAAuB,EAAA;AAC/B,YAAA,WAAA,CAAY,KAAK,GAAG,CAAA;AAAA,WACtB,MAAA,IAAW,OAAO,CAAA,KAAM,QAAU,EAAA;AAChC,YAAA,WAAA,CAAY,IAAK,CAAA,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,CAAC,CAAE,CAAA,CAAA;AAAA;AAChC;AACF;AAGF,MAAA,IAAI,YAAY,MAAQ,EAAA;AACtB,QAAA,OAAA,CAAQ,IAAK,CAAA,WAAA,CAAY,IAAK,CAAA,GAAG,CAAC,CAAA;AAAA;AACpC;AAEF,IAAO,OAAA,OAAA;AAAA;AAEX;;;;"}
@@ -2,7 +2,7 @@ import { parseEntityRef, stringifyLocationRef } from '@backstage/catalog-model';
2
2
  import { ResponseError } from '@backstage/errors';
3
3
  import { CATALOG_FILTER_EXISTS } from './types/api.esm.js';
4
4
  import { splitRefsIntoChunks, isQueryEntitiesInitialRequest } from './utils.esm.js';
5
- import { DefaultApiClient } from './generated/apis/DefaultApi.client.esm.js';
5
+ import { DefaultApiClient } from './schema/openapi/generated/apis/DefaultApi.client.esm.js';
6
6
 
7
7
  class CatalogClient {
8
8
  apiClient;
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogClient.esm.js","sources":["../src/CatalogClient.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n CatalogRequestOptions,\n EntityFilterQuery,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\n GetEntitiesRequest,\n GetEntitiesResponse,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n Location,\n QueryEntitiesRequest,\n QueryEntitiesResponse,\n ValidateEntityResponse,\n} from './types/api';\nimport { isQueryEntitiesInitialRequest, splitRefsIntoChunks } from './utils';\nimport { DefaultApiClient, TypedResponse } from './generated';\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.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.apiClient\n .getEntitiesByQuery({ query: params }, options)\n .then(r => r.json());\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 new Error(await response.text());\n }\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityFacets}\n */\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter = [], facets } = request;\n 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 new Error(await response.text());\n }\n\n const { location, entities, exists } = await response.json();\n\n if (!location) {\n throw new Error(`Location wasn't added: ${target}`);\n }\n\n return {\n location,\n entities,\n exists,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByRef}\n */\n async getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const all = 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 // Private methods\n //\n\n private async requestIgnored(response: Response): Promise<void> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private async requestOptional(response: Response): Promise<any | undefined> {\n if (!response.ok) {\n if (response.status === 404) {\n return undefined;\n }\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n private getFilterValue(filter: EntityFilterQuery = []) {\n const filters: string[] = [];\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(key);\n } else if (typeof v === 'string') {\n filterParts.push(`${key}=${v}`);\n }\n }\n }\n\n if (filterParts.length) {\n filters.push(filterParts.join(','));\n }\n }\n return filters;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CatalogClient.esm.js","sources":["../src/CatalogClient.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n CatalogRequestOptions,\n EntityFilterQuery,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\n GetEntitiesRequest,\n GetEntitiesResponse,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n Location,\n QueryEntitiesRequest,\n QueryEntitiesResponse,\n ValidateEntityResponse,\n} from './types/api';\nimport { isQueryEntitiesInitialRequest, splitRefsIntoChunks } from './utils';\nimport { DefaultApiClient, TypedResponse } from './schema/openapi';\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.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.apiClient\n .getEntitiesByQuery({ query: params }, options)\n .then(r => r.json());\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 new Error(await response.text());\n }\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityFacets}\n */\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter = [], facets } = request;\n 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 new Error(await response.text());\n }\n\n const { location, entities, exists } = await response.json();\n\n if (!location) {\n throw new Error(`Location wasn't added: ${target}`);\n }\n\n return {\n location,\n entities,\n exists,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByRef}\n */\n async getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const all = 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 // Private methods\n //\n\n private async requestIgnored(response: Response): Promise<void> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private async requestOptional(response: Response): Promise<any | undefined> {\n if (!response.ok) {\n if (response.status === 404) {\n return undefined;\n }\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n private getFilterValue(filter: EntityFilterQuery = []) {\n const filters: string[] = [];\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(key);\n } else if (typeof v === 'string') {\n filterParts.push(`${key}=${v}`);\n }\n }\n }\n\n if (filterParts.length) {\n filters.push(filterParts.join(','));\n }\n }\n return filters;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"buildEntitySearch.cjs.js","sources":["../../../../../../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.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 { DEFAULT_NAMESPACE, Entity } from '@backstage/catalog-model';\nimport { InputError } from '@backstage/errors';\nimport { DbSearchRow } from '../../tables';\n\n// These are excluded in the generic loop, either because they do not make sense\n// to index, or because they are special-case always inserted whether they are\n// null or not\nconst SPECIAL_KEYS = [\n 'attachments',\n 'relations',\n 'status',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.uid',\n 'metadata.etag',\n];\n\n// The maximum length allowed for search values. These columns are indexed, and\n// database engines do not like to index on massive values. For example,\n// postgres will balk after 8191 byte line sizes.\nconst MAX_KEY_LENGTH = 200;\nconst MAX_VALUE_LENGTH = 200;\n\ntype Kv = {\n key: string;\n value: unknown;\n};\n\n// Helper for traversing through a nested structure and outputting a list of\n// path->value entries of the leaves.\n//\n// For example, this yaml structure\n//\n// a: 1\n// b:\n// c: null\n// e: [f, g]\n// h:\n// - i: 1\n// j: k\n// - i: 2\n// j: l\n//\n// will result in\n//\n// \"a\", 1\n// \"b.c\", null\n// \"b.e\": \"f\"\n// \"b.e.f\": true\n// \"b.e\": \"g\"\n// \"b.e.g\": true\n// \"h.i\": 1\n// \"h.j\": \"k\"\n// \"h.i\": 2\n// \"h.j\": \"l\"\nexport function traverse(root: unknown): Kv[] {\n const output: Kv[] = [];\n\n function visit(path: string, current: unknown) {\n if (SPECIAL_KEYS.includes(path)) {\n return;\n }\n\n // empty or scalar\n if (\n current === undefined ||\n current === null ||\n ['string', 'number', 'boolean'].includes(typeof current)\n ) {\n output.push({ key: path, value: current });\n return;\n }\n\n // unknown\n if (typeof current !== 'object') {\n return;\n }\n\n // array\n if (Array.isArray(current)) {\n for (const item of current) {\n // NOTE(freben): The reason that these are output in two different ways,\n // is to support use cases where you want to express that MORE than one\n // tag is present in a list. Since the EntityFilters structure is a\n // record, you can't have several entries of the same key. Therefore\n // you will have to match on\n //\n // { \"a.b\": [\"true\"], \"a.c\": [\"true\"] }\n //\n // rather than\n //\n // { \"a\": [\"b\", \"c\"] }\n //\n // because the latter means EITHER b or c has to be present.\n visit(path, item);\n if (typeof item === 'string') {\n output.push({ key: `${path}.${item}`, value: true });\n }\n }\n return;\n }\n\n // object\n for (const [key, value] of Object.entries(current!)) {\n visit(path ? `${path}.${key}` : key, value);\n }\n }\n\n visit('', root);\n\n return output;\n}\n\n// Translates a number of raw data rows to search table rows\nexport function mapToRows(input: Kv[], entityId: string): DbSearchRow[] {\n const result: DbSearchRow[] = [];\n\n for (const { key: rawKey, value: rawValue } of input) {\n const key = rawKey.toLocaleLowerCase('en-US');\n if (key.length > MAX_KEY_LENGTH) {\n continue;\n }\n if (rawValue === undefined || rawValue === null) {\n result.push({\n entity_id: entityId,\n key,\n original_value: null,\n value: null,\n });\n } else {\n const value = String(rawValue).toLocaleLowerCase('en-US');\n if (value.length <= MAX_VALUE_LENGTH) {\n result.push({\n entity_id: entityId,\n key,\n original_value: String(rawValue),\n value: value,\n });\n } else {\n result.push({\n entity_id: entityId,\n key,\n original_value: null,\n value: null,\n });\n }\n }\n }\n\n return result;\n}\n\n/**\n * Generates all of the search rows that are relevant for this entity.\n *\n * @param entityId - The uid of the entity\n * @param entity - The entity\n * @returns A list of entity search rows\n */\nexport function buildEntitySearch(\n entityId: string,\n entity: Entity,\n): DbSearchRow[] {\n // Visit the base structure recursively\n const raw = traverse(entity);\n\n // Start with some special keys that are always present because you want to\n // be able to easily search for null specifically\n raw.push({ key: 'metadata.name', value: entity.metadata.name });\n raw.push({ key: 'metadata.namespace', value: entity.metadata.namespace });\n raw.push({ key: 'metadata.uid', value: entity.metadata.uid });\n\n // Namespace not specified has the default value \"default\", so we want to\n // match on that as well\n if (!entity.metadata.namespace) {\n raw.push({ key: 'metadata.namespace', value: DEFAULT_NAMESPACE });\n }\n\n // Visit relations\n for (const relation of entity.relations ?? []) {\n raw.push({\n key: `relations.${relation.type}`,\n value: relation.targetRef,\n });\n }\n\n // This validates that there are no keys that vary only in casing, such\n // as `spec.foo` and `spec.Foo`.\n const keys = new Set(raw.map(r => r.key));\n const lowerKeys = new Set(raw.map(r => r.key.toLocaleLowerCase('en-US')));\n if (keys.size !== lowerKeys.size) {\n const difference = [];\n for (const key of keys) {\n const lower = key.toLocaleLowerCase('en-US');\n if (!lowerKeys.delete(lower)) {\n difference.push(lower);\n }\n }\n const badKeys = `'${difference.join(\"', '\")}'`;\n throw new InputError(\n `Entity has duplicate keys that vary only in casing, ${badKeys}`,\n );\n }\n\n return mapToRows(raw, entityId);\n}\n"],"names":[],"mappings":";;;;;AAuBA,MAAM,YAAe,GAAA;AAAA,EACnB,aAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA;AAAA,EACA,oBAAA;AAAA,EACA,cAAA;AAAA,EACA,eAAA;AACF,CAAA,CAAA;AAwCO,SAAS,SAAS,IAAqB,EAAA;AAC5C,EAAA,MAAM,SAAe,EAAC,CAAA;AAEtB,EAAS,SAAA,KAAA,CAAM,MAAc,OAAkB,EAAA;AAC7C,IAAI,IAAA,YAAA,CAAa,QAAS,CAAA,IAAI,CAAG,EAAA;AAC/B,MAAA,OAAA;AAAA,KACF;AAGA,IAAA,IACE,OAAY,KAAA,KAAA,CAAA,IACZ,OAAY,KAAA,IAAA,IACZ,CAAC,QAAA,EAAU,QAAU,EAAA,SAAS,CAAE,CAAA,QAAA,CAAS,OAAO,OAAO,CACvD,EAAA;AACA,MAAA,MAAA,CAAO,KAAK,EAAE,GAAA,EAAK,IAAM,EAAA,KAAA,EAAO,SAAS,CAAA,CAAA;AACzC,MAAA,OAAA;AAAA,KACF;AAGA,IAAI,IAAA,OAAO,YAAY,QAAU,EAAA;AAC/B,MAAA,OAAA;AAAA,KACF;AAGA,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,OAAO,CAAG,EAAA;AAC1B,MAAA,KAAA,MAAW,QAAQ,OAAS,EAAA;AAc1B,QAAA,KAAA,CAAM,MAAM,IAAI,CAAA,CAAA;AAChB,QAAI,IAAA,OAAO,SAAS,QAAU,EAAA;AAC5B,UAAO,MAAA,CAAA,IAAA,CAAK,EAAE,GAAA,EAAK,CAAG,EAAA,IAAI,IAAI,IAAI,CAAA,CAAA,EAAI,KAAO,EAAA,IAAA,EAAM,CAAA,CAAA;AAAA,SACrD;AAAA,OACF;AACA,MAAA,OAAA;AAAA,KACF;AAGA,IAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,OAAQ,CAAG,EAAA;AACnD,MAAA,KAAA,CAAM,OAAO,CAAG,EAAA,IAAI,IAAI,GAAG,CAAA,CAAA,GAAK,KAAK,KAAK,CAAA,CAAA;AAAA,KAC5C;AAAA,GACF;AAEA,EAAA,KAAA,CAAM,IAAI,IAAI,CAAA,CAAA;AAEd,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
1
+ {"version":3,"file":"buildEntitySearch.cjs.js","sources":["../../../../../../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.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 { DEFAULT_NAMESPACE, Entity } from '@backstage/catalog-model';\nimport { InputError } from '@backstage/errors';\nimport { DbSearchRow } from '../../tables';\n\n// These are excluded in the generic loop, either because they do not make sense\n// to index, or because they are special-case always inserted whether they are\n// null or not\nconst SPECIAL_KEYS = [\n 'attachments',\n 'relations',\n 'status',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.uid',\n 'metadata.etag',\n];\n\n// The maximum length allowed for search values. These columns are indexed, and\n// database engines do not like to index on massive values. For example,\n// postgres will balk after 8191 byte line sizes.\nconst MAX_KEY_LENGTH = 200;\nconst MAX_VALUE_LENGTH = 200;\n\ntype Kv = {\n key: string;\n value: unknown;\n};\n\n// Helper for traversing through a nested structure and outputting a list of\n// path->value entries of the leaves.\n//\n// For example, this yaml structure\n//\n// a: 1\n// b:\n// c: null\n// e: [f, g]\n// h:\n// - i: 1\n// j: k\n// - i: 2\n// j: l\n//\n// will result in\n//\n// \"a\", 1\n// \"b.c\", null\n// \"b.e\": \"f\"\n// \"b.e.f\": true\n// \"b.e\": \"g\"\n// \"b.e.g\": true\n// \"h.i\": 1\n// \"h.j\": \"k\"\n// \"h.i\": 2\n// \"h.j\": \"l\"\nexport function traverse(root: unknown): Kv[] {\n const output: Kv[] = [];\n\n function visit(path: string, current: unknown) {\n if (SPECIAL_KEYS.includes(path)) {\n return;\n }\n\n // empty or scalar\n if (\n current === undefined ||\n current === null ||\n ['string', 'number', 'boolean'].includes(typeof current)\n ) {\n output.push({ key: path, value: current });\n return;\n }\n\n // unknown\n if (typeof current !== 'object') {\n return;\n }\n\n // array\n if (Array.isArray(current)) {\n for (const item of current) {\n // NOTE(freben): The reason that these are output in two different ways,\n // is to support use cases where you want to express that MORE than one\n // tag is present in a list. Since the EntityFilters structure is a\n // record, you can't have several entries of the same key. Therefore\n // you will have to match on\n //\n // { \"a.b\": [\"true\"], \"a.c\": [\"true\"] }\n //\n // rather than\n //\n // { \"a\": [\"b\", \"c\"] }\n //\n // because the latter means EITHER b or c has to be present.\n visit(path, item);\n if (typeof item === 'string') {\n output.push({ key: `${path}.${item}`, value: true });\n }\n }\n return;\n }\n\n // object\n for (const [key, value] of Object.entries(current!)) {\n visit(path ? `${path}.${key}` : key, value);\n }\n }\n\n visit('', root);\n\n return output;\n}\n\n// Translates a number of raw data rows to search table rows\nexport function mapToRows(input: Kv[], entityId: string): DbSearchRow[] {\n const result: DbSearchRow[] = [];\n\n for (const { key: rawKey, value: rawValue } of input) {\n const key = rawKey.toLocaleLowerCase('en-US');\n if (key.length > MAX_KEY_LENGTH) {\n continue;\n }\n if (rawValue === undefined || rawValue === null) {\n result.push({\n entity_id: entityId,\n key,\n original_value: null,\n value: null,\n });\n } else {\n const value = String(rawValue).toLocaleLowerCase('en-US');\n if (value.length <= MAX_VALUE_LENGTH) {\n result.push({\n entity_id: entityId,\n key,\n original_value: String(rawValue),\n value: value,\n });\n } else {\n result.push({\n entity_id: entityId,\n key,\n original_value: null,\n value: null,\n });\n }\n }\n }\n\n return result;\n}\n\n/**\n * Generates all of the search rows that are relevant for this entity.\n *\n * @param entityId - The uid of the entity\n * @param entity - The entity\n * @returns A list of entity search rows\n */\nexport function buildEntitySearch(\n entityId: string,\n entity: Entity,\n): DbSearchRow[] {\n // Visit the base structure recursively\n const raw = traverse(entity);\n\n // Start with some special keys that are always present because you want to\n // be able to easily search for null specifically\n raw.push({ key: 'metadata.name', value: entity.metadata.name });\n raw.push({ key: 'metadata.namespace', value: entity.metadata.namespace });\n raw.push({ key: 'metadata.uid', value: entity.metadata.uid });\n\n // Namespace not specified has the default value \"default\", so we want to\n // match on that as well\n if (!entity.metadata.namespace) {\n raw.push({ key: 'metadata.namespace', value: DEFAULT_NAMESPACE });\n }\n\n // Visit relations\n for (const relation of entity.relations ?? []) {\n raw.push({\n key: `relations.${relation.type}`,\n value: relation.targetRef,\n });\n }\n\n // This validates that there are no keys that vary only in casing, such\n // as `spec.foo` and `spec.Foo`.\n const keys = new Set(raw.map(r => r.key));\n const lowerKeys = new Set(raw.map(r => r.key.toLocaleLowerCase('en-US')));\n if (keys.size !== lowerKeys.size) {\n const difference = [];\n for (const key of keys) {\n const lower = key.toLocaleLowerCase('en-US');\n if (!lowerKeys.delete(lower)) {\n difference.push(lower);\n }\n }\n const badKeys = `'${difference.join(\"', '\")}'`;\n throw new InputError(\n `Entity has duplicate keys that vary only in casing, ${badKeys}`,\n );\n }\n\n return mapToRows(raw, entityId);\n}\n"],"names":[],"mappings":";;;;;AAuBA,MAAM,YAAe,GAAA;AAAA,EACnB,aAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA;AAAA,EACA,oBAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA;AAwCO,SAAS,SAAS,IAAqB,EAAA;AAC5C,EAAA,MAAM,SAAe,EAAC;AAEtB,EAAS,SAAA,KAAA,CAAM,MAAc,OAAkB,EAAA;AAC7C,IAAI,IAAA,YAAA,CAAa,QAAS,CAAA,IAAI,CAAG,EAAA;AAC/B,MAAA;AAAA;AAIF,IAAA,IACE,OAAY,KAAA,KAAA,CAAA,IACZ,OAAY,KAAA,IAAA,IACZ,CAAC,QAAA,EAAU,QAAU,EAAA,SAAS,CAAE,CAAA,QAAA,CAAS,OAAO,OAAO,CACvD,EAAA;AACA,MAAA,MAAA,CAAO,KAAK,EAAE,GAAA,EAAK,IAAM,EAAA,KAAA,EAAO,SAAS,CAAA;AACzC,MAAA;AAAA;AAIF,IAAI,IAAA,OAAO,YAAY,QAAU,EAAA;AAC/B,MAAA;AAAA;AAIF,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,OAAO,CAAG,EAAA;AAC1B,MAAA,KAAA,MAAW,QAAQ,OAAS,EAAA;AAc1B,QAAA,KAAA,CAAM,MAAM,IAAI,CAAA;AAChB,QAAI,IAAA,OAAO,SAAS,QAAU,EAAA;AAC5B,UAAO,MAAA,CAAA,IAAA,CAAK,EAAE,GAAA,EAAK,CAAG,EAAA,IAAI,IAAI,IAAI,CAAA,CAAA,EAAI,KAAO,EAAA,IAAA,EAAM,CAAA;AAAA;AACrD;AAEF,MAAA;AAAA;AAIF,IAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,OAAQ,CAAG,EAAA;AACnD,MAAA,KAAA,CAAM,OAAO,CAAG,EAAA,IAAI,IAAI,GAAG,CAAA,CAAA,GAAK,KAAK,KAAK,CAAA;AAAA;AAC5C;AAGF,EAAA,KAAA,CAAM,IAAI,IAAI,CAAA;AAEd,EAAO,OAAA,MAAA;AACT;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"buildEntitySearch.esm.js","sources":["../../../../../../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.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 { DEFAULT_NAMESPACE, Entity } from '@backstage/catalog-model';\nimport { InputError } from '@backstage/errors';\nimport { DbSearchRow } from '../../tables';\n\n// These are excluded in the generic loop, either because they do not make sense\n// to index, or because they are special-case always inserted whether they are\n// null or not\nconst SPECIAL_KEYS = [\n 'attachments',\n 'relations',\n 'status',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.uid',\n 'metadata.etag',\n];\n\n// The maximum length allowed for search values. These columns are indexed, and\n// database engines do not like to index on massive values. For example,\n// postgres will balk after 8191 byte line sizes.\nconst MAX_KEY_LENGTH = 200;\nconst MAX_VALUE_LENGTH = 200;\n\ntype Kv = {\n key: string;\n value: unknown;\n};\n\n// Helper for traversing through a nested structure and outputting a list of\n// path->value entries of the leaves.\n//\n// For example, this yaml structure\n//\n// a: 1\n// b:\n// c: null\n// e: [f, g]\n// h:\n// - i: 1\n// j: k\n// - i: 2\n// j: l\n//\n// will result in\n//\n// \"a\", 1\n// \"b.c\", null\n// \"b.e\": \"f\"\n// \"b.e.f\": true\n// \"b.e\": \"g\"\n// \"b.e.g\": true\n// \"h.i\": 1\n// \"h.j\": \"k\"\n// \"h.i\": 2\n// \"h.j\": \"l\"\nexport function traverse(root: unknown): Kv[] {\n const output: Kv[] = [];\n\n function visit(path: string, current: unknown) {\n if (SPECIAL_KEYS.includes(path)) {\n return;\n }\n\n // empty or scalar\n if (\n current === undefined ||\n current === null ||\n ['string', 'number', 'boolean'].includes(typeof current)\n ) {\n output.push({ key: path, value: current });\n return;\n }\n\n // unknown\n if (typeof current !== 'object') {\n return;\n }\n\n // array\n if (Array.isArray(current)) {\n for (const item of current) {\n // NOTE(freben): The reason that these are output in two different ways,\n // is to support use cases where you want to express that MORE than one\n // tag is present in a list. Since the EntityFilters structure is a\n // record, you can't have several entries of the same key. Therefore\n // you will have to match on\n //\n // { \"a.b\": [\"true\"], \"a.c\": [\"true\"] }\n //\n // rather than\n //\n // { \"a\": [\"b\", \"c\"] }\n //\n // because the latter means EITHER b or c has to be present.\n visit(path, item);\n if (typeof item === 'string') {\n output.push({ key: `${path}.${item}`, value: true });\n }\n }\n return;\n }\n\n // object\n for (const [key, value] of Object.entries(current!)) {\n visit(path ? `${path}.${key}` : key, value);\n }\n }\n\n visit('', root);\n\n return output;\n}\n\n// Translates a number of raw data rows to search table rows\nexport function mapToRows(input: Kv[], entityId: string): DbSearchRow[] {\n const result: DbSearchRow[] = [];\n\n for (const { key: rawKey, value: rawValue } of input) {\n const key = rawKey.toLocaleLowerCase('en-US');\n if (key.length > MAX_KEY_LENGTH) {\n continue;\n }\n if (rawValue === undefined || rawValue === null) {\n result.push({\n entity_id: entityId,\n key,\n original_value: null,\n value: null,\n });\n } else {\n const value = String(rawValue).toLocaleLowerCase('en-US');\n if (value.length <= MAX_VALUE_LENGTH) {\n result.push({\n entity_id: entityId,\n key,\n original_value: String(rawValue),\n value: value,\n });\n } else {\n result.push({\n entity_id: entityId,\n key,\n original_value: null,\n value: null,\n });\n }\n }\n }\n\n return result;\n}\n\n/**\n * Generates all of the search rows that are relevant for this entity.\n *\n * @param entityId - The uid of the entity\n * @param entity - The entity\n * @returns A list of entity search rows\n */\nexport function buildEntitySearch(\n entityId: string,\n entity: Entity,\n): DbSearchRow[] {\n // Visit the base structure recursively\n const raw = traverse(entity);\n\n // Start with some special keys that are always present because you want to\n // be able to easily search for null specifically\n raw.push({ key: 'metadata.name', value: entity.metadata.name });\n raw.push({ key: 'metadata.namespace', value: entity.metadata.namespace });\n raw.push({ key: 'metadata.uid', value: entity.metadata.uid });\n\n // Namespace not specified has the default value \"default\", so we want to\n // match on that as well\n if (!entity.metadata.namespace) {\n raw.push({ key: 'metadata.namespace', value: DEFAULT_NAMESPACE });\n }\n\n // Visit relations\n for (const relation of entity.relations ?? []) {\n raw.push({\n key: `relations.${relation.type}`,\n value: relation.targetRef,\n });\n }\n\n // This validates that there are no keys that vary only in casing, such\n // as `spec.foo` and `spec.Foo`.\n const keys = new Set(raw.map(r => r.key));\n const lowerKeys = new Set(raw.map(r => r.key.toLocaleLowerCase('en-US')));\n if (keys.size !== lowerKeys.size) {\n const difference = [];\n for (const key of keys) {\n const lower = key.toLocaleLowerCase('en-US');\n if (!lowerKeys.delete(lower)) {\n difference.push(lower);\n }\n }\n const badKeys = `'${difference.join(\"', '\")}'`;\n throw new InputError(\n `Entity has duplicate keys that vary only in casing, ${badKeys}`,\n );\n }\n\n return mapToRows(raw, entityId);\n}\n"],"names":[],"mappings":";;;AAuBA,MAAM,YAAe,GAAA;AAAA,EACnB,aAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA;AAAA,EACA,oBAAA;AAAA,EACA,cAAA;AAAA,EACA,eAAA;AACF,CAAA,CAAA;AAwCO,SAAS,SAAS,IAAqB,EAAA;AAC5C,EAAA,MAAM,SAAe,EAAC,CAAA;AAEtB,EAAS,SAAA,KAAA,CAAM,MAAc,OAAkB,EAAA;AAC7C,IAAI,IAAA,YAAA,CAAa,QAAS,CAAA,IAAI,CAAG,EAAA;AAC/B,MAAA,OAAA;AAAA,KACF;AAGA,IAAA,IACE,OAAY,KAAA,KAAA,CAAA,IACZ,OAAY,KAAA,IAAA,IACZ,CAAC,QAAA,EAAU,QAAU,EAAA,SAAS,CAAE,CAAA,QAAA,CAAS,OAAO,OAAO,CACvD,EAAA;AACA,MAAA,MAAA,CAAO,KAAK,EAAE,GAAA,EAAK,IAAM,EAAA,KAAA,EAAO,SAAS,CAAA,CAAA;AACzC,MAAA,OAAA;AAAA,KACF;AAGA,IAAI,IAAA,OAAO,YAAY,QAAU,EAAA;AAC/B,MAAA,OAAA;AAAA,KACF;AAGA,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,OAAO,CAAG,EAAA;AAC1B,MAAA,KAAA,MAAW,QAAQ,OAAS,EAAA;AAc1B,QAAA,KAAA,CAAM,MAAM,IAAI,CAAA,CAAA;AAChB,QAAI,IAAA,OAAO,SAAS,QAAU,EAAA;AAC5B,UAAO,MAAA,CAAA,IAAA,CAAK,EAAE,GAAA,EAAK,CAAG,EAAA,IAAI,IAAI,IAAI,CAAA,CAAA,EAAI,KAAO,EAAA,IAAA,EAAM,CAAA,CAAA;AAAA,SACrD;AAAA,OACF;AACA,MAAA,OAAA;AAAA,KACF;AAGA,IAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,OAAQ,CAAG,EAAA;AACnD,MAAA,KAAA,CAAM,OAAO,CAAG,EAAA,IAAI,IAAI,GAAG,CAAA,CAAA,GAAK,KAAK,KAAK,CAAA,CAAA;AAAA,KAC5C;AAAA,GACF;AAEA,EAAA,KAAA,CAAM,IAAI,IAAI,CAAA,CAAA;AAEd,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
1
+ {"version":3,"file":"buildEntitySearch.esm.js","sources":["../../../../../../../../../plugins/catalog-backend/src/database/operations/stitcher/buildEntitySearch.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 { DEFAULT_NAMESPACE, Entity } from '@backstage/catalog-model';\nimport { InputError } from '@backstage/errors';\nimport { DbSearchRow } from '../../tables';\n\n// These are excluded in the generic loop, either because they do not make sense\n// to index, or because they are special-case always inserted whether they are\n// null or not\nconst SPECIAL_KEYS = [\n 'attachments',\n 'relations',\n 'status',\n 'metadata.name',\n 'metadata.namespace',\n 'metadata.uid',\n 'metadata.etag',\n];\n\n// The maximum length allowed for search values. These columns are indexed, and\n// database engines do not like to index on massive values. For example,\n// postgres will balk after 8191 byte line sizes.\nconst MAX_KEY_LENGTH = 200;\nconst MAX_VALUE_LENGTH = 200;\n\ntype Kv = {\n key: string;\n value: unknown;\n};\n\n// Helper for traversing through a nested structure and outputting a list of\n// path->value entries of the leaves.\n//\n// For example, this yaml structure\n//\n// a: 1\n// b:\n// c: null\n// e: [f, g]\n// h:\n// - i: 1\n// j: k\n// - i: 2\n// j: l\n//\n// will result in\n//\n// \"a\", 1\n// \"b.c\", null\n// \"b.e\": \"f\"\n// \"b.e.f\": true\n// \"b.e\": \"g\"\n// \"b.e.g\": true\n// \"h.i\": 1\n// \"h.j\": \"k\"\n// \"h.i\": 2\n// \"h.j\": \"l\"\nexport function traverse(root: unknown): Kv[] {\n const output: Kv[] = [];\n\n function visit(path: string, current: unknown) {\n if (SPECIAL_KEYS.includes(path)) {\n return;\n }\n\n // empty or scalar\n if (\n current === undefined ||\n current === null ||\n ['string', 'number', 'boolean'].includes(typeof current)\n ) {\n output.push({ key: path, value: current });\n return;\n }\n\n // unknown\n if (typeof current !== 'object') {\n return;\n }\n\n // array\n if (Array.isArray(current)) {\n for (const item of current) {\n // NOTE(freben): The reason that these are output in two different ways,\n // is to support use cases where you want to express that MORE than one\n // tag is present in a list. Since the EntityFilters structure is a\n // record, you can't have several entries of the same key. Therefore\n // you will have to match on\n //\n // { \"a.b\": [\"true\"], \"a.c\": [\"true\"] }\n //\n // rather than\n //\n // { \"a\": [\"b\", \"c\"] }\n //\n // because the latter means EITHER b or c has to be present.\n visit(path, item);\n if (typeof item === 'string') {\n output.push({ key: `${path}.${item}`, value: true });\n }\n }\n return;\n }\n\n // object\n for (const [key, value] of Object.entries(current!)) {\n visit(path ? `${path}.${key}` : key, value);\n }\n }\n\n visit('', root);\n\n return output;\n}\n\n// Translates a number of raw data rows to search table rows\nexport function mapToRows(input: Kv[], entityId: string): DbSearchRow[] {\n const result: DbSearchRow[] = [];\n\n for (const { key: rawKey, value: rawValue } of input) {\n const key = rawKey.toLocaleLowerCase('en-US');\n if (key.length > MAX_KEY_LENGTH) {\n continue;\n }\n if (rawValue === undefined || rawValue === null) {\n result.push({\n entity_id: entityId,\n key,\n original_value: null,\n value: null,\n });\n } else {\n const value = String(rawValue).toLocaleLowerCase('en-US');\n if (value.length <= MAX_VALUE_LENGTH) {\n result.push({\n entity_id: entityId,\n key,\n original_value: String(rawValue),\n value: value,\n });\n } else {\n result.push({\n entity_id: entityId,\n key,\n original_value: null,\n value: null,\n });\n }\n }\n }\n\n return result;\n}\n\n/**\n * Generates all of the search rows that are relevant for this entity.\n *\n * @param entityId - The uid of the entity\n * @param entity - The entity\n * @returns A list of entity search rows\n */\nexport function buildEntitySearch(\n entityId: string,\n entity: Entity,\n): DbSearchRow[] {\n // Visit the base structure recursively\n const raw = traverse(entity);\n\n // Start with some special keys that are always present because you want to\n // be able to easily search for null specifically\n raw.push({ key: 'metadata.name', value: entity.metadata.name });\n raw.push({ key: 'metadata.namespace', value: entity.metadata.namespace });\n raw.push({ key: 'metadata.uid', value: entity.metadata.uid });\n\n // Namespace not specified has the default value \"default\", so we want to\n // match on that as well\n if (!entity.metadata.namespace) {\n raw.push({ key: 'metadata.namespace', value: DEFAULT_NAMESPACE });\n }\n\n // Visit relations\n for (const relation of entity.relations ?? []) {\n raw.push({\n key: `relations.${relation.type}`,\n value: relation.targetRef,\n });\n }\n\n // This validates that there are no keys that vary only in casing, such\n // as `spec.foo` and `spec.Foo`.\n const keys = new Set(raw.map(r => r.key));\n const lowerKeys = new Set(raw.map(r => r.key.toLocaleLowerCase('en-US')));\n if (keys.size !== lowerKeys.size) {\n const difference = [];\n for (const key of keys) {\n const lower = key.toLocaleLowerCase('en-US');\n if (!lowerKeys.delete(lower)) {\n difference.push(lower);\n }\n }\n const badKeys = `'${difference.join(\"', '\")}'`;\n throw new InputError(\n `Entity has duplicate keys that vary only in casing, ${badKeys}`,\n );\n }\n\n return mapToRows(raw, entityId);\n}\n"],"names":[],"mappings":";;;AAuBA,MAAM,YAAe,GAAA;AAAA,EACnB,aAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,eAAA;AAAA,EACA,oBAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA;AAwCO,SAAS,SAAS,IAAqB,EAAA;AAC5C,EAAA,MAAM,SAAe,EAAC;AAEtB,EAAS,SAAA,KAAA,CAAM,MAAc,OAAkB,EAAA;AAC7C,IAAI,IAAA,YAAA,CAAa,QAAS,CAAA,IAAI,CAAG,EAAA;AAC/B,MAAA;AAAA;AAIF,IAAA,IACE,OAAY,KAAA,KAAA,CAAA,IACZ,OAAY,KAAA,IAAA,IACZ,CAAC,QAAA,EAAU,QAAU,EAAA,SAAS,CAAE,CAAA,QAAA,CAAS,OAAO,OAAO,CACvD,EAAA;AACA,MAAA,MAAA,CAAO,KAAK,EAAE,GAAA,EAAK,IAAM,EAAA,KAAA,EAAO,SAAS,CAAA;AACzC,MAAA;AAAA;AAIF,IAAI,IAAA,OAAO,YAAY,QAAU,EAAA;AAC/B,MAAA;AAAA;AAIF,IAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,OAAO,CAAG,EAAA;AAC1B,MAAA,KAAA,MAAW,QAAQ,OAAS,EAAA;AAc1B,QAAA,KAAA,CAAM,MAAM,IAAI,CAAA;AAChB,QAAI,IAAA,OAAO,SAAS,QAAU,EAAA;AAC5B,UAAO,MAAA,CAAA,IAAA,CAAK,EAAE,GAAA,EAAK,CAAG,EAAA,IAAI,IAAI,IAAI,CAAA,CAAA,EAAI,KAAO,EAAA,IAAA,EAAM,CAAA;AAAA;AACrD;AAEF,MAAA;AAAA;AAIF,IAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,OAAQ,CAAG,EAAA;AACnD,MAAA,KAAA,CAAM,OAAO,CAAG,EAAA,IAAI,IAAI,GAAG,CAAA,CAAA,GAAK,KAAK,KAAK,CAAA;AAAA;AAC5C;AAGF,EAAA,KAAA,CAAM,IAAI,IAAI,CAAA;AAEd,EAAO,OAAA,MAAA;AACT;;;;"}
@@ -36,7 +36,7 @@ class DefaultApiClient {
36
36
  }
37
37
  /**
38
38
  * Validate a given location.
39
- * @param analyzeLocationRequest
39
+ * @param analyzeLocationRequest -
40
40
  */
41
41
  async analyzeLocation(request, options) {
42
42
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -53,8 +53,8 @@ class DefaultApiClient {
53
53
  }
54
54
  /**
55
55
  * Create a location for a given target.
56
- * @param createLocationRequest
57
- * @param dryRun
56
+ * @param createLocationRequest -
57
+ * @param dryRun -
58
58
  */
59
59
  async createLocation(request, options) {
60
60
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -73,7 +73,7 @@ class DefaultApiClient {
73
73
  }
74
74
  /**
75
75
  * Delete a single entity by UID.
76
- * @param uid
76
+ * @param uid -
77
77
  */
78
78
  async deleteEntityByUid(request, options) {
79
79
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -91,7 +91,7 @@ class DefaultApiClient {
91
91
  }
92
92
  /**
93
93
  * Delete a location by id.
94
- * @param id
94
+ * @param id -
95
95
  */
96
96
  async deleteLocation(request, options) {
97
97
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -109,12 +109,12 @@ class DefaultApiClient {
109
109
  }
110
110
  /**
111
111
  * Get all entities matching a given filter.
112
- * @param fields Restrict to just these fields in the response.
113
- * @param limit Number of records to return in the response.
114
- * @param filter Filter for just the entities defined by this filter.
115
- * @param offset Number of records to skip in the query page.
116
- * @param after Pointer to the previous page of results.
117
- * @param order
112
+ * @param fields - Restrict to just these fields in the response.
113
+ * @param limit - Number of records to return in the response.
114
+ * @param filter - Filter for just the entities defined by this filter.
115
+ * @param offset - Number of records to skip in the query page.
116
+ * @param after - Pointer to the previous page of results.
117
+ * @param order -
118
118
  */
119
119
  async getEntities(request, options) {
120
120
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -132,13 +132,14 @@ class DefaultApiClient {
132
132
  }
133
133
  /**
134
134
  * Search for entities by a given query.
135
- * @param fields Restrict to just these fields in the response.
136
- * @param limit Number of records to return in the response.
137
- * @param orderField The fields to sort returned results by.
138
- * @param cursor Cursor to a set page of results.
139
- * @param filter Filter for just the entities defined by this filter.
140
- * @param fullTextFilterTerm Text search term.
141
- * @param fullTextFilterFields A comma separated list of fields to sort returned results by.
135
+ * @param fields - Restrict to just these fields in the response.
136
+ * @param limit - Number of records to return in the response.
137
+ * @param offset - Number of records to skip in the query page.
138
+ * @param orderField - The fields to sort returned results by.
139
+ * @param cursor - Cursor to a set page of results.
140
+ * @param filter - Filter for just the entities defined by this filter.
141
+ * @param fullTextFilterTerm - Text search term.
142
+ * @param fullTextFilterFields - A comma separated list of fields to sort returned results by.
142
143
  */
143
144
  async getEntitiesByQuery(request, options) {
144
145
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -156,12 +157,15 @@ class DefaultApiClient {
156
157
  }
157
158
  /**
158
159
  * Get a batch set of entities given an array of entityRefs.
159
- * @param getEntitiesByRefsRequest
160
+ * @param filter - Filter for just the entities defined by this filter.
161
+ * @param getEntitiesByRefsRequest -
160
162
  */
161
163
  async getEntitiesByRefs(request, options) {
162
164
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
163
- const uriTemplate = `/entities/by-refs/{?filter*}`;
164
- const uri = parser__namespace.parse(uriTemplate).expand({ ...request.query });
165
+ const uriTemplate = `/entities/by-refs{?filter*}`;
166
+ const uri = parser__namespace.parse(uriTemplate).expand({
167
+ ...request.query
168
+ });
165
169
  return await this.fetchApi.fetch(`${baseUrl}${uri}`, {
166
170
  headers: {
167
171
  "Content-Type": "application/json",
@@ -173,9 +177,9 @@ class DefaultApiClient {
173
177
  }
174
178
  /**
175
179
  * Get an entity's ancestry by entity ref.
176
- * @param kind
177
- * @param namespace
178
- * @param name
180
+ * @param kind -
181
+ * @param namespace -
182
+ * @param name -
179
183
  */
180
184
  async getEntityAncestryByName(request, options) {
181
185
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -195,9 +199,9 @@ class DefaultApiClient {
195
199
  }
196
200
  /**
197
201
  * Get an entity by an entity ref.
198
- * @param kind
199
- * @param namespace
200
- * @param name
202
+ * @param kind -
203
+ * @param namespace -
204
+ * @param name -
201
205
  */
202
206
  async getEntityByName(request, options) {
203
207
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -217,7 +221,7 @@ class DefaultApiClient {
217
221
  }
218
222
  /**
219
223
  * Get a single entity by the UID.
220
- * @param uid
224
+ * @param uid -
221
225
  */
222
226
  async getEntityByUid(request, options) {
223
227
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -235,8 +239,8 @@ class DefaultApiClient {
235
239
  }
236
240
  /**
237
241
  * Get all entity facets that match the given filters.
238
- * @param facet
239
- * @param filter Filter for just the entities defined by this filter.
242
+ * @param facet -
243
+ * @param filter - Filter for just the entities defined by this filter.
240
244
  */
241
245
  async getEntityFacets(request, options) {
242
246
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -254,7 +258,7 @@ class DefaultApiClient {
254
258
  }
255
259
  /**
256
260
  * Get a location by id.
257
- * @param id
261
+ * @param id -
258
262
  */
259
263
  async getLocation(request, options) {
260
264
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -272,9 +276,9 @@ class DefaultApiClient {
272
276
  }
273
277
  /**
274
278
  * Get a location for entity.
275
- * @param kind
276
- * @param namespace
277
- * @param name
279
+ * @param kind -
280
+ * @param namespace -
281
+ * @param name -
278
282
  */
279
283
  async getLocationByEntity(request, options) {
280
284
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -309,7 +313,7 @@ class DefaultApiClient {
309
313
  }
310
314
  /**
311
315
  * Refresh the entity related to entityRef.
312
- * @param refreshEntityRequest
316
+ * @param refreshEntityRequest -
313
317
  */
314
318
  async refreshEntity(request, options) {
315
319
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -326,7 +330,7 @@ class DefaultApiClient {
326
330
  }
327
331
  /**
328
332
  * Validate that a passed in entity has no errors in schema.
329
- * @param validateEntityRequest
333
+ * @param validateEntityRequest -
330
334
  */
331
335
  async validateEntity(request, options) {
332
336
  const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultApi.client.cjs.js","sources":["../../../../../src/schema/openapi/generated/apis/DefaultApi.client.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\n// ******************************************************************\n// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *\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';\n\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 { 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 { GetLocations200ResponseInner } from '../models/GetLocations200ResponseInner.model';\nimport { Location } from '../models/Location.model';\nimport { RefreshEntityRequest } from '../models/RefreshEntityRequest.model';\nimport { ValidateEntityRequest } from '../models/ValidateEntityRequest.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/**\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 DeleteEntityByUid = {\n path: {\n uid: string;\n };\n};\n/**\n * @public\n */\nexport type DeleteLocation = {\n path: {\n id: 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 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 RefreshEntity = {\n body: RefreshEntityRequest;\n};\n/**\n * @public\n */\nexport type ValidateEntity = {\n body: ValidateEntityRequest;\n};\n\n/**\n * no description\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 * 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 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 * 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 all entities matching a given filter.\n * @param fields - Restrict to just these fields in the response.\n * @param limit - Number of records to return in the response.\n * @param filter - Filter for just the entities defined by this filter.\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 - Restrict to just these fields in the response.\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 - The fields to sort returned results by.\n * @param cursor - Cursor to a set page of results.\n * @param filter - Filter for just the entities defined by this filter.\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 - Filter for just the entities defined by this filter.\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 - Filter for just the entities defined by this filter.\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 * 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 * 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"],"names":["crossFetch","pluginId","parser"],"mappings":"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"}