fix: Typescript type and Zod parser were not the same.
Signed-off-by: Sandor Karpf <sandor.karpf@lastpass.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
$contains may have string value in an entity filter. Typescript type and Zod parser were not the same.
|
||||
@@ -478,6 +478,7 @@ export const EntityIconLinkBlueprint: ExtensionBlueprint<{
|
||||
export type EntityPredicate =
|
||||
| EntityPredicateExpression
|
||||
| EntityPredicatePrimitive
|
||||
| EntityPredicatePrimitive[]
|
||||
| {
|
||||
$all: EntityPredicate[];
|
||||
}
|
||||
@@ -506,6 +507,7 @@ export function entityPredicateToFilterFunction<T extends JsonValue>(
|
||||
// @alpha (undocumented)
|
||||
export type EntityPredicateValue =
|
||||
| EntityPredicatePrimitive
|
||||
| EntityPredicatePrimitive[]
|
||||
| {
|
||||
$exists: boolean;
|
||||
}
|
||||
@@ -513,7 +515,7 @@ export type EntityPredicateValue =
|
||||
$in: EntityPredicatePrimitive[];
|
||||
}
|
||||
| {
|
||||
$contains: EntityPredicateExpression;
|
||||
$contains: EntityPredicate;
|
||||
};
|
||||
|
||||
// @alpha
|
||||
|
||||
@@ -16,84 +16,98 @@
|
||||
|
||||
import { z } from 'zod';
|
||||
import { createEntityPredicateSchema } from './createEntityPredicateSchema';
|
||||
import { EntityPredicate } from './types';
|
||||
|
||||
describe('createEntityPredicateSchema', () => {
|
||||
const schema = createEntityPredicateSchema(z);
|
||||
|
||||
it.each([
|
||||
'string',
|
||||
'',
|
||||
[],
|
||||
1,
|
||||
{ kind: 'component', 'spec.type': 'service' },
|
||||
{ 'metadata.tags': { $in: ['java'] } },
|
||||
{
|
||||
$all: [
|
||||
{ 'metadata.tags': { $contains: 'java' } },
|
||||
{ 'metadata.tags': { $contains: 'spring' } },
|
||||
],
|
||||
},
|
||||
{ 'metadata.tags': ['java', 'spring'] },
|
||||
{ 'metadata.tags': { $in: ['go'] } },
|
||||
{ 'metadata.tags.0': 'java' },
|
||||
{ $not: { 'metadata.tags': { $in: ['java'] } } },
|
||||
{
|
||||
$any: [{ kind: 'component', 'spec.type': 'service' }, { kind: 'group' }],
|
||||
},
|
||||
{
|
||||
relations: {
|
||||
$contains: { type: 'ownedBy', targetRef: 'group:default/g' },
|
||||
describe('valid predicates', () => {
|
||||
const predicates: EntityPredicate[] = [
|
||||
'string',
|
||||
'',
|
||||
[],
|
||||
1,
|
||||
{ kind: 'component', 'spec.type': 'service' },
|
||||
{ 'metadata.tags': { $in: ['java'] } },
|
||||
{
|
||||
$all: [
|
||||
{ 'metadata.tags': { $contains: 'java' } },
|
||||
{ 'metadata.tags': { $contains: 'spring' } },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
metadata: { $contains: { name: 'a' } },
|
||||
},
|
||||
{ kind: 'component', 'spec.type': { $in: ['service', 'website'] } },
|
||||
{
|
||||
$any: [
|
||||
{
|
||||
$all: [
|
||||
{
|
||||
kind: 'component',
|
||||
'spec.type': { $in: ['service', 'website'] },
|
||||
},
|
||||
],
|
||||
{ 'metadata.tags': ['java', 'spring'] },
|
||||
{ 'metadata.tags': { $in: ['go'] } },
|
||||
{ 'metadata.tags.0': 'java' },
|
||||
{ $not: { 'metadata.tags': { $in: ['java'] } } },
|
||||
{
|
||||
$any: [
|
||||
{ kind: 'component', 'spec.type': 'service' },
|
||||
{ kind: 'group' },
|
||||
],
|
||||
},
|
||||
{
|
||||
relations: {
|
||||
$contains: { type: 'ownedBy', targetRef: 'group:default/g' },
|
||||
},
|
||||
{ $all: [{ kind: 'api', 'spec.type': 'grpc' }] },
|
||||
],
|
||||
},
|
||||
{ kind: 'component', 'spec.type': { $in: ['service'] } },
|
||||
{ 'spec.owner': { $exists: true } },
|
||||
{ 'spec.owner': { $exists: false } },
|
||||
{ 'spec.type': 'service' },
|
||||
{ $not: { 'spec.type': 'service' } },
|
||||
{
|
||||
kind: 'component',
|
||||
'metadata.annotations.github.com/repo': { $exists: true },
|
||||
},
|
||||
{ $all: [{ x: { $exists: true } }] },
|
||||
{ $any: [{ x: { $exists: true } }] },
|
||||
{ $not: { x: { $exists: true } } },
|
||||
{ $not: { $all: [{ x: { $exists: true } }] } },
|
||||
])('should accept valid predicate %j', predicate => {
|
||||
expect(schema.parse(predicate)).toEqual(predicate);
|
||||
},
|
||||
{
|
||||
metadata: { $contains: { name: 'a' } },
|
||||
},
|
||||
{ kind: 'component', 'spec.type': { $in: ['service', 'website'] } },
|
||||
{
|
||||
$any: [
|
||||
{
|
||||
$all: [
|
||||
{
|
||||
kind: 'component',
|
||||
'spec.type': { $in: ['service', 'website'] },
|
||||
},
|
||||
],
|
||||
},
|
||||
{ $all: [{ kind: 'api', 'spec.type': 'grpc' }] },
|
||||
],
|
||||
},
|
||||
{ kind: 'component', 'spec.type': { $in: ['service'] } },
|
||||
{ 'spec.owner': { $exists: true } },
|
||||
{ 'spec.owner': { $exists: false } },
|
||||
{ 'spec.type': 'service' },
|
||||
{ $not: { 'spec.type': 'service' } },
|
||||
{
|
||||
kind: 'component',
|
||||
'metadata.annotations.github.com/repo': { $exists: true },
|
||||
},
|
||||
{ $all: [{ x: { $exists: true } }] },
|
||||
{ $any: [{ x: { $exists: true } }] },
|
||||
{ $not: { x: { $exists: true } } },
|
||||
{ $not: { $all: [{ x: { $exists: true } }] } },
|
||||
];
|
||||
|
||||
it.each(predicates)('should accept valid predicate %j', predicate => {
|
||||
expect(schema.parse(predicate)).toEqual(predicate);
|
||||
});
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ kind: { 1: 'foo' } },
|
||||
{ kind: { foo: 'bar' } },
|
||||
{ kind: { $unknown: 'foo' } },
|
||||
{ kind: { $in: 'foo' } },
|
||||
{ kind: { $in: [{ x: 'foo' }] } },
|
||||
{ kind: { $in: [{ x: 'foo' }] } },
|
||||
{ 'spec.type': null },
|
||||
{ $all: [{ x: { $unknown: true } }] },
|
||||
{ $any: [{ x: { $unknown: true } }] },
|
||||
{ $not: { x: { $unknown: true } } },
|
||||
{ $not: { $all: [{ x: { $unknown: true } }] } },
|
||||
{ $unknown: 'foo' },
|
||||
])('should reject invalid predicate %j', predicate => {
|
||||
const result = schema.safeParse(predicate);
|
||||
expect(result.success).toBe(false);
|
||||
describe('invalid predicates', () => {
|
||||
const predicates: Array<
|
||||
Exclude<EntityPredicate | unknown, EntityPredicate>
|
||||
> = [
|
||||
{ kind: { 1: 'foo' } },
|
||||
{ kind: { foo: 'bar' } },
|
||||
{ kind: { $unknown: 'foo' } },
|
||||
{ kind: { $in: 'foo' } },
|
||||
{ kind: { $in: [{ x: 'foo' }] } },
|
||||
{ kind: { $in: [{ x: 'foo' }] } },
|
||||
{ 'spec.type': null },
|
||||
{ $all: [{ x: { $unknown: true } }] },
|
||||
{ $any: [{ x: { $unknown: true } }] },
|
||||
{ $not: { x: { $unknown: true } } },
|
||||
{ $not: { $all: [{ x: { $unknown: true } }] } },
|
||||
{ $unknown: 'foo' },
|
||||
];
|
||||
|
||||
it.each(predicates)('should reject invalid predicate %j', predicate => {
|
||||
const result = schema.safeParse(predicate);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
export type EntityPredicate =
|
||||
| EntityPredicateExpression
|
||||
| EntityPredicatePrimitive
|
||||
| EntityPredicatePrimitive[]
|
||||
| { $all: EntityPredicate[] }
|
||||
| { $any: EntityPredicate[] }
|
||||
| { $not: EntityPredicate };
|
||||
@@ -32,9 +33,10 @@ export type EntityPredicateExpression = {
|
||||
/** @alpha */
|
||||
export type EntityPredicateValue =
|
||||
| EntityPredicatePrimitive
|
||||
| EntityPredicatePrimitive[]
|
||||
| { $exists: boolean }
|
||||
| { $in: EntityPredicatePrimitive[] }
|
||||
| { $contains: EntityPredicateExpression };
|
||||
| { $contains: EntityPredicate };
|
||||
|
||||
/** @alpha */
|
||||
export type EntityPredicatePrimitive = string | number | boolean;
|
||||
|
||||
Reference in New Issue
Block a user