Skip to content

Commit

Permalink
Improve visits params types
Browse files Browse the repository at this point in the history
  • Loading branch information
acelaya committed Jan 20, 2024
1 parent d6a52d9 commit b56373f
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 65 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org).

## [0.2.1] - 2024-01-20
### Added
* Export different types for short URL visits params and other visits params.

### Changed
* Export API contract as TypeScript types instead of interfaces.

### Deprecated
* *Nothing*

### Removed
* *Nothing*

### Fixed
* *Nothing*


## [0.2.0] - 2023-10-27
### Added
* [#2](https://github.com/shlinkio/shlink-js-sdk/issues/2) Implement node.js `HttpClient`.
Expand All @@ -18,6 +35,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Removed
* *Nothing*

### Fixed
* *Nothing*


### Fixed
* *Nothing*
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: '3'
services:
shlink_js_sdk:
container_name: shlink_js_sdk
image: node:20.5-alpine
image: node:20.11-alpine
volumes:
- ./:/shlink-js-sdk
ports:
Expand Down
119 changes: 61 additions & 58 deletions src/api-contract/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ type Nullable<T> = {
[P in keyof T]: T[P] | null
};

export interface ShlinkDeviceLongUrls {
export type ShlinkDeviceLongUrls = {
android?: OptionalString;
ios?: OptionalString;
desktop?: OptionalString;
}
};

export interface ShlinkShortUrlMeta {
export type ShlinkShortUrlMeta = {
validSince?: string;
validUntil?: string;
maxVisits?: number;
}
};

export interface ShlinkShortUrl {
export type ShlinkShortUrl = {
shortCode: string;
shortUrl: string;
longUrl: string;
Expand All @@ -33,9 +33,9 @@ export interface ShlinkShortUrl {
title?: string | null;
crawlable?: boolean;
forwardQuery?: boolean;
}
};

export interface ShlinkEditShortUrlData {
export type ShlinkEditShortUrlData = {
longUrl?: string;
title?: string | null;
tags?: string[];
Expand All @@ -48,9 +48,9 @@ export interface ShlinkEditShortUrlData {

/** @deprecated To be removed in Shlink 4.0.0 */
validateUrl?: boolean;
}
};

export interface ShlinkCreateShortUrlData extends Omit<ShlinkEditShortUrlData, 'deviceLongUrls'> {
export type ShlinkCreateShortUrlData = Omit<ShlinkEditShortUrlData, 'deviceLongUrls'> & {
longUrl: string;
customSlug?: string;
shortCodeLength?: number;
Expand All @@ -61,63 +61,63 @@ export interface ShlinkCreateShortUrlData extends Omit<ShlinkEditShortUrlData, '
ios?: string;
desktop?: string;
}
}
};

export interface ShlinkShortUrlsResponse {
export type ShlinkShortUrlsResponse = {
data: ShlinkShortUrl[];
pagination: ShlinkPaginator;
}
};

export interface ShlinkMercureInfo {
export type ShlinkMercureInfo = {
token: string;
mercureHubUrl: string;
}
};

export interface ShlinkHealth {
export type ShlinkHealth = {
status: 'pass' | 'fail';
version: string;
}
};

export interface ShlinkTagsStats {
export type ShlinkTagsStats = {
tag: string;
shortUrlsCount: number;
/** Optional only before Shlink 3.5.0 */
visitsSummary?: ShlinkVisitsSummary;

/** @deprecated Use `visitsSummary.total` instead */
visitsCount: number;
}
};

export interface ShlinkTags {
export type ShlinkTags = {
tags: string[];
stats: ShlinkTagsStats[];
}
};

export interface ShlinkTagsResponse {
export type ShlinkTagsResponse = {
data: string[];
/** @deprecated Present only when withStats=true is provided, which is deprecated */
stats?: ShlinkTagsStats[];
}
};

export interface ShlinkTagsStatsResponse {
export type ShlinkTagsStatsResponse = {
data: ShlinkTagsStats[];
}
};

export interface ShlinkPaginator {
export type ShlinkPaginator = {
currentPage: number;
pagesCount: number;
totalItems: number;
}
};

export interface ShlinkVisitsSummary {
export type ShlinkVisitsSummary = {
total: number;
nonBots: number;
bots: number;
}
};

export type ShlinkOrphanVisitType = 'base_url' | 'invalid_short_url' | 'regular_404';

export interface ShlinkVisitLocation {
export type ShlinkVisitLocation = {
countryCode: string | null;
countryName: string | null;
regionName: string | null;
Expand All @@ -126,33 +126,33 @@ export interface ShlinkVisitLocation {
longitude: number | null;
timezone: string | null;
isEmpty: boolean;
}
};

export interface ShlinkRegularVisit {
export type ShlinkRegularVisit = {
referer: string;
date: string;
userAgent: string;
visitLocation: ShlinkVisitLocation | null;
potentialBot: boolean;
}
};

export interface ShlinkOrphanVisit extends ShlinkRegularVisit {
export type ShlinkOrphanVisit = ShlinkRegularVisit & {
visitedUrl: string;
type: ShlinkOrphanVisitType;
}
};

export type ShlinkVisit = ShlinkRegularVisit | ShlinkOrphanVisit;

export interface ShlinkVisits {
export type ShlinkVisits = {
data: ShlinkVisit[];
pagination: ShlinkPaginator;
}
};

export type ShlinkDeleteVisitsResponse = {
deletedVisits: number;
};

export interface ShlinkVisitsOverview {
export type ShlinkVisitsOverview = {
/** Optional only before Shlink 3.5.0 */
nonOrphanVisits?: ShlinkVisitsSummary;
/** Optional only before Shlink 3.5.0 */
Expand All @@ -162,37 +162,40 @@ export interface ShlinkVisitsOverview {
visitsCount: number;
/** @deprecated Use `orphanVisits.total` instead */
orphanVisitsCount: number;
}
};

export interface ShlinkVisitsParams {
domain?: string | null;
export type ShlinkVisitsParams = {
page?: number;
itemsPerPage?: number;
startDate?: string;
endDate?: string;
excludeBots?: boolean;
}
};

export interface ShlinkDomainRedirects {
export type ShlinkShortUrlVisitsParams = ShlinkVisitsParams & {
domain?: string | null;
};

export type ShlinkDomainRedirects = {
baseUrlRedirect: string | null;
regular404Redirect: string | null;
invalidShortUrlRedirect: string | null;
}
};

export interface ShlinkEditDomainRedirects extends Partial<ShlinkDomainRedirects> {
export type ShlinkEditDomainRedirects = Partial<ShlinkDomainRedirects> & {
domain: string;
}
};

export interface ShlinkDomain {
export type ShlinkDomain = {
domain: string;
isDefault: boolean;
redirects: ShlinkDomainRedirects;
}
};

export interface ShlinkDomainsResponse {
export type ShlinkDomainsResponse = {
data: ShlinkDomain[];
defaultRedirects: ShlinkDomainRedirects;
}
};

export type TagsFilteringMode = 'all' | 'any';

Expand All @@ -201,7 +204,7 @@ export type ShlinkShortUrlsOrder = {
dir?: 'ASC' | 'DESC';
};

export interface ShlinkShortUrlsListParams {
export type ShlinkShortUrlsListParams = {
page?: string;
itemsPerPage?: number;
searchTerm?: string;
Expand All @@ -212,11 +215,11 @@ export interface ShlinkShortUrlsListParams {
endDate?: string;
excludeMaxVisitsReached?: boolean;
excludePastValidUntil?: boolean;
}

export interface ShlinkShortUrlsListNormalizedParams extends
Omit<ShlinkShortUrlsListParams, 'orderBy' | 'excludeMaxVisitsReached' | 'excludePastValidUntil'> {
orderBy?: string;
excludeMaxVisitsReached?: 'true';
excludePastValidUntil?: 'true';
}
};

export type ShlinkShortUrlsListNormalizedParams =
Omit<ShlinkShortUrlsListParams, 'orderBy' | 'excludeMaxVisitsReached' | 'excludePastValidUntil'> & {
orderBy?: string;
excludeMaxVisitsReached?: 'true';
excludePastValidUntil?: 'true';
};
12 changes: 6 additions & 6 deletions src/api/ShlinkApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type {
ShlinkMercureInfo,
ShlinkShortUrl,
ShlinkShortUrlsListParams,
ShlinkShortUrlsResponse,
ShlinkShortUrlsResponse, ShlinkShortUrlVisitsParams,
ShlinkTags,
ShlinkTagsResponse,
ShlinkTagsStatsResponse,
Expand Down Expand Up @@ -69,7 +69,7 @@ export class ShlinkApiClient implements BaseShlinkApiClient {
return this.performRequest<ShlinkShortUrl>({ url: '/short-urls', method: 'POST', body });
}

public async getShortUrlVisits(shortCode: string, query?: ShlinkVisitsParams): Promise<ShlinkVisits> {
public async getShortUrlVisits(shortCode: string, query?: ShlinkShortUrlVisitsParams): Promise<ShlinkVisits> {
return this.performRequest<{ visits: ShlinkVisits }>({ url: `/short-urls/${shortCode}/visits`, query })
.then(({ visits }) => visits);
}
Expand All @@ -81,25 +81,25 @@ export class ShlinkApiClient implements BaseShlinkApiClient {
);
}

public async getTagVisits(tag: string, query?: Omit<ShlinkVisitsParams, 'domain'>): Promise<ShlinkVisits> {
public async getTagVisits(tag: string, query?: ShlinkVisitsParams): Promise<ShlinkVisits> {
return this.performRequest<{ visits: ShlinkVisits }>({ url: `/tags/${tag}/visits`, query })
.then(({ visits }) => visits);
}

public async getDomainVisits(domain: string, query?: Omit<ShlinkVisitsParams, 'domain'>): Promise<ShlinkVisits> {
public async getDomainVisits(domain: string, query?: ShlinkVisitsParams): Promise<ShlinkVisits> {
return this.performRequest<{ visits: ShlinkVisits }>({ url: `/domains/${domain}/visits`, query })
.then(({ visits }) => visits);
}

public async getOrphanVisits(query?: Omit<ShlinkVisitsParams, 'domain'>): Promise<ShlinkVisits> {
public async getOrphanVisits(query?: ShlinkVisitsParams): Promise<ShlinkVisits> {
return this.performRequest<{ visits: ShlinkVisits }>({ url: '/visits/orphan', query }).then(({ visits }) => visits);
}

public async deleteOrphanVisits(): Promise<ShlinkDeleteVisitsResponse> {
return this.performRequest<ShlinkDeleteVisitsResponse>({ method: 'DELETE', url: '/visits/orphan' });
}

public async getNonOrphanVisits(query?: Omit<ShlinkVisitsParams, 'domain'>): Promise<ShlinkVisits> {
public async getNonOrphanVisits(query?: ShlinkVisitsParams): Promise<ShlinkVisits> {
return this.performRequest<{ visits: ShlinkVisits }>({ url: '/visits/non-orphan', query })
.then(({ visits }) => visits);
}
Expand Down

0 comments on commit b56373f

Please sign in to comment.