@adventurelabs/scout-core 1.5.4 → 2.0.0

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 (219) hide show
  1. package/README.md +47 -0
  2. package/dist/api_keys/actions.d.ts +0 -1
  3. package/dist/api_keys/actions.js +0 -14
  4. package/dist/client/index.d.ts +75 -0
  5. package/dist/client/index.js +82 -0
  6. package/dist/constants/index.d.ts +1 -0
  7. package/dist/constants/index.js +1 -0
  8. package/dist/helpers/analysis_usage/jobs_server.d.ts +25 -0
  9. package/dist/helpers/analysis_usage/jobs_server.js +10 -0
  10. package/dist/helpers/analysis_usage/tasks_server.d.ts +63 -0
  11. package/dist/helpers/analysis_usage/tasks_server.js +14 -0
  12. package/dist/helpers/artifacts.d.ts +0 -1
  13. package/dist/helpers/artifacts.js +10 -147
  14. package/dist/helpers/artifacts.queries.d.ts +26 -0
  15. package/dist/helpers/{artifacts.internal.js → artifacts.queries.js} +24 -41
  16. package/dist/helpers/auth.d.ts +1 -1
  17. package/dist/helpers/auth.js +2 -3
  18. package/dist/helpers/auth_server.d.ts +2 -0
  19. package/dist/helpers/auth_server.js +10 -0
  20. package/dist/helpers/certificates_server.d.ts +101 -0
  21. package/dist/helpers/certificates_server.js +42 -0
  22. package/dist/helpers/chat.d.ts +1 -2
  23. package/dist/helpers/chat.js +3 -38
  24. package/dist/helpers/chat.queries.d.ts +13 -0
  25. package/dist/helpers/chat.queries.js +39 -0
  26. package/dist/helpers/client_abilities_jwt_keys.js +0 -1
  27. package/dist/helpers/client_abilities_token_server.d.ts +1 -0
  28. package/dist/helpers/client_abilities_token_server.js +5 -2
  29. package/dist/helpers/connectivity.d.ts +1 -5
  30. package/dist/helpers/connectivity.js +7 -140
  31. package/dist/helpers/connectivity.queries.d.ts +18 -0
  32. package/dist/helpers/connectivity.queries.js +121 -0
  33. package/dist/helpers/contacts_server.d.ts +63 -0
  34. package/dist/helpers/contacts_server.js +18 -0
  35. package/dist/helpers/deviceTransfer.js +2 -11
  36. package/dist/helpers/deviceTransfer.queries.d.ts +4 -0
  37. package/dist/helpers/deviceTransfer.queries.js +11 -0
  38. package/dist/helpers/devices.js +4 -61
  39. package/dist/helpers/devices.queries.d.ts +4 -1
  40. package/dist/helpers/devices.queries.js +52 -0
  41. package/dist/helpers/document_templates.js +6 -52
  42. package/dist/helpers/document_templates.queries.d.ts +9 -0
  43. package/dist/helpers/document_templates.queries.js +56 -0
  44. package/dist/helpers/documents_server.d.ts +226 -0
  45. package/dist/helpers/documents_server.js +38 -0
  46. package/dist/helpers/email.d.ts +0 -6
  47. package/dist/helpers/email.js +1 -19
  48. package/dist/helpers/embeddings.d.ts +0 -5
  49. package/dist/helpers/embeddings.js +2 -19
  50. package/dist/helpers/embeddings.queries.d.ts +7 -0
  51. package/dist/helpers/{embeddings.internal.js → embeddings.queries.js} +2 -2
  52. package/dist/helpers/eventUtils.d.ts +3 -12
  53. package/dist/helpers/eventUtils.js +0 -10
  54. package/dist/helpers/events.d.ts +0 -1
  55. package/dist/helpers/events.js +7 -107
  56. package/dist/helpers/events.queries.d.ts +17 -0
  57. package/dist/helpers/{events.internal.js → events.queries.js} +24 -15
  58. package/dist/helpers/health_metrics.js +3 -38
  59. package/dist/helpers/health_metrics.queries.d.ts +12 -0
  60. package/dist/helpers/health_metrics.queries.js +39 -0
  61. package/dist/helpers/heartbeats.js +4 -83
  62. package/dist/helpers/heartbeats.queries.d.ts +11 -0
  63. package/dist/helpers/heartbeats.queries.js +76 -0
  64. package/dist/helpers/herd_allowed_domains.js +2 -12
  65. package/dist/helpers/{herd_allowed_domains_internal.d.ts → herd_allowed_domains.queries.d.ts} +1 -1
  66. package/dist/helpers/{herd_allowed_domains_internal.js → herd_allowed_domains.queries.js} +2 -2
  67. package/dist/helpers/herd_credentials_server.d.ts +76 -0
  68. package/dist/helpers/herd_credentials_server.js +22 -0
  69. package/dist/helpers/herd_modules.queries.js +10 -7
  70. package/dist/helpers/herd_roles.js +13 -148
  71. package/dist/helpers/herd_roles.queries.d.ts +18 -0
  72. package/dist/helpers/{herd_roles_internal.js → herd_roles.queries.js} +28 -28
  73. package/dist/helpers/herds.js +5 -47
  74. package/dist/helpers/herds.queries.d.ts +8 -1
  75. package/dist/helpers/herds.queries.js +48 -0
  76. package/dist/helpers/invitations.js +7 -58
  77. package/dist/helpers/invitations.queries.d.ts +10 -0
  78. package/dist/helpers/{invitations_internal.js → invitations.queries.js} +12 -12
  79. package/dist/helpers/issuers.js +6 -52
  80. package/dist/helpers/issuers.queries.d.ts +9 -0
  81. package/dist/helpers/issuers.queries.js +53 -0
  82. package/dist/helpers/layers.js +2 -20
  83. package/dist/helpers/layers.queries.d.ts +2 -1
  84. package/dist/helpers/layers.queries.js +9 -13
  85. package/dist/helpers/lifecycle_server.d.ts +175 -0
  86. package/dist/helpers/lifecycle_server.js +38 -0
  87. package/dist/helpers/localizations.js +5 -42
  88. package/dist/helpers/localizations.queries.d.ts +8 -0
  89. package/dist/helpers/localizations.queries.js +45 -0
  90. package/dist/helpers/maintenance_requests_server.d.ts +124 -0
  91. package/dist/helpers/maintenance_requests_server.js +34 -0
  92. package/dist/helpers/manufacturers.js +5 -43
  93. package/dist/helpers/manufacturers.queries.d.ts +10 -0
  94. package/dist/helpers/manufacturers.queries.js +46 -0
  95. package/dist/helpers/media_urls.d.ts +13 -0
  96. package/dist/helpers/media_urls.js +21 -0
  97. package/dist/helpers/models.js +8 -80
  98. package/dist/helpers/models.queries.d.ts +13 -0
  99. package/dist/helpers/models.queries.js +79 -0
  100. package/dist/helpers/observations_server.d.ts +51 -0
  101. package/dist/helpers/observations_server.js +22 -0
  102. package/dist/helpers/operating_contexts.js +39 -154
  103. package/dist/helpers/operating_contexts.queries.d.ts +48 -0
  104. package/dist/helpers/operating_contexts.queries.js +223 -0
  105. package/dist/helpers/operators.js +4 -57
  106. package/dist/helpers/operators.queries.d.ts +7 -0
  107. package/dist/helpers/operators.queries.js +55 -0
  108. package/dist/helpers/parts.d.ts +0 -87
  109. package/dist/helpers/parts.js +4 -90
  110. package/dist/helpers/parts_server.d.ts +260 -0
  111. package/dist/helpers/parts_server.js +71 -0
  112. package/dist/helpers/pins_server.d.ts +118 -0
  113. package/dist/helpers/pins_server.js +38 -0
  114. package/dist/helpers/plans.js +4 -56
  115. package/dist/helpers/plans.queries.d.ts +4 -1
  116. package/dist/helpers/plans.queries.js +39 -12
  117. package/dist/helpers/points_for_user_server.d.ts +9 -0
  118. package/dist/helpers/points_for_user_server.js +14 -0
  119. package/dist/helpers/product_compatibilities.js +6 -78
  120. package/dist/helpers/product_compatibilities.queries.d.ts +9 -0
  121. package/dist/helpers/product_compatibilities.queries.js +83 -0
  122. package/dist/helpers/product_numbers.js +6 -55
  123. package/dist/helpers/product_numbers.queries.d.ts +9 -0
  124. package/dist/helpers/product_numbers.queries.js +58 -0
  125. package/dist/helpers/products.js +6 -54
  126. package/dist/helpers/products.queries.d.ts +11 -0
  127. package/dist/helpers/products.queries.js +58 -0
  128. package/dist/helpers/providers.js +5 -71
  129. package/dist/helpers/providers.queries.d.ts +5 -1
  130. package/dist/helpers/providers.queries.js +52 -11
  131. package/dist/helpers/pubsub_token_server.d.ts +1 -0
  132. package/dist/helpers/pubsub_token_server.js +5 -2
  133. package/dist/helpers/segmentations_sam3.js +5 -78
  134. package/dist/helpers/segmentations_sam3.queries.d.ts +16 -0
  135. package/dist/helpers/segmentations_sam3.queries.js +81 -0
  136. package/dist/helpers/sensor_poses_server.d.ts +98 -0
  137. package/dist/helpers/sensor_poses_server.js +26 -0
  138. package/dist/helpers/session_incidents_server.d.ts +106 -0
  139. package/dist/helpers/session_incidents_server.js +22 -0
  140. package/dist/helpers/session_summaries.d.ts +2 -0
  141. package/dist/helpers/session_summaries.js +7 -23
  142. package/dist/helpers/session_summaries.queries.d.ts +6 -3
  143. package/dist/helpers/session_summaries.queries.js +27 -0
  144. package/dist/helpers/sessions.js +8 -122
  145. package/dist/helpers/sessions.queries.d.ts +14 -2
  146. package/dist/helpers/sessions.queries.js +88 -1
  147. package/dist/helpers/storage.js +0 -1
  148. package/dist/helpers/supabase_auth.d.ts +6 -0
  149. package/dist/helpers/supabase_auth.js +37 -0
  150. package/dist/helpers/tags.d.ts +0 -1
  151. package/dist/helpers/tags.js +13 -559
  152. package/dist/helpers/tags.queries.d.ts +33 -0
  153. package/dist/helpers/tags.queries.js +454 -0
  154. package/dist/helpers/user_credentials_server.d.ts +76 -0
  155. package/dist/helpers/user_credentials_server.js +22 -0
  156. package/dist/helpers/users.d.ts +2 -2
  157. package/dist/helpers/users.js +8 -107
  158. package/dist/helpers/users.queries.d.ts +9 -1
  159. package/dist/helpers/users.queries.js +107 -0
  160. package/dist/helpers/versions_software.d.ts +3 -1
  161. package/dist/helpers/versions_software.js +24 -0
  162. package/dist/helpers/versions_software_server.d.ts +83 -4
  163. package/dist/helpers/versions_software_server.js +23 -50
  164. package/dist/helpers/zones.d.ts +1 -16
  165. package/dist/helpers/zones.js +4 -104
  166. package/dist/helpers/zones.queries.d.ts +6 -0
  167. package/dist/helpers/zones.queries.js +78 -0
  168. package/dist/hooks/useAuthorizedRealtimeTopics.js +8 -2
  169. package/dist/hooks/useInfiniteQuery.js +18 -14
  170. package/dist/hooks/useScoutRealtimeBroadcast.js +8 -6
  171. package/dist/hooks/useScoutRealtimeDocuments.js +3 -2
  172. package/dist/hooks/useScoutRefresh.d.ts +9 -25
  173. package/dist/hooks/useScoutRefresh.js +33 -213
  174. package/dist/providers/ScoutRefreshProvider.d.ts +1 -1
  175. package/dist/providers/ScoutRefreshProvider.js +56 -13
  176. package/dist/server/index.d.ts +77 -0
  177. package/dist/server/index.js +79 -0
  178. package/dist/server/middleware.d.ts +2 -0
  179. package/dist/server/middleware.js +2 -0
  180. package/dist/server/supabase.d.ts +2 -0
  181. package/dist/server/supabase.js +2 -0
  182. package/dist/store/api.d.ts +40 -40
  183. package/dist/store/api.js +38 -109
  184. package/dist/store/configureStore.d.ts +0 -55
  185. package/dist/store/configureStore.js +1 -8
  186. package/dist/store/hooks.js +1 -0
  187. package/dist/supabase/client.d.ts +3 -0
  188. package/dist/supabase/client.js +10 -0
  189. package/dist/supabase/middleware.d.ts +1 -0
  190. package/dist/supabase/middleware.js +6 -20
  191. package/dist/supabase/server.d.ts +7 -2
  192. package/dist/supabase/server.js +13 -1
  193. package/dist/types/db.d.ts +2 -2
  194. package/dist/types/index.d.ts +5 -0
  195. package/dist/types/index.js +5 -0
  196. package/package.json +53 -4
  197. package/dist/api_keys/index.d.ts +0 -1
  198. package/dist/api_keys/index.js +0 -1
  199. package/dist/helpers/artifacts.internal.d.ts +0 -22
  200. package/dist/helpers/client_abilities_jwt_keys_internal.d.ts +0 -9
  201. package/dist/helpers/client_abilities_jwt_keys_internal.js +0 -20
  202. package/dist/helpers/connectivity.internal.d.ts +0 -10
  203. package/dist/helpers/connectivity.internal.js +0 -47
  204. package/dist/helpers/credentials.d.ts +0 -9
  205. package/dist/helpers/credentials.js +0 -92
  206. package/dist/helpers/embeddings.internal.d.ts +0 -5
  207. package/dist/helpers/events.internal.d.ts +0 -13
  208. package/dist/helpers/herd_roles_internal.d.ts +0 -18
  209. package/dist/helpers/index.d.ts +0 -56
  210. package/dist/helpers/index.js +0 -56
  211. package/dist/helpers/invitations_internal.d.ts +0 -10
  212. package/dist/helpers/versions_software_internal.d.ts +0 -6
  213. package/dist/helpers/versions_software_internal.js +0 -53
  214. package/dist/hooks/useDeviceDisplayName.d.ts +0 -8
  215. package/dist/hooks/useDeviceDisplayName.js +0 -49
  216. package/dist/index.d.ts +0 -108
  217. package/dist/index.js +0 -114
  218. package/dist/supabase/index.d.ts +0 -2
  219. package/dist/supabase/index.js +0 -2
