diff --git a/.changeset/itchy-suits-live.md b/.changeset/itchy-suits-live.md new file mode 100644 index 00000000..fa856165 --- /dev/null +++ b/.changeset/itchy-suits-live.md @@ -0,0 +1,5 @@ +--- +"@supabase-cache-helpers/postgrest-core": patch +--- + +fix: enrich parsed filter paths with declaration from query paths diff --git a/packages/postgrest-core/__tests__/lib/extract-paths-from-filters.spec.ts b/packages/postgrest-core/__tests__/lib/extract-paths-from-filters.spec.ts new file mode 100644 index 00000000..8d77d3df --- /dev/null +++ b/packages/postgrest-core/__tests__/lib/extract-paths-from-filters.spec.ts @@ -0,0 +1,28 @@ +import { SupabaseClient, createClient } from '@supabase/supabase-js'; + +import { extractPathsFromFilters } from '../../src/lib/extract-paths-from-filter'; +import { PostgrestParser } from '../../src/postgrest-parser'; + +describe('extractPathsFromFilters', () => { + let c: SupabaseClient; + + beforeAll(() => { + c = createClient('https://localhost', '1234'); + }); + + it('should add declarations from path to matching filter path', () => { + const parser = new PostgrestParser( + c + .from('conversation') + .select('inbox:inbox_id!inner(id,name,emoji)') + .eq('inbox_id.id', 'inbox-id'), + ); + expect(extractPathsFromFilters(parser.filters, parser.paths)).toEqual([ + { + alias: 'inbox.id', + declaration: 'inbox:inbox_id!inner.id', + path: 'inbox_id.id', + }, + ]); + }); +}); diff --git a/packages/postgrest-core/src/fetch/build-normalized-query.ts b/packages/postgrest-core/src/fetch/build-normalized-query.ts index 70b30db9..2857969e 100644 --- a/packages/postgrest-core/src/fetch/build-normalized-query.ts +++ b/packages/postgrest-core/src/fetch/build-normalized-query.ts @@ -50,7 +50,10 @@ export const buildNormalizedQuery = ({ if (!disabled) { for (const tableQuery of queriesForTable()) { - for (const filterPath of extractPathsFromFilters(tableQuery.filters)) { + for (const filterPath of extractPathsFromFilters( + tableQuery.filters, + tableQuery.paths, + )) { // add paths used in filter const path = tableQuery.paths.find( (p) => p.path === filterPath.path && p.alias === filterPath.alias, diff --git a/packages/postgrest-core/src/lib/extract-paths-from-filter.ts b/packages/postgrest-core/src/lib/extract-paths-from-filter.ts index c0ea64f6..86861b61 100644 --- a/packages/postgrest-core/src/lib/extract-paths-from-filter.ts +++ b/packages/postgrest-core/src/lib/extract-paths-from-filter.ts @@ -6,21 +6,31 @@ import { FilterDefinitions, } from './query-types'; -export const extractPathsFromFilters = (f: FilterDefinitions) => { +export const extractPathsFromFilters = (f: FilterDefinitions, p: Path[]) => { return f.reduce((prev, filter) => { if (isAndFilter(filter)) { - prev.push(...extractPathsFromFilters(filter.and)); + prev.push(...extractPathsFromFilters(filter.and, p)); } else if (isOrFilter(filter)) { - prev.push(...extractPathsFromFilters(filter.or)); + prev.push(...extractPathsFromFilters(filter.or, p)); } else if (isFilterDefinition(filter)) { + const relatedPath = p.find((p) => p.path === filter.path); const pathElements = filter.path.split('.'); const aliasElements = filter.alias?.split('.'); const declaration = pathElements .map( - (el, idx) => `${aliasElements ? `${aliasElements[idx]}:` : ''}${el}`, + (el, idx) => + `${ + aliasElements && aliasElements[idx] !== el + ? `${aliasElements[idx]}:` + : '' + }${el}`, ) .join('.'); - prev.push({ path: filter.path, alias: filter.alias, declaration }); + prev.push({ + path: filter.path, + alias: filter.alias, + declaration: relatedPath ? relatedPath.declaration : declaration, + }); } return prev; }, []); diff --git a/packages/postgrest-core/src/postgrest-filter.ts b/packages/postgrest-core/src/postgrest-filter.ts index a8d78c0e..51ca052b 100644 --- a/packages/postgrest-core/src/postgrest-filter.ts +++ b/packages/postgrest-core/src/postgrest-filter.ts @@ -29,7 +29,10 @@ export class PostgrestFilter> { constructor( public readonly params: { filters: FilterDefinitions; paths: Path[] }, ) { - this._filterPaths = extractPathsFromFilters(this.params.filters); + this._filterPaths = extractPathsFromFilters( + this.params.filters, + this.params.paths, + ); } public static fromQuery(query: string, opts?: PostgrestQueryParserOptions) {