Add support for passing paging parameters to the getEntities call of the catalog client

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2021-12-15 22:47:52 +01:00
parent 7bd536c985
commit 5463c03b35
5 changed files with 107 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/catalog-client': patch
---
Add support for passing paging parameters to the getEntities call of the catalog client
+3
View File
@@ -121,6 +121,9 @@ export type CatalogEntitiesRequest = {
| Record<string, string | symbol | (string | symbol)[]>
| undefined;
fields?: string[] | undefined;
offset?: number;
limit?: number;
after?: string;
};
// @public
@@ -175,6 +175,24 @@ describe('CatalogClient', () => {
{ apiVersion: '2' },
]);
});
it('builds paging parameters properly', async () => {
expect.assertions(2);
server.use(
rest.get(`${mockBaseUrl}/entities`, (req, res, ctx) => {
expect(req.url.search).toBe('?offset=1&limit=2&after=%3D');
return res(ctx.json([]));
}),
);
const response = await client.getEntities(
{ offset: 1, limit: 2, after: '=' },
{ token },
);
expect(response.items).toEqual([]);
});
});
describe('getLocationById', () => {
+11 -1
View File
@@ -110,7 +110,7 @@ export class CatalogClient implements CatalogApi {
request?: CatalogEntitiesRequest,
options?: CatalogRequestOptions,
): Promise<CatalogListResponse<Entity>> {
const { filter = [], fields = [] } = request ?? {};
const { filter = [], fields = [], offset, limit, after } = request ?? {};
const filterItems = [filter].flat();
const params: string[] = [];
@@ -141,6 +141,16 @@ export class CatalogClient implements CatalogApi {
params.push(`fields=${fields.map(encodeURIComponent).join(',')}`);
}
if (offset !== undefined) {
params.push(`offset=${offset}`);
}
if (limit !== undefined) {
params.push(`limit=${limit}`);
}
if (after !== undefined) {
params.push(`after=${encodeURIComponent(after)}`);
}
const query = params.length ? `?${params.join('&')}` : '';
const entities: Entity[] = await this.requestRequired(
'GET',
+70
View File
@@ -29,11 +29,81 @@ export const CATALOG_FILTER_EXISTS = Symbol('CATALOG_FILTER_EXISTS');
* @public
*/
export type CatalogEntitiesRequest = {
/**
* If given, return only entities that match the given patterns.
*
* @remarks
*
* If multiple filter sets are given as an array, then there is effectively an
* OR between each filter set.
*
* Within one filter set, there is effectively an AND between the various
* keys.
*
* Within one key, if there are more than one value, then there is effectively
* an OR between them.
*
* Example: For an input of
*
* ```
* [
* { kind: ['API', 'Component'] },
* { 'metadata.name': 'a', 'metadata.namespace': 'b' }
* ]
* ```
*
* This effectively means
*
* ```
* (kind = EITHER 'API' OR 'Component')
* OR
* (metadata.name = 'a' AND metadata.namespace = 'b' )
* ```
*
* Each key is a dot separated path in each object.
*
* As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`
* (exported from this package), which means that you assert on the existence
* of that key, no matter what its value is.
*/
filter?:
| Record<string, string | symbol | (string | symbol)[]>[]
| Record<string, string | symbol | (string | symbol)[]>
| undefined;
/**
* If given, return only the parts of each entity that match those dot
* separated paths in each object.
*
* @remarks
*
* Example: For an input of `['kind', 'metadata.annotations']`, then response
* objects will be shaped like
*
* ```
* {
* "kind": "Component",
* "metadata": {
* "annotations": {
* "foo": "bar"
* }
* }
* }
* ```
*/
fields?: string[] | undefined;
/**
* If given, skips over the first N items in the result set.
*/
offset?: number;
/**
* If given, returns at most N items from the result set.
*/
limit?: number;
/**
* If given, skips over all items before that cursor as returned by a previous
* request.
*/
after?: string;
};
/**