Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .changeset/6001-drop-redundant-filter-casts.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
---
---

Test-only change; nothing published changes. `ValueDataSource.test.ts` drops the ten
`as any` casts on its AST-array `$filter` fixtures
(`packages/core/src/adapters/__tests__/ValueDataSource.test.ts`, objectui#6001).

The casts were written when `QueryParams.$filter` was declared as the MongoDB-style
record alone, so an author writing an ObjectQL AST array had to push the type out of the
way. objectui#3909 / PR objectui#5999 replaced that declaration with the union the data
sources always accepted, and all ten literals — the nine AST shapes plus the degenerate
empty array — now assign bare. No replacement assertion, no widening, no helper, and no
runtime assertion touched: `pnpm --filter @object-ui/core type-check` is green.

One claim on the card did **not** survive measurement, and the correction is worth
keeping. The card justified the deletion partly by predicting that the un-cast fixtures
would become compile-time evidence — that narrowing `$filter` back to the record form
would turn this file red. It does not. Dropping the `| FilterArray` arm locally,
rebuilding `@object-ui/types` so the change reached the `dist/data.d.ts` that
`packages/core/tsconfig.test.json` actually resolves, and re-running the type-check
leaves the file green with zero errors — exactly as PR objectui#5999's own doc comment
says it must, since `Record<string, any>` already accepts arrays structurally. A positive
control under the identical mutation (a slot that genuinely excludes arrays) does turn
these ten lines red, so the zero is a measurement rather than a blind apparatus.

The deletion is therefore worth making for the smaller, true reason: `as any` at a site
where the value is already legal is a no-op that reads as a live constraint, and a reader
who trusts it concludes the array form is illegal here.
20 changes: 10 additions & 10 deletions packages/core/src/adapters/__tests__/ValueDataSource.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -165,7 +165,7 @@ describe('ValueDataSource — AST filter', () => {
it('should filter with simple AST equality condition', async () => {
const ds = createDS();
const result = await ds.find('users', {
$filter: ['role', '=', 'admin'] as any,
$filter: ['role', '=', 'admin'],
});
expect(result.data).toHaveLength(2);
expect(result.data.every((r: any) => r.role === 'admin')).toBe(true);
Expand All@@ -174,15 +174,15 @@ describe('ValueDataSource — AST filter', () => {
it('should filter with AST "in" operator', async () => {
const ds = createDS();
const result = await ds.find('users', {
$filter: ['role', 'in', ['admin', 'guest']] as any,
$filter: ['role', 'in', ['admin', 'guest']],
});
expect(result.data).toHaveLength(3);
});

it('should filter with AST "and" logical operator', async () => {
const ds = createDS();
const result = await ds.find('users', {
$filter: ['and', ['role', '=', 'admin'], ['age', '>', 30]] as any,
$filter: ['and', ['role', '=', 'admin'], ['age', '>', 30]],
});
expect(result.data).toHaveLength(1);
expect(result.data[0].name).toBe('Charlie');
Expand All@@ -191,23 +191,23 @@ describe('ValueDataSource — AST filter', () => {
it('should filter with AST "or" logical operator', async () => {
const ds = createDS();
const result = await ds.find('users', {
$filter: ['or', ['role', '=', 'guest'], ['name', '=', 'Alice']] as any,
$filter: ['or', ['role', '=', 'guest'], ['name', '=', 'Alice']],
});
expect(result.data).toHaveLength(2);
});

it('should filter with AST "!=" operator', async () => {
const ds = createDS();
const result = await ds.find('users', {
$filter: ['role', '!=', 'admin'] as any,
$filter: ['role', '!=', 'admin'],
});
expect(result.data).toHaveLength(3);
});

it('should filter with AST "not in" operator', async () => {
const ds = createDS();
const result = await ds.find('users', {
$filter: ['role', 'not in', ['admin', 'guest']] as any,
$filter: ['role', 'not in', ['admin', 'guest']],
});
expect(result.data).toHaveLength(2);
expect(result.data.every((r: any) => r.role === 'user')).toBe(true);
Expand All@@ -216,29 +216,29 @@ describe('ValueDataSource — AST filter', () => {
it('should filter with AST "contains" operator', async () => {
const ds = createDS();
const result = await ds.find('users', {
$filter: ['name', 'contains', 'li'] as any,
$filter: ['name', 'contains', 'li'],
});
expect(result.data).toHaveLength(2); // Alice, Charlie
});

it('should filter with nested AST (and with in operator)', async () => {
const ds = createDS();
const result = await ds.find('users', {
$filter: ['and', ['role', 'in', ['admin', 'user']], ['age', '>=', 28]] as any,
$filter: ['and', ['role', 'in', ['admin', 'user']], ['age', '>=', 28]],
});
expect(result.data).toHaveLength(3); // Alice (30, admin), Charlie (35, admin), Diana (28, user)
});

it('should return all items with empty AST filter', async () => {
const ds = createDS();
const result = await ds.find('users', { $filter: [] as any });
const result = await ds.find('users', { $filter: [] });
expect(result.data).toHaveLength(5);
});

it('should combine AST filter with sort', async () => {
const ds = createDS();
const result = await ds.find('users', {
$filter: ['role', '=', 'admin'] as any,
$filter: ['role', '=', 'admin'],
$orderby: { age: 'asc' },
});
expect(result.data).toHaveLength(2);
Expand Down
Loading