Merge pull request #11130 from webark/entity-query-with-dot-params
Updated parseEntityTransformParams to handle keys with '.' in them
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user