@@ -0,0 +1,454 @@
1
+ import { EnumWebResponse, IWebResponse, } from "../types/requests";
2
+ import { addEventMediaUrls } from "./media_urls";
3
+ function extractLatitude(location) {
4
+ try {
5
+ if (typeof location === "object" && location !== null) {
6
+ if ("coordinates" in location && Array.isArray(location.coordinates)) {
7
+ return location.coordinates[1];
8
+ }
9
+ if ("y" in location) {
10
+ return location.y;
11
+ }
12
+ }
13
+ if (typeof location === "string") {
14
+ const match = location.match(/Point\(([^)]+)\)/);
15
+ if (match) {
16
+ const coords = match[1].split(" ").map(Number);
17
+ if (coords.length === 2) {
18
+ return coords[1];
19
+ }
20
+ }
21
+ }
22
+ }
23
+ catch (error) {
24
+ console.warn("Error extracting latitude:", error);
25
+ }
26
+ return null;
27
+ }
28
+ function extractLongitude(location) {
29
+ try {
30
+ if (typeof location === "object" && location !== null) {
31
+ if ("coordinates" in location && Array.isArray(location.coordinates)) {
32
+ return location.coordinates[0];
33
+ }
34
+ if ("x" in location) {
35
+ return location.x;
36
+ }
37
+ }
38
+ if (typeof location === "string") {
39
+ const match = location.match(/Point\(([^)]+)\)/);
40
+ if (match) {
41
+ const coords = match[1].split(" ").map(Number);
42
+ if (coords.length === 2) {
43
+ return coords[0];
44
+ }
45
+ }
46
+ }
47
+ }
48
+ catch (error) {
49
+ console.warn("Error extracting longitude:", error);
50
+ }
51
+ return null;
52
+ }
53
+ function rpcModelIdsParam(model_ids) {
54
+ if (model_ids != null && model_ids.length > 0) {
55
+ return { model_ids_caller: model_ids };
56
+ }
57
+ return {};
58
+ }
59
+ export async function create_tags_query(client, tags) {
60
+ const formatted_tags = tags.map((tag) => {
61
+ const { id, ...rest } = tag;
62
+ return {
63
+ ...rest,
64
+ observation_type: rest.observation_type,
65
+ };
66
+ });
67
+ const { data, error } = await client
68
+ .from("tags")
69
+ .insert(formatted_tags)
70
+ .select("*");
71
+ if (error) {
72
+ return {
73
+ status: EnumWebResponse.ERROR,
74
+ msg: error.message,
75
+ data: null,
76
+ };
77
+ }
78
+ return IWebResponse.success(data).to_compatible();
79
+ }
80
+ export async function delete_tags_by_ids_query(client, tag_ids) {
81
+ const { error } = await client.from("tags").delete().in("id", tag_ids);
82
+ if (error) {
83
+ return {
84
+ status: EnumWebResponse.ERROR,
85
+ msg: error.message,
86
+ data: false,
87
+ };
88
+ }
89
+ return IWebResponse.success(true).to_compatible();
90
+ }
91
+ export async function update_tags_query(client, tags) {
92
+ const updatedTags = [];
93
+ for (const tag of tags) {
94
+ const { id, inserted_at: _ignoredInsertedAt, ...updateData } = tag;
95
+ const { data, error } = await client
96
+ .from("tags")
97
+ .update({
98
+ ...updateData,
99
+ observation_type: updateData.observation_type,
100
+ })
101
+ .eq("id", id)
102
+ .select("*")
103
+ .single();
104
+ if (error) {
105
+ return {
106
+ status: EnumWebResponse.ERROR,
107
+ msg: error.message,
108
+ data: null,
109
+ };
110
+ }
111
+ if (data) {
112
+ updatedTags.push(data);
113
+ }
114
+ }
115
+ return IWebResponse.success(updatedTags).to_compatible();
116
+ }
117
+ export async function get_more_events_with_tags_by_herd_query(client, herd_id, offset, page_count = 10) {
118
+ const from = offset * page_count;
119
+ const { data, error } = await client.rpc("get_events_and_tags_for_herd", {
120
+ herd_id_caller: herd_id,
121
+ offset_caller: from,
122
+ limit_caller: page_count,
123
+ });
124
+ if (error) {
125
+ console.warn("Error fetching events with tags by herd:", error.message);
126
+ return {
127
+ status: EnumWebResponse.ERROR,
128
+ msg: error.message,
129
+ data: [],
130
+ };
131
+ }
132
+ const filteredData = (data || []).map((event) => {
133
+ if (!event.tags)
134
+ return event;
135
+ event.tags = event.tags.filter((tag) => tag !== null);
136
+ return event;
137
+ });
138
+ return IWebResponse.success(await addEventMediaUrls(client, filteredData)).to_compatible();
139
+ }
140
+ export async function get_events_and_tags_for_device_query(client, device_id, limit = 3) {
141
+ const { data, error } = await client.rpc("get_events_and_tags_for_device", {
142
+ device_id_caller: device_id,
143
+ limit_caller: limit,
144
+ });
145
+ if (error) {
146
+ console.warn("Error fetching recent events with tags by device:", error.message);
147
+ return {
148
+ status: EnumWebResponse.ERROR,
149
+ msg: error.message,
150
+ data: [],
151
+ };
152
+ }
153
+ return IWebResponse.success(await addEventMediaUrls(client, data || [])).to_compatible();
154
+ }
155
+ export async function get_events_and_tags_for_devices_batch_query(client, device_ids, limit = 1) {
156
+ var _a;
157
+ const { data, error } = await client.rpc("get_events_and_tags_for_devices_batch", {
158
+ device_ids,
159
+ limit_per_device: limit,
160
+ });
161
+ if (error) {
162
+ console.error(`[Events Batch] Database error:`, error.message);
163
+ console.log(`[Events Batch] Falling back to individual calls...`);
164
+ const result = {};
165
+ const promises = device_ids.map(async (device_id) => {
166
+ try {
167
+ const response = await get_events_and_tags_for_device_query(client, device_id, limit);
168
+ if (response.status === EnumWebResponse.SUCCESS &&
169
+ response.data) {
170
+ result[device_id] = response.data;
171
+ }
172
+ else {
173
+ result[device_id] = [];
174
+ }
175
+ }
176
+ catch (err) {
177
+ console.warn(`[Events Batch] Failed for device ${device_id}:`, err);
178
+ result[device_id] = [];
179
+ }
180
+ });
181
+ await Promise.all(promises);
182
+ return IWebResponse.success(result).to_compatible();
183
+ }
184
+ if (!data) {
185
+ return IWebResponse.success({}).to_compatible();
186
+ }
187
+ const eventsByDevice = {};
188
+ data.forEach((row) => {
189
+ const device_id = row.device_id;
190
+ if (!eventsByDevice[device_id]) {
191
+ eventsByDevice[device_id] = [];
192
+ }
193
+ eventsByDevice[device_id].push({
194
+ id: row.id,
195
+ inserted_at: row.inserted_at,
196
+ message: row.message,
197
+ media_url: row.media_url,
198
+ file_path: row.file_path,
199
+ latitude: row.latitude,
200
+ longitude: row.longitude,
201
+ altitude: row.altitude,
202
+ heading: row.heading,
203
+ media_type: row.media_type,
204
+ device_id,
205
+ timestamp_observation: row.timestamp_observation,
206
+ is_public: row.is_public,
207
+ earthranger_url: row.earthranger_url,
208
+ herd_id: row.herd_id,
209
+ tags: Array.isArray(row.tags) ? row.tags : [],
210
+ embedded_at: row.embedded_at ?? null,
211
+ segmented_at: row.segmented_at ?? null,
212
+ tagged_at: row.tagged_at ?? null,
213
+ });
214
+ });
215
+ const eventsWithUrls = await addEventMediaUrls(client, Object.values(eventsByDevice).flat());
216
+ const result = {};
217
+ for (const event of eventsWithUrls) {
218
+ if (event.device_id == null)
219
+ continue;
220
+ (result[_a = event.device_id] ?? (result[_a] = [])).push(event);
221
+ }
222
+ return IWebResponse.success(result).to_compatible();
223
+ }
224
+ export async function get_event_and_tags_by_event_id_query(client, event_id) {
225
+ const { data, error } = await client
226
+ .from("events")
227
+ .select(`
228
+ *,
229
+ tags: tags (*)
230
+ `)
231
+ .eq("id", event_id);
232
+ if (error) {
233
+ console.warn("Error fetching event with tags by event id:", error.message);
234
+ return {
235
+ status: EnumWebResponse.ERROR,
236
+ msg: error.message,
237
+ data: null,
238
+ };
239
+ }
240
+ if (!data || data.length === 0) {
241
+ return {
242
+ status: EnumWebResponse.ERROR,
243
+ msg: "Event not found",
244
+ data: null,
245
+ };
246
+ }
247
+ const { data: deviceData, error: deviceError } = await client
248
+ .from("devices")
249
+ .select("herd_id")
250
+ .eq("id", data[0].device_id)
251
+ .single();
252
+ if (deviceError) {
253
+ console.warn("Error fetching device herd_id:", deviceError.message);
254
+ return {
255
+ status: EnumWebResponse.ERROR,
256
+ msg: deviceError.message,
257
+ data: null,
258
+ };
259
+ }
260
+ let latitude = null;
261
+ let longitude = null;
262
+ try {
263
+ if (data[0].location) {
264
+ if (typeof data[0].location === "object" && data[0].location !== null) {
265
+ if ("coordinates" in data[0].location &&
266
+ Array.isArray(data[0].location.coordinates)) {
267
+ longitude = data[0].location.coordinates[0];
268
+ latitude = data[0].location.coordinates[1];
269
+ }
270
+ else if ("x" in data[0].location && "y" in data[0].location) {
271
+ longitude = data[0].location.x;
272
+ latitude = data[0].location.y;
273
+ }
274
+ }
275
+ else if (typeof data[0].location === "string") {
276
+ const match = data[0].location.match(/Point\(([^)]+)\)/);
277
+ if (match) {
278
+ const coords = match[1].split(" ").map(Number);
279
+ if (coords.length === 2) {
280
+ longitude = coords[0];
281
+ latitude = coords[1];
282
+ }
283
+ }
284
+ }
285
+ }
286
+ }
287
+ catch (locationError) {
288
+ console.warn("Error parsing location data:", locationError);
289
+ }
290
+ const transformedData = {
291
+ id: data[0].id,
292
+ inserted_at: data[0].inserted_at,
293
+ message: data[0].message,
294
+ media_url: data[0].media_url,
295
+ latitude,
296
+ longitude,
297
+ altitude: data[0].altitude,
298
+ heading: data[0].heading,
299
+ media_type: data[0].media_type,
300
+ device_id: data[0].device_id,
301
+ timestamp_observation: data[0].timestamp_observation,
302
+ is_public: data[0].is_public,
303
+ herd_id: deviceData.herd_id,
304
+ tags: (data[0].tags || []).map((tag) => {
305
+ const originLoc = tag.origin_location;
306
+ const subjectLoc = tag.subject_location;
307
+ return {
308
+ id: tag.id,
309
+ inserted_at: tag.inserted_at,
310
+ artifact_id: tag.artifact_id,
311
+ event_id: tag.event_id,
312
+ model_id: tag.model_id,
313
+ width: tag.width,
314
+ height: tag.height,
315
+ conf: tag.conf,
316
+ x: tag.x,
317
+ y: tag.y,
318
+ class: tag.class,
319
+ timestamp_observation: tag.timestamp_observation,
320
+ frame_index: tag.frame_index ?? null,
321
+ origin_location: tag.origin_location ?? null,
322
+ origin_pitch: tag.origin_pitch,
323
+ origin_heading: tag.origin_heading,
324
+ origin_roll: tag.origin_roll,
325
+ sensor_pitch: tag.sensor_pitch,
326
+ sensor_yaw: tag.sensor_yaw,
327
+ sensor_roll: tag.sensor_roll,
328
+ origin_height: tag.origin_height,
329
+ subject_location: tag.subject_location ?? null,
330
+ subject_height: tag.subject_height,
331
+ origin_latitude: originLoc ? extractLatitude(originLoc) : null,
332
+ origin_longitude: originLoc ? extractLongitude(originLoc) : null,
333
+ subject_latitude: subjectLoc ? extractLatitude(subjectLoc) : null,
334
+ subject_longitude: subjectLoc ? extractLongitude(subjectLoc) : null,
335
+ subject_id: tag.subject_id ?? null,
336
+ };
337
+ }),
338
+ earthranger_url: data[0].earthranger_url,
339
+ file_path: data[0].file_path,
340
+ embedded_at: data[0].embedded_at ?? null,
341
+ segmented_at: data[0].segmented_at ?? null,
342
+ tagged_at: data[0].tagged_at ?? null,
343
+ };
344
+ const [eventWithUrl] = await addEventMediaUrls(client, [transformedData]);
345
+ return IWebResponse.success(eventWithUrl).to_compatible();
346
+ }
347
+ export async function get_tags_for_artifact_query(client, artifactId, options) {
348
+ const { data, error } = await client.rpc("get_tags_for_artifact", {
349
+ artifact_id_caller: artifactId,
350
+ ...(options?.start_timestamp != null && {
351
+ start_timestamp_caller: options.start_timestamp,
352
+ }),
353
+ ...(options?.end_timestamp != null && {
354
+ end_timestamp_caller: options.end_timestamp,
355
+ }),
356
+ ...rpcModelIdsParam(options?.model_ids),
357
+ ...(options?.max_elements != null && {
358
+ max_elements_caller: options.max_elements,
359
+ }),
360
+ });
361
+ if (error) {
362
+ console.warn("Error fetching tags for artifact:", error.message);
363
+ return {
364
+ status: EnumWebResponse.ERROR,
365
+ msg: error.message,
366
+ data: [],
367
+ };
368
+ }
369
+ return IWebResponse.success(data ?? []).to_compatible();
370
+ }
371
+ export async function get_tags_for_artifact_by_frame_index_query(client, artifactId, minConf, frameIndexStart, frameIndexEnd, model_ids = null, maxElements = null) {
372
+ const { data, error } = await client.rpc("get_tags_for_artifact_by_frame_index", {
373
+ artifact_id_caller: artifactId,
374
+ min_conf_caller: minConf,
375
+ frame_index_start_caller: frameIndexStart,
376
+ frame_index_end_caller: frameIndexEnd,
377
+ ...rpcModelIdsParam(model_ids),
378
+ ...(maxElements != null && { max_elements_caller: maxElements }),
379
+ });
380
+ if (error) {
381
+ console.warn("Error fetching tags for artifact by frame index:", error.message);
382
+ return {
383
+ status: EnumWebResponse.ERROR,
384
+ msg: error.message,
385
+ data: [],
386
+ };
387
+ }
388
+ return IWebResponse.success(data ?? []).to_compatible();
389
+ }
390
+ export async function get_tags_for_artifact_by_subject_id_query(client, artifactId, subjectId, model_ids = null, maxElements = null) {
391
+ const { data, error } = await client.rpc("get_tags_for_artifact_by_subject_id", {
392
+ artifact_id_caller: artifactId,
393
+ subject_id_caller: subjectId,
394
+ ...rpcModelIdsParam(model_ids),
395
+ ...(maxElements != null && { max_elements_caller: maxElements }),
396
+ });
397
+ if (error) {
398
+ console.warn("Error fetching tags for artifact by subject id:", error.message);
399
+ return {
400
+ status: EnumWebResponse.ERROR,
401
+ msg: error.message,
402
+ data: [],
403
+ };
404
+ }
405
+ return IWebResponse.success(data ?? []).to_compatible();
406
+ }
407
+ export async function get_minimal_subjects_for_artifact_query(client, artifactId, options) {
408
+ const { data, error } = await client.rpc("get_minimal_subjects_for_artifact", {
409
+ artifact_id_caller: artifactId,
410
+ ...(options?.min_avg_conf != null && {
411
+ min_avg_conf_caller: options.min_avg_conf,
412
+ }),
413
+ ...(options?.min_count != null && {
414
+ min_count_caller: options.min_count,
415
+ }),
416
+ ...rpcModelIdsParam(options?.model_ids),
417
+ ...(options?.max_elements != null && {
418
+ max_elements_caller: options.max_elements,
419
+ }),
420
+ });
421
+ if (error) {
422
+ console.warn("Error fetching minimal subjects for artifact:", error.message);
423
+ return {
424
+ status: EnumWebResponse.ERROR,
425
+ msg: error.message,
426
+ data: [],
427
+ };
428
+ }
429
+ return IWebResponse.success(data ?? []).to_compatible();
430
+ }
431
+ export async function get_tags_for_event_query(client, eventId, options) {
432
+ const { data, error } = await client.rpc("get_tags_for_event", {
433
+ event_id_caller: eventId,
434
+ ...(options?.start_timestamp != null && {
435
+ start_timestamp_caller: options.start_timestamp,
436
+ }),
437
+ ...(options?.end_timestamp != null && {
438
+ end_timestamp_caller: options.end_timestamp,
439
+ }),
440
+ ...rpcModelIdsParam(options?.model_ids),
441
+ ...(options?.max_elements != null && {
442
+ max_elements_caller: options.max_elements,
443
+ }),
444
+ });
445
+ if (error) {
446
+ console.warn("Error fetching tags for event:", error.message);
447
+ return {
448
+ status: EnumWebResponse.ERROR,
449
+ msg: error.message,
450
+ data: [],
451
+ };
452
+ }
453
+ return IWebResponse.success(data ?? []).to_compatible();
454
+ }
@@ -0,0 +1,76 @@
1
+ import { CredentialQueryArgs, UserCredentialInsert, UserCredentialUpdate } from "../types/db";
2
+ export declare function server_get_user_credentials_by_user_id(user_id: string, args?: CredentialQueryArgs): Promise<import("../types").IWebResponseCompatible<{
3
+ created_at: string;
4
+ expiration: string | null;
5
+ file_uri: string | null;
6
+ id: number;
7
+ issuer: string;
8
+ lifecycle: import("../types").Database["public"]["Enums"]["entity_lifecycle"];
9
+ lifecycle_changed_at: string;
10
+ lifecycle_changed_by: string | null;
11
+ lifecycle_reason: string | null;
12
+ tracking_number: string | null;
13
+ type: string;
14
+ updated_at: string;
15
+ user_id: string;
16
+ }[]>>;
17
+ export declare function server_get_user_credential_by_id(credential_id: number): Promise<import("../types").IWebResponseCompatible<{
18
+ created_at: string;
19
+ expiration: string | null;
20
+ file_uri: string | null;
21
+ id: number;
22
+ issuer: string;
23
+ lifecycle: import("../types").Database["public"]["Enums"]["entity_lifecycle"];
24
+ lifecycle_changed_at: string;
25
+ lifecycle_changed_by: string | null;
26
+ lifecycle_reason: string | null;
27
+ tracking_number: string | null;
28
+ type: string;
29
+ updated_at: string;
30
+ user_id: string;
31
+ } | null>>;
32
+ export declare function server_create_user_credential(row: UserCredentialInsert): Promise<import("../types").IWebResponseCompatible<{
33
+ created_at: string;
34
+ expiration: string | null;
35
+ file_uri: string | null;
36
+ id: number;
37
+ issuer: string;
38
+ lifecycle: import("../types").Database["public"]["Enums"]["entity_lifecycle"];
39
+ lifecycle_changed_at: string;
40
+ lifecycle_changed_by: string | null;
41
+ lifecycle_reason: string | null;
42
+ tracking_number: string | null;
43
+ type: string;
44
+ updated_at: string;
45
+ user_id: string;
46
+ } | null>>;
47
+ export declare function server_update_user_credential(credential_id: number, patch: UserCredentialUpdate): Promise<import("../types").IWebResponseCompatible<{
48
+ created_at: string;
49
+ expiration: string | null;
50
+ file_uri: string | null;
51
+ id: number;
52
+ issuer: string;
53
+ lifecycle: import("../types").Database["public"]["Enums"]["entity_lifecycle"];
54
+ lifecycle_changed_at: string;
55
+ lifecycle_changed_by: string | null;
56
+ lifecycle_reason: string | null;
57
+ tracking_number: string | null;
58
+ type: string;
59
+ updated_at: string;
60
+ user_id: string;
61
+ } | null>>;
62
+ export declare function server_delete_user_credential(credential_id: number): Promise<import("../types").IWebResponseCompatible<{
63
+ created_at: string;
64
+ expiration: string | null;
65
+ file_uri: string | null;
66
+ id: number;
67
+ issuer: string;
68
+ lifecycle: import("../types").Database["public"]["Enums"]["entity_lifecycle"];
69
+ lifecycle_changed_at: string;
70
+ lifecycle_changed_by: string | null;
71
+ lifecycle_reason: string | null;
72
+ tracking_number: string | null;
73
+ type: string;
74
+ updated_at: string;
75
+ user_id: string;
76
+ } | null>>;
@@ -0,0 +1,22 @@
1
+ import { newServerClient } from "../supabase/server";
2
+ import { create_user_credential, delete_user_credential, get_user_credential_by_id, get_user_credentials_by_user_id, update_user_credential, } from "./user_credentials";
3
+ export async function server_get_user_credentials_by_user_id(user_id, args) {
4
+ const client = await newServerClient();
5
+ return get_user_credentials_by_user_id(client, user_id, args);
6
+ }
7
+ export async function server_get_user_credential_by_id(credential_id) {
8
+ const client = await newServerClient();
9
+ return get_user_credential_by_id(client, credential_id);
10
+ }
11
+ export async function server_create_user_credential(row) {
12
+ const client = await newServerClient();
13
+ return create_user_credential(client, row);
14
+ }
15
+ export async function server_update_user_credential(credential_id, patch) {
16
+ const client = await newServerClient();
17
+ return update_user_credential(client, credential_id, patch);
18
+ }
19
+ export async function server_delete_user_credential(credential_id) {
20
+ const client = await newServerClient();
21
+ return delete_user_credential(client, credential_id);
22
+ }
@@ -1,7 +1,7 @@
1
1
  import { IUser, IUserAndRole, IUserProfileRow, IUserRolePerHerd } from "../types/db";
