umami-api-js 0.2.0 → 0.2.2

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 CHANGED
@@ -1,5 +1,47 @@
1
- A package to interact with [the API of self-hosted instances of Umami](https://umami.is/docs/api). It is a lightweight alternative to [@umami/api-client](https://github.com/umami-software/api-client), forked from [osu-api-v2-js](https://github.com/TTTaevas/osu-api-v2-js).
1
+ # umami-api-js
2
2
 
3
- If you are reading this from the [package's documentation](https://umami-api-js.taevas.xyz/), please be aware that the documentation is for **umami-api-js@0.2.0**, so make sure your package is up to date! Report any bug on [Codeberg](https://codeberg.org/Taevas/umami-api-js/issues).
3
+ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/V7V4J78L0)
4
4
 
5
- Please note that this package is expected to work with self-hosted instances of **Umami v3.0.3**, and is *not* expected to work with [Umami Cloud](https://umami.is/docs/cloud), the instance of Umami hosted by its creators.
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
+ ```
27
+
28
+ Finally, you will want to create an API object, which you will use for essentially all of your requests. You can do something like that:
29
+
30
+ ```typescript
31
+ // TypeScript
32
+ import * as umami from "umami-api-js"
33
+
34
+ // The API of self-hosted Umami instances authenticates with the credentials of actual accounts
35
+ const api = new umami.API("https://visitors.taevas.xyz/api", "<username>", "<password>") // first argument being the API route of a self-hosted Umami instance
36
+
37
+ // The website_id is featured in multiple places, like where you'd see the analytics script or the settings interface
38
+ async function displayStats(website_id: string) {
39
+ const now = new Date();
40
+ const sevendaysago = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
41
+ const stats = await api.getWebsiteStats(website_id, {startAt: sevendaysago, endAt: now, timezone: "UTC"});
42
+
43
+ console.log(`This website recently had ${stats.visits} visits from ${stats.visitors} visitors!`);
44
+ }
45
+
46
+ displayStats("f196d626-e609-4841-9a80-0dc60f523ed5");
47
+ ```
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
- status_code?: number | undefined;
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
@@ -90,17 +93,29 @@ export declare class APIError extends Error {
90
93
  * @param method The method used for this request (like "get", "post", etc...)
91
94
  * @param endpoint The type of resource that was requested from the server
92
95
  * @param parameters The filters that were used to specify what resource was wanted
93
- * @param status_code The status code that was returned by the server, if there is one
96
+ * @param response The status code and the original body 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], status_code?: number | undefined, original_error?: Error | undefined);
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
- /** If you are already in possession of an {@link API.token} and don't necessarily wish to be able to get a new one, you might want to use this constructor */
103
- constructor(token: API["token"], settings?: Partial<API>);
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;
@@ -258,7 +277,7 @@ export declare class API {
258
277
  data?: {
259
278
  [k: string]: any;
260
279
  };
261
- }): Promise<{
280
+ }, type?: "event" | "identify"): Promise<{
262
281
  cache: string;
263
282
  sessionId: Events.Event["sessionId"];
264
283
  visitId: string;
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ export class APIError extends Error {
19
19
  method;
20
20
  endpoint;
21
21
  parameters;
22
- status_code;
22
+ response;
23
23
  original_error;
24
24
  /**
25
25
  * @param message The reason why things didn't go as expected
@@ -27,17 +27,17 @@ export class APIError extends Error {
27
27
  * @param method The method used for this request (like "get", "post", etc...)
28
28
  * @param endpoint The type of resource that was requested from the server
29
29
  * @param parameters The filters that were used to specify what resource was wanted
30
- * @param status_code The status code that was returned by the server, if there is one
30
+ * @param response The status code and the original body 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, status_code, original_error) {
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.status_code = status_code;
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(username_or_token, password_or_settings, settings) {
50
- settings ??= typeof password_or_settings !== "string" ? password_or_settings : undefined;
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 username_or_token === "string" && typeof password_or_settings === "string") {
60
- this.username = username_or_token;
61
- this.password = password_or_settings;
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
- throw new APIError(error_message, this.server, method, endpoint, parameters, error_code, error_object);
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
  }
@@ -390,8 +423,8 @@ export class API {
390
423
  * To register an event
391
424
  * @group Sending stats
392
425
  */
393
- async sendStats(websiteId, payload) {
394
- return await this.request("post", ["send"], { payload: { website: websiteId, ...payload }, type: "event" });
426
+ async sendStats(websiteId, payload, type = "event") {
427
+ return await this.request("post", ["send"], { payload: { website: websiteId, ...payload }, type });
395
428
  }
396
429
  // ADMIN
397
430
  /** @group Admin endpoints */
@@ -23,7 +23,10 @@ export declare namespace Events {
23
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: Filters & Timestamps & GenericRequestParameters): Promise<Event[]>;
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[]>;
27
30
  interface Data {
28
31
  websiteId: Websites.Website["id"];
29
32
  sessionId?: Sessions.Session["id"];
@@ -43,12 +46,19 @@ export declare namespace Events {
43
46
  eventName: Event["eventName"];
44
47
  propertyName: string;
45
48
  dataType: number;
49
+ propertyValue: string | number;
46
50
  total: number;
47
51
  }
48
- /** Gets event data names, properties, and counts: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-dataevents (TODO Server returns a 500) */
49
- function get_WEBSITEID_EventdataEvents(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps & {
52
+ /**
53
+ * Gets event data names, properties, and counts: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-dataevents
54
+ * @remarks At least on Umami v3.0.3 and likely prior versions, **this will not work if not using the optional event name filter**
55
+ * https://github.com/umami-software/umami/issues/3837
56
+ */
57
+ function get_WEBSITEID_EventdataEvents(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
50
58
  /** Event name filter */
51
59
  event?: Event["eventName"];
60
+ /** Can accept filter parameters */
61
+ filters?: Filters;
52
62
  }): Promise<DataMultiple[]>;
53
63
  interface DataFields {
54
64
  propertyName: string;
@@ -57,24 +67,32 @@ export declare namespace Events {
57
67
  total: number;
58
68
  }
59
69
  /** Gets event data property and value counts within a given time range: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-datafields */
60
- function get_WEBSITEID_EventdataFields(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps): Promise<DataFields[]>;
70
+ function get_WEBSITEID_EventdataFields(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
71
+ /** Can accept filter parameters */
72
+ filters?: Filters;
73
+ }): Promise<DataFields[]>;
61
74
  interface DataProperties {
62
75
  eventName: Event["eventName"] | null;
63
76
  propertyName: string;
64
77
  total: number;
65
78
  }
66
79
  /** Gets event name and property counts for a website: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-dataproperties */
67
- function get_WEBSITEID_EventdataProperties(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps): Promise<DataProperties[]>;
80
+ function get_WEBSITEID_EventdataProperties(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
81
+ /** Can accept filter parameters */
82
+ filters?: Filters;
83
+ }): Promise<DataProperties[]>;
68
84
  interface DataValues {
69
85
  value: string;
70
86
  total: number;
71
87
  }
72
88
  /** Gets event data counts for a given event and property: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-datavalues */
73
- function get_WEBSITEID_EventdataValues(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps & {
89
+ function get_WEBSITEID_EventdataValues(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
74
90
  /** Event name filter */
75
91
  event: Event["eventName"];
76
92
  /** Property name */
77
93
  propertyName: string;
94
+ /** Can accept filter parameters */
95
+ filters?: Filters;
78
96
  }): Promise<DataValues[]>;
79
97
  interface DataStats {
80
98
  events: number;
@@ -82,5 +100,8 @@ export declare namespace Events {
82
100
  records: number;
83
101
  }
84
102
  /** Gets aggregated website events, properties, and records within a given time range: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-datastats */
85
- function get_WEBSITEID_EventdataStats(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps): Promise<DataStats>;
103
+ function get_WEBSITEID_EventdataStats(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
104
+ /** Can accept filter parameters */
105
+ filters?: Filters;
106
+ }): Promise<DataStats>;
86
107
  }
@@ -12,7 +12,11 @@ export var Events;
12
12
  return await this.request("get", ["websites", websiteId, "event-data", eventId]);
13
13
  }
14
14
  Events.get_WEBSITEID_Eventdata_EVENTID = get_WEBSITEID_Eventdata_EVENTID;
15
- /** Gets event data names, properties, and counts: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-dataevents (TODO Server returns a 500) */
15
+ /**
16
+ * Gets event data names, properties, and counts: https://umami.is/docs/api/events#get-apiwebsiteswebsiteidevent-dataevents
17
+ * @remarks At least on Umami v3.0.3 and likely prior versions, **this will not work if not using the optional event name filter**
18
+ * https://github.com/umami-software/umami/issues/3837
19
+ */
16
20
  async function get_WEBSITEID_EventdataEvents(websiteId, parameters) {
17
21
  return await this.request("get", ["websites", websiteId, "event-data", "events"], parameters);
18
22
  }
@@ -1,5 +1,5 @@
1
- import { API, DeletionResult, Filters, GenericRequestParameters, NameValue, Timestamps, Users, Websites, XTY } from "../index.js";
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
- type ReportType = {
19
- type: "attribution" | "breakdown" | "funnel" | "goal" | "journey" | "retention" | "revenue" | "utm";
20
- };
21
- interface UTM {
22
- utm: string;
23
- views: number;
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: ReportType & Omit<GenericRequestParameters, "search">): Promise<Report[]>;
27
- /** Creates a report: https://umami.is/docs/api/reports#post-apireports (TODO UNTESTED) */
28
- function post(this: API, websiteId: Websites.Website["id"], parameters: ReportType & {
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?: any;
39
+ parameters: Report["parameters"];
35
40
  }): Promise<Report>;
36
- /** Gets a report by ID: https://umami.is/docs/api/reports#get-apireportsreportid (TODO UNTESTED) */
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 (TODO UNTESTED) */
39
- function post_REPORTID(this: API, reportId: Report["id"], websiteId: Websites.Website["id"], parameters: ReportType & {
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: Report["name"];
50
+ name?: Report["name"];
42
51
  /** Description of report */
43
52
  description?: Report["description"];
44
53
  /** Parameters for report */
45
- parameters?: any;
54
+ parameters?: Report["parameters"];
46
55
  }): Promise<Report>;
47
- /** Deletes a report: https://umami.is/docs/api/reports#delete-apireportsreportid (TODO UNTESTED) */
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
- /** See how users engage with your marketing and what drives conversions: https://umami.is/docs/api/reports#post-apireportsattribution (TODO UNTESTED) */
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
- /** Dive deeper into your data by using segments and filters: https://umami.is/docs/api/reports#post-apireportsbreakdown (TODO UNTESTED) */
72
- function postBreakdown(this: API, websiteId: Websites.Website["id"], parameters: ReportType & Filters & Timestamps & {
73
- fields: ("path" | "title" | "query" | "referrer" | "browser" | "os" | "device" | "country" | "region" | "city" | "hostname" | "tag" | "event")[];
74
- }): Promise<{
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
- /** Understand the conversion and drop-off rate of users: https://umami.is/docs/api/reports#post-apireportsfunnel (TODO UNTESTED) */
84
- function postFunnel(this: API, websiteId: Websites.Website["id"], parameters: ReportType & Filters & Timestamps & {
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
- type: string;
94
- value: string;
95
- visitors: number;
96
- previous: number;
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: ReportType & Filters & Timestamps & {
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: ("path" | "event")[];
129
+ type: "path" | "event";
105
130
  /** Conversion step value */
106
131
  value: string;
107
- }): Promise<{
108
- num: number;
109
- total: number;
110
- }>;
111
- /** Understand how users nagivate through your website: https://umami.is/docs/api/reports#post-apireportsjourney (TODO UNTESTED) */
112
- function postJourney(this: API, websiteId: Websites.Website["id"], parameters: ReportType & Filters & Timestamps & {
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
- items: (string | null)[];
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
- /** Get currency for given range. Needed for Revenue and optional in Attribution reports: https://umami.is/docs/api/reports#post-apireportsrevenue (TODO UNTESTED) */
135
- function postRevenue(this: API, websiteId: Websites.Website["id"], parameters: ReportType & Filters & Timestamps & {
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
- /** Currency code (ISO 4217) */
139
- currency: string;
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
- /** Track your campaigns through UTM parameters: https://umami.is/docs/api/reports#post-apireportsutm (TODO UNTESTED) */
151
- function postUTM(this: API, websiteId: Websites.Website["id"], parameters: ReportType & Filters & Timestamps): Promise<{
152
- utm_source: UTM[];
153
- utm_medium: UTM[];
154
- utm_campaign: UTM[];
155
- utm_term: UTM[];
156
- utm_content: UTM[];
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 (TODO UNTESTED) */
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 (TODO UNTESTED) */
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 (TODO UNTESTED) */
21
- async function post_REPORTID(reportId, websiteId, parameters) {
22
- return await this.request("get", ["reports", reportId], { websiteId, ...parameters });
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 (TODO UNTESTED) */
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
- /** See how users engage with your marketing and what drives conversions: https://umami.is/docs/api/reports#post-apireportsattribution (TODO UNTESTED) */
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.request("post", ["reports", "attribution"], { websiteId, ...parameters });
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 (TODO UNTESTED) */
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.request("post", ["reports", "breakdown"], { websiteId, ...parameters });
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 (TODO UNTESTED) */
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.request("post", ["reports", "funnel"], { websiteId, ...parameters });
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.request("post", ["reports", "goals"], { websiteId, ...parameters });
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 (TODO UNTESTED) */
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.request("post", ["reports", "journey"], { websiteId, ...parameters });
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 (TODO UNTESTED) */
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.request("post", ["reports", "retention"], { websiteId, ...parameters });
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 (TODO UNTESTED) */
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.request("post", ["reports", "revenue"], { websiteId, ...parameters });
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 (TODO UNTESTED) */
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.request("post", ["reports", "utm"], { websiteId, ...parameters });
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 = {}));
@@ -7,7 +7,7 @@ export declare namespace Sessions {
7
7
  browser: string | null;
8
8
  os: string | null;
9
9
  device: string;
10
- screen: string;
10
+ screen: string | null;
11
11
  language: string | null;
12
12
  country: string;
13
13
  region: string;
@@ -22,7 +22,10 @@ export declare namespace Sessions {
22
22
  createdAt: Date;
23
23
  }
24
24
  /** Gets website session details within a given time range: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessions */
25
- function get_WEBSITEID_Sessions(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps & GenericRequestParameters): Promise<SessionWithHostnameCreatedate[]>;
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[]>;
26
29
  interface Stats {
27
30
  /** Pages hits */
28
31
  pageviews: {
@@ -54,10 +57,16 @@ export declare namespace Sessions {
54
57
  };
55
58
  }
56
59
  /** Gets summarized website session statistics: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionsstats */
57
- function get_WEBSITEID_SessionsStats(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps): Promise<Stats>;
60
+ function get_WEBSITEID_SessionsStats(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
61
+ /** Can accept filter parameters */
62
+ filters?: Filters;
63
+ }): Promise<Stats>;
58
64
  /** Get collected count of sessions by hour of weekday: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionsweekly */
59
- function get_WEBSITEID_SessionsWeekly(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps & {
65
+ function get_WEBSITEID_SessionsWeekly(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
66
+ /** Timezone (ex. America/Los_Angeles) */
60
67
  timezone: string;
68
+ /** Can accept filter parameters */
69
+ filters?: Filters;
61
70
  }): Promise<number[][]>;
62
71
  interface SessionWithDistinctidEventsTotaltime extends Session {
63
72
  distinctId: string | null;
@@ -89,20 +98,26 @@ export declare namespace Sessions {
89
98
  dateValue: Date | null;
90
99
  createdAt: Date;
91
100
  }
92
- /** Gets session properties for a individual session: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionssessionidproperties (TODO Server returns empty array) */
101
+ /** Gets session properties for a individual session: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionssessionidproperties */
93
102
  function get_WEBSITEID_Sessions_SESSIONID_Properties(this: API, websiteId: Websites.Website["id"], sessionId: Session["id"]): Promise<Properties[]>;
94
103
  interface DataProperties {
95
104
  propertyName: string;
96
105
  total: number;
97
106
  }
98
- /** Gets session data counts by property name: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-dataproperties (TODO Server returns empty array) */
99
- function get_WEBSITEID_SessiondataProperties(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps): Promise<DataProperties[]>;
107
+ /** Gets session data counts by property name: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-dataproperties */
108
+ function get_WEBSITEID_SessiondataProperties(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
109
+ /** Can accept filter parameters */
110
+ filters?: Filters;
111
+ }): Promise<DataProperties[]>;
100
112
  interface DataValues {
101
113
  value: string;
102
114
  total: number;
103
115
  }
104
- /** Gets session data counts for a given property: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-datavalues (TODO Server returns empty array) */
105
- function get_WEBSITEID_SessiondataValues(this: API, websiteId: Websites.Website["id"], parameters: Filters & Timestamps & {
116
+ /** Gets session data counts for a given property: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-datavalues */
117
+ function get_WEBSITEID_SessiondataValues(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
118
+ /** Property name */
106
119
  propertyName: string;
120
+ /** Can accept filter parameters */
121
+ filters?: Filters;
107
122
  }): Promise<DataValues[]>;
108
123
  }
@@ -29,17 +29,17 @@ export var Sessions;
29
29
  return await this.request("get", ["websites", websiteId, "sessions", sessionId, "activity"], parameters);
30
30
  }
31
31
  Sessions.get_WEBSITEID_Sessions_SESSIONID_Activity = get_WEBSITEID_Sessions_SESSIONID_Activity;
32
- /** Gets session properties for a individual session: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionssessionidproperties (TODO Server returns empty array) */
32
+ /** Gets session properties for a individual session: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsessionssessionidproperties */
33
33
  async function get_WEBSITEID_Sessions_SESSIONID_Properties(websiteId, sessionId) {
34
34
  return await this.request("get", ["websites", websiteId, "sessions", sessionId, "properties"]);
35
35
  }
36
36
  Sessions.get_WEBSITEID_Sessions_SESSIONID_Properties = get_WEBSITEID_Sessions_SESSIONID_Properties;
37
- /** Gets session data counts by property name: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-dataproperties (TODO Server returns empty array) */
37
+ /** Gets session data counts by property name: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-dataproperties */
38
38
  async function get_WEBSITEID_SessiondataProperties(websiteId, parameters) {
39
39
  return await this.request("get", ["websites", websiteId, "session-data", "properties"], parameters);
40
40
  }
41
41
  Sessions.get_WEBSITEID_SessiondataProperties = get_WEBSITEID_SessiondataProperties;
42
- /** Gets session data counts for a given property: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-datavalues (TODO Server returns empty array) */
42
+ /** Gets session data counts for a given property: https://umami.is/docs/api/sessions#get-apiwebsiteswebsiteidsession-datavalues */
43
43
  async function get_WEBSITEID_SessiondataValues(websiteId, parameters) {
44
44
  return await this.request("get", ["websites", websiteId, "session-data", "values"], parameters);
45
45
  }
@@ -30,43 +30,45 @@ export declare namespace WebsiteStats {
30
30
  totaltime: number;
31
31
  }
32
32
  type MetricsTypes = "path" | "entry" | "exit" | "title" | "query" | "referrer" | "channel" | "domain" | "country" | "region" | "city" | "browser" | "os" | "device" | "language" | "screen" | "event" | "hostname" | "tag";
33
- /** Gets the number of active users on a website: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidactive */
34
- function get_WEBSITEID_Active(this: API, websiteId: Websites.Website["id"]): Promise<{
33
+ interface Active {
34
+ /** Number of unique visitors within the last 5 minutes */
35
35
  visitors: number;
36
- }>;
36
+ }
37
+ /** Gets the number of active users on a website: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidactive */
38
+ function get_WEBSITEID_Active(this: API, websiteId: Websites.Website["id"]): Promise<Active>;
37
39
  /** 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 & Filters & {
40
+ function get_WEBSITEID_EventsSeries(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & Units & {
41
+ /** Can accept filter parameters */
42
+ filters?: Filters;
39
43
  /** Timezone (ex. America/Los_Angeles) */
40
44
  timezone: string;
41
45
  }): Promise<XTY[]>;
42
- /** 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 & Filters & {
46
+ interface Metrics {
47
+ /** Unique value, depending on metric type */
48
+ x: string;
49
+ /** Number of visitors */
50
+ y: number;
51
+ }
52
+ /** Gets metrics for a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidmetrics */
53
+ function get_WEBSITEID_Metrics(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & Units & {
44
54
  /** Timezone (ex. America/Los_Angeles) */
45
55
  timezone: string;
46
56
  /** Metrics type */
47
57
  type: MetricsTypes;
58
+ /** Can accept filter parameters */
59
+ filters?: Filters;
48
60
  /** (optional, default 500) Number of rows returned */
49
61
  limit?: number;
50
62
  /** (optional, default 0) Number of ows to skip */
51
63
  offset?: number;
52
- }): Promise<{
53
- /** Unique value, depending on metric type */
54
- x: string;
55
- /** Number of visitors */
56
- y: number;
57
- }[]>;
58
- /** Gets expanded metrics for a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidmetricsexpanded (TODO UNTESTED) */
59
- function get_WEBSITEID_MetricsExpanded(this: API, ...args: Parameters<typeof get_WEBSITEID_Metrics>): Promise<(Stats & {
64
+ }): Promise<Metrics[]>;
65
+ interface ExpandedMetrics extends Stats {
60
66
  /** Unique value, depending on metric type */
61
67
  name: string;
62
- })[]>;
63
- /** 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 & Filters & {
65
- /** Timezone (ex. America/Los_Angeles) */
66
- timezone: string;
67
- /** Comparison value `prev` | `yoy` */
68
- compare?: string;
69
- }): Promise<{
68
+ }
69
+ /** Gets expanded metrics for a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidmetricsexpanded */
70
+ function get_WEBSITEID_MetricsExpanded(this: API, ...args: Parameters<typeof get_WEBSITEID_Metrics>): Promise<ExpandedMetrics[]>;
71
+ interface Pageviews {
70
72
  pageviews: {
71
73
  /** Timestamp */
72
74
  x: Date;
@@ -79,12 +81,22 @@ export declare namespace WebsiteStats {
79
81
  /** Number of pageviews or visitors */
80
82
  y: number;
81
83
  }[];
82
- }>;
83
- /** 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 & Filters & Units & {
84
+ }
85
+ /** Gets pageviews within a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidpageviews */
86
+ function get_WEBSITEID_Pageviews(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & Units & {
85
87
  /** Timezone (ex. America/Los_Angeles) */
86
88
  timezone: string;
87
- }): Promise<Stats & {
89
+ /** Comparison value `prev` | `yoy` */
90
+ compare?: string;
91
+ /** Can accept filter parameters */
92
+ filters?: Filters;
93
+ }): Promise<Pageviews>;
94
+ interface StatsWithComparison extends Stats {
88
95
  comparison: Stats;
89
- }>;
96
+ }
97
+ /** Gets summarized website statistics: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidstats */
98
+ function get_WEBSITEID_Stats(this: API, websiteId: Websites.Website["id"], parameters: Timestamps & {
99
+ /** Can accept filter parameters */
100
+ filters?: Filters;
101
+ }): Promise<StatsWithComparison>;
90
102
  }
@@ -11,22 +11,22 @@ export var WebsiteStats;
11
11
  return await this.request("get", ["websites", websiteId, "events", "series"], parameters);
12
12
  }
13
13
  WebsiteStats.get_WEBSITEID_EventsSeries = get_WEBSITEID_EventsSeries;
14
- /** Gets metrics for a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidmetrics (TODO UNTESTED) */
14
+ /** Gets metrics for a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidmetrics */
15
15
  async function get_WEBSITEID_Metrics(websiteId, parameters) {
16
16
  return await this.request("get", ["websites", websiteId, "metrics"], parameters);
17
17
  }
18
18
  WebsiteStats.get_WEBSITEID_Metrics = get_WEBSITEID_Metrics;
19
- /** Gets expanded metrics for a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidmetricsexpanded (TODO UNTESTED) */
19
+ /** Gets expanded metrics for a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidmetricsexpanded */
20
20
  async function get_WEBSITEID_MetricsExpanded(...args) {
21
21
  return await this.request("get", ["websites", args[0], "metrics", "expanded"], args[1]);
22
22
  }
23
23
  WebsiteStats.get_WEBSITEID_MetricsExpanded = get_WEBSITEID_MetricsExpanded;
24
- /** Gets pageviews within a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidpageviews (TODO UNTESTED) */
24
+ /** Gets pageviews within a given time range: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidpageviews */
25
25
  async function get_WEBSITEID_Pageviews(websiteId, parameters) {
26
26
  return await this.request("get", ["websites", websiteId, "pageviews"], parameters);
27
27
  }
28
28
  WebsiteStats.get_WEBSITEID_Pageviews = get_WEBSITEID_Pageviews;
29
- /** Gets summarized website statistics: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidstats (TODO UNTESTED) */
29
+ /** Gets summarized website statistics: https://umami.is/docs/api/website-stats#get-apiwebsiteswebsiteidstats */
30
30
  async function get_WEBSITEID_Stats(websiteId, parameters) {
31
31
  return await this.request("get", ["websites", websiteId, "stats"], parameters);
32
32
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "umami-api-js",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Package to easily access the Umami api!",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -9,7 +9,7 @@
9
9
  "prepublish": "npm run build",
10
10
  "build": "tsc",
11
11
  "test": "npm run build && node ./dist/test.js",
12
- "docs": "npx typedoc lib/index.ts"
12
+ "docs": "npx typedoc lib/index.ts --cname umami-api-js.taevas.xyz --plugin ./docs_plugins/visitors.ts"
13
13
  },
14
14
  "engines": {
15
15
  "node": ">=20.0.0"