diff --git a/src/api/services/ShlinkApiClient.ts b/src/api/services/ShlinkApiClient.ts index 8617a30a..d3f1626b 100644 --- a/src/api/services/ShlinkApiClient.ts +++ b/src/api/services/ShlinkApiClient.ts @@ -24,9 +24,14 @@ import { HttpClient } from '../../common/services/HttpClient'; const buildShlinkBaseUrl = (url: string, version: 2 | 3) => `${url}/rest/v${version}`; const rejectNilProps = reject(isNil); -const normalizeOrderByInParams = ( - { orderBy = {}, ...rest }: ShlinkShortUrlsListParams, -): ShlinkShortUrlsListNormalizedParams => ({ ...rest, orderBy: orderToString(orderBy) }); +const normalizeListParams = ( + { orderBy = {}, excludeMaxVisitsReached, excludePastValidUntil, ...rest }: ShlinkShortUrlsListParams, +): ShlinkShortUrlsListNormalizedParams => ({ + ...rest, + excludeMaxVisitsReached: excludeMaxVisitsReached === true ? 'true' : undefined, + excludePastValidUntil: excludePastValidUntil === true ? 'true' : undefined, + orderBy: orderToString(orderBy), +}); export class ShlinkApiClient { private apiVersion: 2 | 3; @@ -40,7 +45,7 @@ export class ShlinkApiClient { } public readonly listShortUrls = async (params: ShlinkShortUrlsListParams = {}): Promise => - this.performRequest<{ shortUrls: ShlinkShortUrlsResponse }>('/short-urls', 'GET', normalizeOrderByInParams(params)) + this.performRequest<{ shortUrls: ShlinkShortUrlsResponse }>('/short-urls', 'GET', normalizeListParams(params)) .then(({ shortUrls }) => shortUrls); public readonly createShortUrl = async (options: ShortUrlData): Promise => { diff --git a/src/api/types/index.ts b/src/api/types/index.ts index 4acda7c0..235ccd5b 100644 --- a/src/api/types/index.ts +++ b/src/api/types/index.ts @@ -96,14 +96,20 @@ export type ShlinkShortUrlsOrder = Order; export interface ShlinkShortUrlsListParams { page?: string; itemsPerPage?: number; - tags?: string[]; searchTerm?: string; + tags?: string[]; + tagsMode?: TagsFilteringMode; + orderBy?: ShlinkShortUrlsOrder; startDate?: string; endDate?: string; - orderBy?: ShlinkShortUrlsOrder; - tagsMode?: TagsFilteringMode; + excludeMaxVisitsReached?: boolean; + excludePastValidUntil?: boolean; } -export interface ShlinkShortUrlsListNormalizedParams extends Omit { +export interface ShlinkShortUrlsListNormalizedParams extends + Omit +{ orderBy?: string; + excludeMaxVisitsReached?: 'true'; + excludePastValidUntil?: 'true'; } diff --git a/src/short-urls/data/index.ts b/src/short-urls/data/index.ts index 343f385a..c0ed41e2 100644 --- a/src/short-urls/data/index.ts +++ b/src/short-urls/data/index.ts @@ -83,4 +83,6 @@ export interface ExportableShortUrl { export interface ShortUrlsFilter { excludeBots?: boolean; + excludeMaxVisitsReached?: boolean; + excludePastValidUntil?: boolean; } diff --git a/src/utils/helpers/features.ts b/src/utils/helpers/features.ts index bfb88215..b85551cc 100644 --- a/src/utils/helpers/features.ts +++ b/src/utils/helpers/features.ts @@ -11,3 +11,4 @@ export const supportsNonOrphanVisits = serverMatchesMinVersion('3.0.0'); export const supportsAllTagsFiltering = supportsNonOrphanVisits; export const supportsDomainVisits = serverMatchesMinVersion('3.1.0'); export const supportsExcludeBotsOnShortUrls = serverMatchesMinVersion('3.4.0'); +export const supportsFilterDisabledUrls = supportsExcludeBotsOnShortUrls; diff --git a/test/api/services/ShlinkApiClient.test.ts b/test/api/services/ShlinkApiClient.test.ts index 0b15299e..802e0678 100644 --- a/test/api/services/ShlinkApiClient.test.ts +++ b/test/api/services/ShlinkApiClient.test.ts @@ -46,6 +46,28 @@ describe('ShlinkApiClient', () => { expect.anything(), ); }); + + it.each([ + [{}, ''], + [{ excludeMaxVisitsReached: false }, ''], + [{ excludeMaxVisitsReached: true }, '?excludeMaxVisitsReached=true'], + [{ excludePastValidUntil: false }, ''], + [{ excludePastValidUntil: true }, '?excludePastValidUntil=true'], + [ + { excludePastValidUntil: true, excludeMaxVisitsReached: true }, + '?excludeMaxVisitsReached=true&excludePastValidUntil=true', + ], + ])('parses disabled URLs params', async (params, expectedQuery) => { + fetchJson.mockResolvedValue({ data: expectedList }); + const { listShortUrls } = buildApiClient(); + + await listShortUrls(params); + + expect(fetchJson).toHaveBeenCalledWith( + expect.stringContaining(`/short-urls${expectedQuery}`), + expect.anything(), + ); + }); }); describe('createShortUrl', () => {