2
- import { Database } from "../types/supabase";
3
2
  import { IWebResponseCompatible } from "../types/requests";
4
- export type UserProfileUpdate = Database["public"]["Tables"]["users"]["Update"];
3
+ import type { UserProfileUpdate } from "./users.queries";
4
+ export type { UserProfileUpdate } from "./users.queries";
5
5
  export declare function server_get_user_roles(herd_id: number): Promise<IWebResponseCompatible<IUserRolePerHerd[]>>;
6
6
  export declare function server_get_user(): Promise<IWebResponseCompatible<IUser | null>>;
7
7
  export declare function server_get_users_with_herd_access(herd_id: number): Promise<IWebResponseCompatible<IUserAndRole[]>>;
@@ -1,125 +1,26 @@
1
- "use server";
2
1
  import { newServerClient } from "../supabase/server";
3
- import { IWebResponse, EnumWebResponse, } from "../types/requests";
4
- import { get_users_with_herd_access_batch_query, } from "./users.queries";
2
+ import { get_user_query, get_user_roles_query, get_users_with_herd_access_query, get_users_with_herd_access_batch_query, leave_herd_for_current_user_query, remove_user_from_herd_for_admin_query, update_user_profile_query, upsert_user_herd_role_query, } from "./users.queries";
5
3
  export async function server_get_user_roles(herd_id) {
6
- const supabase = await newServerClient();
7
- // fetch user role for herd
8
- const { data, error } = await supabase
9
- .from("users_roles_per_herd")
10
- .select("*")
11
- .eq("herd_id", herd_id);
12
- if (!data) {
13
- return {
14
- status: EnumWebResponse.ERROR,
15
- msg: `No user role found for herd ${herd_id}`,
16
- data: null,
17
- };
18
- }
19
- // TODO: DETERMINE WHEN TO PASS ERROR
20
- let response = IWebResponse.success(data);
21
- return response.to_compatible();
4
+ return get_user_roles_query(await newServerClient(), herd_id);
22
5
  }
