Skip to content

Commit

Permalink
Merge pull request #111 from poap-xyz/filter-recursive
Browse files Browse the repository at this point in the history
Filter recursive
  • Loading branch information
jm42 authored Apr 13, 2024
2 parents bd904e5 + 6a0af0b commit 5aefad9
Show file tree
Hide file tree
Showing 18 changed files with 225 additions and 78 deletions.
1 change: 1 addition & 0 deletions docs/pages/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
- Compass variables can be typed.
- Compass throws errors on malformed requests/queries.
- Fetch moments order must be value from enum `Order` instead of string.
- Rename POAP client fetch prop `filterByZeroAddress` to `filterZeroAddress`.
14 changes: 9 additions & 5 deletions docs/pages/packages/utils/Queries.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ sort order, for example:
```graphql
query MyDrops(
$orderBy: [drops_order_by!]
$where: {
drop_id: { _in: [14] }
}
) {
drops(order_by: $orderBy) {
drops(
order_by: $orderBy
where: {
drop_id: { _in: [14] }
}
) {
id
name
}
Expand Down Expand Up @@ -72,6 +74,8 @@ The possible filters to create are:
- `createEqFilter`: match exact field value.
- `createNeqFilter`: match not equal field value.
- `createBoolFilter`: when the value is true or false.
- `createAddressFilter`: given the address match it case-unsensitive and/or excludes the zero address.
- `createAddressFilter`: given the address match it case-unsensitive.
- `createNotNullAddressFilter`: excludes the zero and/or dead addresses.
- `createInFilter`: if the field is contained in any of the given values.
- `createNinFilter`: not contained in the given values.
- `createBetweenFilter`: from and to values, mostly used for dates.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export const fetch_multiple_poaps_by_drop_id = async (
limit: 10,
offset: 0,
dropId: 3,
filterByZeroAddress: true,
filterZeroAddress: true,
filterDeadAddress: true,
});
console.log(data);
console.log('The first 10 POAP tokens minted for the drop 14.');
Expand Down
6 changes: 3 additions & 3 deletions packages/drops/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@poap-xyz/drops",
"version": "0.2.0",
"version": "0.2.1",
"description": "Drops module for the poap.js library",
"main": "dist/cjs/index.cjs",
"module": "dist/esm/index.mjs",
Expand Down Expand Up @@ -29,7 +29,7 @@
"node": ">=18"
},
"dependencies": {
"@poap-xyz/providers": "0.2.0",
"@poap-xyz/utils": "0.2.0"
"@poap-xyz/providers": "0.2.1",
"@poap-xyz/utils": "0.2.1"
}
}
6 changes: 3 additions & 3 deletions packages/moments/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@poap-xyz/moments",
"version": "0.2.0",
"version": "0.2.1",
"description": "Moments module for the poap.js library",
"main": "dist/cjs/index.cjs",
"module": "dist/esm/index.mjs",
Expand All @@ -26,8 +26,8 @@
"build": "rollup -c --bundleConfigAsCjs"
},
"dependencies": {
"@poap-xyz/providers": "0.2.0",
"@poap-xyz/utils": "0.2.0",
"@poap-xyz/providers": "0.2.1",
"@poap-xyz/utils": "0.2.1",
"uuid": "^9.0.0"
},
"engines": {
Expand Down
6 changes: 3 additions & 3 deletions packages/poaps/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@poap-xyz/poaps",
"version": "0.2.0",
"version": "0.2.1",
"description": "Poaps module for the poap.js library",
"main": "dist/cjs/index.cjs",
"module": "dist/esm/index.mjs",
Expand All @@ -26,8 +26,8 @@
"build": "rollup -c --bundleConfigAsCjs"
},
"dependencies": {
"@poap-xyz/providers": "0.2.0",
"@poap-xyz/utils": "0.2.0"
"@poap-xyz/providers": "0.2.1",
"@poap-xyz/utils": "0.2.1"
},
"engines": {
"node": ">=18"
Expand Down
11 changes: 7 additions & 4 deletions packages/poaps/src/PoapsClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
createBetweenFilter,
createEqFilter,
createInFilter,
createNotNullAddressFilter,
createOrderBy,
nextCursor,
PaginatedResult,
Expand Down Expand Up @@ -64,18 +65,20 @@ export class PoapsClient {
dropId,
sortField,
sortDir,
filterByZeroAddress = true,
filterZeroAddress = true,
filterDeadAddress = true,
} = input;

const variables: PaginatedPoapsVariables = {
limit,
offset,
orderBy: createOrderBy<PoapsSortFields>(sortField, sortDir),
where: {
...createAddressFilter(
...createAddressFilter('collector_address', collectorAddress),
...createNotNullAddressFilter(
'collector_address',
filterByZeroAddress,
collectorAddress,
filterZeroAddress,
filterDeadAddress,
),
...createEqFilter('chain', chain),
...createEqFilter('drop_id', dropId),
Expand Down
4 changes: 3 additions & 1 deletion packages/poaps/src/types/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ export interface FetchPoapsInput extends PaginationInput {
/** Direction in which to sort the results. */
sortDir?: Order;
/** Filter to include/exclude POAPs with zero addresses. */
filterByZeroAddress?: boolean;
filterZeroAddress?: boolean;
/** Filter out dead addresses? */
filterDeadAddress?: boolean;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/providers/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@poap-xyz/providers",
"version": "0.2.0",
"version": "0.2.1",
"description": "Providers module for the poap.js library",
"main": "dist/cjs/index.cjs",
"module": "dist/esm/index.mjs",
Expand All @@ -26,7 +26,7 @@
"build": "rollup -c --bundleConfigAsCjs"
},
"dependencies": {
"@poap-xyz/utils": "0.2.0",
"@poap-xyz/utils": "0.2.1",
"axios": "^1.3.5"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/utils/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@poap-xyz/utils",
"version": "0.2.0",
"version": "0.2.1",
"description": "Utils module for the poap.js library",
"main": "dist/cjs/index.cjs",
"module": "dist/esm/index.mjs",
Expand Down
122 changes: 93 additions & 29 deletions packages/utils/src/queries/filter.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,132 @@
import {
EqFilter,
FieldFilter,
GtFilter,
GteFilter,
InFilter,
LikeFilter,
LtFilter,
LteFilter,
NeqFilter,
NinFilter,
Value,
} from '../types/filter';

export function createLikeFilter(
key: string,
value?: string,
): { [key: string]: { _ilike: string } } {
): FieldFilter<LikeFilter<string>> {
return value ? { [key]: { _ilike: `%${value}%` } } : {};
}

export function createEqFilter(
export function createEqFilter<V = Value>(
key: string,
value?: string | number,
): { [key: string]: { _eq: string | number } } {
value?: V,
): FieldFilter<EqFilter<V>> {
return value ? { [key]: { _eq: value } } : {};
}

export function createNeqFilter(
export function createNeqFilter<V = Value>(
key: string,
value?: string | number,
): { [key: string]: { _neq: string | number } } {
value?: V,
): FieldFilter<NeqFilter<V>> {
return value ? { [key]: { _neq: value } } : {};
}

export function createBoolFilter(
key: string,
value?: boolean,
): { [key: string]: { _eq: 'true' | 'false' } } {
): FieldFilter<EqFilter<'true' | 'false'>> {
return typeof value === 'boolean'
? { [key]: { _eq: value ? 'true' : 'false' } }
: {};
}

export function createAddressFilter(
key: string,
filterZeroAddress: boolean,
value?: string,
): {
[key: string]: {
_neq?: string;
_eq?: string;
};
} {
return filterZeroAddress || value
): FieldFilter<EqFilter<string>> {
return value
? {
[key]: {
...(filterZeroAddress
? { _neq: '0x0000000000000000000000000000000000000000' }
: {}),
...(value ? { _eq: value.toLowerCase() } : {}),
_eq: value.toLowerCase(),
},
}
: {};
}

export function createInFilter(
export function createNotNullAddressFilter(
key: string,
filterZeroAddress = true,
filterDeadAddress = true,
): FieldFilter<NeqFilter<string>> | FieldFilter<NinFilter<string>> {
if (filterZeroAddress && filterDeadAddress) {
return {
[key]: {
_nin: [
'0x0000000000000000000000000000000000000000',
'0x000000000000000000000000000000000000dead',
],
},
};
}
if (filterZeroAddress) {
return { [key]: { _neq: '0x0000000000000000000000000000000000000000' } };
}
if (filterDeadAddress) {
return { [key]: { _neq: '0x000000000000000000000000000000000000dead' } };
}
return {};
}

export function createInFilter<V = Value>(
key: string,
values?: Array<V>,
): FieldFilter<InFilter<V>> {
return values && values.length > 0 ? { [key]: { _in: values } } : {};
}

export function createNinFilter<V = Value>(
key: string,
values?: Array<V>,
): FieldFilter<NinFilter<V>> {
return values && values.length > 0 ? { [key]: { _nin: values } } : {};
}

export function createLtFilter<V = Value>(
key: string,
value?: V,
): FieldFilter<LtFilter<V>> {
return value ? { [key]: { _lt: value } } : {};
}

export function createLteFilter<V = Value>(
key: string,
value?: V,
): FieldFilter<LteFilter<V>> {
return value ? { [key]: { _lte: value } } : {};
}

export function createGtFilter<V = Value>(
key: string,
value?: V,
): FieldFilter<GtFilter<V>> {
return value ? { [key]: { _gt: value } } : {};
}

export function createGteFilter<V = Value>(
key: string,
values?: Array<string | number>,
): { [key: string]: { _in: Array<string | number> } } {
return values && values.length ? { [key]: { _in: values } } : {};
value?: V,
): FieldFilter<GteFilter<V>> {
return value ? { [key]: { _gte: value } } : {};
}

export function createBetweenFilter(
export function createBetweenFilter<V = Value>(
key: string,
from?: string,
to?: string,
): { [key: string]: { _gte?: string; _lte?: string } } {
const betweenFilter: { _gte?: string; _lte?: string } = {};
from?: V,
to?: V,
): FieldFilter<Partial<GteFilter<V>> & Partial<LteFilter<V>>> {
const betweenFilter: Partial<GteFilter<V>> & Partial<LteFilter<V>> = {};
if (from) {
betweenFilter._gte = from;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/utils/src/queries/order.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Order } from '../types/order';
import { Order, OrderBy } from '../types/order';

export function createOrderBy<E extends string = string>(
key: E | undefined,
value?: Order | undefined,
): { [key: string]: Order } {
): OrderBy {
return key && value ? { [key]: value } : {};
}
Loading

0 comments on commit 5aefad9

Please sign in to comment.