Skip to content

Commit

Permalink
@kbn/io-ts-utils: make sure keys from objects in arrays are validated
Browse files Browse the repository at this point in the history
  • Loading branch information
dgieselaar committed Aug 28, 2024
1 parent 9d967e0 commit 2f62d1f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 6 deletions.
33 changes: 32 additions & 1 deletion packages/kbn-io-ts-utils/src/strict_keys_rt/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,38 @@ describe('strictKeysRt', () => {
{
type: t.array(t.type({ foo: t.string })),
passes: [[{ foo: 'bar' }], [{ foo: 'baz' }, { foo: 'bar' }]],
fails: [],
fails: [{ foo: 'bar', bar: 'foo' }],
},
{
type: t.type({
nestedArray: t.array(
t.type({
bar: t.string,
})
),
}),
passes: [
{
nestedArray: [],
},
{
nestedArray: [
{
bar: 'foo',
},
],
},
],
fails: [
{
nestedArray: [
{
bar: 'foo',
foo: 'bar',
},
],
},
],
},
];

Expand Down
30 changes: 25 additions & 5 deletions packages/kbn-io-ts-utils/src/strict_keys_rt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import * as t from 'io-ts';
import { either, isRight } from 'fp-ts/lib/Either';
import { difference, isPlainObject, forEach } from 'lodash';
import { difference, isPlainObject, forEach, isArray, castArray } from 'lodash';
import { MergeType } from '../merge_rt';

/*
Expand Down Expand Up @@ -100,11 +100,31 @@ function getHandledKeys<T extends Record<string, unknown>>(
keys.handled.add(ownPrefix);
}

const processObject = (typeForObject: t.Mixed, objectToProcess: Record<string, unknown>) => {
const nextKeys = getHandledKeys(typeForObject, objectToProcess, ownPrefix);
nextKeys.all.forEach((k) => keys.all.add(k));
nextKeys.handled.forEach((k) => keys.handled.add(k));
};

if (isPlainObject(value)) {
handlingTypes.forEach((i) => {
const nextKeys = getHandledKeys(i, value as Record<string, unknown>, ownPrefix);
nextKeys.all.forEach((k) => keys.all.add(k));
nextKeys.handled.forEach((k) => keys.handled.add(k));
handlingTypes.forEach((typeAtIndex) => {
processObject(typeAtIndex, value as Record<string, unknown>);
});
}

if (isArray(value)) {
handlingTypes.forEach((typeAtIndex) => {
if (!isParsableType(typeAtIndex) || typeAtIndex._tag !== 'ArrayType') {
return;
}

const innerType = typeAtIndex.type;

castArray(value).forEach((valueAtIndex) => {
if (isPlainObject(valueAtIndex)) {
processObject(innerType, valueAtIndex as Record<string, unknown>);
}
});
});
}
});
Expand Down

0 comments on commit 2f62d1f

Please sign in to comment.