23
6
  export async function server_get_user() {
24
- const supabase = await newServerClient();
25
- const { data } = await supabase.auth.getUser();
26
- const new_user = data.user;
27
- return IWebResponse.success(new_user).to_compatible();
7
+ return get_user_query(await newServerClient());
28
8
  }
29
9
  export async function server_get_users_with_herd_access(herd_id) {
30
- const supabase = await newServerClient();
31
- const { data, error } = await supabase
32
- .from("users_roles_per_herd")
33
- .select(`
34
- herd_role_id,
35
- herd_roles (*),
36
- users!users_roles_per_herd_user_id_fkey (*)
37
- `)
38
- .eq("herd_id", herd_id);
39
- if (error) {
40
- return { status: EnumWebResponse.ERROR, msg: error.message, data: null };
41
- }
42
- const transformedData = (data ?? []).map((item) => ({
43
- user: item.users,
44
- herd_role_id: item.herd_role_id,
45
- herd_role: item.herd_roles,
46
- }));
47
- return IWebResponse.success(transformedData).to_compatible();
10
+ return get_users_with_herd_access_query(await newServerClient(), herd_id);
48
11
  }
49
- // Fetches users-with-role for many herds in one query, grouped by herd_id.
50
12
  export async function server_get_users_with_herd_access_batch(herd_ids) {
51
13
  return get_users_with_herd_access_batch_query(await newServerClient(), herd_ids);
52
14
  }
