@backstage/catalog-client 1.6.4 → 1.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/CatalogClient.esm.js +340 -0
- package/dist/CatalogClient.esm.js.map +1 -0
- package/dist/generated/apis/DefaultApi.client.esm.js +328 -0
- package/dist/generated/apis/DefaultApi.client.esm.js.map +1 -0
- package/dist/generated/pluginId.esm.js +4 -0
- package/dist/generated/pluginId.esm.js.map +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +3 -673
- package/dist/index.esm.js.map +1 -1
- package/dist/types/api.esm.js +7 -0
- package/dist/types/api.esm.js.map +1 -0
- package/dist/types/status.esm.js +4 -0
- package/dist/types/status.esm.js.map +1 -0
- package/dist/utils.esm.js +6 -0
- package/dist/utils.esm.js.map +1 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @backstage/catalog-client
|
|
2
2
|
|
|
3
|
+
## 1.6.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/catalog-model@1.5.0
|
|
9
|
+
|
|
10
|
+
## 1.6.5-next.0
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
- @backstage/catalog-model@1.5.0-next.0
|
|
16
|
+
- @backstage/errors@1.2.4
|
|
17
|
+
|
|
3
18
|
## 1.6.4
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { parseEntityRef, stringifyLocationRef, stringifyEntityRef } from '@backstage/catalog-model';
|
|
2
|
+
import { ResponseError } from '@backstage/errors';
|
|
3
|
+
import { CATALOG_FILTER_EXISTS } from './types/api.esm.js';
|
|
4
|
+
import { isQueryEntitiesInitialRequest } from './utils.esm.js';
|
|
5
|
+
import { DefaultApiClient } from './generated/apis/DefaultApi.client.esm.js';
|
|
6
|
+
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __publicField = (obj, key, value) => {
|
|
10
|
+
__defNormalProp(obj, key + "" , value);
|
|
11
|
+
return value;
|
|
12
|
+
};
|
|
13
|
+
class CatalogClient {
|
|
14
|
+
constructor(options) {
|
|
15
|
+
__publicField(this, "apiClient");
|
|
16
|
+
this.apiClient = new DefaultApiClient(options);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* {@inheritdoc CatalogApi.getEntityAncestors}
|
|
20
|
+
*/
|
|
21
|
+
async getEntityAncestors(request, options) {
|
|
22
|
+
return await this.requestRequired(
|
|
23
|
+
await this.apiClient.getEntityAncestryByName(
|
|
24
|
+
{ path: parseEntityRef(request.entityRef) },
|
|
25
|
+
options
|
|
26
|
+
)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* {@inheritdoc CatalogApi.getLocationById}
|
|
31
|
+
*/
|
|
32
|
+
async getLocationById(id, options) {
|
|
33
|
+
return await this.requestOptional(
|
|
34
|
+
await this.apiClient.getLocation({ path: { id } }, options)
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* {@inheritdoc CatalogApi.getLocationByEntity}
|
|
39
|
+
*/
|
|
40
|
+
async getLocationByEntity(entityRef, options) {
|
|
41
|
+
return await this.requestOptional(
|
|
42
|
+
await this.apiClient.getLocationByEntity(
|
|
43
|
+
{ path: parseEntityRef(entityRef) },
|
|
44
|
+
options
|
|
45
|
+
)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* {@inheritdoc CatalogApi.getEntities}
|
|
50
|
+
*/
|
|
51
|
+
async getEntities(request, options) {
|
|
52
|
+
const {
|
|
53
|
+
filter = [],
|
|
54
|
+
fields = [],
|
|
55
|
+
order,
|
|
56
|
+
offset,
|
|
57
|
+
limit,
|
|
58
|
+
after
|
|
59
|
+
} = request != null ? request : {};
|
|
60
|
+
const encodedOrder = [];
|
|
61
|
+
if (order) {
|
|
62
|
+
for (const directive of [order].flat()) {
|
|
63
|
+
if (directive) {
|
|
64
|
+
encodedOrder.push(`${directive.order}:${directive.field}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const entities = await this.requestRequired(
|
|
69
|
+
await this.apiClient.getEntities(
|
|
70
|
+
{
|
|
71
|
+
query: {
|
|
72
|
+
fields,
|
|
73
|
+
limit,
|
|
74
|
+
filter: this.getFilterValue(filter),
|
|
75
|
+
offset,
|
|
76
|
+
after,
|
|
77
|
+
order: order ? encodedOrder : void 0
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
options
|
|
81
|
+
)
|
|
82
|
+
);
|
|
83
|
+
if (encodedOrder.length) {
|
|
84
|
+
return { items: entities };
|
|
85
|
+
}
|
|
86
|
+
const refCompare = (a, b) => {
|
|
87
|
+
var _a, _b;
|
|
88
|
+
if (((_a = a.metadata) == null ? void 0 : _a.name) === void 0 || a.kind === void 0 || ((_b = b.metadata) == null ? void 0 : _b.name) === void 0 || b.kind === void 0) {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
const aRef = stringifyEntityRef(a);
|
|
92
|
+
const bRef = stringifyEntityRef(b);
|
|
93
|
+
if (aRef < bRef) {
|
|
94
|
+
return -1;
|
|
95
|
+
}
|
|
96
|
+
if (aRef > bRef) {
|
|
97
|
+
return 1;
|
|
98
|
+
}
|
|
99
|
+
return 0;
|
|
100
|
+
};
|
|
101
|
+
return { items: entities.sort(refCompare) };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* {@inheritdoc CatalogApi.getEntitiesByRefs}
|
|
105
|
+
*/
|
|
106
|
+
async getEntitiesByRefs(request, options) {
|
|
107
|
+
const response = await this.apiClient.getEntitiesByRefs(
|
|
108
|
+
{
|
|
109
|
+
body: {
|
|
110
|
+
entityRefs: request.entityRefs,
|
|
111
|
+
fields: request.fields
|
|
112
|
+
},
|
|
113
|
+
query: {
|
|
114
|
+
filter: this.getFilterValue(request.filter)
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
options
|
|
118
|
+
);
|
|
119
|
+
if (!response.ok) {
|
|
120
|
+
throw await ResponseError.fromResponse(response);
|
|
121
|
+
}
|
|
122
|
+
const { items } = await response.json();
|
|
123
|
+
return { items: items.map((i) => i != null ? i : void 0) };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* {@inheritdoc CatalogApi.queryEntities}
|
|
127
|
+
*/
|
|
128
|
+
async queryEntities(request = {}, options) {
|
|
129
|
+
var _a, _b;
|
|
130
|
+
const params = {};
|
|
131
|
+
if (isQueryEntitiesInitialRequest(request)) {
|
|
132
|
+
const {
|
|
133
|
+
fields = [],
|
|
134
|
+
filter,
|
|
135
|
+
limit,
|
|
136
|
+
orderFields,
|
|
137
|
+
fullTextFilter
|
|
138
|
+
} = request;
|
|
139
|
+
params.filter = this.getFilterValue(filter);
|
|
140
|
+
if (limit !== void 0) {
|
|
141
|
+
params.limit = limit;
|
|
142
|
+
}
|
|
143
|
+
if (orderFields !== void 0) {
|
|
144
|
+
params.orderField = (Array.isArray(orderFields) ? orderFields : [orderFields]).map(({ field, order }) => `${field},${order}`);
|
|
145
|
+
}
|
|
146
|
+
if (fields.length) {
|
|
147
|
+
params.fields = fields;
|
|
148
|
+
}
|
|
149
|
+
const normalizedFullTextFilterTerm = (_a = fullTextFilter == null ? void 0 : fullTextFilter.term) == null ? void 0 : _a.trim();
|
|
150
|
+
if (normalizedFullTextFilterTerm) {
|
|
151
|
+
params.fullTextFilterTerm = normalizedFullTextFilterTerm;
|
|
152
|
+
}
|
|
153
|
+
if ((_b = fullTextFilter == null ? void 0 : fullTextFilter.fields) == null ? void 0 : _b.length) {
|
|
154
|
+
params.fullTextFilterFields = fullTextFilter.fields;
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
const { fields = [], limit, cursor } = request;
|
|
158
|
+
params.cursor = cursor;
|
|
159
|
+
if (limit !== void 0) {
|
|
160
|
+
params.limit = limit;
|
|
161
|
+
}
|
|
162
|
+
if (fields.length) {
|
|
163
|
+
params.fields = fields;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return this.apiClient.getEntitiesByQuery({ query: params }, options).then((r) => r.json());
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* {@inheritdoc CatalogApi.getEntityByRef}
|
|
170
|
+
*/
|
|
171
|
+
async getEntityByRef(entityRef, options) {
|
|
172
|
+
return this.requestOptional(
|
|
173
|
+
await this.apiClient.getEntityByName(
|
|
174
|
+
{
|
|
175
|
+
path: parseEntityRef(entityRef)
|
|
176
|
+
},
|
|
177
|
+
options
|
|
178
|
+
)
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
// NOTE(freben): When we deprecate getEntityByName from the interface, we may
|
|
182
|
+
// still want to leave this implementation in place for quite some time
|
|
183
|
+
// longer, to minimize the risk for breakages. Suggested date for removal:
|
|
184
|
+
// August 2022
|
|
185
|
+
/**
|
|
186
|
+
* @deprecated Use getEntityByRef instead
|
|
187
|
+
*/
|
|
188
|
+
async getEntityByName(compoundName, options) {
|
|
189
|
+
const { kind, namespace = "default", name } = compoundName;
|
|
190
|
+
return this.requestOptional(
|
|
191
|
+
await this.apiClient.getEntityByName(
|
|
192
|
+
{ path: { kind, namespace, name } },
|
|
193
|
+
options
|
|
194
|
+
)
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* {@inheritdoc CatalogApi.refreshEntity}
|
|
199
|
+
*/
|
|
200
|
+
async refreshEntity(entityRef, options) {
|
|
201
|
+
const response = await this.apiClient.refreshEntity(
|
|
202
|
+
{ body: { entityRef } },
|
|
203
|
+
options
|
|
204
|
+
);
|
|
205
|
+
if (response.status !== 200) {
|
|
206
|
+
throw new Error(await response.text());
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* {@inheritdoc CatalogApi.getEntityFacets}
|
|
211
|
+
*/
|
|
212
|
+
async getEntityFacets(request, options) {
|
|
213
|
+
const { filter = [], facets } = request;
|
|
214
|
+
return await this.requestOptional(
|
|
215
|
+
await this.apiClient.getEntityFacets(
|
|
216
|
+
{
|
|
217
|
+
query: { facet: facets, filter: this.getFilterValue(filter) }
|
|
218
|
+
},
|
|
219
|
+
options
|
|
220
|
+
)
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* {@inheritdoc CatalogApi.addLocation}
|
|
225
|
+
*/
|
|
226
|
+
async addLocation(request, options) {
|
|
227
|
+
const { type = "url", target, dryRun } = request;
|
|
228
|
+
const response = await this.apiClient.createLocation(
|
|
229
|
+
{
|
|
230
|
+
body: { type, target },
|
|
231
|
+
query: { dryRun: dryRun ? "true" : void 0 }
|
|
232
|
+
},
|
|
233
|
+
options
|
|
234
|
+
);
|
|
235
|
+
if (response.status !== 201) {
|
|
236
|
+
throw new Error(await response.text());
|
|
237
|
+
}
|
|
238
|
+
const { location, entities, exists } = await response.json();
|
|
239
|
+
if (!location) {
|
|
240
|
+
throw new Error(`Location wasn't added: ${target}`);
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
location,
|
|
244
|
+
entities,
|
|
245
|
+
exists
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* {@inheritdoc CatalogApi.getLocationByRef}
|
|
250
|
+
*/
|
|
251
|
+
async getLocationByRef(locationRef, options) {
|
|
252
|
+
const all = await this.requestRequired(
|
|
253
|
+
await this.apiClient.getLocations({}, options)
|
|
254
|
+
);
|
|
255
|
+
return all.map((r) => r.data).find((l) => locationRef === stringifyLocationRef(l));
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* {@inheritdoc CatalogApi.removeLocationById}
|
|
259
|
+
*/
|
|
260
|
+
async removeLocationById(id, options) {
|
|
261
|
+
await this.requestIgnored(
|
|
262
|
+
await this.apiClient.deleteLocation({ path: { id } }, options)
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* {@inheritdoc CatalogApi.removeEntityByUid}
|
|
267
|
+
*/
|
|
268
|
+
async removeEntityByUid(uid, options) {
|
|
269
|
+
await this.requestIgnored(
|
|
270
|
+
await this.apiClient.deleteEntityByUid({ path: { uid } }, options)
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* {@inheritdoc CatalogApi.validateEntity}
|
|
275
|
+
*/
|
|
276
|
+
async validateEntity(entity, locationRef, options) {
|
|
277
|
+
const response = await this.apiClient.validateEntity(
|
|
278
|
+
{ body: { entity, location: locationRef } },
|
|
279
|
+
options
|
|
280
|
+
);
|
|
281
|
+
if (response.ok) {
|
|
282
|
+
return {
|
|
283
|
+
valid: true
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
if (response.status !== 400) {
|
|
287
|
+
throw await ResponseError.fromResponse(response);
|
|
288
|
+
}
|
|
289
|
+
const { errors = [] } = await response.json();
|
|
290
|
+
return {
|
|
291
|
+
valid: false,
|
|
292
|
+
errors
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
//
|
|
296
|
+
// Private methods
|
|
297
|
+
//
|
|
298
|
+
async requestIgnored(response) {
|
|
299
|
+
if (!response.ok) {
|
|
300
|
+
throw await ResponseError.fromResponse(response);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async requestRequired(response) {
|
|
304
|
+
if (!response.ok) {
|
|
305
|
+
throw await ResponseError.fromResponse(response);
|
|
306
|
+
}
|
|
307
|
+
return response.json();
|
|
308
|
+
}
|
|
309
|
+
async requestOptional(response) {
|
|
310
|
+
if (!response.ok) {
|
|
311
|
+
if (response.status === 404) {
|
|
312
|
+
return void 0;
|
|
313
|
+
}
|
|
314
|
+
throw await ResponseError.fromResponse(response);
|
|
315
|
+
}
|
|
316
|
+
return await response.json();
|
|
317
|
+
}
|
|
318
|
+
getFilterValue(filter = []) {
|
|
319
|
+
const filters = [];
|
|
320
|
+
for (const filterItem of [filter].flat()) {
|
|
321
|
+
const filterParts = [];
|
|
322
|
+
for (const [key, value] of Object.entries(filterItem)) {
|
|
323
|
+
for (const v of [value].flat()) {
|
|
324
|
+
if (v === CATALOG_FILTER_EXISTS) {
|
|
325
|
+
filterParts.push(key);
|
|
326
|
+
} else if (typeof v === "string") {
|
|
327
|
+
filterParts.push(`${key}=${v}`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (filterParts.length) {
|
|
332
|
+
filters.push(filterParts.join(","));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return filters;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export { CatalogClient };
|
|
340
|
+
//# sourceMappingURL=CatalogClient.esm.js.map
|
|
@@ -0,0 +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 stringifyEntityRef,\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 } 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\n // do not sort entities, if order is provided\n if (encodedOrder.length) {\n return { items: entities };\n }\n\n const refCompare = (a: Entity, b: Entity) => {\n // in case field filtering is used, these fields might not be part of the response\n if (\n a.metadata?.name === undefined ||\n a.kind === undefined ||\n b.metadata?.name === undefined ||\n b.kind === undefined\n ) {\n return 0;\n }\n\n const aRef = stringifyEntityRef(a);\n const bRef = stringifyEntityRef(b);\n if (aRef < bRef) {\n return -1;\n }\n if (aRef > bRef) {\n return 1;\n }\n return 0;\n };\n\n return { items: entities.sort(refCompare) };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntitiesByRefs}\n */\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesByRefsResponse> {\n const response = await this.apiClient.getEntitiesByRefs(\n {\n body: {\n entityRefs: request.entityRefs,\n fields: request.fields,\n },\n query: {\n filter: this.getFilterValue(request.filter),\n },\n },\n options,\n );\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { items } = (await response.json()) as {\n items: Array<Entity | null>;\n };\n\n return { items: items.map(i => i ?? undefined) };\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 orderFields,\n fullTextFilter,\n } = request;\n params.filter = this.getFilterValue(filter);\n\n if (limit !== undefined) {\n params.limit = limit;\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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"}
|