umami-api-js 0.1.4 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -3
- package/dist/index.d.ts +28 -9
- package/dist/index.js +47 -14
- package/dist/namespaces/Admin.d.ts +1 -4
- package/dist/namespaces/Events.d.ts +47 -25
- package/dist/namespaces/Links.d.ts +4 -4
- package/dist/namespaces/Links.js +4 -4
- package/dist/namespaces/Me.d.ts +2 -2
- package/dist/namespaces/Pixels.d.ts +4 -4
- package/dist/namespaces/Pixels.js +4 -4
- package/dist/namespaces/Realtime.d.ts +7 -6
- package/dist/namespaces/Reports.d.ts +116 -77
- package/dist/namespaces/Reports.js +65 -22
- package/dist/namespaces/Sessions.d.ts +47 -33
- package/dist/namespaces/Teams.d.ts +4 -1
- package/dist/namespaces/Users.d.ts +1 -1
- package/dist/namespaces/WebsiteStats.d.ts +12 -6
- package/dist/namespaces/WebsiteStats.js +2 -7
- package/dist/namespaces/Websites.d.ts +6 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
# umami-api-js
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://ko-fi.com/V7V4J78L0)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A package to interact with [the API of **self-hosted instances** of Umami](https://umami.is/docs/api).
|
|
6
|
+
|
|
7
|
+
It has not been tested on [Umami Cloud](https://umami.is/docs/cloud) (the instance of Umami hosted by its creators) and is therefore not expected to work there.
|
|
8
|
+
|
|
9
|
+
The documentation for the latest version of this package can be found at any time on [umami-api-js.taevas.xyz](https://umami-api-js.taevas.xyz)!
|
|
10
|
+
|
|
11
|
+
## How to install and get started
|
|
12
|
+
|
|
13
|
+
Before installing, if using Node.js, check if you're running version 20 or above:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
node -v # displays your version of node.js
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then to install the package, use a command from your package manager:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm i umami-api-js # if using npm
|
|
23
|
+
yarn add umami-api-js # if using yarn
|
|
24
|
+
pnpm add umami-api-js # if using pnpm
|
|
25
|
+
bun a umami-api-js # if using bun
|
|
26
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -82,7 +82,10 @@ export declare class APIError extends Error {
|
|
|
82
82
|
method: Parameters<API["request"]>[0];
|
|
83
83
|
endpoint: Parameters<API["request"]>[1];
|
|
84
84
|
parameters: Parameters<API["request"]>[2];
|
|
85
|
-
|
|
85
|
+
response?: {
|
|
86
|
+
status_code: number;
|
|
87
|
+
json: unknown;
|
|
88
|
+
} | undefined;
|
|
86
89
|
original_error?: Error | undefined;
|
|
87
90
|
/**
|
|
88
91
|
* @param message The reason why things didn't go as expected
|
|
@@ -93,14 +96,26 @@ export declare class APIError extends Error {
|
|
|
93
96
|
* @param status_code The status code that was returned by the server, if there is one
|
|
94
97
|
* @param original_error The error that caused the api to throw an {@link APIError} in the first place, if there is one
|
|
95
98
|
*/
|
|
96
|
-
constructor(message: string, server: API["server"], method: Parameters<API["request"]>[0], endpoint: Parameters<API["request"]>[1], parameters: Parameters<API["request"]>[2],
|
|
99
|
+
constructor(message: string, server: API["server"], method: Parameters<API["request"]>[0], endpoint: Parameters<API["request"]>[1], parameters: Parameters<API["request"]>[2], response?: {
|
|
100
|
+
status_code: number;
|
|
101
|
+
json: unknown;
|
|
102
|
+
} | undefined, original_error?: Error | undefined);
|
|
97
103
|
}
|
|
98
104
|
/** An API instance is needed to make requests to the server! */
|
|
99
105
|
export declare class API {
|
|
100
106
|
/** If you have account credentials, you might want to use this constructor */
|
|
101
|
-
constructor(username: API["username"], password: API["password"], settings?: Partial<API>);
|
|
102
|
-
/**
|
|
103
|
-
constructor(
|
|
107
|
+
constructor(server: API["server"], username: API["username"], password: API["password"], settings?: Partial<API>);
|
|
108
|
+
/** You might want to use this constructor if you'd like the freedom to set whatever you like, for example a {@link API.token} without setting account credentials */
|
|
109
|
+
constructor(settings: Partial<API>);
|
|
110
|
+
/**
|
|
111
|
+
* The alternative way of creating an API instance, awaiting this method waits for the server's authorization
|
|
112
|
+
* and allows you to catch errors if the authorization fails
|
|
113
|
+
* @param server The base URL where requests should land, **should include the `/api` portion if applicable** (e.g. `https://my-instance.com/api`)
|
|
114
|
+
* @param username The username of the user you're logging in as
|
|
115
|
+
* @param password The password of the user you're logging in as
|
|
116
|
+
* @param settings Additional settings you'd like to specify now rather than later, check out the Accessors at https://umami-api-js.taevas.xyz/classes/API.html
|
|
117
|
+
*/
|
|
118
|
+
static createAsync(server: API["server"], username: API["username"], password: API["password"], settings?: Partial<API>): Promise<API>;
|
|
104
119
|
private _token;
|
|
105
120
|
/** The key that allows you to talk with the API */
|
|
106
121
|
get token(): string;
|
|
@@ -113,6 +128,10 @@ export declare class API {
|
|
|
113
128
|
/** The expiration date of your token */
|
|
114
129
|
get expires(): Date;
|
|
115
130
|
set expires(date: Date);
|
|
131
|
+
private _server;
|
|
132
|
+
/** The base URL where requests should land, **should include the `/api` portion if applicable** */
|
|
133
|
+
get server(): string;
|
|
134
|
+
set server(server: string);
|
|
116
135
|
private _username;
|
|
117
136
|
/** The username of the account */
|
|
118
137
|
get username(): string;
|
|
@@ -121,10 +140,6 @@ export declare class API {
|
|
|
121
140
|
/** The password of the account */
|
|
122
141
|
get password(): string;
|
|
123
142
|
set password(password: string);
|
|
124
|
-
private _server;
|
|
125
|
-
/** The base URL where requests should land, **should include the `/api` portion if applicable** */
|
|
126
|
-
get server(): string;
|
|
127
|
-
set server(server: string);
|
|
128
143
|
private _headers;
|
|
129
144
|
/**
|
|
130
145
|
* Used in practically all requests, those are all the headers the package uses excluding `Authorization`, the one with the token
|
|
@@ -151,6 +166,10 @@ export declare class API {
|
|
|
151
166
|
* @returns Whether or not the token has changed (**should be true** as otherwise the server would complain and an {@link APIError} would be thrown to give you some details)
|
|
152
167
|
*/
|
|
153
168
|
setNewToken(): Promise<boolean>;
|
|
169
|
+
private _set_token_on_creation;
|
|
170
|
+
/** If true, when creating your API object, a call to {@link API.setNewToken} will be automatically made (defaults to **true**) */
|
|
171
|
+
get set_token_on_creation(): boolean;
|
|
172
|
+
set set_token_on_creation(bool: boolean);
|
|
154
173
|
private _set_token_on_401;
|
|
155
174
|
/** If true, upon failing a request due to a 401, it will call {@link API.setNewToken} (defaults to **true**) */
|
|
156
175
|
get set_token_on_401(): boolean;
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ export class APIError extends Error {
|
|
|
19
19
|
method;
|
|
20
20
|
endpoint;
|
|
21
21
|
parameters;
|
|
22
|
-
|
|
22
|
+
response;
|
|
23
23
|
original_error;
|
|
24
24
|
/**
|
|
25
25
|
* @param message The reason why things didn't go as expected
|
|
@@ -30,14 +30,14 @@ export class APIError extends Error {
|
|
|
30
30
|
* @param status_code The status code that was returned by the server, if there is one
|
|
31
31
|
* @param original_error The error that caused the api to throw an {@link APIError} in the first place, if there is one
|
|
32
32
|
*/
|
|
33
|
-
constructor(message, server, method, endpoint, parameters,
|
|
33
|
+
constructor(message, server, method, endpoint, parameters, response, original_error) {
|
|
34
34
|
super();
|
|
35
35
|
this.message = message;
|
|
36
36
|
this.server = server;
|
|
37
37
|
this.method = method;
|
|
38
38
|
this.endpoint = endpoint;
|
|
39
39
|
this.parameters = parameters;
|
|
40
|
-
this.
|
|
40
|
+
this.response = response;
|
|
41
41
|
this.original_error = original_error;
|
|
42
42
|
if (this.parameters?.password) {
|
|
43
43
|
this.parameters.password = "<REDACTED>";
|
|
@@ -46,8 +46,8 @@ export class APIError extends Error {
|
|
|
46
46
|
}
|
|
47
47
|
/** An API instance is needed to make requests to the server! */
|
|
48
48
|
export class API {
|
|
49
|
-
constructor(
|
|
50
|
-
settings ??= typeof
|
|
49
|
+
constructor(server_or_settings, username, password, settings) {
|
|
50
|
+
settings ??= typeof server_or_settings !== "string" ? server_or_settings : undefined;
|
|
51
51
|
if (settings) {
|
|
52
52
|
/** Delete every property that is `undefined` so the class defaults aren't overwritten by `undefined` */
|
|
53
53
|
Object.keys(settings).forEach((key) => {
|
|
@@ -55,13 +55,38 @@ export class API {
|
|
|
55
55
|
});
|
|
56
56
|
Object.assign(this, settings);
|
|
57
57
|
}
|
|
58
|
+
if (this.is_setting_token) { // Very likely a clone created while the original didn't have a valid token
|
|
59
|
+
this.set_token_on_expires = false; // In which case allow the clone to get its own token, but not renewing it automatically
|
|
60
|
+
} // And if the clone keeps getting used, `set_token_on_401` being true should cover that
|
|
58
61
|
/** We want to set a new token instantly if account credentials have been provided */
|
|
59
|
-
if (typeof
|
|
60
|
-
this.
|
|
61
|
-
this.
|
|
62
|
+
if (this.set_token_on_creation && typeof server_or_settings === "string" && username && password) {
|
|
63
|
+
this.server = server_or_settings;
|
|
64
|
+
this.username = username;
|
|
65
|
+
this.password = password;
|
|
62
66
|
this.setNewToken();
|
|
63
67
|
}
|
|
64
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* The alternative way of creating an API instance, awaiting this method waits for the server's authorization
|
|
71
|
+
* and allows you to catch errors if the authorization fails
|
|
72
|
+
* @param server The base URL where requests should land, **should include the `/api` portion if applicable** (e.g. `https://my-instance.com/api`)
|
|
73
|
+
* @param username The username of the user you're logging in as
|
|
74
|
+
* @param password The password of the user you're logging in as
|
|
75
|
+
* @param settings Additional settings you'd like to specify now rather than later, check out the Accessors at https://umami-api-js.taevas.xyz/classes/API.html
|
|
76
|
+
*/
|
|
77
|
+
static async createAsync(server, username, password, settings) {
|
|
78
|
+
// We don't want `new API` to set the token, as we can't await it (and awaiting `token_promise` sounds like a bad idea)
|
|
79
|
+
if (settings) {
|
|
80
|
+
settings.set_token_on_creation = false;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
settings = { set_token_on_creation: false };
|
|
84
|
+
}
|
|
85
|
+
const new_api = new API({ server, username, password, ...settings });
|
|
86
|
+
// We set the token ourselves, which also means we'll be the first to throw if it fails, so the APIError should be useful to users
|
|
87
|
+
await new_api.setNewToken();
|
|
88
|
+
return new_api;
|
|
89
|
+
}
|
|
65
90
|
_token = "";
|
|
66
91
|
/** The key that allows you to talk with the API */
|
|
67
92
|
get token() { return this._token; }
|
|
@@ -78,6 +103,10 @@ export class API {
|
|
|
78
103
|
this.updateTokenTimer();
|
|
79
104
|
}
|
|
80
105
|
// CLIENT INFO
|
|
106
|
+
_server = "";
|
|
107
|
+
/** The base URL where requests should land, **should include the `/api` portion if applicable** */
|
|
108
|
+
get server() { return this._server; }
|
|
109
|
+
set server(server) { this._server = server; }
|
|
81
110
|
_username = "";
|
|
82
111
|
/** The username of the account */
|
|
83
112
|
get username() { return this._username; }
|
|
@@ -86,10 +115,6 @@ export class API {
|
|
|
86
115
|
/** The password of the account */
|
|
87
116
|
get password() { return this._password; }
|
|
88
117
|
set password(password) { this._password = password; }
|
|
89
|
-
_server = "";
|
|
90
|
-
/** The base URL where requests should land, **should include the `/api` portion if applicable** */
|
|
91
|
-
get server() { return this._server; }
|
|
92
|
-
set server(server) { this._server = server; }
|
|
93
118
|
_headers = {
|
|
94
119
|
"Accept": "application/json",
|
|
95
120
|
"Accept-Encoding": "gzip",
|
|
@@ -138,7 +163,7 @@ export class API {
|
|
|
138
163
|
if (!json.token) {
|
|
139
164
|
const error_message = json.error_description ?? json.message ?? "No token obtained"; // Expect "Client authentication failed"
|
|
140
165
|
this.log(true, "Unable to obtain a token! Here's what was received from the API:", json);
|
|
141
|
-
reject(new APIError(error_message, this.server, "post", ["auth", "login"], body, response.status));
|
|
166
|
+
reject(new APIError(error_message, this.server, "post", ["auth", "login"], body, { status_code: response.status, json }));
|
|
142
167
|
}
|
|
143
168
|
// Note: `json` currently only has `token` & `user`
|
|
144
169
|
this.token = json.token;
|
|
@@ -157,6 +182,10 @@ export class API {
|
|
|
157
182
|
this.log(false, "A new token has been set!");
|
|
158
183
|
return old_token !== this.token;
|
|
159
184
|
}
|
|
185
|
+
_set_token_on_creation = true;
|
|
186
|
+
/** If true, when creating your API object, a call to {@link API.setNewToken} will be automatically made (defaults to **true**) */
|
|
187
|
+
get set_token_on_creation() { return this._set_token_on_creation; }
|
|
188
|
+
set set_token_on_creation(bool) { this._set_token_on_creation = bool; }
|
|
160
189
|
_set_token_on_401 = true;
|
|
161
190
|
/** If true, upon failing a request due to a 401, it will call {@link API.setNewToken} (defaults to **true**) */
|
|
162
191
|
get set_token_on_401() { return this._set_token_on_401; }
|
|
@@ -351,7 +380,11 @@ export class API {
|
|
|
351
380
|
return await this.fetch(is_token_related, method, endpoint, parameters, { number_try: info.number_try + 1, has_new_token: info.has_new_token });
|
|
352
381
|
}
|
|
353
382
|
if (!response || !response.ok) {
|
|
354
|
-
|
|
383
|
+
const resp = response ? {
|
|
384
|
+
status_code: response.status,
|
|
385
|
+
json: await response.json()
|
|
386
|
+
} : undefined;
|
|
387
|
+
throw new APIError(error_message, this.server, method, endpoint, parameters, resp, error_object);
|
|
355
388
|
}
|
|
356
389
|
return response;
|
|
357
390
|
}
|
|
@@ -4,10 +4,7 @@ export declare namespace Admin {
|
|
|
4
4
|
/** Returns all users: https://umami.is/docs/api/admin#get-apiadminusers */
|
|
5
5
|
function getUsers(this: API, parameters?: GenericRequestParameters): Promise<Users.DetailedUser[]>;
|
|
6
6
|
/** Returns all websites: https://umami.is/docs/api/admin#get-apiadminwebsites */
|
|
7
|
-
function getWebsites(this: API, parameters?: GenericRequestParameters): Promise<
|
|
8
|
-
/** @remarks TODO Documentation says it can be null but doesn't actually say what else it can be, ***presumed* to be string**, check */
|
|
9
|
-
team: string | null;
|
|
10
|
-
})[]>;
|
|
7
|
+
function getWebsites(this: API, parameters?: GenericRequestParameters): Promise<Websites.WebsiteWithUserTeam[]>;
|
|
11
8
|
/** Returns all teams: https://umami.is/docs/api/admin#get-apiadminteams */
|
|
12
9
|
function getTeams(this: API, parameters?: GenericRequestParameters): Promise<Teams.TeamWithMembersCount[]>;
|
|
13
10
|
}
|
|
@@ -20,12 +20,14 @@ export declare namespace Events {
|
|
|
20
20
|
pageTitle: string | null;
|
|
21
21
|
eventType: number;
|
|
22
22
|
eventName: string;
|
|
23
|
-
hasData?:
|
|
23
|
+
hasData?: boolean;
|
|
24
24
|
}
|
|
25
25
|
/** Gets website event details within a given time range: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevents */
|
|
26
|
-
function get_WEBSITEID_Events(this: API, websiteId: Websites.Website["id"], parameters:
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
function get_WEBSITEID_Events(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & GenericRequestParameters & {
|
|
27
|
+
/** Can accept filter parameters */
|
|
28
|
+
filters?: Filters;
|
|
29
|
+
}): Promise<Event[]>;
|
|
30
|
+
interface Data {
|
|
29
31
|
websiteId: Websites.Website["id"];
|
|
30
32
|
sessionId?: Sessions.Session["id"];
|
|
31
33
|
eventId: Event["id"];
|
|
@@ -37,44 +39,64 @@ export declare namespace Events {
|
|
|
37
39
|
dateValue: Date | null;
|
|
38
40
|
dataType: number;
|
|
39
41
|
createdAt: Date;
|
|
40
|
-
}
|
|
41
|
-
/** Gets event
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
event?: Event["eventName"];
|
|
45
|
-
}): Promise<{
|
|
42
|
+
}
|
|
43
|
+
/** Gets event-data for a individual event: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-dataeventid */
|
|
44
|
+
function get_WEBSITEID_Eventdata_EVENTID(this: API, websiteId: Websites.Website["id"], eventId: Event["id"]): Promise<Data[]>;
|
|
45
|
+
interface DataMultiple {
|
|
46
46
|
eventName: Event["eventName"];
|
|
47
47
|
propertyName: string;
|
|
48
48
|
dataType: number;
|
|
49
49
|
total: number;
|
|
50
|
-
}
|
|
51
|
-
/** Gets event data
|
|
52
|
-
function
|
|
50
|
+
}
|
|
51
|
+
/** Gets event data names, properties, and counts: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-dataevents (TODO Server returns a 500) */
|
|
52
|
+
function get_WEBSITEID_EventdataEvents(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
53
|
+
/** Event name filter */
|
|
54
|
+
event?: Event["eventName"];
|
|
55
|
+
/** Can accept filter parameters */
|
|
56
|
+
filters?: Filters;
|
|
57
|
+
}): Promise<DataMultiple[]>;
|
|
58
|
+
interface DataFields {
|
|
53
59
|
propertyName: string;
|
|
54
60
|
dataType: number;
|
|
55
61
|
value: string;
|
|
56
62
|
total: number;
|
|
57
|
-
}
|
|
58
|
-
/** Gets event
|
|
59
|
-
function
|
|
63
|
+
}
|
|
64
|
+
/** Gets event data property and value counts within a given time range: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-datafields */
|
|
65
|
+
function get_WEBSITEID_EventdataFields(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
66
|
+
/** Can accept filter parameters */
|
|
67
|
+
filters?: Filters;
|
|
68
|
+
}): Promise<DataFields[]>;
|
|
69
|
+
interface DataProperties {
|
|
60
70
|
eventName: Event["eventName"] | null;
|
|
61
71
|
propertyName: string;
|
|
62
72
|
total: number;
|
|
63
|
-
}
|
|
73
|
+
}
|
|
74
|
+
/** Gets event name and property counts for a website: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-dataproperties */
|
|
75
|
+
function get_WEBSITEID_EventdataProperties(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
76
|
+
/** Can accept filter parameters */
|
|
77
|
+
filters?: Filters;
|
|
78
|
+
}): Promise<DataProperties[]>;
|
|
79
|
+
interface DataValues {
|
|
80
|
+
value: string;
|
|
81
|
+
total: number;
|
|
82
|
+
}
|
|
64
83
|
/** Gets event data counts for a given event and property: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-datavalues */
|
|
65
|
-
function get_WEBSITEID_EventdataValues(this: API, websiteId: Websites.Website["id"], parameters:
|
|
84
|
+
function get_WEBSITEID_EventdataValues(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
66
85
|
/** Event name filter */
|
|
67
86
|
event: Event["eventName"];
|
|
68
87
|
/** Property name */
|
|
69
88
|
propertyName: string;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
/** Gets aggregated website events, properties, and records within a given time range: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-datastats */
|
|
75
|
-
function get_WEBSITEID_EventdataStats(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps): Promise<{
|
|
89
|
+
/** Can accept filter parameters */
|
|
90
|
+
filters?: Filters;
|
|
91
|
+
}): Promise<DataValues[]>;
|
|
92
|
+
interface DataStats {
|
|
76
93
|
events: number;
|
|
77
94
|
properties: number;
|
|
78
95
|
records: number;
|
|
79
|
-
}
|
|
96
|
+
}
|
|
97
|
+
/** Gets aggregated website events, properties, and records within a given time range: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-datastats */
|
|
98
|
+
function get_WEBSITEID_EventdataStats(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
99
|
+
/** Can accept filter parameters */
|
|
100
|
+
filters?: Filters;
|
|
101
|
+
}): Promise<DataStats>;
|
|
80
102
|
}
|
|
@@ -12,11 +12,11 @@ export declare namespace Links {
|
|
|
12
12
|
updatedAt: Date;
|
|
13
13
|
deletedAt: Date | null;
|
|
14
14
|
}
|
|
15
|
-
/** Returns all user links: https://umami.is/docs/api/links#get-apilinks
|
|
15
|
+
/** Returns all user links: https://umami.is/docs/api/links#get-apilinks */
|
|
16
16
|
function get(this: API, parameters?: GenericRequestParameters): Promise<Link[]>;
|
|
17
|
-
/** Gets a link by ID: https://umami.is/docs/api/links#get-apilinkslinkid
|
|
17
|
+
/** Gets a link by ID: https://umami.is/docs/api/links#get-apilinkslinkid */
|
|
18
18
|
function get_LINKID(this: API, linkId: Link["id"]): Promise<Link>;
|
|
19
|
-
/** Updates a link: https://umami.is/docs/api/links#post-apilinkslinkid
|
|
19
|
+
/** Updates a link: https://umami.is/docs/api/links#post-apilinkslinkid */
|
|
20
20
|
function post_LINKID(this: API, linkId: Link["id"], parameters: {
|
|
21
21
|
/** The link's name */
|
|
22
22
|
name?: Link["name"];
|
|
@@ -25,6 +25,6 @@ export declare namespace Links {
|
|
|
25
25
|
/** The link's URL slug, **with a minimum of 8 characters** */
|
|
26
26
|
slug?: Link["slug"];
|
|
27
27
|
}): Promise<Link>;
|
|
28
|
-
/** Deletes a link: https://umami.is/docs/api/links#delete-apilinkslinkid
|
|
28
|
+
/** Deletes a link: https://umami.is/docs/api/links#delete-apilinkslinkid */
|
|
29
29
|
function delete_LINKID(this: API, linkId: Link["id"]): Promise<DeletionResult>;
|
|
30
30
|
}
|
package/dist/namespaces/Links.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
/** Operations around Links management: https://umami.is/docs/api/links */
|
|
2
2
|
export var Links;
|
|
3
3
|
(function (Links) {
|
|
4
|
-
/** Returns all user links: https://umami.is/docs/api/links#get-apilinks
|
|
4
|
+
/** Returns all user links: https://umami.is/docs/api/links#get-apilinks */
|
|
5
5
|
async function get(parameters) {
|
|
6
6
|
const response = await this.request("get", ["links"], parameters);
|
|
7
7
|
return response.data;
|
|
8
8
|
}
|
|
9
9
|
Links.get = get;
|
|
10
|
-
/** Gets a link by ID: https://umami.is/docs/api/links#get-apilinkslinkid
|
|
10
|
+
/** Gets a link by ID: https://umami.is/docs/api/links#get-apilinkslinkid */
|
|
11
11
|
async function get_LINKID(linkId) {
|
|
12
12
|
return await this.request("get", ["links", linkId]);
|
|
13
13
|
}
|
|
14
14
|
Links.get_LINKID = get_LINKID;
|
|
15
|
-
/** Updates a link: https://umami.is/docs/api/links#post-apilinkslinkid
|
|
15
|
+
/** Updates a link: https://umami.is/docs/api/links#post-apilinkslinkid */
|
|
16
16
|
async function post_LINKID(linkId, parameters) {
|
|
17
17
|
return await this.request("post", ["links", linkId], parameters);
|
|
18
18
|
}
|
|
19
19
|
Links.post_LINKID = post_LINKID;
|
|
20
|
-
/** Deletes a link: https://umami.is/docs/api/links#delete-apilinkslinkid
|
|
20
|
+
/** Deletes a link: https://umami.is/docs/api/links#delete-apilinkslinkid */
|
|
21
21
|
async function delete_LINKID(linkId) {
|
|
22
22
|
return await this.request("delete", ["links", linkId]);
|
|
23
23
|
}
|
package/dist/namespaces/Me.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { API, Teams, Users, Websites } from "../index.js";
|
|
|
2
2
|
/** All information about your session: https://umami.is/docs/api/me */
|
|
3
3
|
export declare namespace Me {
|
|
4
4
|
interface TokenInformation {
|
|
5
|
-
token:
|
|
6
|
-
authKey: string;
|
|
5
|
+
token: string;
|
|
7
6
|
shareToken: string | null;
|
|
7
|
+
authKey?: string;
|
|
8
8
|
user: Users.User;
|
|
9
9
|
}
|
|
10
10
|
/** Get information based on your auth token: https://umami.is/docs/api/me#get-apime */
|
|
@@ -11,17 +11,17 @@ export declare namespace Pixels {
|
|
|
11
11
|
updatedAt: Date;
|
|
12
12
|
deletedAt: Date | null;
|
|
13
13
|
}
|
|
14
|
-
/** Returns all user pixels: https://umami.is/docs/api/pixels#get-apipixels
|
|
14
|
+
/** Returns all user pixels: https://umami.is/docs/api/pixels#get-apipixels */
|
|
15
15
|
function get(this: API, parameters?: GenericRequestParameters): Promise<Pixel[]>;
|
|
16
|
-
/** Gets a pixel by ID: https://umami.is/docs/api/pixels#get-apipixelspixelid
|
|
16
|
+
/** Gets a pixel by ID: https://umami.is/docs/api/pixels#get-apipixelspixelid */
|
|
17
17
|
function get_PIXELID(this: API, pixelId: Pixel["id"]): Promise<Pixel>;
|
|
18
|
-
/** Updates a pixel: https://umami.is/docs/api/pixels#post-apipixelspixelid
|
|
18
|
+
/** Updates a pixel: https://umami.is/docs/api/pixels#post-apipixelspixelid */
|
|
19
19
|
function post_PIXELID(this: API, pixelId: Pixel["id"], parameters: {
|
|
20
20
|
/** The pixel's name */
|
|
21
21
|
name?: Pixel["name"];
|
|
22
22
|
/** The pixel's URL slug, **with a minimum of 8 characters** */
|
|
23
23
|
slug?: Pixel["slug"];
|
|
24
24
|
}): Promise<Pixel>;
|
|
25
|
-
/** Deletes a pixel: https://umami.is/docs/api/pixels#delete-apipixelspixelid
|
|
25
|
+
/** Deletes a pixel: https://umami.is/docs/api/pixels#delete-apipixelspixelid */
|
|
26
26
|
function delete_PIXELID(this: API, pixelId: Pixel["id"]): Promise<DeletionResult>;
|
|
27
27
|
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
/** Operations around Pixels management: https://umami.is/docs/api/pixels */
|
|
2
2
|
export var Pixels;
|
|
3
3
|
(function (Pixels) {
|
|
4
|
-
/** Returns all user pixels: https://umami.is/docs/api/pixels#get-apipixels
|
|
4
|
+
/** Returns all user pixels: https://umami.is/docs/api/pixels#get-apipixels */
|
|
5
5
|
async function get(parameters) {
|
|
6
6
|
const response = await this.request("get", ["pixels"], parameters);
|
|
7
7
|
return response.data;
|
|
8
8
|
}
|
|
9
9
|
Pixels.get = get;
|
|
10
|
-
/** Gets a pixel by ID: https://umami.is/docs/api/pixels#get-apipixelspixelid
|
|
10
|
+
/** Gets a pixel by ID: https://umami.is/docs/api/pixels#get-apipixelspixelid */
|
|
11
11
|
async function get_PIXELID(pixelId) {
|
|
12
12
|
return await this.request("get", ["pixels", pixelId]);
|
|
13
13
|
}
|
|
14
14
|
Pixels.get_PIXELID = get_PIXELID;
|
|
15
|
-
/** Updates a pixel: https://umami.is/docs/api/pixels#post-apipixelspixelid
|
|
15
|
+
/** Updates a pixel: https://umami.is/docs/api/pixels#post-apipixelspixelid */
|
|
16
16
|
async function post_PIXELID(pixelId, parameters) {
|
|
17
17
|
return await this.request("post", ["pixels", pixelId], parameters);
|
|
18
18
|
}
|
|
19
19
|
Pixels.post_PIXELID = post_PIXELID;
|
|
20
|
-
/** Deletes a pixel: https://umami.is/docs/api/pixels#delete-apipixelspixelid
|
|
20
|
+
/** Deletes a pixel: https://umami.is/docs/api/pixels#delete-apipixelspixelid */
|
|
21
21
|
async function delete_PIXELID(pixelId) {
|
|
22
22
|
return await this.request("delete", ["pixels", pixelId]);
|
|
23
23
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { API, Sessions, Websites } from "../index.js";
|
|
2
2
|
/** Realtime data for your website: https://umami.is/docs/api/realtime */
|
|
3
3
|
export declare namespace Realtime {
|
|
4
|
-
|
|
5
|
-
function get_WEBSITEID(this: API, websiteId: Websites.Website["id"]): Promise<{
|
|
4
|
+
interface Stats {
|
|
6
5
|
countries: {
|
|
7
6
|
[k: string]: number;
|
|
8
7
|
};
|
|
@@ -17,12 +16,12 @@ export declare namespace Realtime {
|
|
|
17
16
|
sessionId: Sessions.Session["id"];
|
|
18
17
|
eventName: string;
|
|
19
18
|
createdAt: Date;
|
|
20
|
-
browser: string;
|
|
21
|
-
os: string;
|
|
19
|
+
browser: string | null;
|
|
20
|
+
os: string | null;
|
|
22
21
|
device: string;
|
|
23
22
|
country: string;
|
|
24
23
|
urlPath: string;
|
|
25
|
-
referrerDomain: string;
|
|
24
|
+
referrerDomain: string | null;
|
|
26
25
|
}[];
|
|
27
26
|
series: {
|
|
28
27
|
views: {
|
|
@@ -41,5 +40,7 @@ export declare namespace Realtime {
|
|
|
41
40
|
countries: number;
|
|
42
41
|
};
|
|
43
42
|
timestamp: number;
|
|
44
|
-
}
|
|
43
|
+
}
|
|
44
|
+
/** Realtime stats within the last 30 minutes: https://umami.is/docs/api/realtime#get-apirealtimewebsiteid */
|
|
45
|
+
function get_WEBSITEID(this: API, websiteId: Websites.Website["id"]): Promise<Stats>;
|
|
45
46
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { API, DeletionResult, Filters, GenericRequestParameters, NameValue,
|
|
2
|
-
/** Using reports throught the api: https://umami.is/docs/api/reports */
|
|
1
|
+
import { API, DeletionResult, Filters, GenericRequestParameters, NameValue, Users, Websites, XTY } from "../index.js";
|
|
2
|
+
/** Using reports throught [sic] the api: https://umami.is/docs/api/reports */
|
|
3
3
|
export declare namespace Reports {
|
|
4
4
|
interface Report {
|
|
5
5
|
id: string;
|
|
@@ -15,46 +15,47 @@ export declare namespace Reports {
|
|
|
15
15
|
createdAt: Date;
|
|
16
16
|
updatedAt: Date;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
/** The Reports endpoints use `startDate` instead of `startAt`, and `endDate` instead of `endAt` */
|
|
19
|
+
interface Timestamps {
|
|
20
|
+
/** Timestamp of starting date */
|
|
21
|
+
startDate: Date | number;
|
|
22
|
+
/** Timestamp of end date */
|
|
23
|
+
endDate: Date | number;
|
|
24
24
|
}
|
|
25
|
+
type ReportType = "attribution" | "breakdown" | "funnel" | "goal" | "journey" | "retention" | "revenue" | "utm";
|
|
25
26
|
/** Get all reports by website ID: https://umami.is/docs/api/reports#get-apireports (TODO UNTESTED) */
|
|
26
|
-
function get(this: API, websiteId: Websites.Website["id"], parameters:
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
function get(this: API, websiteId: Websites.Website["id"], parameters: {
|
|
28
|
+
type: ReportType;
|
|
29
|
+
} & Omit<GenericRequestParameters, "search">): Promise<Report[]>;
|
|
30
|
+
/** Creates a report: https://umami.is/docs/api/reports#post-apireports */
|
|
31
|
+
function post(this: API, websiteId: Websites.Website["id"], parameters: {
|
|
32
|
+
/** Report type */
|
|
33
|
+
type: ReportType;
|
|
29
34
|
/** Name of report */
|
|
30
35
|
name: Report["name"];
|
|
31
36
|
/** Description of report */
|
|
32
37
|
description?: Report["description"];
|
|
33
38
|
/** Parameters for report */
|
|
34
|
-
parameters
|
|
39
|
+
parameters: Report["parameters"];
|
|
35
40
|
}): Promise<Report>;
|
|
36
|
-
/** Gets a report by ID: https://umami.is/docs/api/reports#get-apireportsreportid
|
|
41
|
+
/** Gets a report by ID: https://umami.is/docs/api/reports#get-apireportsreportid */
|
|
37
42
|
function get_REPORTID(this: API, reportId: Report["id"]): Promise<Report>;
|
|
38
|
-
/** Updates a report: https://umami.is/docs/api/reports#post-apireportsreportid
|
|
39
|
-
function post_REPORTID(this: API, reportId: Report["id"],
|
|
43
|
+
/** Updates a report: https://umami.is/docs/api/reports#post-apireportsreportid */
|
|
44
|
+
function post_REPORTID(this: API, reportId: Report["id"], parameters?: {
|
|
45
|
+
/** Your website id */
|
|
46
|
+
websiteId?: Websites.Website["id"];
|
|
47
|
+
/** Report type */
|
|
48
|
+
type?: ReportType;
|
|
40
49
|
/** Name of report */
|
|
41
|
-
name
|
|
50
|
+
name?: Report["name"];
|
|
42
51
|
/** Description of report */
|
|
43
52
|
description?: Report["description"];
|
|
44
53
|
/** Parameters for report */
|
|
45
|
-
parameters?:
|
|
54
|
+
parameters?: Report["parameters"];
|
|
46
55
|
}): Promise<Report>;
|
|
47
|
-
/** Deletes a report: https://umami.is/docs/api/reports#delete-apireportsreportid
|
|
56
|
+
/** Deletes a report: https://umami.is/docs/api/reports#delete-apireportsreportid */
|
|
48
57
|
function delete_REPORTID(this: API, reportId: Report["id"]): Promise<DeletionResult>;
|
|
49
|
-
|
|
50
|
-
function postAttribution(this: API, websiteId: Websites.Website["id"], parameters: ReportType & Filters & Timestamps & {
|
|
51
|
-
/** Attribution model */
|
|
52
|
-
model: "firstClick" | "lastClick";
|
|
53
|
-
/** Conversion type */
|
|
54
|
-
type: ("path" | "event")[];
|
|
55
|
-
/** Conversion step */
|
|
56
|
-
step: string;
|
|
57
|
-
}): Promise<{
|
|
58
|
+
interface Attribution {
|
|
58
59
|
referrer: NameValue[];
|
|
59
60
|
paidAds: NameValue[];
|
|
60
61
|
utm_source: NameValue[];
|
|
@@ -67,11 +68,19 @@ export declare namespace Reports {
|
|
|
67
68
|
visitors: number;
|
|
68
69
|
visits: number;
|
|
69
70
|
};
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
function
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
}
|
|
72
|
+
/** See how users engage with your marketing and what drives conversions: https://umami.is/docs/api/reports#post-apireportsattribution */
|
|
73
|
+
function postAttribution(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
74
|
+
/** Can accept filter parameters */
|
|
75
|
+
filters?: Filters;
|
|
76
|
+
/** Attribution model */
|
|
77
|
+
model: "first-click" | "last-click";
|
|
78
|
+
/** Conversion type */
|
|
79
|
+
type: "path" | "event";
|
|
80
|
+
/** Conversion step */
|
|
81
|
+
step: string;
|
|
82
|
+
}): Promise<Attribution>;
|
|
83
|
+
interface Breakdown {
|
|
75
84
|
views: number;
|
|
76
85
|
visitors: number;
|
|
77
86
|
visits: number;
|
|
@@ -79,9 +88,27 @@ export declare namespace Reports {
|
|
|
79
88
|
totaltime: number;
|
|
80
89
|
os: string;
|
|
81
90
|
country: string;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
function
|
|
91
|
+
}
|
|
92
|
+
/** Dive deeper into your data by using segments and filters: https://umami.is/docs/api/reports#post-apireportsbreakdown */
|
|
93
|
+
function postBreakdown(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
94
|
+
/** Can accept filter parameters */
|
|
95
|
+
filters?: Filters;
|
|
96
|
+
/** List of column fields */
|
|
97
|
+
fields: ("path" | "title" | "query" | "referrer" | "browser" | "os" | "device" | "country" | "region" | "city" | "hostname" | "tag" | "event")[];
|
|
98
|
+
}): Promise<Breakdown[]>;
|
|
99
|
+
interface Funnel {
|
|
100
|
+
type: string;
|
|
101
|
+
value: string;
|
|
102
|
+
visitors: number;
|
|
103
|
+
previous: number;
|
|
104
|
+
dropped: number;
|
|
105
|
+
dropoff: number | null;
|
|
106
|
+
remaining: number | null;
|
|
107
|
+
}
|
|
108
|
+
/** Understand the conversion and drop-off rate of users: https://umami.is/docs/api/reports#post-apireportsfunnel */
|
|
109
|
+
function postFunnel(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
110
|
+
/** Can accept filter parameters */
|
|
111
|
+
filters?: Filters;
|
|
85
112
|
/** Type of event and conversion step */
|
|
86
113
|
steps: {
|
|
87
114
|
type: "path" | "event";
|
|
@@ -89,70 +116,82 @@ export declare namespace Reports {
|
|
|
89
116
|
}[];
|
|
90
117
|
/** Window of days between funnel steps to be considered a conversion */
|
|
91
118
|
window: number;
|
|
92
|
-
}): Promise<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
dropped: number;
|
|
98
|
-
dropoff: number | null;
|
|
99
|
-
remaining: number;
|
|
100
|
-
}[]>;
|
|
119
|
+
}): Promise<Funnel[]>;
|
|
120
|
+
interface Goals {
|
|
121
|
+
num: number;
|
|
122
|
+
total: number;
|
|
123
|
+
}
|
|
101
124
|
/** Track your goals for pageviews and events: https://umami.is/docs/api/reports#post-apireportsgoals (TODO UNTESTED) */
|
|
102
|
-
function postGoals(this: API, websiteId: Websites.Website["id"], parameters:
|
|
125
|
+
function postGoals(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
126
|
+
/** Can accept filter parameters */
|
|
127
|
+
filters?: Filters;
|
|
103
128
|
/** Conversion type */
|
|
104
|
-
type:
|
|
129
|
+
type: "path" | "event";
|
|
105
130
|
/** Conversion step value */
|
|
106
131
|
value: string;
|
|
107
|
-
}): Promise<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
132
|
+
}): Promise<Goals>;
|
|
133
|
+
interface Journey {
|
|
134
|
+
items: (string | null)[];
|
|
135
|
+
count: number;
|
|
136
|
+
}
|
|
137
|
+
/** Understand how users nagivate [sic] through your website: https://umami.is/docs/api/reports#post-apireportsjourney */
|
|
138
|
+
function postJourney(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
139
|
+
/** Can accept filter parameters */
|
|
140
|
+
filters?: Filters;
|
|
113
141
|
/** Number of steps from 3 to 7 */
|
|
114
142
|
steps: number;
|
|
115
143
|
/** Starting step URL or event name */
|
|
116
144
|
startStep: string;
|
|
117
145
|
/** Ending step URL or event name */
|
|
118
146
|
endStep?: string;
|
|
119
|
-
}): Promise<
|
|
120
|
-
|
|
121
|
-
count: number;
|
|
122
|
-
}[]>;
|
|
123
|
-
/** Measure your website stickiness by tracking how often users return: https://umami.is/docs/api/reports#post-apireportsretention (TODO UNTESTED) */
|
|
124
|
-
function postRetention(this: API, websiteId: Websites.Website["id"], parameters: ReportType & Filters & Timestamps & {
|
|
125
|
-
/** Timezone (ex. America/Los_Angeles) */
|
|
126
|
-
timezone: string;
|
|
127
|
-
}): Promise<{
|
|
147
|
+
}): Promise<Journey[]>;
|
|
148
|
+
interface Retention {
|
|
128
149
|
date: Date;
|
|
129
150
|
day: number;
|
|
130
151
|
visitors: number;
|
|
131
152
|
returnVisitors: number;
|
|
132
153
|
percentage: number;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
function
|
|
154
|
+
}
|
|
155
|
+
/** Measure your website stickiness by tracking how often users return: https://umami.is/docs/api/reports#post-apireportsretention */
|
|
156
|
+
function postRetention(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
157
|
+
/** Can accept filter parameters */
|
|
158
|
+
filters?: Filters;
|
|
136
159
|
/** Timezone (ex. America/Los_Angeles) */
|
|
137
160
|
timezone: string;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}): Promise<{
|
|
161
|
+
}): Promise<Retention[]>;
|
|
162
|
+
interface Revenue {
|
|
141
163
|
chart: XTY[];
|
|
142
164
|
country: NameValue[];
|
|
143
165
|
total: {
|
|
144
|
-
sum: number;
|
|
166
|
+
sum: number | null;
|
|
145
167
|
count: number;
|
|
146
168
|
unique_count: number;
|
|
147
169
|
average: number;
|
|
148
170
|
};
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
function
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
171
|
+
}
|
|
172
|
+
/** Get currency for given range. Needed for Revenue and optional in Attribution reports: https://umami.is/docs/api/reports#post-apireportsrevenue */
|
|
173
|
+
function postRevenue(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
174
|
+
/** Can accept filter parameters */
|
|
175
|
+
filters?: Filters;
|
|
176
|
+
/** Timezone (ex. America/Los_Angeles) */
|
|
177
|
+
timezone: string;
|
|
178
|
+
/** Currency code (ISO 4217) */
|
|
179
|
+
currency: string;
|
|
180
|
+
}): Promise<Revenue>;
|
|
181
|
+
interface UTMProperty {
|
|
182
|
+
utm: string;
|
|
183
|
+
views: number;
|
|
184
|
+
}
|
|
185
|
+
interface UTM {
|
|
186
|
+
utm_source: UTMProperty[];
|
|
187
|
+
utm_medium: UTMProperty[];
|
|
188
|
+
utm_campaign: UTMProperty[];
|
|
189
|
+
utm_term: UTMProperty[];
|
|
190
|
+
utm_content: UTMProperty[];
|
|
191
|
+
}
|
|
192
|
+
/** Track your campaigns through UTM parameters: https://umami.is/docs/api/reports#post-apireportsutm */
|
|
193
|
+
function postUTM(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
194
|
+
/** Can accept filter parameters */
|
|
195
|
+
filters?: Filters;
|
|
196
|
+
}): Promise<UTM>;
|
|
158
197
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Using reports throught the api: https://umami.is/docs/api/reports */
|
|
1
|
+
/** Using reports throught [sic] the api: https://umami.is/docs/api/reports */
|
|
2
2
|
export var Reports;
|
|
3
3
|
(function (Reports) {
|
|
4
4
|
/** Get all reports by website ID: https://umami.is/docs/api/reports#get-apireports (TODO UNTESTED) */
|
|
@@ -7,64 +7,107 @@ export var Reports;
|
|
|
7
7
|
return response.data;
|
|
8
8
|
}
|
|
9
9
|
Reports.get = get;
|
|
10
|
-
/** Creates a report: https://umami.is/docs/api/reports#post-apireports
|
|
10
|
+
/** Creates a report: https://umami.is/docs/api/reports#post-apireports */
|
|
11
11
|
async function post(websiteId, parameters) {
|
|
12
12
|
return await this.request("post", ["reports"], { websiteId, ...parameters });
|
|
13
13
|
}
|
|
14
14
|
Reports.post = post;
|
|
15
|
-
/** Gets a report by ID: https://umami.is/docs/api/reports#get-apireportsreportid
|
|
15
|
+
/** Gets a report by ID: https://umami.is/docs/api/reports#get-apireportsreportid */
|
|
16
16
|
async function get_REPORTID(reportId) {
|
|
17
17
|
return await this.request("get", ["reports", reportId]);
|
|
18
18
|
}
|
|
19
19
|
Reports.get_REPORTID = get_REPORTID;
|
|
20
|
-
/** Updates a report: https://umami.is/docs/api/reports#post-apireportsreportid
|
|
21
|
-
async function post_REPORTID(reportId,
|
|
22
|
-
return await this.request("get", ["reports", reportId],
|
|
20
|
+
/** Updates a report: https://umami.is/docs/api/reports#post-apireportsreportid */
|
|
21
|
+
async function post_REPORTID(reportId, parameters) {
|
|
22
|
+
return await this.request("get", ["reports", reportId], parameters);
|
|
23
23
|
}
|
|
24
24
|
Reports.post_REPORTID = post_REPORTID;
|
|
25
|
-
/** Deletes a report: https://umami.is/docs/api/reports#delete-apireportsreportid
|
|
25
|
+
/** Deletes a report: https://umami.is/docs/api/reports#delete-apireportsreportid */
|
|
26
26
|
async function delete_REPORTID(reportId) {
|
|
27
27
|
return await this.request("delete", ["reports", reportId]);
|
|
28
28
|
}
|
|
29
29
|
Reports.delete_REPORTID = delete_REPORTID;
|
|
30
|
-
/**
|
|
30
|
+
/** Private function to deal more easily with the post functions that don't involve actual reports */
|
|
31
|
+
async function postNonReports(api, type, websiteId, filters, parameters) {
|
|
32
|
+
const endpoint = type === "goal" ? "goals" : type; // so close yet so far away from clean code
|
|
33
|
+
return await api.request("post", ["reports", endpoint], { websiteId, type, filters: filters ?? {}, parameters });
|
|
34
|
+
}
|
|
35
|
+
/** See how users engage with your marketing and what drives conversions: https://umami.is/docs/api/reports#post-apireportsattribution */
|
|
31
36
|
async function postAttribution(websiteId, parameters) {
|
|
32
|
-
return await this
|
|
37
|
+
return await postNonReports(this, "attribution", websiteId, parameters.filters, {
|
|
38
|
+
startDate: parameters.startDate,
|
|
39
|
+
endDate: parameters.endDate,
|
|
40
|
+
model: parameters.model,
|
|
41
|
+
type: parameters.type,
|
|
42
|
+
step: parameters.step,
|
|
43
|
+
});
|
|
33
44
|
}
|
|
34
45
|
Reports.postAttribution = postAttribution;
|
|
35
|
-
/** Dive deeper into your data by using segments and filters: https://umami.is/docs/api/reports#post-apireportsbreakdown
|
|
46
|
+
/** Dive deeper into your data by using segments and filters: https://umami.is/docs/api/reports#post-apireportsbreakdown */
|
|
36
47
|
async function postBreakdown(websiteId, parameters) {
|
|
37
|
-
return await this
|
|
48
|
+
return await postNonReports(this, "breakdown", websiteId, parameters.filters, {
|
|
49
|
+
startDate: parameters.startDate,
|
|
50
|
+
endDate: parameters.endDate,
|
|
51
|
+
fields: parameters.fields,
|
|
52
|
+
});
|
|
38
53
|
}
|
|
39
54
|
Reports.postBreakdown = postBreakdown;
|
|
40
|
-
/** Understand the conversion and drop-off rate of users: https://umami.is/docs/api/reports#post-apireportsfunnel
|
|
55
|
+
/** Understand the conversion and drop-off rate of users: https://umami.is/docs/api/reports#post-apireportsfunnel */
|
|
41
56
|
async function postFunnel(websiteId, parameters) {
|
|
42
|
-
return await this
|
|
57
|
+
return await postNonReports(this, "funnel", websiteId, parameters.filters, {
|
|
58
|
+
startDate: parameters.startDate,
|
|
59
|
+
endDate: parameters.endDate,
|
|
60
|
+
steps: parameters.steps,
|
|
61
|
+
window: parameters.window,
|
|
62
|
+
});
|
|
43
63
|
}
|
|
44
64
|
Reports.postFunnel = postFunnel;
|
|
45
65
|
/** Track your goals for pageviews and events: https://umami.is/docs/api/reports#post-apireportsgoals (TODO UNTESTED) */
|
|
46
66
|
async function postGoals(websiteId, parameters) {
|
|
47
|
-
return await this
|
|
67
|
+
return await postNonReports(this, "goal", websiteId, parameters.filters, {
|
|
68
|
+
startDate: parameters.startDate,
|
|
69
|
+
endDate: parameters.endDate,
|
|
70
|
+
type: parameters.type,
|
|
71
|
+
value: parameters.value,
|
|
72
|
+
});
|
|
48
73
|
}
|
|
49
74
|
Reports.postGoals = postGoals;
|
|
50
|
-
/** Understand how users nagivate through your website: https://umami.is/docs/api/reports#post-apireportsjourney
|
|
75
|
+
/** Understand how users nagivate [sic] through your website: https://umami.is/docs/api/reports#post-apireportsjourney */
|
|
51
76
|
async function postJourney(websiteId, parameters) {
|
|
52
|
-
return await this
|
|
77
|
+
return await postNonReports(this, "journey", websiteId, parameters.filters, {
|
|
78
|
+
startDate: parameters.startDate,
|
|
79
|
+
endDate: parameters.endDate,
|
|
80
|
+
steps: parameters.steps,
|
|
81
|
+
startStep: parameters.startStep,
|
|
82
|
+
endStep: parameters.endStep,
|
|
83
|
+
});
|
|
53
84
|
}
|
|
54
85
|
Reports.postJourney = postJourney;
|
|
55
|
-
/** Measure your website stickiness by tracking how often users return: https://umami.is/docs/api/reports#post-apireportsretention
|
|
86
|
+
/** Measure your website stickiness by tracking how often users return: https://umami.is/docs/api/reports#post-apireportsretention */
|
|
56
87
|
async function postRetention(websiteId, parameters) {
|
|
57
|
-
return await this
|
|
88
|
+
return await postNonReports(this, "retention", websiteId, parameters.filters, {
|
|
89
|
+
startDate: parameters.startDate,
|
|
90
|
+
endDate: parameters.endDate,
|
|
91
|
+
timezone: parameters.timezone,
|
|
92
|
+
});
|
|
58
93
|
}
|
|
59
94
|
Reports.postRetention = postRetention;
|
|
60
|
-
/** Get currency for given range. Needed for Revenue and optional in Attribution reports: https://umami.is/docs/api/reports#post-apireportsrevenue
|
|
95
|
+
/** Get currency for given range. Needed for Revenue and optional in Attribution reports: https://umami.is/docs/api/reports#post-apireportsrevenue */
|
|
61
96
|
async function postRevenue(websiteId, parameters) {
|
|
62
|
-
return await this
|
|
97
|
+
return await postNonReports(this, "revenue", websiteId, parameters.filters, {
|
|
98
|
+
startDate: parameters.startDate,
|
|
99
|
+
endDate: parameters.endDate,
|
|
100
|
+
timezone: parameters.timezone,
|
|
101
|
+
currency: parameters.currency,
|
|
102
|
+
});
|
|
63
103
|
}
|
|
64
104
|
Reports.postRevenue = postRevenue;
|
|
65
|
-
/** Track your campaigns through UTM parameters: https://umami.is/docs/api/reports#post-apireportsutm
|
|
105
|
+
/** Track your campaigns through UTM parameters: https://umami.is/docs/api/reports#post-apireportsutm */
|
|
66
106
|
async function postUTM(websiteId, parameters) {
|
|
67
|
-
return await this
|
|
107
|
+
return await postNonReports(this, "utm", websiteId, parameters.filters, {
|
|
108
|
+
startDate: parameters.startDate,
|
|
109
|
+
endDate: parameters.endDate,
|
|
110
|
+
});
|
|
68
111
|
}
|
|
69
112
|
Reports.postUTM = postUTM;
|
|
70
113
|
})(Reports || (Reports = {}));
|
|
@@ -17,19 +17,16 @@ export declare namespace Sessions {
|
|
|
17
17
|
visits: number;
|
|
18
18
|
views: number;
|
|
19
19
|
}
|
|
20
|
-
interface
|
|
20
|
+
interface SessionWithHostnameCreatedate extends Session {
|
|
21
21
|
hostname: string;
|
|
22
22
|
createdAt: Date;
|
|
23
23
|
}
|
|
24
|
-
interface SessionWithDistinctidEventsTotaltime extends Session {
|
|
25
|
-
distinctId: string | null;
|
|
26
|
-
events: number;
|
|
27
|
-
totaltime: number;
|
|
28
|
-
}
|
|
29
24
|
/** Gets website session details within a given time range: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessions */
|
|
30
|
-
function get_WEBSITEID_Sessions(this: API, websiteId: Websites.Website["id"], parameters:
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
function get_WEBSITEID_Sessions(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & GenericRequestParameters & {
|
|
26
|
+
/** Can accept filter parameters */
|
|
27
|
+
filters?: Filters;
|
|
28
|
+
}): Promise<SessionWithHostnameCreatedate[]>;
|
|
29
|
+
interface Stats {
|
|
33
30
|
/** Pages hits */
|
|
34
31
|
pageviews: {
|
|
35
32
|
value: number;
|
|
@@ -50,29 +47,35 @@ export declare namespace Sessions {
|
|
|
50
47
|
events: {
|
|
51
48
|
value: number;
|
|
52
49
|
};
|
|
53
|
-
/**
|
|
54
|
-
* Number of visitors who only visit a single page
|
|
55
|
-
* @remarks While featured in the documentation, it doesn't seem to exist
|
|
56
|
-
*/
|
|
50
|
+
/** Number of visitors who only visit a single page */
|
|
57
51
|
bounces?: {
|
|
58
52
|
value: number;
|
|
59
53
|
};
|
|
60
|
-
/**
|
|
61
|
-
* Time spent on the website
|
|
62
|
-
* @remarks While featured in the documentation, it doesn't seem to exist
|
|
63
|
-
*/
|
|
54
|
+
/** Time spent on the website */
|
|
64
55
|
totaltime?: {
|
|
65
56
|
value: number;
|
|
66
57
|
};
|
|
67
|
-
}
|
|
58
|
+
}
|
|
59
|
+
/** Gets summarized website session statistics: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionsstats */
|
|
60
|
+
function get_WEBSITEID_SessionsStats(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
61
|
+
/** Can accept filter parameters */
|
|
62
|
+
filters?: Filters;
|
|
63
|
+
}): Promise<Stats>;
|
|
68
64
|
/** Get collected count of sessions by hour of weekday: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionsweekly */
|
|
69
|
-
function get_WEBSITEID_SessionsWeekly(this: API, websiteId: Websites.Website["id"], parameters:
|
|
65
|
+
function get_WEBSITEID_SessionsWeekly(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
66
|
+
/** Timezone (ex. America/Los_Angeles) */
|
|
70
67
|
timezone: string;
|
|
68
|
+
/** Can accept filter parameters */
|
|
69
|
+
filters?: Filters;
|
|
71
70
|
}): Promise<number[][]>;
|
|
71
|
+
interface SessionWithDistinctidEventsTotaltime extends Session {
|
|
72
|
+
distinctId: string | null;
|
|
73
|
+
events: number;
|
|
74
|
+
totaltime: number;
|
|
75
|
+
}
|
|
72
76
|
/** Gets session details for a individual session: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionssessionid */
|
|
73
77
|
function get_WEBSITEID_Sessions_SESSIONID(this: API, websiteId: Websites.Website["id"], sessionId: Session["id"]): Promise<SessionWithDistinctidEventsTotaltime>;
|
|
74
|
-
|
|
75
|
-
function get_WEBSITEID_Sessions_SESSIONID_Activity(this: API, websiteId: Websites.Website["id"], sessionId: Session["id"], parameters: Timestamps): Promise<{
|
|
78
|
+
interface Activity {
|
|
76
79
|
createdAt: Date;
|
|
77
80
|
urlPath: string;
|
|
78
81
|
urlQuery: string;
|
|
@@ -82,9 +85,10 @@ export declare namespace Sessions {
|
|
|
82
85
|
eventName: Events.Event["eventName"] | null;
|
|
83
86
|
visitId: string;
|
|
84
87
|
hasData: boolean;
|
|
85
|
-
}
|
|
86
|
-
/** Gets session
|
|
87
|
-
function
|
|
88
|
+
}
|
|
89
|
+
/** Gets session activity for a individual session: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionssessionidactivity */
|
|
90
|
+
function get_WEBSITEID_Sessions_SESSIONID_Activity(this: API, websiteId: Websites.Website["id"], sessionId: Session["id"], parameters: Timestamps): Promise<Activity[]>;
|
|
91
|
+
interface Properties {
|
|
88
92
|
websiteId: Websites.Website["id"];
|
|
89
93
|
sessionId: Session["id"];
|
|
90
94
|
dataKey: string;
|
|
@@ -93,17 +97,27 @@ export declare namespace Sessions {
|
|
|
93
97
|
numberValue: number | null;
|
|
94
98
|
dateValue: Date | null;
|
|
95
99
|
createdAt: Date;
|
|
96
|
-
}
|
|
97
|
-
/** Gets session
|
|
98
|
-
function
|
|
100
|
+
}
|
|
101
|
+
/** Gets session properties for a individual session: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionssessionidproperties (TODO Server returns empty array) */
|
|
102
|
+
function get_WEBSITEID_Sessions_SESSIONID_Properties(this: API, websiteId: Websites.Website["id"], sessionId: Session["id"]): Promise<Properties[]>;
|
|
103
|
+
interface DataProperties {
|
|
99
104
|
propertyName: string;
|
|
100
105
|
total: number;
|
|
101
|
-
}
|
|
102
|
-
/** Gets session data counts
|
|
103
|
-
function
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
}
|
|
107
|
+
/** Gets session data counts by property name: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-dataproperties (TODO Server returns empty array) */
|
|
108
|
+
function get_WEBSITEID_SessiondataProperties(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
109
|
+
/** Can accept filter parameters */
|
|
110
|
+
filters?: Filters;
|
|
111
|
+
}): Promise<DataProperties[]>;
|
|
112
|
+
interface DataValues {
|
|
106
113
|
value: string;
|
|
107
114
|
total: number;
|
|
108
|
-
}
|
|
115
|
+
}
|
|
116
|
+
/** Gets session data counts for a given property: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-datavalues (TODO Server returns empty array) */
|
|
117
|
+
function get_WEBSITEID_SessiondataValues(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
118
|
+
/** Property name */
|
|
119
|
+
propertyName: string;
|
|
120
|
+
/** Can accept filter parameters */
|
|
121
|
+
filters?: Filters;
|
|
122
|
+
}): Promise<DataValues[]>;
|
|
109
123
|
}
|
|
@@ -22,9 +22,12 @@ export declare namespace Teams {
|
|
|
22
22
|
user: Users.MinimalUser;
|
|
23
23
|
}
|
|
24
24
|
interface TeamWithMembers extends Team {
|
|
25
|
+
members: TeamMember[];
|
|
26
|
+
}
|
|
27
|
+
interface TeamWithMembersWithUser extends Team {
|
|
25
28
|
members: TeamMemberWithUser[];
|
|
26
29
|
}
|
|
27
|
-
interface TeamWithMembersCount extends
|
|
30
|
+
interface TeamWithMembersCount extends TeamWithMembersWithUser {
|
|
28
31
|
_count: {
|
|
29
32
|
websites: number;
|
|
30
33
|
members: number;
|
|
@@ -14,7 +14,7 @@ export declare namespace Users {
|
|
|
14
14
|
}
|
|
15
15
|
interface MinimalUserWithRoleCreatedAt extends MinimalUserWithRole, MinimalUserWithCreatedAt {
|
|
16
16
|
}
|
|
17
|
-
interface User extends
|
|
17
|
+
interface User extends MinimalUserWithRoleCreatedAt {
|
|
18
18
|
isAdmin: boolean;
|
|
19
19
|
}
|
|
20
20
|
interface DetailedUser extends MinimalUserWithRole, MinimalUserWithCreatedAt {
|
|
@@ -35,16 +35,20 @@ export declare namespace WebsiteStats {
|
|
|
35
35
|
visitors: number;
|
|
36
36
|
}>;
|
|
37
37
|
/** Gets events within a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteideventsseries */
|
|
38
|
-
function get_WEBSITEID_EventsSeries(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & Units &
|
|
38
|
+
function get_WEBSITEID_EventsSeries(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & Units & {
|
|
39
|
+
/** Can accept filter parameters */
|
|
40
|
+
filters?: Filters;
|
|
39
41
|
/** Timezone (ex. America/Los_Angeles) */
|
|
40
42
|
timezone: string;
|
|
41
43
|
}): Promise<XTY[]>;
|
|
42
44
|
/** Gets metrics for a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidmetrics (TODO UNTESTED) */
|
|
43
|
-
function get_WEBSITEID_Metrics(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & Units &
|
|
45
|
+
function get_WEBSITEID_Metrics(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & Units & {
|
|
44
46
|
/** Timezone (ex. America/Los_Angeles) */
|
|
45
47
|
timezone: string;
|
|
46
48
|
/** Metrics type */
|
|
47
49
|
type: MetricsTypes;
|
|
50
|
+
/** Can accept filter parameters */
|
|
51
|
+
filters?: Filters;
|
|
48
52
|
/** (optional, default 500) Number of rows returned */
|
|
49
53
|
limit?: number;
|
|
50
54
|
/** (optional, default 0) Number of ows to skip */
|
|
@@ -61,11 +65,13 @@ export declare namespace WebsiteStats {
|
|
|
61
65
|
name: string;
|
|
62
66
|
})[]>;
|
|
63
67
|
/** Gets pageviews within a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidpageviews (TODO UNTESTED) */
|
|
64
|
-
function get_WEBSITEID_Pageviews(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & Units &
|
|
68
|
+
function get_WEBSITEID_Pageviews(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & Units & {
|
|
65
69
|
/** Timezone (ex. America/Los_Angeles) */
|
|
66
70
|
timezone: string;
|
|
67
71
|
/** Comparison value `prev` | `yoy` */
|
|
68
72
|
compare?: string;
|
|
73
|
+
/** Can accept filter parameters */
|
|
74
|
+
filters?: Filters;
|
|
69
75
|
}): Promise<{
|
|
70
76
|
pageviews: {
|
|
71
77
|
/** Timestamp */
|
|
@@ -81,9 +87,9 @@ export declare namespace WebsiteStats {
|
|
|
81
87
|
}[];
|
|
82
88
|
}>;
|
|
83
89
|
/** Gets summarized website statistics: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidstats (TODO UNTESTED) */
|
|
84
|
-
function get_WEBSITEID_Stats(this: API, websiteId: Websites.Website["id"], parameters: Timestamps &
|
|
85
|
-
/**
|
|
86
|
-
|
|
90
|
+
function get_WEBSITEID_Stats(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
|
|
91
|
+
/** Can accept filter parameters */
|
|
92
|
+
filters?: Filters;
|
|
87
93
|
}): Promise<Stats & {
|
|
88
94
|
comparison: Stats;
|
|
89
95
|
}>;
|
|
@@ -8,9 +8,7 @@ export var WebsiteStats;
|
|
|
8
8
|
WebsiteStats.get_WEBSITEID_Active = get_WEBSITEID_Active;
|
|
9
9
|
/** Gets events within a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteideventsseries */
|
|
10
10
|
async function get_WEBSITEID_EventsSeries(websiteId, parameters) {
|
|
11
|
-
|
|
12
|
-
response.t = new Date(response.t);
|
|
13
|
-
return response;
|
|
11
|
+
return await this.request("get", ["websites", websiteId, "events", "series"], parameters);
|
|
14
12
|
}
|
|
15
13
|
WebsiteStats.get_WEBSITEID_EventsSeries = get_WEBSITEID_EventsSeries;
|
|
16
14
|
/** Gets metrics for a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidmetrics (TODO UNTESTED) */
|
|
@@ -25,10 +23,7 @@ export var WebsiteStats;
|
|
|
25
23
|
WebsiteStats.get_WEBSITEID_MetricsExpanded = get_WEBSITEID_MetricsExpanded;
|
|
26
24
|
/** Gets pageviews within a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidpageviews (TODO UNTESTED) */
|
|
27
25
|
async function get_WEBSITEID_Pageviews(websiteId, parameters) {
|
|
28
|
-
|
|
29
|
-
response.pageviews = response.pageviews.map((v) => { v.x = new Date(v.x); return v; });
|
|
30
|
-
response.sessions = response.sessions.map((s) => { s.x = new Date(s.x); return s; });
|
|
31
|
-
return response;
|
|
26
|
+
return await this.request("get", ["websites", websiteId, "pageviews"], parameters);
|
|
32
27
|
}
|
|
33
28
|
WebsiteStats.get_WEBSITEID_Pageviews = get_WEBSITEID_Pageviews;
|
|
34
29
|
/** Gets summarized website statistics: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidstats (TODO UNTESTED) */
|
|
@@ -19,7 +19,12 @@ export declare namespace Websites {
|
|
|
19
19
|
createUser: Users.MinimalUser;
|
|
20
20
|
}
|
|
21
21
|
interface WebsiteWithUser extends Website {
|
|
22
|
-
|
|
22
|
+
/** @remarks Might be undefined if owned by a team? */
|
|
23
|
+
user?: Users.MinimalUser;
|
|
24
|
+
}
|
|
25
|
+
interface WebsiteWithUserTeam extends Website {
|
|
26
|
+
user: Users.MinimalUser | null;
|
|
27
|
+
team: Teams.TeamWithMembers | null;
|
|
23
28
|
}
|
|
24
29
|
/** Returns all user websites: https://umami.is/docs/api/websites#get-apiwebsites */
|
|
25
30
|
function get(this: API, parameters?: GenericRequestParameters & {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "umami-api-js",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "Package to easily access the
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Package to easily access the Umami api!",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"keywords": [
|
|
24
24
|
"umami",
|
|
25
25
|
"api",
|
|
26
|
+
"analytics",
|
|
26
27
|
"wrapper",
|
|
27
28
|
"api-wrapper"
|
|
28
29
|
],
|
|
@@ -30,8 +31,10 @@
|
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"@types/chai": "^5.2.3",
|
|
32
33
|
"@types/node": "^24.9.2",
|
|
34
|
+
"ajv": "^8.17.1",
|
|
33
35
|
"chai": "^6.2.2",
|
|
34
36
|
"dotenv": "^17.2.3",
|
|
37
|
+
"ts-json-schema-generator": "^2.4.0",
|
|
35
38
|
"typedoc": "^0.28.16",
|
|
36
39
|
"typescript": "^5.9.3"
|
|
37
40
|
}
|