53
15
  export async function server_upsert_user_herd_role(herd_id, username, herd_role_id) {
54
- const supabase = await newServerClient();
55
- const { data: user, error: user_error } = await supabase
56
- .from("users")
57
- .select("*")
58
- .eq("username", username)
59
- .single();
60
- if (user_error) {
61
- return IWebResponse.error("Unable to fetch user with provided username").to_compatible();
62
- }
63
- if (!user) {
64
- return IWebResponse.error("User not found").to_compatible();
65
- }
66
- const { data: herdRole, error: role_error } = await supabase
67
- .from("herd_roles")
68
- .select("*")
69
- .eq("id", herd_role_id)
70
- .eq("herd_id", herd_id)
71
- .single();
72
- if (role_error || !herdRole) {
73
- return IWebResponse.error("Invalid herd role for this herd").to_compatible();
74
- }
75
- const { error } = await supabase.from("users_roles_per_herd").upsert({
76
- user_id: user.id,
77
- herd_id,
78
- herd_role_id,
79
- });
80
- if (error) {
81
- return IWebResponse.error("Unable to update or add user with provided username. Ensure you have sufficient permissions.").to_compatible();
82
- }
83
- return IWebResponse.success({
84
- user,
85
- herd_role_id,
86
- herd_role: herdRole,
87
- }).to_compatible();
16
+ return upsert_user_herd_role_query(await newServerClient(), herd_id, username, herd_role_id);
88
17
  }
