@iotready/nextjs-components-library 1.0.0-preview1

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.
Files changed (47) hide show
  1. package/components/accounts/AccountMenu.d.ts +9 -0
  2. package/components/accounts/AccountMenu.js +37 -0
  3. package/components/accounts/AccountProfile.d.ts +15 -0
  4. package/components/accounts/AccountProfile.js +153 -0
  5. package/components/accounts/index.d.ts +2 -0
  6. package/components/accounts/index.js +2 -0
  7. package/components/charts/TrendChart.d.ts +17 -0
  8. package/components/charts/TrendChart.js +454 -0
  9. package/components/charts/index.d.ts +1 -0
  10. package/components/charts/index.js +1 -0
  11. package/components/groups/GroupUpdate.d.ts +24 -0
  12. package/components/groups/GroupUpdate.js +134 -0
  13. package/components/groups/GroupsDevices.d.ts +37 -0
  14. package/components/groups/GroupsDevices.js +299 -0
  15. package/components/groups/Map.d.ts +14 -0
  16. package/components/groups/Map.js +17 -0
  17. package/components/groups/index.d.ts +3 -0
  18. package/components/groups/index.js +3 -0
  19. package/components/index.d.ts +5 -0
  20. package/components/index.js +5 -0
  21. package/components/settings/DynamicMenu.d.ts +17 -0
  22. package/components/settings/DynamicMenu.js +42 -0
  23. package/components/settings/index.d.ts +1 -0
  24. package/components/settings/index.js +1 -0
  25. package/components/users/UserUpdate.d.ts +11 -0
  26. package/components/users/UserUpdate.js +26 -0
  27. package/components/users/UsersDataGrid.d.ts +23 -0
  28. package/components/users/UsersDataGrid.js +76 -0
  29. package/components/users/index.d.ts +2 -0
  30. package/components/users/index.js +2 -0
  31. package/index.d.ts +3 -0
  32. package/index.js +4 -0
  33. package/package.json +45 -0
  34. package/server-actions/groups.d.ts +22 -0
  35. package/server-actions/groups.js +109 -0
  36. package/server-actions/index.d.ts +4 -0
  37. package/server-actions/index.js +5 -0
  38. package/server-actions/influx.d.ts +13 -0
  39. package/server-actions/influx.js +145 -0
  40. package/server-actions/logto.d.ts +39 -0
  41. package/server-actions/logto.js +194 -0
  42. package/server-actions/trackle.d.ts +35 -0
  43. package/server-actions/trackle.js +158 -0
  44. package/types/index.d.ts +1 -0
  45. package/types/index.js +1 -0
  46. package/types/user.d.ts +12 -0
  47. package/types/user.js +1 -0
