Merge pull request #11130 from webark/entity-query-with-dot-params

Updated parseEntityTransformParams to handle keys with '.' in them
This commit is contained in:
Fredrik Adelöw
2022-05-09 16:32:47 +02:00
committed by GitHub
3 changed files with 138 additions and 3 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
Updated parseEntityTransformParams to handle keys with '.' in them. This will allow for querying of entities based off annotations such as 'backstage.io/orgin-location' or other entity field keys that have '.' in them.
@@ -24,6 +24,11 @@ describe('parseEntityTransformParams', () => {
metadata: {
name: 'n',
tags: ['t1', 't2'],
annotations: {
'example.test/url-like-key': 'ul1',
'example.com/other-url-like-key': 'ul2',
'other-example.test/next-url-like-key': 'ul3',
},
},
spec: {
type: 't',
@@ -61,7 +66,115 @@ describe('parseEntityTransformParams', () => {
parseEntityTransformParams({ fields: 'kind,metadata.name' })!(entity),
).toEqual({ kind: 'k', metadata: { name: 'n' } });
expect(parseEntityTransformParams({ fields: 'metadata' })!(entity)).toEqual(
{ metadata: { name: 'n', tags: ['t1', 't2'] } },
{
metadata: {
name: 'n',
tags: ['t1', 't2'],
annotations: {
'example.test/url-like-key': 'ul1',
'example.com/other-url-like-key': 'ul2',
'other-example.test/next-url-like-key': 'ul3',
},
},
},
);
});
it('supports dot notated fields properly', () => {
expect(
parseEntityTransformParams({
fields: 'kind,metadata.annotations.example.com/other-url-like-key',
})!(entity),
).toEqual({
kind: 'k',
metadata: { annotations: { 'example.com/other-url-like-key': 'ul2' } },
});
});
it('supports nested dot notated fields properly', () => {
entity.spec = {
...entity.spec,
'field-with.dot': 'fd1',
'other-field-with.dot-also': {
subItem: 'fd2.sub',
'subite.with/dot': 'fd2.sub.dot',
},
'third-field-with.dot-again': 'fd3',
};
expect(
parseEntityTransformParams({
fields: 'kind,spec.other-field-with.dot-also',
})!(entity),
).toEqual({
kind: 'k',
spec: {
'other-field-with.dot-also': {
subItem: 'fd2.sub',
'subite.with/dot': 'fd2.sub.dot',
},
},
});
expect(
parseEntityTransformParams({
fields: 'kind,spec.other-field-with.dot-also.subite.with/dot',
})!(entity),
).toEqual({
kind: 'k',
spec: {
'other-field-with.dot-also': {
'subite.with/dot': 'fd2.sub.dot',
},
},
});
});
it('does not return a sub key if an incorrect longer key is requested', () => {
entity.spec = {
...entity.spec,
strValue: 'st1',
boolValue: true,
numValue: 4,
arrValue: [4, 5],
nullValue: null,
undefValue: undefined,
'field-with.dot': 'fd1',
};
expect(
parseEntityTransformParams({ fields: 'kind,spec.strValue.other' })!(
entity,
),
).toEqual({ kind: 'k' });
expect(
parseEntityTransformParams({ fields: 'kind,spec.boolValue.other' })!(
entity,
),
).toEqual({ kind: 'k' });
expect(
parseEntityTransformParams({ fields: 'kind,spec.numValue.other' })!(
entity,
),
).toEqual({ kind: 'k' });
expect(
parseEntityTransformParams({ fields: 'kind,spec.arrValue.other' })!(
entity,
),
).toEqual({ kind: 'k' });
expect(
parseEntityTransformParams({ fields: 'kind,spec.nullValue.other' })!(
entity,
),
).toEqual({ kind: 'k' });
expect(
parseEntityTransformParams({ fields: 'kind,spec.undefValue.other' })!(
entity,
),
).toEqual({ kind: 'k' });
expect(
parseEntityTransformParams({ fields: 'kind,spec.field-with.dot.other' })!(
entity,
),
).toEqual({ kind: 'k' });
});
});
@@ -20,6 +20,22 @@ import lodash from 'lodash';
import { RecursivePartial } from '../../util/RecursivePartial';
import { parseStringsParam } from './common';
function getPathArrayAndValue(input: Entity, field: string) {
return field.split('.').reduce(
([pathArray, inputSubset], pathPart, index, fieldParts) => {
if (lodash.hasIn(inputSubset, pathPart)) {
return [pathArray.concat(pathPart), inputSubset[pathPart]];
} else if (fieldParts[index + 1] !== undefined) {
fieldParts[index + 1] = `${pathPart}.${fieldParts[index + 1]}`;
return [pathArray, inputSubset];
}
return [pathArray, undefined];
},
[[] as string[], input as any],
);
}
export function parseEntityTransformParams(
params: Record<string, unknown>,
): ((entity: Entity) => Entity) | undefined {
@@ -46,9 +62,10 @@ export function parseEntityTransformParams(
const output: RecursivePartial<Entity> = {};
for (const field of fields) {
const value = lodash.get(input, field);
const [pathArray, value] = getPathArrayAndValue(input, field);
if (value !== undefined) {
lodash.set(output, field, value);
lodash.set(output, pathArray, value);
}
}