89
18
  export async function update_user_profile(user_id, patch) {
90
- const supabase = await newServerClient();
91
- const { data, error } = await supabase
92
- .from("users")
93
- .update(patch)
94
- .eq("id", user_id)
95
- .select("*")
96
- .single();
97
- if (error) {
98
- return IWebResponse.error(error.message).to_compatible();
99
- }
100
- if (!data) {
101
- return IWebResponse.error("User not found or profile update failed").to_compatible();
102
- }
103
- return IWebResponse.success(data).to_compatible();
19
+ return update_user_profile_query(await newServerClient(), user_id, patch);
104
20
  }
105
21
  export async function leave_herd_for_current_user(herd_id) {
106
- const supabase = await newServerClient();
107
- const { data, error } = await supabase.rpc("leave_herd_for_current_user", {
108
- p_herd_id: herd_id,
109
- });
110
- if (error) {
111
- return IWebResponse.error(error.message).to_compatible();
112
- }
113
- return IWebResponse.success(data).to_compatible();
22
+ return leave_herd_for_current_user_query(await newServerClient(), herd_id);
114
23
  }
115
24
  export async function remove_user_from_herd_for_admin(herd_id, user_id) {
116
- const supabase = await newServerClient();
117
- const { data, error } = await supabase.rpc("remove_user_from_herd_for_admin", {
118
- p_herd_id: herd_id,
119
- p_user_id: user_id,
120
- });
121
- if (error) {
122
- return IWebResponse.error(error.message).to_compatible();
123
- }
124
- return IWebResponse.success(data).to_compatible();
25
+ return remove_user_from_herd_for_admin_query(await newServerClient(), herd_id, user_id);
125
26
  }