@@ -0,0 +1,22 @@
1
+ export type FirebaseConfig = {
2
+ apiKey: string;
3
+ authDomain: string;
4
+ projectId: string;
5
+ storageBucket: string;
6
+ messagingSenderId: string;
7
+ appId: string;
8
+ };
9
+ export declare const getGroups: (firebaseConfig: FirebaseConfig, productID: number, userID?: string) => Promise<{
10
+ id: string;
11
+ }[]>;
12
+ export declare const getGroupById: (firebaseConfig: FirebaseConfig, id: string) => Promise<{
13
+ id: string;
14
+ }>;
15
+ export declare const createGroup: (firebaseConfig: FirebaseConfig, group: any) => Promise<string>;
16
+ export declare const updateGroup: (firebaseConfig: FirebaseConfig, id: string, group: any) => Promise<any>;
17
+ export declare const deleteGroup: (firebaseConfig: FirebaseConfig, id: string) => Promise<void>;
18
+ export declare const getUsersGroup: (firebaseConfig: FirebaseConfig, groupID: string) => Promise<{
19
+ id: string;
20
+ }[]>;
21
+ export declare const addUsersGroup: (firebaseConfig: FirebaseConfig, groupID: string, userName: string, userID: string) => Promise<string>;
22
+ export declare const removeUserGroup: (firebaseConfig: FirebaseConfig, groupID: string, userID: string) => Promise<string | undefined>;
@@ -0,0 +1,109 @@
1
+ "use server";
2
+ import { initializeApp } from "firebase/app";
3
+ import { getDoc, doc, updateDoc, deleteDoc, collection, query, orderBy, getDocs, where, addDoc } from "@firebase/firestore";
4
+ import { getFirestore } from "@firebase/firestore";
5
+ export const getGroups = async (firebaseConfig, productID, userID) => {
6
+ // Initialize Firebase
7
+ const app = initializeApp(firebaseConfig);
8
+ const db = getFirestore(app);
9
+ const groupsQuery = query(collection(db, "groups"), where("productID", "==", productID), orderBy("created", "desc"));
10
+ let groupIds = null;
11
+ if (userID) {
12
+ const usersGroupQuery = query(collection(db, "userGroups"), where("user.userId", "==", userID));
13
+ const userSnapshot = await getDocs(usersGroupQuery);
14
+ groupIds = userSnapshot.docs.map((ug) => ug.data().groupId);
15
+ }
16
+ const groupsSnapshot = await getDocs(groupsQuery);
17
+ if (groupIds) {
18
+ return groupsSnapshot.docs
19
+ .filter((entry) => groupIds?.includes(entry.id))
20
+ .map((doc) => ({
21
+ id: doc.id,
22
+ ...doc.data()
23
+ }));
24
+ }
25
+ return groupsSnapshot.docs.map((doc) => ({
26
+ id: doc.id,
27
+ ...doc.data()
28
+ }));
29
+ };
30
+ export const getGroupById = async (firebaseConfig, id) => {
31
+ const app = initializeApp(firebaseConfig);
32
+ const db = getFirestore(app);
33
+ const groupSnapshot = await getDoc(doc(db, "groups", id));
34
+ return {
35
+ id: groupSnapshot.id,
36
+ ...groupSnapshot.data()
37
+ };
38
+ };
39
+ export const createGroup = async (firebaseConfig, group) => {
40
+ const created = new Date().toISOString();
41
+ const newGroup = {
42
+ ...group,
43
+ created
44
+ };
45
+ const app = initializeApp(firebaseConfig);
46
+ const db = getFirestore(app);
47
+ const docRef = await addDoc(collection(db, "groups"), newGroup);
48
+ return docRef.id;
49
+ };
50
+ export const updateGroup = async (firebaseConfig, id, group) => {
51
+ const app = initializeApp(firebaseConfig);
52
+ const db = getFirestore(app);
53
+ const groupRef = doc(db, "groups", id);
54
+ await updateDoc(groupRef, group);
55
+ return group;
56
+ };
57
+ export const deleteGroup = async (firebaseConfig, id) => {
58
+ const app = initializeApp(firebaseConfig);
59
+ const db = getFirestore(app);
60
+ const usersGroupQuery = query(collection(db, "userGroups"), where("groupId", "==", id));
61
+ const groupsSnapshot = await getDocs(usersGroupQuery);
62
+ groupsSnapshot.docs.forEach(async (ug) => {
63
+ const userGroupRef = doc(db, "userGroups", ug.id);
64
+ await deleteDoc(userGroupRef);
65
+ });
66
+ const groupRef = doc(db, "groups", id);
67
+ await deleteDoc(groupRef);
68
+ };
69
+ // USERS GROUPS
70
+ export const getUsersGroup = async (firebaseConfig, groupID) => {
71
+ // Initialize Firebase
72
+ const app = initializeApp(firebaseConfig);
73
+ const db = getFirestore(app);
74
+ const usersGroupQuery = query(collection(db, "userGroups"), where("groupId", "==", groupID));
75
+ const groupsSnapshot = await getDocs(usersGroupQuery);
76
+ return groupsSnapshot.docs.map((doc) => ({
77
+ id: doc.id,
78
+ ...doc.data()
79
+ }));
80
+ };
81
+ export const addUsersGroup = async (firebaseConfig, groupID, userName, userID) => {
82
+ // Initialize Firebase
83
+ const app = initializeApp(firebaseConfig);
84
+ const db = getFirestore(app);
85
+ const created = new Date().toISOString();
86
+ const newUserGroup = {
87
+ user: {
88
+ fullName: userName,
89
+ userId: userID
90
+ },
91
+ groupId: groupID,
92
+ created
93
+ };
94
+ const docRef = await addDoc(collection(db, "userGroups"), newUserGroup);
95
+ return docRef.id;
96
+ };
97
+ export const removeUserGroup = async (firebaseConfig, groupID, userID) => {
98
+ // Initialize Firebase
99
+ const app = initializeApp(firebaseConfig);
100
+ const db = getFirestore(app);
101
+ const usersGroupQuery = query(collection(db, "userGroups"), where("groupId", "==", groupID), where("user.userId", "==", userID));
102
+ const groupsSnapshot = await getDocs(usersGroupQuery);
103
+ if (groupsSnapshot.docs[0]) {
104
+ const userGroupId = groupsSnapshot.docs[0].id;
105
+ const groupRef = doc(db, "userGroups", userGroupId);
106
+ await deleteDoc(groupRef);
107
+ return userGroupId;
108
+ }
109
+ };
@@ -0,0 +1,4 @@
1
+ export * from "./groups";
2
+ export * from "./influx";
3
+ export * from "./logto";
4
+ export * from "./trackle";
@@ -0,0 +1,5 @@
1
+ // Server Actions
2
+ export * from "./groups";
3
+ export * from "./influx";
4
+ export * from "./logto";
5
+ export * from "./trackle";
@@ -0,0 +1,13 @@
1
+ export type InfluxConfig = {
2
+ url: string;
3
+ accessToken: string;
4
+ bucket: string;
5
+ orgId: string;
6
+ measurement: string;
7
+ dbName: string;
8
+ username: string;
9
+ password: string;
10
+ };
11
+ export declare function getInfluxDataV1(influxConfig: InfluxConfig, field: string, timeStart: number, timeEnd: number, deviceID: string, timeGroup: string, raw: boolean): Promise<any>;
12
+ export declare function getManyMeasuresV1(influxConfig: InfluxConfig, fields: string[], limit: number, offset: number, sort: any, deviceID: string, timeStart?: number, timeEnd?: number): Promise<any>;
13
+ export declare function getFirstTimestamp(influxConfig: InfluxConfig, deviceID: string): Promise<any>;
@@ -0,0 +1,145 @@
1
+ "use server";
2
+ import moment from "moment";
3
+ /* export async function getInfluxDataV2(influxConfig: InfluxConfig, field: string, timeStart: string, timeEnd: string, deviceID: string, timeGroup: string, raw: boolean): Promise<Point[]> {
4
+ const query = `
5
+ from(bucket: "${influxConfig.bucket}")
6
+ |> range(start: ${timeStart}, stop: ${timeEnd})
7
+ |> filter(fn: (r) => r._measurement == "${influxConfig.measurement}")
8
+ |> filter(fn: (r) => r["_field"] == "${field}")
9
+ |> filter(fn: (r) => r["deviceid"] == "${deviceID}")
10
+ |> aggregateWindow(every: ${timeGroup}m, fn: last, createEmpty: false)
11
+ |> yield(name: "last")
12
+ `;
13
+
14
+ const response = await fetch(`${influxConfig.url}/api/v2/query?org=${influxConfig.orgId}`, {
15
+ method: 'POST',
16
+ headers: {
17
+ 'Content-Type': 'application/json',
18
+ 'Authorization': `Token ${influxConfig.accessToken}`,
19
+ 'Accept': 'application/csv'
20
+ },
21
+ body: JSON.stringify({
22
+ query: query
23
+ })
24
+ });
25
+ if (!response.ok) {
26
+ throw new Error(`Failed to fetch data from InfluxDB: ${response.statusText}`);
27
+ }
28
+ const data = await response.text();
29
+ return data.split('\n').map(line => {
30
+ const row = line.split(',');
31
+ const timestamp = row[5];
32
+ const value = parseFloat(row[6]);
33
+ console.log(timestamp, value);
34
+ if (isNaN(value)) {
35
+ return null;
36
+ }
37
+ return { x: new Date(timestamp).getTime(), y: value };
38
+ }).filter(point => point !== null);
39
+ }*/ // NOT WORKING, NEED TO FIX
40
+ export async function getInfluxDataV1(influxConfig, field, timeStart, timeEnd, deviceID, timeGroup, raw) {
41
+ let query;
42
+ if (raw) {
43
+ query = `SELECT ("value") FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' AND "valueName" = '${field}' AND time >= '${moment
44
+ .unix(timeStart)
45
+ .toISOString()}' AND time <= '${moment.unix(timeEnd).toISOString()}'`;
46
+ }
47
+ else {
48
+ query = `SELECT last("value") FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' AND "valueName" = '${field}' AND time >= '${moment
49
+ .unix(timeStart)
50
+ .toISOString()}' AND time <= '${moment
51
+ .unix(timeEnd)
52
+ .toISOString()}' GROUP BY time(${timeGroup}) fill(null)`;
53
+ }
54
+ const response = await fetch(encodeURI(`${influxConfig.url}/query?db=${influxConfig.dbName}&epoch=s&q=${query}`), {
55
+ headers: {
56
+ Authorization: `Basic ${btoa(`${influxConfig.username}:${influxConfig.password}`)}`
57
+ }
58
+ });
59
+ if (!response.ok) {
60
+ console.log(response);
61
+ throw new Error(`Failed to fetch data from InfluxDB: ${response.statusText}`);
62
+ }
63
+ const data = await response.json();
64
+ // Ensure the name is manually set to the field
65
+ if (!data.results[0].series) {
66
+ // Set default value with null time and null value
67
+ data.results[0].series = [
68
+ {
69
+ name: field, // Manually set the series name as the field
70
+ columns: ["time", "value"],
71
+ values: [] // Set null point for time and value
72
+ }
73
+ ];
74
+ }
75
+ else {
76
+ // Always override the name to be the field
77
+ data.results[0].series.forEach((series) => {
78
+ series.name = field; // Force the series name to be the field name
79
+ });
80
+ }
81
+ return data;
82
+ }
83
+ export async function getManyMeasuresV1(influxConfig, fields, limit, offset, sort, deviceID, timeStart, timeEnd) {
84
+ if (fields.length > 0) {
85
+ const conditions = fields
86
+ .map((field) => `"valueName" = '${field}'`)
87
+ .join(" OR ");
88
+ let queryCount = `SELECT count(*) FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' AND (${conditions})`;
89
+ let queryPagination = `SELECT "valueName", "value" FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' AND (${conditions})`;
90
+ if (timeStart) {
91
+ queryCount += ` AND time >= '${moment.unix(timeStart).toISOString()}'`;
92
+ queryPagination += ` AND time >= '${moment
93
+ .unix(timeStart)
94
+ .toISOString()}'`;
95
+ }
96
+ if (timeEnd) {
97
+ queryCount += ` AND time <= '${moment.unix(timeEnd).toISOString()}'`;
98
+ queryPagination += ` AND time <= '${moment.unix(timeEnd).toISOString()}'`;
99
+ }
100
+ if (sort && sort.field === "time") {
101
+ queryPagination = `${queryPagination} ORDER BY "${sort.field}" ${sort.sort}`;
102
+ }
103
+ queryPagination = `${queryPagination} LIMIT ${limit} OFFSET ${offset}`;
104
+ const responses = await Promise.all([
105
+ fetch(encodeURI(`${influxConfig.url}/query?db=${influxConfig.dbName}&epoch=s&q=${queryPagination}`), {
106
+ headers: {
107
+ Authorization: `Basic ${btoa(`${influxConfig.username}:${influxConfig.password}`)}`
108
+ }
109
+ }),
110
+ fetch(encodeURI(`${influxConfig.url}/query?db=${influxConfig.dbName}&epoch=s&q=${queryCount}`), {
111
+ headers: {
112
+ Authorization: `Basic ${btoa(`${influxConfig.username}:${influxConfig.password}`)}`
113
+ }
114
+ })
115
+ ]);
116
+ if (!responses[0].ok) {
117
+ throw new Error(`Failed to fetch data from InfluxDB: ${responses[0].statusText}`);
118
+ }
119
+ const data = await responses[0].json();
120
+ const count = await responses[1].json();
121
+ return { data, count };
122
+ }
123
+ else {
124
+ return null;
125
+ }
126
+ }
127
+ export async function getFirstTimestamp(influxConfig, deviceID) {
128
+ // Query per ottenere il primo timestamp e il valore ordinato per "time" in modo crescente
129
+ const query = `SELECT "time", "value" FROM "${influxConfig.measurement}" WHERE "deviceid" = '${deviceID}' ORDER BY time ASC LIMIT 1`;
130
+ const response = await fetch(encodeURI(`${influxConfig.url}/query?db=${influxConfig.dbName}&epoch=s&q=${query}`), {
131
+ headers: {
132
+ Authorization: `Basic ${btoa(`${influxConfig.username}:${influxConfig.password}`)}`
133
+ }
134
+ });
135
+ if (!response.ok) {
136
+ throw new Error(`Failed to fetch data from InfluxDB: ${response.statusText}`);
137
+ }
138
+ const data = await response.json();
139
+ // Verifica che ci siano risultati nella risposta
140
+ if (data?.results[0]?.series && data?.results[0]?.series[0]?.values[0]?.[0]) {
141
+ // Ritorna il primo timestamp
142
+ return data.results[0].series[0].values[0][0];
143
+ }
144
+ return null; // Se non ci sono record, ritorna null
145
+ }
@@ -0,0 +1,39 @@
1
+ export type LogtoConfig = {
2
+ endpoint: string;
3
+ appId: string;
4
+ appSecret: string;
5
+ baseUrl: string;
6
+ cookieSecret: string;
7
+ cookieSecure: boolean;
8
+ scopes: string[];
9
+ username: string;
10
+ password: string;
11
+ resource: string;
12
+ };
13
+ export declare const LogtoManagementClient: (logtoConfig: LogtoConfig) => Promise<{
14
+ getUser: (uid: string) => Promise<any>;
15
+ getUserList: (page: number, pageSize: number, filter?: {
16
+ field?: string;
17
+ operator?: string;
18
+ value: string;
19
+ }) => Promise<{
20
+ data: any;
21
+ rowCount: number;
22
+ }>;
23
+ searchUsers: (value: string) => Promise<any>;
24
+ updateUser: (uid: string, info: {
25
+ name: string;
26
+ }) => Promise<void>;
27
+ updateCustomData: (uid: string, info: {
28
+ role: string;
29
+ uid?: string;
30
+ }) => Promise<void>;
31
+ updateProfileData: (uid: string, info: {
32
+ givenName?: string;
33
+ familyName?: string;
34
+ }) => Promise<void>;
35
+ updatePassword: (uid: string, password: string) => Promise<void>;
36
+ unlinkConnectedAccount: (uid: string, target: string) => Promise<void>;
37
+ deleteUser: (uid: string) => Promise<void>;
38
+ getUserByEmailAndPassword: (email: string, password: string) => Promise<any>;
39
+ }>;
@@ -0,0 +1,194 @@
1
+ "use server";
2
+ const getManagementToken = async (logtoConfig) => {
3
+ if (logtoConfig.username === "" || logtoConfig.password === "") {
4
+ throw new Error("no valid admin credentials");
5
+ }
6
+ const res = await fetch(`${logtoConfig.endpoint}oidc/token`, {
7
+ method: "POST",
8
+ body: new URLSearchParams({
9
+ grant_type: "client_credentials",
10
+ resource: logtoConfig.resource,
11
+ scope: "all"
12
+ }),
13
+ headers: {
14
+ "Content-Type": "application/x-www-form-urlencoded",
15
+ Authorization: `Basic ${btoa(`${logtoConfig.username}:${logtoConfig.password}`)}`
16
+ }
17
+ });
18
+ if (!res.ok) {
19
+ throw new Error("Failed to fetch management token");
20
+ }
21
+ const data = await res.json();
22
+ return data.access_token;
23
+ };
24
+ export const LogtoManagementClient = async (logtoConfig) => ({
25
+ getUser: async (uid) => {
26
+ const access_token = await getManagementToken(logtoConfig);
27
+ const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}?includeSsoIdentities=1`, {
28
+ method: "GET",
29
+ headers: {
30
+ Authorization: `Bearer ${access_token}`
31
+ }
32
+ });
33
+ if (!res.ok) {
34
+ throw new Error(`Failed to get user with ID ${uid}`);
35
+ }
36
+ return await res.json();
37
+ },
38
+ getUserList: async (page, pageSize, filter) => {
39
+ const access_token = await getManagementToken(logtoConfig);
40
+ const search = filter && filter.value
41
+ ? `&search${filter.field ? `.${filter.field}` : ""}=${filter.operator && filter.operator === "equals"
42
+ ? filter.value
43
+ : `%${filter.value}%`}`
44
+ : "";
45
+ const res = await fetch(`${logtoConfig.endpoint}api/users?page=${page}&page_size=${pageSize}${search}`, {
46
+ method: "GET",
47
+ headers: {
48
+ Authorization: `Bearer ${access_token}`
49
+ }
50
+ });
51
+ if (!res.ok) {
52
+ throw new Error("Failed to fetch user list");
53
+ }
54
+ const data = await res.json();
55
+ const rowCount = res.headers.get("total-number") || "0";
56
+ return {
57
+ data,
58
+ rowCount: parseInt(rowCount, 10)
59
+ };
60
+ },
61
+ searchUsers: async (value) => {
62
+ const access_token = await getManagementToken(logtoConfig);
63
+ const res = await fetch(`${logtoConfig.endpoint}api/users?search=%25${encodeURIComponent(value)}%25`, {
64
+ method: "GET",
65
+ headers: {
66
+ Authorization: `Bearer ${access_token}`
67
+ }
68
+ });
69
+ if (!res.ok) {
70
+ throw new Error("Failed to search users");
71
+ }
72
+ return await res.json();
73
+ },
74
+ updateUser: async (uid, info) => {
75
+ const access_token = await getManagementToken(logtoConfig);
76
+ const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}`, {
77
+ method: "PATCH",
78
+ headers: {
79
+ "Content-Type": "application/json",
80
+ Authorization: `Bearer ${access_token}`
81
+ },
82
+ body: JSON.stringify(info)
83
+ });
84
+ if (!res.ok) {
85
+ throw new Error(`Failed to update user with ID ${uid}`);
86
+ }
87
+ },
88
+ updateCustomData: async (uid, info) => {
89
+ const newInfo = {
90
+ role: info.role,
91
+ uid: info.uid || undefined
92
+ };
93
+ const access_token = await getManagementToken(logtoConfig);
94
+ const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}/custom-data`, {
95
+ method: "PATCH",
96
+ headers: {
97
+ "Content-Type": "application/json",
98
+ Authorization: `Bearer ${access_token}`
99
+ },
100
+ body: JSON.stringify({ customData: newInfo })
101
+ });
102
+ if (!res.ok) {
103
+ throw new Error(`Failed to update custom data for user with ID ${uid}`);
104
+ }
105
+ },
106
+ updateProfileData: async (uid, info) => {
107
+ const newInfo = {
108
+ givenName: info.givenName || undefined,
109
+ familyName: info.familyName || undefined
110
+ };
111
+ const access_token = await getManagementToken(logtoConfig);
112
+ const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}/profile`, {
113
+ method: "PATCH",
114
+ headers: {
115
+ "Content-Type": "application/json",
116
+ Authorization: `Bearer ${access_token}`
117
+ },
118
+ body: JSON.stringify({ profile: newInfo })
119
+ });
120
+ if (!res.ok) {
121
+ throw new Error(`Failed to update custom data for user with ID ${uid}`);
122
+ }
123
+ },
124
+ updatePassword: async (uid, password) => {
125
+ const access_token = await getManagementToken(logtoConfig);
126
+ const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}/password`, {
127
+ method: "PATCH",
128
+ headers: {
129
+ "Content-Type": "application/json",
130
+ Authorization: `Bearer ${access_token}`
131
+ },
132
+ body: JSON.stringify({ password })
133
+ });
134
+ if (!res.ok) {
135
+ throw new Error(`Failed to update password for user with ID ${uid}`);
136
+ }
137
+ },
138
+ unlinkConnectedAccount: async (uid, target) => {
139
+ const access_token = await getManagementToken(logtoConfig);
140
+ const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}/identities/${target}`, {
141
+ method: "DELETE",
142
+ headers: {
143
+ Authorization: `Bearer ${access_token}`
144
+ }
145
+ });
146
+ if (!res.ok) {
147
+ throw new Error(`Failed to unlink connected account '${target}' for user with ID ${uid}`);
148
+ }
149
+ },
150
+ deleteUser: async (uid) => {
151
+ const access_token = await getManagementToken(logtoConfig);
152
+ const res = await fetch(`${logtoConfig.endpoint}api/users/${uid}`, {
153
+ method: "DELETE",
154
+ headers: {
155
+ Authorization: `Bearer ${access_token}`
156
+ }
157
+ });
158
+ if (!res.ok) {
159
+ throw new Error(`Failed to delete user with ID ${uid}`);
160
+ }
161
+ },
162
+ getUserByEmailAndPassword: async (email, password) => {
163
+ const access_token = await getManagementToken(logtoConfig);
164
+ const res = await fetch(`${logtoConfig.endpoint}api/users?search.primaryEmail=${encodeURIComponent(email)}`, {
165
+ method: "GET",
166
+ headers: {
167
+ Authorization: `Bearer ${access_token}`
168
+ }
169
+ });
170
+ if (!res.ok) {
171
+ throw new Error("Failed to fetch user by email");
172
+ }
173
+ const data = await res.json();
174
+ if (data && data[0]) {
175
+ const user = data[0];
176
+ // verify password
177
+ const verifyRes = await fetch(`${logtoConfig.endpoint}/api/users/${user.id}/password/verify`, {
178
+ method: "POST",
179
+ headers: {
180
+ "Content-Type": "application/json",
181
+ Authorization: `Bearer ${access_token}`
182
+ },
183
+ body: JSON.stringify({ password })
184
+ });
185
+ if (verifyRes.status !== 204) {
186
+ throw new Error("no user found by email: password mismatch");
187
+ }
188
+ return user;
189
+ }
190
+ else {
191
+ throw new Error("no user found by email: user not found");
192
+ }
193
+ }
194
+ });
@@ -0,0 +1,35 @@
1
+ export type TrackleConfig = {
2
+ apiUrl: string;
3
+ createCustomerUrl: string;
4
+ clientId: string;
5
+ clientSecret: string;
6
+ tokenUrl: string;
7
+ cookieName: string;
8
+ cookieSecure: boolean;
9
+ apiTimeout: number;
10
+ };
11
+ export declare function logOut(trackleConfig: TrackleConfig): Promise<void>;
12
+ export declare function createCustomer(trackleConfig: TrackleConfig, uid: string): Promise<{
13
+ organization: string;
14
+ uid: string;
15
+ }>;
16
+ export declare function getDevices(trackleConfig: TrackleConfig, productId?: number, uid?: string, group?: string, selected?: string): Promise<{
17
+ devices: any[];
18
+ }>;
19
+ export declare function getDevice(trackleConfig: TrackleConfig, id: string, productId?: number, uid?: string): Promise<{
20
+ id: string;
21
+ state: object;
22
+ metadata: object;
23
+ }>;
24
+ export declare function updateDevice(trackleConfig: TrackleConfig, id: string, body: any, productId?: number, uid?: string): Promise<unknown>;
25
+ export declare function get(trackleConfig: TrackleConfig, id: string, endpoint: string, params?: string, productId?: number, uid?: string): Promise<{
26
+ result: any;
27
+ }>;
28
+ export declare function post(trackleConfig: TrackleConfig, id: string, endpoint: string, args: string, productId?: number, uid?: string): Promise<{
29
+ return_value: number;
30
+ }>;
31
+ export declare function put(trackleConfig: TrackleConfig, id: string, endpoint: string, value: any, productId?: number, uid?: string): Promise<{
32
+ return_value: number;
33
+ }>;
34
+ export declare function addDevicesToGroup(trackleConfig: TrackleConfig, productId: number, uid: string, group: string, devicesToPatch: any[]): Promise<string[]>;
35
+ export declare function removeDevicesFromGroup(trackleConfig: TrackleConfig, productId: number, uid: string, group: string, devicesToPatch: any[]): Promise<string[]>;