Skip to content

Commit af64536

Browse files
committed
2 parents e19b808 + 9b12c86 commit af64536

File tree

6 files changed

+117
-26
lines changed

6 files changed

+117
-26
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@umami/api-client",
3-
"version": "0.37.0",
3+
"version": "0.41.0",
44
"description": "API client for Umami Analytics",
55
"main": "dist/cjs/index.js",
66
"module": "dist/esm/index.js",

src/UmamiApiClient.ts

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createSecureToken, hash, get, post, put, del, buildUrl, ApiResponse } from 'next-basics';
22
import * as Umami from './types';
33
import { log } from 'utils';
4+
import { FilterResult } from './types';
45

56
export const API_KEY_HEADER = 'x-umami-api-key';
67

@@ -47,31 +48,31 @@ export class UmamiApiClient {
4748
get(url: string, params?: object, headers?: object) {
4849
const dest = buildUrl(`${this.apiEndpoint}/${url}`, params);
4950

50-
log(`GET ${dest}`);
51+
log(`GET ${dest}`, params, headers);
5152

5253
return get(dest, undefined, this.getHeaders(headers));
5354
}
5455

5556
post(url: string, params?: object, headers?: object) {
5657
const dest = `${this.apiEndpoint}/${url}`;
5758

58-
log(`POST ${dest}`);
59+
log(`POST ${dest}`, params, headers);
5960

6061
return post(dest, params, this.getHeaders(headers));
6162
}
6263

6364
put(url: string, params?: object, headers?: object) {
6465
const dest = `${this.apiEndpoint}/${url}`;
6566

66-
log(`PUT ${dest}`);
67+
log(`PUT ${dest}`, params, headers);
6768

6869
return put(dest, params, this.getHeaders(headers));
6970
}
7071

7172
del(url: string, params?: object, headers?: object) {
7273
const dest = buildUrl(`${this.apiEndpoint}/${url}`, params);
7374

74-
log(`DELETE ${dest}`);
75+
log(`DELETE ${dest}`, params, headers);
7576

7677
return del(dest, undefined, this.getHeaders(headers));
7778
}
@@ -84,8 +85,8 @@ export class UmamiApiClient {
8485
return this.get(`users/${userId}`);
8586
}
8687

87-
async getUsers(): Promise<ApiResponse<Umami.User[]>> {
88-
return this.get(`users`);
88+
async getUsers(params: Umami.UserSearchFilter): Promise<ApiResponse<FilterResult<Umami.User[]>>> {
89+
return this.get(`users`, params);
8990
}
9091

9192
async getUserUsage(
@@ -98,8 +99,11 @@ export class UmamiApiClient {
9899
return this.get(`users/${userId}/usage`, params);
99100
}
100101

101-
async getUserWebsites(userId: string): Promise<ApiResponse<Umami.User[]>> {
102-
return this.get(`users/${userId}/websites`);
102+
async getUserWebsites(
103+
userId: string,
104+
params: Umami.WebsiteSearchFilter,
105+
): Promise<ApiResponse<FilterResult<Umami.User[]>>> {
106+
return this.get(`users/${userId}/websites`, params);
103107
}
104108

105109
async deleteUser(userId: string): Promise<ApiResponse<Umami.Empty>> {
@@ -144,8 +148,10 @@ export class UmamiApiClient {
144148
return this.post(`websites/${websiteId}/reset`);
145149
}
146150

147-
async getWebsites(): Promise<ApiResponse<Umami.Website[]>> {
148-
return this.get(`websites`);
151+
async getWebsites(
152+
params?: Umami.WebsiteSearchFilter,
153+
): Promise<ApiResponse<FilterResult<Umami.Website[]>>> {
154+
return this.get(`websites`, params);
149155
}
150156

151157
async getWebsiteActive(websiteId: string): Promise<ApiResponse<Umami.WebsiteActive[]>> {
@@ -260,24 +266,30 @@ export class UmamiApiClient {
260266
return this.get(`teams/${teamId}`);
261267
}
262268

263-
async getTeams(): Promise<ApiResponse<Umami.Team[]>> {
264-
return this.get(`teams`);
269+
async getTeams(params?: Umami.TeamSearchFilter): Promise<ApiResponse<Umami.Team[]>> {
270+
return this.get(`teams`, params);
265271
}
266272

267273
async joinTeam(data: { accessCode: string }): Promise<ApiResponse<Umami.Team>> {
268274
return this.post(`teams/join`, data);
269275
}
270276

271-
async getTeamUsers(teamId: string): Promise<ApiResponse<Umami.User[]>> {
272-
return this.get(`teams/${teamId}/users`);
277+
async getTeamUsers(
278+
teamId: string,
279+
params?: Umami.UserSearchFilter,
280+
): Promise<ApiResponse<FilterResult<FilterResult<Umami.User[]>>>> {
281+
return this.get(`teams/${teamId}/users`, params);
273282
}
274283

275284
async deleteTeamUser(teamId: string, userId: string): Promise<ApiResponse<Umami.Empty>> {
276285
return this.del(`teams/${teamId}/users/${userId}`);
277286
}
278287

279-
async getTeamWebsites(teamId: string): Promise<ApiResponse<Umami.Website[]>> {
280-
return this.get(`teams/${teamId}/websites`);
288+
async getTeamWebsites(
289+
teamId: string,
290+
params?: Umami.WebsiteSearchFilter,
291+
): Promise<ApiResponse<FilterResult<FilterResult<Umami.Website[]>>>> {
292+
return this.get(`teams/${teamId}/websites`, params);
281293
}
282294

283295
async createTeamWebsites(
@@ -318,8 +330,12 @@ export class UmamiApiClient {
318330
return this.get('me');
319331
}
320332

321-
async getMyWebsites() {
322-
return this.post('me/websites');
333+
async getMyWebsites(params?: Umami.WebsiteSearchFilter) {
334+
return this.get('me/websites', params);
335+
}
336+
337+
async getMyTeams(params?: Umami.TeamSearchFilter) {
338+
return this.get('me/teams', params);
323339
}
324340

325341
async updateMyPassword(data: { currentPassword: string; newPassword: string }) {

src/client.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ export const queryMap = [
1414
},
1515
{
1616
path: /^me\/websites$/,
17-
get: async () => client.getMyWebsites(),
17+
get: async (args, data) => client.getMyWebsites(data),
18+
},
19+
{
20+
path: /^me\/teams$/,
21+
get: async (args, data) => client.getMyTeams(data),
1822
},
1923
{
2024
path: /^event-data\/events$/,
@@ -30,7 +34,7 @@ export const queryMap = [
3034
},
3135
{
3236
path: /^teams$/,
33-
get: async () => client.getTeams(),
37+
get: async (args, data) => client.getTeams(data),
3438
post: async (args, data) => client.createTeam(data),
3539
},
3640
{
@@ -43,14 +47,17 @@ export const queryMap = [
4347
post: async ([, id], data) => client.updateTeam(id, data),
4448
delete: async ([, id]) => client.deleteTeam(id),
4549
},
46-
{ path: /^teams\/[0-9a-f-]+\/users$/, get: async ([, id]) => client.getTeamUsers(id) },
50+
{
51+
path: /^teams\/[0-9a-f-]+\/users$/,
52+
get: async ([, id], data) => client.getTeamUsers(id, data),
53+
},
4754
{
4855
path: /^teams\/[0-9a-f-]+\/users\/[0-9a-f-]+$/,
4956
delete: async ([, teamId, , userId]) => client.deleteTeamUser(teamId, userId),
5057
},
5158
{
5259
path: /^teams\/[0-9a-f-]+\/websites$/,
53-
get: async ([, id]) => client.getTeamWebsites(id),
60+
get: async ([, id], data) => client.getTeamWebsites(id, data),
5461
post: async ([, id], data) => client.createTeamWebsites(id, data),
5562
},
5663
{
@@ -59,7 +66,7 @@ export const queryMap = [
5966
},
6067
{
6168
path: /^users$/,
62-
get: async () => client.getUsers(),
69+
get: async (args, data) => client.getUsers(data),
6370
post: async (args, data) => client.createUser(data),
6471
},
6572
{
@@ -70,15 +77,15 @@ export const queryMap = [
7077
},
7178
{
7279
path: /^users\/[0-9a-f-]+\/websites$/,
73-
get: async ([, id]) => client.getUserWebsites(id),
80+
get: async ([, id], data) => client.getUserWebsites(id, data),
7481
},
7582
{
7683
path: /^users\/[0-9a-f-]+\/usage$/,
7784
get: async ([, id], data) => client.getUserUsage(id, data),
7885
},
7986
{
8087
path: /^websites$/,
81-
get: async () => client.getWebsites(),
88+
get: async (args, data) => client.getWebsites(data),
8289
post: async (args, data) => client.createWebsite(data),
8390
},
8491
{

src/constants.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export const USER_FILTER_TYPES = {
2+
all: 'All',
3+
username: 'Username',
4+
} as const;
5+
6+
export const WEBSITE_FILTER_TYPES = { all: 'All', name: 'Name', domain: 'Domain' } as const;
7+
8+
export const TEAM_FILTER_TYPES = { all: 'All', name: 'Name', 'user:username': 'Owner' } as const;
9+
10+
export const REPORT_FILTER_TYPES = {
11+
all: 'All',
12+
name: 'Name',
13+
description: 'Description',
14+
type: 'Type',
15+
'user:username': 'Username',
16+
'website:name': 'Website Name',
17+
'website:domain': 'Website Domain',
18+
} as const;

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from './client';
22
export * from './types';
33
export * from './UmamiApiClient';
44
export * from './utils';
5+
export * from './constants';

src/types.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
import {
2+
REPORT_FILTER_TYPES,
3+
TEAM_FILTER_TYPES,
4+
USER_FILTER_TYPES,
5+
WEBSITE_FILTER_TYPES,
6+
} from './constants';
7+
18
export interface User {
29
id: string;
310
username: string;
@@ -89,3 +96,45 @@ export interface WebsiteEventData {
8996
}
9097

9198
export interface Empty {}
99+
100+
type ObjectValues<T> = T[keyof T];
101+
102+
export type ReportSearchFilterType = ObjectValues<typeof REPORT_FILTER_TYPES>;
103+
export type UserSearchFilterType = ObjectValues<typeof USER_FILTER_TYPES>;
104+
export type WebsiteSearchFilterType = ObjectValues<typeof WEBSITE_FILTER_TYPES>;
105+
export type TeamSearchFilterType = ObjectValues<typeof TEAM_FILTER_TYPES>;
106+
107+
export interface WebsiteSearchFilter extends SearchFilter<WebsiteSearchFilterType> {
108+
userId?: string;
109+
teamId?: string;
110+
includeTeams?: boolean;
111+
}
112+
113+
export interface UserSearchFilter extends SearchFilter<UserSearchFilterType> {
114+
teamId?: string;
115+
}
116+
117+
export interface TeamSearchFilter extends SearchFilter<TeamSearchFilterType> {
118+
userId?: string;
119+
}
120+
121+
export interface ReportSearchFilter extends SearchFilter<ReportSearchFilterType> {
122+
userId?: string;
123+
websiteId?: string;
124+
}
125+
126+
export interface SearchFilter<T> {
127+
filter?: string;
128+
filterType?: T;
129+
pageSize?: number;
130+
page?: number;
131+
orderBy?: string;
132+
}
133+
134+
export interface FilterResult<T> {
135+
data: T;
136+
count: number;
137+
pageSize: number;
138+
page: number;
139+
orderBy?: string;
140+
}

0 commit comments

Comments
 (0)