een-api-toolkit 0.3.16 → 0.3.20
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/CHANGELOG.md +43 -10
- package/README.md +1 -0
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +561 -0
- package/dist/index.js +483 -260
- package/dist/index.js.map +1 -1
- package/docs/AI-CONTEXT.md +12 -1
- package/examples/vue-event-subscriptions/.env.example +15 -0
- package/examples/vue-event-subscriptions/README.md +103 -0
- package/examples/vue-event-subscriptions/e2e/app.spec.ts +71 -0
- package/examples/vue-event-subscriptions/e2e/auth.spec.ts +290 -0
- package/examples/vue-event-subscriptions/index.html +13 -0
- package/examples/vue-event-subscriptions/package-lock.json +1719 -0
- package/examples/vue-event-subscriptions/package.json +28 -0
- package/examples/vue-event-subscriptions/playwright.config.ts +47 -0
- package/examples/vue-event-subscriptions/src/App.vue +233 -0
- package/examples/vue-event-subscriptions/src/main.ts +25 -0
- package/examples/vue-event-subscriptions/src/router/index.ts +68 -0
- package/examples/vue-event-subscriptions/src/views/Callback.vue +76 -0
- package/examples/vue-event-subscriptions/src/views/Home.vue +192 -0
- package/examples/vue-event-subscriptions/src/views/LiveEvents.vue +640 -0
- package/examples/vue-event-subscriptions/src/views/Login.vue +33 -0
- package/examples/vue-event-subscriptions/src/views/Logout.vue +59 -0
- package/examples/vue-event-subscriptions/src/views/Subscriptions.vue +402 -0
- package/examples/vue-event-subscriptions/src/vite-env.d.ts +12 -0
- package/examples/vue-event-subscriptions/tsconfig.json +21 -0
- package/examples/vue-event-subscriptions/tsconfig.node.json +10 -0
- package/examples/vue-event-subscriptions/vite.config.ts +12 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,29 +2,62 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## [0.3.
|
|
5
|
+
## [0.3.20] - 2026-01-19
|
|
6
6
|
|
|
7
7
|
### Release Summary
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
#### PR #62: feat: Add EventSubscriptions API with SSE support and example app
|
|
10
|
+
## Summary
|
|
11
|
+
- Implement EventSubscriptions API endpoints (list, get, create, delete)
|
|
12
|
+
- Add SSE connection helper `connectToEventSubscription()` for real-time events
|
|
13
|
+
- Create vue-event-subscriptions example app with full CRUD and live event viewer
|
|
14
|
+
- Add session refresh UI (token expiry countdown, refresh status banner)
|
|
15
|
+
- Add modal window for detailed event viewing in Live Events page
|
|
16
|
+
|
|
17
|
+
## Changes
|
|
18
|
+
### Toolkit (`src/eventSubscriptions/`)
|
|
19
|
+
- `service.ts` - CRUD operations and SSE connection with fetch/ReadableStream
|
|
20
|
+
- `types.ts` - EventSubscription, SSEConnection, SSEEvent types
|
|
21
|
+
- Unit tests with 337 total tests passing
|
|
22
|
+
|
|
23
|
+
### Example App (`examples/vue-event-subscriptions/`)
|
|
24
|
+
- Subscriptions management (list, create, delete)
|
|
25
|
+
- Live Events page with real-time SSE event display
|
|
26
|
+
- Event details modal with JSON data viewer
|
|
27
|
+
- Token expiry countdown and session refresh UI
|
|
28
|
+
|
|
29
|
+
## Test Results
|
|
30
|
+
- **Lint**: Passed (1 warning)
|
|
31
|
+
- **Unit Tests**: 337 passed
|
|
32
|
+
- **Build**: Passed
|
|
33
|
+
- **E2E Tests**: vue-event-subscriptions passed (15 tests)
|
|
34
|
+
- Other example apps had port conflict issues (pre-existing infrastructure issue)
|
|
35
|
+
|
|
36
|
+
## Version
|
|
37
|
+
`0.3.17`
|
|
38
|
+
|
|
39
|
+
## Commits
|
|
40
|
+
- 6aa1332 feat: Add EventSubscriptions API with SSE support and example app
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
44
|
+
|
|
10
45
|
|
|
11
46
|
### Detailed Changes
|
|
12
47
|
|
|
13
48
|
#### Features
|
|
14
|
-
- feat: Add
|
|
49
|
+
- feat: Add EventSubscriptions API with SSE support and example app
|
|
15
50
|
|
|
16
51
|
#### Bug Fixes
|
|
17
|
-
- fix: Address
|
|
18
|
-
- fix: Address code
|
|
19
|
-
- fix: Address code review feedback for HLS video playback
|
|
20
|
-
- fix: Update E2E test for new default time range selection
|
|
52
|
+
- fix: Address code review feedback from PR #63
|
|
53
|
+
- fix: Address code review recommendations from PR #62
|
|
21
54
|
|
|
22
55
|
#### Other Changes
|
|
23
|
-
-
|
|
56
|
+
- docs: Add EventSubscriptions to documentation and fix Pinia version
|
|
24
57
|
|
|
25
58
|
### Links
|
|
26
59
|
- [npm package](https://www.npmjs.com/package/een-api-toolkit)
|
|
27
|
-
- [Full Changelog](https://github.com/klaushofrichter/een-api-toolkit/compare/v0.3.
|
|
60
|
+
- [Full Changelog](https://github.com/klaushofrichter/een-api-toolkit/compare/v0.3.16...v0.3.20)
|
|
28
61
|
|
|
29
62
|
---
|
|
30
|
-
*Released: 2026-01-
|
|
63
|
+
*Released: 2026-01-19 05:31:27 CST*
|
package/README.md
CHANGED
|
@@ -189,6 +189,7 @@ The `examples/` directory contains complete Vue 3 applications demonstrating too
|
|
|
189
189
|
| **[vue-feeds](./examples/vue-feeds/)** | Live video streaming with preview and main streams | `getCameras()`, `listFeeds()`, `initMediaSession()` |
|
|
190
190
|
| **[vue-events](./examples/vue-events/)** | Event listing with bounding box overlays | `listEvents()`, `listEventTypes()`, `listEventFieldValues()`, `getRecordedImage()` |
|
|
191
191
|
| **[vue-alerts-metrics](./examples/vue-alerts-metrics/)** | Event metrics, alerts, and notifications dashboard | `getEventMetrics()`, `listAlerts()`, `listAlertTypes()`, `listNotifications()` |
|
|
192
|
+
| **[vue-event-subscriptions](./examples/vue-event-subscriptions/)** | Real-time event streaming with SSE | `listEventSubscriptions()`, `createEventSubscription()`, `deleteEventSubscription()`, `connectToEventSubscription()` |
|
|
192
193
|
|
|
193
194
|
Each example includes:
|
|
194
195
|
- Complete OAuth authentication flow
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const he=require("pinia"),h=require("vue"),Re={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1},pe=()=>{try{return Re?.VITE_DEBUG==="true"}catch{return!1}};function c(...e){pe()&&console.log("[een-api-toolkit]",...e)}const Ee={localStorage:"persists across sessions",sessionStorage:"per-tab, cleared on tab close",memory:"tokens lost on page refresh"};class Ie{store=new Map;getItem(n){return this.store.get(n)??null}setItem(n,t){this.store.set(n,t)}removeItem(n){this.store.delete(n)}}class Q{constructor(n){this.storage=n}getItem(n){return this.storage.getItem(n)}setItem(n,t){this.storage.setItem(n,t)}removeItem(n){this.storage.removeItem(n)}}let q="localStorage",b=null;function j(){return b||(b=new Ie),b}function Te(e){q=e}function Ae(){return q}function L(){switch(q){case"memory":return j();case"sessionStorage":return typeof sessionStorage<"u"?new Q(sessionStorage):(c("sessionStorage unavailable, falling back to memory storage"),j());default:return typeof localStorage<"u"?new Q(localStorage):(c("localStorage unavailable, falling back to memory storage"),j())}}const T={};let y={};function Ue(e={}){const n=e.storageStrategy??"localStorage";Te(n),y={proxyUrl:e.proxyUrl??T?.VITE_PROXY_URL,clientId:e.clientId??T?.VITE_EEN_CLIENT_ID,redirectUri:e.redirectUri??T?.VITE_REDIRECT_URI,storageStrategy:n,debug:e.debug??T?.VITE_DEBUG==="true"}}function ye(){return y}function O(){return y.proxyUrl??T?.VITE_PROXY_URL}function M(){return y.clientId??T?.VITE_EEN_CLIENT_ID}function P(){return y.redirectUri??T?.VITE_REDIRECT_URI??"http://127.0.0.1:3333"}function l(e){return{data:e,error:null}}function r(e,n,t,i){return{data:null,error:{code:e,message:n,status:t,details:i}}}function R(e){return e.endsWith("+00:00")?e:e.endsWith("Z")?e.replace("Z","+00:00"):e}let F=null;function Se(){return F||(F=Promise.resolve().then(()=>$e).then(e=>e.refreshToken)),F}const f=he.defineStore("een-auth",()=>{const e=h.ref(null),n=h.ref(null),t=h.ref(null),i=h.ref(null),a=h.ref(null),o=h.ref(443),s=h.ref(null),d=h.ref(null),g=h.ref(!1);let E=null;const p=h.ref(!1),I=h.ref(null),v=h.computed(()=>!!e.value),k=h.computed(()=>a.value?o.value===443?`https://${a.value}`:`https://${a.value}:${o.value}`:null),w=h.computed(()=>n.value?Date.now()>=n.value:!0),te=h.computed(()=>n.value?Math.max(0,n.value-Date.now()):0);function ne(u,_){e.value=u,n.value=Date.now()+_*1e3,A(),N(),c("Token set, expires in",_,"seconds")}function re(u){t.value=u,A()}function ie(u){i.value=u,A()}function oe(u){if(typeof u=="string")try{const _=new URL(u.startsWith("http")?u:`https://${u}`);a.value=_.hostname,o.value=_.port?parseInt(_.port,10):443}catch(_){c("Failed to parse URL, using as hostname:",_ instanceof Error?_.message:String(_)),a.value=u,o.value=443}else a.value=u.hostname,o.value=u.port??443;A(),c("Base URL set:",k.value)}function ae(u){s.value=u,A()}function N(){if(d.value&&(clearTimeout(d.value),d.value=null),!n.value||!e.value)return;const u=Date.now(),U=n.value-u,$=300*1e3,fe=U/2,_e=Math.min($,fe),ge=Math.max(U-_e,60*1e3),C=Math.max(ge,5e3);c("Auto-refresh scheduled in",Math.round(C/1e3),"seconds"),d.value=setTimeout(async()=>{await se()},C)}async function se(){return E?(c("Refresh already in progress, waiting for existing refresh"),E):(g.value=!0,c("Performing auto-refresh"),E=(async()=>{try{const _=await(await Se())();_.error?(p.value=!0,I.value=_.error.message,c("Auto-refresh failed:",_.error.message)):(p.value=!1,I.value=null,c("Auto-refresh successful"))}catch(u){p.value=!0,I.value=u instanceof Error?u.message:String(u),c("Auto-refresh error:",u)}finally{g.value=!1,E=null}})(),E)}function ce(){p.value=!1,I.value=null}function z(){d.value&&(clearTimeout(d.value),d.value=null),e.value=null,n.value=null,t.value=null,i.value=null,a.value=null,o.value=443,s.value=null,p.value=!1,I.value=null,le(),c("Logged out")}function ue(){de(),e.value&&!w.value?(N(),c("Initialized from storage")):e.value&&w.value&&(c("Stored token expired, clearing"),z())}function A(){try{const u=L();e.value&&u.setItem("een_token",e.value),n.value&&u.setItem("een_tokenExpiration",String(n.value)),t.value&&u.setItem("een_refreshTokenMarker",t.value),i.value&&u.setItem("een_sessionId",i.value),a.value&&u.setItem("een_hostname",a.value),o.value!==443&&u.setItem("een_port",String(o.value)),s.value&&u.setItem("een_userProfile",JSON.stringify(s.value))}catch(u){c("Failed to save to storage:",u instanceof Error?u.message:String(u))}}function de(){try{const u=L();e.value=u.getItem("een_token");const _=u.getItem("een_tokenExpiration");n.value=_?parseInt(_,10):null,t.value=u.getItem("een_refreshTokenMarker"),i.value=u.getItem("een_sessionId"),a.value=u.getItem("een_hostname");const U=u.getItem("een_port");o.value=U?parseInt(U,10):443;const $=u.getItem("een_userProfile");s.value=$?JSON.parse($):null}catch(u){c("Failed to load from storage:",u instanceof Error?u.message:String(u))}}function le(){try{const u=L();u.removeItem("een_token"),u.removeItem("een_tokenExpiration"),u.removeItem("een_refreshTokenMarker"),u.removeItem("een_sessionId"),u.removeItem("een_hostname"),u.removeItem("een_port"),u.removeItem("een_userProfile")}catch(u){c("Failed to clear storage:",u instanceof Error?u.message:String(u))}}return{token:e,tokenExpiration:n,refreshTokenMarker:t,sessionId:i,hostname:a,port:o,userProfile:s,isRefreshing:g,refreshFailed:p,refreshFailedMessage:I,isAuthenticated:v,baseUrl:k,isTokenExpired:w,tokenExpiresIn:te,setToken:ne,setRefreshTokenMarker:re,setSessionId:ie,setBaseUrl:oe,setUserProfile:ae,setupAutoRefresh:N,clearRefreshFailed:ce,logout:z,initialize:ue}}),ve="https://auth.eagleeyenetworks.com/oauth2/authorize";function V(){const e=M();if(!e)throw new Error("Client ID not configured. Call initEenToolkit() or set VITE_EEN_CLIENT_ID");const n=crypto.randomUUID();try{sessionStorage.setItem("een_oauth_state",n)}catch{}const t=new URLSearchParams({client_id:e,response_type:"code",scope:"vms.all",redirect_uri:P(),state:n});return c("Generated auth URL with state:",n),`${ve}?${t.toString()}`}async function B(e){const n=O();if(!n)return r("AUTH_FAILED","Proxy URL not configured. Call initEenToolkit() or set VITE_PROXY_URL");const t=new URLSearchParams({code:e,redirect_uri:P()});try{const i=await fetch(`${n}/proxy/getAccessToken?${t.toString()}`,{method:"POST",credentials:"include",headers:{Accept:"application/json"}});if(!i.ok){const o=await i.text().catch(()=>"Unknown error");return r("AUTH_FAILED",`Token exchange failed: ${o}`,i.status)}const a=await i.json();return c("Token received, expires in:",a.expiresIn),l(a)}catch(i){return r("NETWORK_ERROR",`Failed to exchange code: ${String(i)}`)}}async function W(){const e=O();if(!e)return r("AUTH_FAILED","Proxy URL not configured");const n=f();try{const t={Accept:"application/json"};n.sessionId&&(t.Authorization=`Bearer ${n.sessionId}`);const i=await fetch(`${e}/proxy/refreshAccessToken`,{method:"POST",credentials:"include",headers:t});if(!i.ok){const o=await i.text().catch(()=>"Unknown error");return r("AUTH_FAILED",`Token refresh failed: ${o}`,i.status)}const a=await i.json();return n.setToken(a.accessToken,a.expiresIn),c("Token refreshed, expires in:",a.expiresIn),l(a)}catch(t){return r("NETWORK_ERROR",`Failed to refresh token: ${String(t)}`)}}async function K(){const e=O();if(!e)return r("AUTH_FAILED","Proxy URL not configured");const n=f();try{const t={Accept:"application/json"};n.sessionId&&(t.Authorization=`Bearer ${n.sessionId}`);const i=await fetch(`${e}/proxy/revoke`,{method:"POST",credentials:"include",headers:t});if(n.logout(),!i.ok){const a=await i.text().catch(()=>"Unknown error");return r("AUTH_FAILED",`Token revocation failed: ${a}`,i.status)}return c("Token revoked"),l(void 0)}catch(t){return n.logout(),r("NETWORK_ERROR",`Failed to revoke token: ${String(t)}`)}}async function G(e,n){let t=null;try{t=sessionStorage.getItem("een_oauth_state"),sessionStorage.removeItem("een_oauth_state")}catch{}if(!t)return r("AUTH_FAILED","No OAuth state found. Please restart the login process.");if(!ke(n,t))return r("AUTH_FAILED","Invalid OAuth state. Possible CSRF attack.");c("State validated, exchanging code for token");const i=await B(e);if(i.error)return i;const a=f(),o=i.data;return a.setToken(o.accessToken,o.expiresIn),a.setRefreshTokenMarker("present"),a.setSessionId(o.sessionId),a.setBaseUrl(o.httpsBaseUrl),c("Auth callback complete, user:",o.userEmail),l(o)}function ke(e,n){if(e.length!==n.length)return!1;let t=0;for(let i=0;i<e.length;i++)t|=e.charCodeAt(i)^n.charCodeAt(i);return t===0}const $e=Object.freeze(Object.defineProperty({__proto__:null,getAccessToken:B,getAuthUrl:V,handleAuthCallback:G,refreshToken:W,revokeToken:K},Symbol.toStringTag,{value:"Module"}));async function Oe(){const e=f();if(!e.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!e.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const n=`${e.baseUrl}/api/v3.0/users/self`;c("Fetching current user:",n);try{const t=await fetch(n,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${e.token}`}});if(!t.ok)return H(t);const i=await t.json();return c("Current user fetched:",i.email),e.setUserProfile(i),l(i)}catch(t){return r("NETWORK_ERROR",`Failed to fetch current user: ${String(t)}`)}}async function me(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.include&&e.include.length>0&&t.append("include",e.include.join(","));const i=t.toString(),a=`${n.baseUrl}/api/v3.0/users${i?`?${i}`:""}`;c("Fetching users:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return H(o);const s=await o.json();return c("Users fetched:",s.results?.length??0,"users"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch users: ${String(o)}`)}}async function De(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","User ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/users/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching user:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return H(s);const d=await s.json();return c("User fetched:",d.email),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch user: ${String(s)}`)}}async function H(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch{t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function we(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.include&&e.include.length>0&&t.append("include",e.include.join(",")),e?.sort&&e.sort.length>0&&t.append("sort",e.sort.join(",")),e?.locationId__in&&e.locationId__in.length>0&&t.append("locationId__in",e.locationId__in.join(",")),e?.bridgeId__in&&e.bridgeId__in.length>0&&t.append("bridgeId__in",e.bridgeId__in.join(",")),e?.multiCameraId&&t.append("multiCameraId",e.multiCameraId),e?.multiCameraId__ne&&t.append("multiCameraId__ne",e.multiCameraId__ne),e?.multiCameraId__in&&e.multiCameraId__in.length>0&&t.append("multiCameraId__in",e.multiCameraId__in.join(",")),e?.tags__contains&&e.tags__contains.length>0&&t.append("tags__contains",e.tags__contains.join(",")),e?.tags__any&&e.tags__any.length>0&&t.append("tags__any",e.tags__any.join(",")),e?.packages__contains&&e.packages__contains.length>0&&t.append("packages__contains",e.packages__contains.join(",")),e?.name&&t.append("name",e.name),e?.name__contains&&t.append("name__contains",e.name__contains),e?.name__in&&e.name__in.length>0&&t.append("name__in",e.name__in.join(",")),e?.id__in&&e.id__in.length>0&&t.append("id__in",e.id__in.join(",")),e?.id__notIn&&e.id__notIn.length>0&&t.append("id__notIn",e.id__notIn.join(",")),e?.id__contains&&t.append("id__contains",e.id__contains),e?.layoutId&&t.append("layoutId",e.layoutId),typeof e?.shared=="boolean"&&t.append("shareDetails.shared",String(e.shared)),e?.sharedCameraAccount&&t.append("shareDetails.accountId",e.sharedCameraAccount),typeof e?.firstResponder=="boolean"&&t.append("shareDetails.firstResponder",String(e.firstResponder)),typeof e?.directToCloud=="boolean"&&t.append("deviceInfo.directToCloud",String(e.directToCloud)),e?.speakerId__in&&e.speakerId__in.length>0&&t.append("speakerId__in",e.speakerId__in.join(",")),e?.q&&t.append("q",e.q),typeof e?.qRelevance__gte=="number"&&t.append("qRelevance__gte",String(e.qRelevance__gte)),e?.enabledAnalytics__contains&&e.enabledAnalytics__contains.length>0&&t.append("enabledAnalytics__contains",e.enabledAnalytics__contains.join(",")),e?.status__in&&e.status__in.length>0&&t.append("status__in",e.status__in.join(",")),e?.status__ne&&t.append("status__ne",e.status__ne);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/cameras${i?`?${i}`:""}`;c("Fetching cameras:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return J(o);const s=await o.json();return c("Cameras fetched:",s.results?.length??0,"cameras"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch cameras: ${String(o)}`)}}async function Ne(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Camera ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/cameras/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching camera:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return J(s);const d=await s.json();return c("Camera fetched:",d.name),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch camera: ${String(s)}`)}}async function J(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function be(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.include&&e.include.length>0&&t.append("include",e.include.join(",")),e?.sort&&e.sort.length>0&&t.append("sort",e.sort.join(",")),e?.locationId__in&&e.locationId__in.length>0&&t.append("locationId__in",e.locationId__in.join(",")),e?.tags__contains&&e.tags__contains.length>0&&t.append("tags__contains",e.tags__contains.join(",")),e?.tags__any&&e.tags__any.length>0&&t.append("tags__any",e.tags__any.join(",")),e?.name&&t.append("name",e.name),e?.name__contains&&t.append("name__contains",e.name__contains),e?.name__in&&e.name__in.length>0&&t.append("name__in",e.name__in.join(",")),e?.id__in&&e.id__in.length>0&&t.append("id__in",e.id__in.join(",")),e?.id__notIn&&e.id__notIn.length>0&&t.append("id__notIn",e.id__notIn.join(",")),e?.q&&t.append("q",e.q),typeof e?.qRelevance__gte=="number"&&t.append("qRelevance__gte",String(e.qRelevance__gte)),e?.status__in&&e.status__in.length>0&&t.append("status__in",e.status__in.join(",")),e?.status__ne&&t.append("status__ne",e.status__ne);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/bridges${i?`?${i}`:""}`;c("Fetching bridges:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return X(o);const s=await o.json();return c("Bridges fetched:",s.results?.length??0,"bridges"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch bridges: ${String(o)}`)}}async function je(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Bridge ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/bridges/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching bridge:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return X(s);const d=await s.json();return c("Bridge fetched:",d.name),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch bridge: ${String(s)}`)}}async function X(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}const Le=3e4;function S(e=Le){const n=new AbortController,t=setTimeout(()=>n.abort(),e);return{controller:n,timeoutId:t}}function Y(e){const n=new Uint8Array(e),t=8192,i=[];for(let o=0;o<n.byteLength;o+=t){const s=n.subarray(o,Math.min(o+t,n.byteLength));let d="";for(let g=0;g<s.length;g++)d+=String.fromCharCode(s[g]);i.push(d)}const a=i.join("");return typeof btoa=="function"?btoa(a):Buffer.from(a,"binary").toString("base64")}async function Fe(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId)return r("VALIDATION_ERROR","Device ID is required");if(!e.type)return r("VALIDATION_ERROR","Stream type is required (preview or main)");if(!e.mediaType)return r("VALIDATION_ERROR","Media type is required (video or image)");if(!e.startTimestamp)return r("VALIDATION_ERROR","Start timestamp is required");const t=new URLSearchParams;t.append("deviceId",e.deviceId),t.append("type",e.type),t.append("mediaType",e.mediaType),t.append("startTimestamp__gte",e.startTimestamp),e.endTimestamp&&t.append("endTimestamp__lte",e.endTimestamp),typeof e.coalesce=="boolean"&&t.append("coalesce",String(e.coalesce)),e.include&&e.include.length>0&&t.append("include",e.include.join(",")),e.pageToken&&t.append("pageToken",e.pageToken),typeof e.pageSize=="number"&&t.append("pageSize",String(e.pageSize));const i=`${n.baseUrl}/api/v3.0/media?${t.toString()}`;c("Fetching media intervals:",i);const{controller:a,timeoutId:o}=S();try{const s=await fetch(i,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`},signal:a.signal});if(!s.ok)return m(s);const d=await s.json();return c("Media intervals fetched:",d.results?.length??0,"intervals"),l(d)}catch(s){return s instanceof Error&&s.name==="AbortError"?r("NETWORK_ERROR","Request timed out"):r("NETWORK_ERROR",`Failed to fetch media intervals: ${String(s)}`)}finally{clearTimeout(o)}}async function qe(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId)return r("VALIDATION_ERROR","Device ID is required");const t=e.type??"preview",i=new URLSearchParams;i.append("deviceId",e.deviceId),i.append("type",t);const a=`${n.baseUrl}/api/v3.0/media/liveImage.jpeg?${i.toString()}`;c("Fetching live image:",a);const{controller:o,timeoutId:s}=S();try{const d=await fetch(a,{method:"GET",headers:{Accept:"image/jpeg",Authorization:`Bearer ${n.token}`},signal:o.signal}),g=d.headers.get("X-Een-Timestamp"),E=d.headers.get("X-Een-PrevToken");if(!d.ok)return m(d);const p=await d.arrayBuffer(),v=`data:image/jpeg;base64,${Y(p)}`;return c("Live image fetched, timestamp:",g),l({imageData:v,timestamp:g,prevToken:E})}catch(d){return d instanceof Error&&d.name==="AbortError"?r("NETWORK_ERROR","Request timed out"):r("NETWORK_ERROR",`Failed to fetch live image: ${String(d)}`)}finally{clearTimeout(s)}}async function Pe(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId&&!e.pageToken)return r("VALIDATION_ERROR","Either deviceId or pageToken is required");if(!e.pageToken&&!(e.timestamp__lt||e.timestamp__lte||e.timestamp||e.timestamp__gte||e.timestamp__gt))return r("VALIDATION_ERROR","At least one timestamp parameter is required");if(e.include?.includes("overlaySvgHeader")&&(!e.overlayId__in||e.overlayId__in.length===0))return r("VALIDATION_ERROR","At least one overlayId must be provided when requesting overlay headers");const t=new URLSearchParams;e.deviceId&&t.append("deviceId",e.deviceId),e.pageToken&&t.append("pageToken",e.pageToken),e.type&&t.append("type",e.type),e.timestamp__lt&&t.append("timestamp__lt",e.timestamp__lt),e.timestamp__lte&&t.append("timestamp__lte",e.timestamp__lte),e.timestamp&&t.append("timestamp",e.timestamp),e.timestamp__gte&&t.append("timestamp__gte",e.timestamp__gte),e.timestamp__gt&&t.append("timestamp__gt",e.timestamp__gt),e.overlayId__in&&e.overlayId__in.length>0&&t.append("overlayId__in",e.overlayId__in.join(",")),e.include&&e.include.length>0&&t.append("include",e.include.join(",")),typeof e.targetWidth=="number"&&t.append("targetWidth",String(e.targetWidth)),typeof e.targetHeight=="number"&&t.append("targetHeight",String(e.targetHeight));const i=`${n.baseUrl}/api/v3.0/media/recordedImage.jpeg?${t.toString()}`;c("Fetching recorded image:",i);const{controller:a,timeoutId:o}=S();try{const s=await fetch(i,{method:"GET",headers:{Accept:"image/jpeg",Authorization:`Bearer ${n.token}`},signal:a.signal}),d=s.headers.get("X-Een-Timestamp"),g=s.headers.get("X-Een-NextToken"),E=s.headers.get("X-Een-PrevToken"),p=s.headers.get("X-Een-OverlaySvg");if(!s.ok)return m(s);const I=await s.arrayBuffer(),k=`data:image/jpeg;base64,${Y(I)}`;return c("Recorded image fetched, timestamp:",d),l({imageData:k,timestamp:d,nextToken:g,prevToken:E,overlaySvg:p})}catch(s){return s instanceof Error&&s.name==="AbortError"?r("NETWORK_ERROR","Request timed out"):r("NETWORK_ERROR",`Failed to fetch recorded image: ${String(s)}`)}finally{clearTimeout(o)}}async function m(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch{t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);case 503:return r("SERVICE_UNAVAILABLE",`Service unavailable: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function Z(){const e=f();if(!e.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!e.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const n=`${e.baseUrl}/api/v3.0/media/session`;c("Fetching media session:",n);const{controller:t,timeoutId:i}=S();try{const a=await fetch(n,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${e.token}`},signal:t.signal});if(!a.ok)return m(a);const o=await a.json();return c("Media session URL received:",o.url),l(o)}catch(a){return a instanceof Error&&a.name==="AbortError"?r("NETWORK_ERROR","Request timed out"):r("NETWORK_ERROR",`Failed to fetch media session: ${String(a)}`)}finally{clearTimeout(i)}}async function Be(){const e=f();if(!e.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");const n=await Z();if(n.error)return r(n.error.code,`Failed to get media session: ${n.error.message}`,n.error.status);if(!n.data?.url)return r("API_ERROR","No session URL returned from media session endpoint");const t=n.data.url;c("Calling session URL to set cookie:",t);const{controller:i,timeoutId:a}=S();try{const o=await fetch(t,{method:"GET",credentials:"include",headers:{Accept:"*/*",Authorization:`Bearer ${e.token}`},signal:i.signal});if(!o.ok&&o.status!==204){const s=o.status;let d;try{const g=await o.json();d=g.message??g.error??o.statusText}catch{d=o.statusText||"Unknown error"}return r("API_ERROR",`Failed to set media session cookie: ${d}`,s)}return c("Media session cookie set successfully"),l({success:!0,sessionUrl:t})}catch(o){return o instanceof Error&&o.name==="AbortError"?r("NETWORK_ERROR","Request timed out while setting session cookie"):r("NETWORK_ERROR",`Failed to set media session cookie: ${String(o)}`)}finally{clearTimeout(a)}}async function He(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;typeof e?.pageSize=="number"&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.deviceId&&t.append("deviceId",e.deviceId),e?.deviceId__in&&e.deviceId__in.length>0&&t.append("deviceId__in",e.deviceId__in.join(",")),e?.type&&t.append("type",e.type),e?.include&&e.include.length>0&&t.append("include",e.include.join(","));const i=t.toString(),a=`${n.baseUrl}/api/v3.0/feeds${i?`?${i}`:""}`;c("Fetching feeds:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`},signal:e?.signal});if(!o.ok)return xe(o);const s=await o.json();return c("Feeds fetched:",s.results?.length??0,"feeds"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch feeds: ${String(o)}`)}}async function xe(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error}catch(i){c("Failed to parse error response JSON:",i)}switch(n){case 401:return r("AUTH_REQUIRED",t||"Authentication failed",n);case 403:return r("FORBIDDEN",t||"Access denied",n);case 404:return r("NOT_FOUND",t||"Not found",n);case 429:return r("RATE_LIMITED",t||"Rate limited",n);case 503:return r("SERVICE_UNAVAILABLE",t||"Service unavailable",n);default:return r("API_ERROR",t||e.statusText||"API error",n)}}async function ze(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.actor)return r("VALIDATION_ERROR","actor parameter is required");if(!e.type__in||e.type__in.length===0)return r("VALIDATION_ERROR","type__in parameter is required and must not be empty");if(!e.startTimestamp__gte)return r("VALIDATION_ERROR","startTimestamp__gte parameter is required");const t=new URLSearchParams;t.append("actor",e.actor),t.append("type__in",e.type__in.join(",")),t.append("startTimestamp__gte",R(e.startTimestamp__gte)),e.pageSize&&t.append("pageSize",String(e.pageSize)),e.pageToken&&t.append("pageToken",e.pageToken),e.startTimestamp__lte&&t.append("startTimestamp__lte",R(e.startTimestamp__lte)),e.endTimestamp__gte&&t.append("endTimestamp__gte",R(e.endTimestamp__gte)),e.endTimestamp__lte&&t.append("endTimestamp__lte",R(e.endTimestamp__lte)),e.sort&&t.append("sort",e.sort),e.include&&e.include.length>0&&t.append("include",e.include.join(","));const i=t.toString(),a=`${n.baseUrl}/api/v3.0/events${i?`?${i}`:""}`;c("Fetching events:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return D(o);const s=await o.json();return c("Events fetched:",s.results?.length??0,"events"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch events: ${String(o)}`)}}async function Ce(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Event ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/events/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching event:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return D(s);const d=await s.json();return c("Event fetched:",d.id),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch event: ${String(s)}`)}}async function Qe(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.language&&t.append("language",e.language);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/eventTypes${i?`?${i}`:""}`;c("Fetching event types:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return D(o);const s=await o.json();return c("Event types fetched:",s.results?.length??0,"types"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch event types: ${String(o)}`)}}async function Me(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.actor)return r("VALIDATION_ERROR","actor parameter is required");const t=new URLSearchParams;t.append("actor",e.actor);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/events:listFieldValues${i?`?${i}`:""}`;c("Fetching event field values:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return D(o);const s=await o.json();return c("Event field values fetched:",s.type?.length??0,"types"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch event field values: ${String(o)}`)}}async function D(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function Ve(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.actor)return r("VALIDATION_ERROR","actor parameter is required");if(!e.eventType)return r("VALIDATION_ERROR","eventType parameter is required");const t=new URLSearchParams;t.append("actor",e.actor),t.append("eventType",e.eventType),e.timestamp__gte&&t.append("timestamp__gte",R(e.timestamp__gte)),e.timestamp__lte&&t.append("timestamp__lte",R(e.timestamp__lte)),e.aggregateByMinutes!==void 0&&t.append("aggregateByMinutes",String(e.aggregateByMinutes));const i=t.toString(),a=`${n.baseUrl}/api/v3.0/eventMetrics${i?`?${i}`:""}`;c("Fetching event metrics:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return We(o);const s=await o.json();return c("Event metrics fetched:",s.length,"metrics"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch event metrics: ${String(o)}`)}}async function We(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function Ke(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.timestamp__lte&&t.append("timestamp__lte",R(e.timestamp__lte)),e?.timestamp__gte&&t.append("timestamp__gte",R(e.timestamp__gte)),e?.creatorId&&t.append("creatorId",e.creatorId),e?.alertType__in&&e.alertType__in.length>0&&t.append("alertType__in",e.alertType__in.join(",")),e?.actorId__in&&e.actorId__in.length>0&&t.append("actorId__in",e.actorId__in.join(",")),e?.actorType__in&&e.actorType__in.length>0&&t.append("actorType__in",e.actorType__in.join(",")),e?.actorAccountId&&t.append("actorAccountId",e.actorAccountId),e?.ruleId&&t.append("ruleId",e.ruleId),e?.ruleId__in&&e.ruleId__in.length>0&&t.append("ruleId__in",e.ruleId__in.join(",")),e?.eventId&&t.append("eventId",e.eventId),e?.locationId__in&&e.locationId__in.length>0&&t.append("locationId__in",e.locationId__in.join(",")),e?.priority__gte!==void 0&&t.append("priority__gte",String(e.priority__gte)),e?.priority__lte!==void 0&&t.append("priority__lte",String(e.priority__lte)),e?.showInvalidAlerts!==void 0&&t.append("showInvalidAlerts",String(e.showInvalidAlerts)),e?.alertActionId__in&&e.alertActionId__in.length>0&&t.append("alertActionId__in",e.alertActionId__in.join(",")),e?.alertActionStatus__in&&e.alertActionStatus__in.length>0&&t.append("alertActionStatus__in",e.alertActionStatus__in.join(",")),e?.include&&e.include.length>0&&t.append("include",e.include.join(",")),e?.sort&&e.sort.length>0&&t.append("sort",e.sort.join(",")),e?.language&&t.append("language",e.language);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/alerts${i?`?${i}`:""}`;c("Fetching alerts:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return x(o);const s=await o.json();return c("Alerts fetched:",s.results?.length??0,"alerts"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch alerts: ${String(o)}`)}}async function Ge(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Alert ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/alerts/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching alert:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return x(s);const d=await s.json();return c("Alert fetched:",d.id),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch alert: ${String(s)}`)}}async function Je(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/alertTypes${i?`?${i}`:""}`;c("Fetching alert types:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return x(o);const s=await o.json();return c("Alert types fetched:",s.results?.length??0,"types"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch alert types: ${String(o)}`)}}async function x(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function Xe(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.timestamp__lte&&t.append("timestamp__lte",R(e.timestamp__lte)),e?.timestamp__gte&&t.append("timestamp__gte",R(e.timestamp__gte)),e?.alertId&&t.append("alertId",e.alertId),e?.alertType&&t.append("alertType",e.alertType),e?.actorId&&t.append("actorId",e.actorId),e?.actorType&&t.append("actorType",e.actorType),e?.actorAccountId&&t.append("actorAccountId",e.actorAccountId),e?.category&&t.append("category",e.category),e?.userId&&t.append("userId",e.userId),e?.read!==void 0&&t.append("read",String(e.read)),e?.status&&t.append("status",e.status),e?.includeV1Notifications!==void 0&&t.append("includeV1Notifications",String(e.includeV1Notifications)),e?.sort&&e.sort.length>0&&t.append("sort",e.sort.join(",")),e?.language&&t.append("language",e.language);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/notifications${i?`?${i}`:""}`;c("Fetching notifications:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return ee(o);const s=await o.json();return c("Notifications fetched:",s.results?.length??0,"notifications"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch notifications: ${String(o)}`)}}async function Ye(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Notification ID is required");const t=`${n.baseUrl}/api/v3.0/notifications/${encodeURIComponent(e)}`;c("Fetching notification:",t);try{const i=await fetch(t,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!i.ok)return ee(i);const a=await i.json();return c("Notification fetched:",a.id),l(a)}catch(i){return r("NETWORK_ERROR",`Failed to fetch notification: ${String(i)}`)}}async function ee(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}exports.STORAGE_STRATEGY_DESCRIPTIONS=Ee;exports.failure=r;exports.formatTimestamp=R;exports.getAccessToken=B;exports.getAlert=Ge;exports.getAuthUrl=V;exports.getBridge=je;exports.getBridges=be;exports.getCamera=Ne;exports.getCameras=we;exports.getClientId=M;exports.getConfig=ye;exports.getCurrentUser=Oe;exports.getEvent=Ce;exports.getEventMetrics=Ve;exports.getLiveImage=qe;exports.getMediaSession=Z;exports.getNotification=Ye;exports.getProxyUrl=O;exports.getRecordedImage=Pe;exports.getRedirectUri=P;exports.getStorageStrategy=Ae;exports.getUser=De;exports.getUsers=me;exports.handleAuthCallback=G;exports.initEenToolkit=Ue;exports.initMediaSession=Be;exports.listAlertTypes=Je;exports.listAlerts=Ke;exports.listEventFieldValues=Me;exports.listEventTypes=Qe;exports.listEvents=ze;exports.listFeeds=He;exports.listMedia=Fe;exports.listNotifications=Xe;exports.refreshToken=W;exports.revokeToken=K;exports.success=l;exports.useAuthStore=f;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Re=require("pinia"),R=require("vue"),pe={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1},Ee=()=>{try{return pe?.VITE_DEBUG==="true"}catch{return!1}};function c(...e){Ee()&&console.log("[een-api-toolkit]",...e)}const Te={localStorage:"persists across sessions",sessionStorage:"per-tab, cleared on tab close",memory:"tokens lost on page refresh"};class Ie{store=new Map;getItem(n){return this.store.get(n)??null}setItem(n,t){this.store.set(n,t)}removeItem(n){this.store.delete(n)}}class X{constructor(n){this.storage=n}getItem(n){return this.storage.getItem(n)}setItem(n,t){this.storage.setItem(n,t)}removeItem(n){this.storage.removeItem(n)}}let Q="localStorage",H=null;function x(){return H||(H=new Ie),H}function Ae(e){Q=e}function Ue(){return Q}function z(){switch(Q){case"memory":return x();case"sessionStorage":return typeof sessionStorage<"u"?new X(sessionStorage):(c("sessionStorage unavailable, falling back to memory storage"),x());default:return typeof localStorage<"u"?new X(localStorage):(c("localStorage unavailable, falling back to memory storage"),x())}}const v={};let D={};function Se(e={}){const n=e.storageStrategy??"localStorage";Ae(n),D={proxyUrl:e.proxyUrl??v?.VITE_PROXY_URL,clientId:e.clientId??v?.VITE_EEN_CLIENT_ID,redirectUri:e.redirectUri??v?.VITE_REDIRECT_URI,storageStrategy:n,debug:e.debug??v?.VITE_DEBUG==="true"}}function ye(){return D}function N(){return D.proxyUrl??v?.VITE_PROXY_URL}function Y(){return D.clientId??v?.VITE_EEN_CLIENT_ID}function V(){return D.redirectUri??v?.VITE_REDIRECT_URI??"http://127.0.0.1:3333"}function l(e){return{data:e,error:null}}function r(e,n,t,i){return{data:null,error:{code:e,message:n,status:t,details:i}}}function T(e){return e.endsWith("+00:00")?e:e.endsWith("Z")?e.replace("Z","+00:00"):e}let C=null;function ve(){return C||(C=Promise.resolve().then(()=>Oe).then(e=>e.refreshToken)),C}const f=Re.defineStore("een-auth",()=>{const e=R.ref(null),n=R.ref(null),t=R.ref(null),i=R.ref(null),a=R.ref(null),o=R.ref(443),s=R.ref(null),d=R.ref(null),h=R.ref(!1);let I=null;const E=R.ref(!1),g=R.ref(null),S=R.computed(()=>!!e.value),y=R.computed(()=>a.value?o.value===443?`https://${a.value}`:`https://${a.value}:${o.value}`:null),p=R.computed(()=>n.value?Date.now()>=n.value:!0),q=R.computed(()=>n.value?Math.max(0,n.value-Date.now()):0);function B(u,_){e.value=u,n.value=Date.now()+_*1e3,$(),P(),c("Token set, expires in",_,"seconds")}function b(u){t.value=u,$()}function U(u){i.value=u,$()}function k(u){if(typeof u=="string")try{const _=new URL(u.startsWith("http")?u:`https://${u}`);a.value=_.hostname,o.value=_.port?parseInt(_.port,10):443}catch(_){c("Failed to parse URL, using as hostname:",_ instanceof Error?_.message:String(_)),a.value=u,o.value=443}else a.value=u.hostname,o.value=u.port??443;$(),c("Base URL set:",y.value)}function A(u){s.value=u,$()}function P(){if(d.value&&(clearTimeout(d.value),d.value=null),!n.value||!e.value)return;const u=Date.now(),O=n.value-u,w=300*1e3,ge=O/2,_e=Math.min(w,ge),he=Math.max(O-_e,60*1e3),J=Math.max(he,5e3);c("Auto-refresh scheduled in",Math.round(J/1e3),"seconds"),d.value=setTimeout(async()=>{await ce()},J)}async function ce(){return I?(c("Refresh already in progress, waiting for existing refresh"),I):(h.value=!0,c("Performing auto-refresh"),I=(async()=>{try{const _=await(await ve())();_.error?(E.value=!0,g.value=_.error.message,c("Auto-refresh failed:",_.error.message)):(E.value=!1,g.value=null,c("Auto-refresh successful"))}catch(u){E.value=!0,g.value=u instanceof Error?u.message:String(u),c("Auto-refresh error:",u)}finally{h.value=!1,I=null}})(),I)}function ue(){E.value=!1,g.value=null}function G(){d.value&&(clearTimeout(d.value),d.value=null),e.value=null,n.value=null,t.value=null,i.value=null,a.value=null,o.value=443,s.value=null,E.value=!1,g.value=null,fe(),c("Logged out")}function de(){le(),e.value&&!p.value?(P(),c("Initialized from storage")):e.value&&p.value&&(c("Stored token expired, clearing"),G())}function $(){try{const u=z();e.value&&u.setItem("een_token",e.value),n.value&&u.setItem("een_tokenExpiration",String(n.value)),t.value&&u.setItem("een_refreshTokenMarker",t.value),i.value&&u.setItem("een_sessionId",i.value),a.value&&u.setItem("een_hostname",a.value),o.value!==443&&u.setItem("een_port",String(o.value)),s.value&&u.setItem("een_userProfile",JSON.stringify(s.value))}catch(u){c("Failed to save to storage:",u instanceof Error?u.message:String(u))}}function le(){try{const u=z();e.value=u.getItem("een_token");const _=u.getItem("een_tokenExpiration");n.value=_?parseInt(_,10):null,t.value=u.getItem("een_refreshTokenMarker"),i.value=u.getItem("een_sessionId"),a.value=u.getItem("een_hostname");const O=u.getItem("een_port");o.value=O?parseInt(O,10):443;const w=u.getItem("een_userProfile");s.value=w?JSON.parse(w):null}catch(u){c("Failed to load from storage:",u instanceof Error?u.message:String(u))}}function fe(){try{const u=z();u.removeItem("een_token"),u.removeItem("een_tokenExpiration"),u.removeItem("een_refreshTokenMarker"),u.removeItem("een_sessionId"),u.removeItem("een_hostname"),u.removeItem("een_port"),u.removeItem("een_userProfile")}catch(u){c("Failed to clear storage:",u instanceof Error?u.message:String(u))}}return{token:e,tokenExpiration:n,refreshTokenMarker:t,sessionId:i,hostname:a,port:o,userProfile:s,isRefreshing:h,refreshFailed:E,refreshFailedMessage:g,isAuthenticated:S,baseUrl:y,isTokenExpired:p,tokenExpiresIn:q,setToken:B,setRefreshTokenMarker:b,setSessionId:U,setBaseUrl:k,setUserProfile:A,setupAutoRefresh:P,clearRefreshFailed:ue,logout:G,initialize:de}}),ke="https://auth.eagleeyenetworks.com/oauth2/authorize";function Z(){const e=Y();if(!e)throw new Error("Client ID not configured. Call initEenToolkit() or set VITE_EEN_CLIENT_ID");const n=crypto.randomUUID();try{sessionStorage.setItem("een_oauth_state",n)}catch{}const t=new URLSearchParams({client_id:e,response_type:"code",scope:"vms.all",redirect_uri:V(),state:n});return c("Generated auth URL with state:",n),`${ke}?${t.toString()}`}async function M(e){const n=N();if(!n)return r("AUTH_FAILED","Proxy URL not configured. Call initEenToolkit() or set VITE_PROXY_URL");const t=new URLSearchParams({code:e,redirect_uri:V()});try{const i=await fetch(`${n}/proxy/getAccessToken?${t.toString()}`,{method:"POST",credentials:"include",headers:{Accept:"application/json"}});if(!i.ok){const o=await i.text().catch(()=>"Unknown error");return r("AUTH_FAILED",`Token exchange failed: ${o}`,i.status)}const a=await i.json();return c("Token received, expires in:",a.expiresIn),l(a)}catch(i){return r("NETWORK_ERROR",`Failed to exchange code: ${String(i)}`)}}async function ee(){const e=N();if(!e)return r("AUTH_FAILED","Proxy URL not configured");const n=f();try{const t={Accept:"application/json"};n.sessionId&&(t.Authorization=`Bearer ${n.sessionId}`);const i=await fetch(`${e}/proxy/refreshAccessToken`,{method:"POST",credentials:"include",headers:t});if(!i.ok){const o=await i.text().catch(()=>"Unknown error");return r("AUTH_FAILED",`Token refresh failed: ${o}`,i.status)}const a=await i.json();return n.setToken(a.accessToken,a.expiresIn),c("Token refreshed, expires in:",a.expiresIn),l(a)}catch(t){return r("NETWORK_ERROR",`Failed to refresh token: ${String(t)}`)}}async function te(){const e=N();if(!e)return r("AUTH_FAILED","Proxy URL not configured");const n=f();try{const t={Accept:"application/json"};n.sessionId&&(t.Authorization=`Bearer ${n.sessionId}`);const i=await fetch(`${e}/proxy/revoke`,{method:"POST",credentials:"include",headers:t});if(n.logout(),!i.ok){const a=await i.text().catch(()=>"Unknown error");return r("AUTH_FAILED",`Token revocation failed: ${a}`,i.status)}return c("Token revoked"),l(void 0)}catch(t){return n.logout(),r("NETWORK_ERROR",`Failed to revoke token: ${String(t)}`)}}async function ne(e,n){let t=null;try{t=sessionStorage.getItem("een_oauth_state"),sessionStorage.removeItem("een_oauth_state")}catch{}if(!t)return r("AUTH_FAILED","No OAuth state found. Please restart the login process.");if(!$e(n,t))return r("AUTH_FAILED","Invalid OAuth state. Possible CSRF attack.");c("State validated, exchanging code for token");const i=await M(e);if(i.error)return i;const a=f(),o=i.data;return a.setToken(o.accessToken,o.expiresIn),a.setRefreshTokenMarker("present"),a.setSessionId(o.sessionId),a.setBaseUrl(o.httpsBaseUrl),c("Auth callback complete, user:",o.userEmail),l(o)}function $e(e,n){if(e.length!==n.length)return!1;let t=0;for(let i=0;i<e.length;i++)t|=e.charCodeAt(i)^n.charCodeAt(i);return t===0}const Oe=Object.freeze(Object.defineProperty({__proto__:null,getAccessToken:M,getAuthUrl:Z,handleAuthCallback:ne,refreshToken:ee,revokeToken:te},Symbol.toStringTag,{value:"Module"}));async function De(){const e=f();if(!e.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!e.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const n=`${e.baseUrl}/api/v3.0/users/self`;c("Fetching current user:",n);try{const t=await fetch(n,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${e.token}`}});if(!t.ok)return W(t);const i=await t.json();return c("Current user fetched:",i.email),e.setUserProfile(i),l(i)}catch(t){return r("NETWORK_ERROR",`Failed to fetch current user: ${String(t)}`)}}async function me(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.include&&e.include.length>0&&t.append("include",e.include.join(","));const i=t.toString(),a=`${n.baseUrl}/api/v3.0/users${i?`?${i}`:""}`;c("Fetching users:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return W(o);const s=await o.json();return c("Users fetched:",s.results?.length??0,"users"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch users: ${String(o)}`)}}async function be(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","User ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/users/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching user:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return W(s);const d=await s.json();return c("User fetched:",d.email),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch user: ${String(s)}`)}}async function W(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch{t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function we(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.include&&e.include.length>0&&t.append("include",e.include.join(",")),e?.sort&&e.sort.length>0&&t.append("sort",e.sort.join(",")),e?.locationId__in&&e.locationId__in.length>0&&t.append("locationId__in",e.locationId__in.join(",")),e?.bridgeId__in&&e.bridgeId__in.length>0&&t.append("bridgeId__in",e.bridgeId__in.join(",")),e?.multiCameraId&&t.append("multiCameraId",e.multiCameraId),e?.multiCameraId__ne&&t.append("multiCameraId__ne",e.multiCameraId__ne),e?.multiCameraId__in&&e.multiCameraId__in.length>0&&t.append("multiCameraId__in",e.multiCameraId__in.join(",")),e?.tags__contains&&e.tags__contains.length>0&&t.append("tags__contains",e.tags__contains.join(",")),e?.tags__any&&e.tags__any.length>0&&t.append("tags__any",e.tags__any.join(",")),e?.packages__contains&&e.packages__contains.length>0&&t.append("packages__contains",e.packages__contains.join(",")),e?.name&&t.append("name",e.name),e?.name__contains&&t.append("name__contains",e.name__contains),e?.name__in&&e.name__in.length>0&&t.append("name__in",e.name__in.join(",")),e?.id__in&&e.id__in.length>0&&t.append("id__in",e.id__in.join(",")),e?.id__notIn&&e.id__notIn.length>0&&t.append("id__notIn",e.id__notIn.join(",")),e?.id__contains&&t.append("id__contains",e.id__contains),e?.layoutId&&t.append("layoutId",e.layoutId),typeof e?.shared=="boolean"&&t.append("shareDetails.shared",String(e.shared)),e?.sharedCameraAccount&&t.append("shareDetails.accountId",e.sharedCameraAccount),typeof e?.firstResponder=="boolean"&&t.append("shareDetails.firstResponder",String(e.firstResponder)),typeof e?.directToCloud=="boolean"&&t.append("deviceInfo.directToCloud",String(e.directToCloud)),e?.speakerId__in&&e.speakerId__in.length>0&&t.append("speakerId__in",e.speakerId__in.join(",")),e?.q&&t.append("q",e.q),typeof e?.qRelevance__gte=="number"&&t.append("qRelevance__gte",String(e.qRelevance__gte)),e?.enabledAnalytics__contains&&e.enabledAnalytics__contains.length>0&&t.append("enabledAnalytics__contains",e.enabledAnalytics__contains.join(",")),e?.status__in&&e.status__in.length>0&&t.append("status__in",e.status__in.join(",")),e?.status__ne&&t.append("status__ne",e.status__ne);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/cameras${i?`?${i}`:""}`;c("Fetching cameras:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return re(o);const s=await o.json();return c("Cameras fetched:",s.results?.length??0,"cameras"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch cameras: ${String(o)}`)}}async function Ne(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Camera ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/cameras/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching camera:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return re(s);const d=await s.json();return c("Camera fetched:",d.name),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch camera: ${String(s)}`)}}async function re(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function Le(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.include&&e.include.length>0&&t.append("include",e.include.join(",")),e?.sort&&e.sort.length>0&&t.append("sort",e.sort.join(",")),e?.locationId__in&&e.locationId__in.length>0&&t.append("locationId__in",e.locationId__in.join(",")),e?.tags__contains&&e.tags__contains.length>0&&t.append("tags__contains",e.tags__contains.join(",")),e?.tags__any&&e.tags__any.length>0&&t.append("tags__any",e.tags__any.join(",")),e?.name&&t.append("name",e.name),e?.name__contains&&t.append("name__contains",e.name__contains),e?.name__in&&e.name__in.length>0&&t.append("name__in",e.name__in.join(",")),e?.id__in&&e.id__in.length>0&&t.append("id__in",e.id__in.join(",")),e?.id__notIn&&e.id__notIn.length>0&&t.append("id__notIn",e.id__notIn.join(",")),e?.q&&t.append("q",e.q),typeof e?.qRelevance__gte=="number"&&t.append("qRelevance__gte",String(e.qRelevance__gte)),e?.status__in&&e.status__in.length>0&&t.append("status__in",e.status__in.join(",")),e?.status__ne&&t.append("status__ne",e.status__ne);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/bridges${i?`?${i}`:""}`;c("Fetching bridges:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return ie(o);const s=await o.json();return c("Bridges fetched:",s.results?.length??0,"bridges"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch bridges: ${String(o)}`)}}async function je(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Bridge ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/bridges/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching bridge:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return ie(s);const d=await s.json();return c("Bridge fetched:",d.name),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch bridge: ${String(s)}`)}}async function ie(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}const Fe=3e4;function m(e=Fe){const n=new AbortController,t=setTimeout(()=>n.abort(),e);return{controller:n,timeoutId:t}}function oe(e){const n=new Uint8Array(e),t=8192,i=[];for(let o=0;o<n.byteLength;o+=t){const s=n.subarray(o,Math.min(o+t,n.byteLength));let d="";for(let h=0;h<s.length;h++)d+=String.fromCharCode(s[h]);i.push(d)}const a=i.join("");return typeof btoa=="function"?btoa(a):Buffer.from(a,"binary").toString("base64")}async function qe(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId)return r("VALIDATION_ERROR","Device ID is required");if(!e.type)return r("VALIDATION_ERROR","Stream type is required (preview or main)");if(!e.mediaType)return r("VALIDATION_ERROR","Media type is required (video or image)");if(!e.startTimestamp)return r("VALIDATION_ERROR","Start timestamp is required");const t=new URLSearchParams;t.append("deviceId",e.deviceId),t.append("type",e.type),t.append("mediaType",e.mediaType),t.append("startTimestamp__gte",e.startTimestamp),e.endTimestamp&&t.append("endTimestamp__lte",e.endTimestamp),typeof e.coalesce=="boolean"&&t.append("coalesce",String(e.coalesce)),e.include&&e.include.length>0&&t.append("include",e.include.join(",")),e.pageToken&&t.append("pageToken",e.pageToken),typeof e.pageSize=="number"&&t.append("pageSize",String(e.pageSize));const i=`${n.baseUrl}/api/v3.0/media?${t.toString()}`;c("Fetching media intervals:",i);const{controller:a,timeoutId:o}=m();try{const s=await fetch(i,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`},signal:a.signal});if(!s.ok)return L(s);const d=await s.json();return c("Media intervals fetched:",d.results?.length??0,"intervals"),l(d)}catch(s){return s instanceof Error&&s.name==="AbortError"?r("NETWORK_ERROR","Request timed out"):r("NETWORK_ERROR",`Failed to fetch media intervals: ${String(s)}`)}finally{clearTimeout(o)}}async function Be(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId)return r("VALIDATION_ERROR","Device ID is required");const t=e.type??"preview",i=new URLSearchParams;i.append("deviceId",e.deviceId),i.append("type",t);const a=`${n.baseUrl}/api/v3.0/media/liveImage.jpeg?${i.toString()}`;c("Fetching live image:",a);const{controller:o,timeoutId:s}=m();try{const d=await fetch(a,{method:"GET",headers:{Accept:"image/jpeg",Authorization:`Bearer ${n.token}`},signal:o.signal}),h=d.headers.get("X-Een-Timestamp"),I=d.headers.get("X-Een-PrevToken");if(!d.ok)return L(d);const E=await d.arrayBuffer(),S=`data:image/jpeg;base64,${oe(E)}`;return c("Live image fetched, timestamp:",h),l({imageData:S,timestamp:h,prevToken:I})}catch(d){return d instanceof Error&&d.name==="AbortError"?r("NETWORK_ERROR","Request timed out"):r("NETWORK_ERROR",`Failed to fetch live image: ${String(d)}`)}finally{clearTimeout(s)}}async function Pe(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId&&!e.pageToken)return r("VALIDATION_ERROR","Either deviceId or pageToken is required");if(!e.pageToken&&!(e.timestamp__lt||e.timestamp__lte||e.timestamp||e.timestamp__gte||e.timestamp__gt))return r("VALIDATION_ERROR","At least one timestamp parameter is required");if(e.include?.includes("overlaySvgHeader")&&(!e.overlayId__in||e.overlayId__in.length===0))return r("VALIDATION_ERROR","At least one overlayId must be provided when requesting overlay headers");const t=new URLSearchParams;e.deviceId&&t.append("deviceId",e.deviceId),e.pageToken&&t.append("pageToken",e.pageToken),e.type&&t.append("type",e.type),e.timestamp__lt&&t.append("timestamp__lt",e.timestamp__lt),e.timestamp__lte&&t.append("timestamp__lte",e.timestamp__lte),e.timestamp&&t.append("timestamp",e.timestamp),e.timestamp__gte&&t.append("timestamp__gte",e.timestamp__gte),e.timestamp__gt&&t.append("timestamp__gt",e.timestamp__gt),e.overlayId__in&&e.overlayId__in.length>0&&t.append("overlayId__in",e.overlayId__in.join(",")),e.include&&e.include.length>0&&t.append("include",e.include.join(",")),typeof e.targetWidth=="number"&&t.append("targetWidth",String(e.targetWidth)),typeof e.targetHeight=="number"&&t.append("targetHeight",String(e.targetHeight));const i=`${n.baseUrl}/api/v3.0/media/recordedImage.jpeg?${t.toString()}`;c("Fetching recorded image:",i);const{controller:a,timeoutId:o}=m();try{const s=await fetch(i,{method:"GET",headers:{Accept:"image/jpeg",Authorization:`Bearer ${n.token}`},signal:a.signal}),d=s.headers.get("X-Een-Timestamp"),h=s.headers.get("X-Een-NextToken"),I=s.headers.get("X-Een-PrevToken"),E=s.headers.get("X-Een-OverlaySvg");if(!s.ok)return L(s);const g=await s.arrayBuffer(),y=`data:image/jpeg;base64,${oe(g)}`;return c("Recorded image fetched, timestamp:",d),l({imageData:y,timestamp:d,nextToken:h,prevToken:I,overlaySvg:E})}catch(s){return s instanceof Error&&s.name==="AbortError"?r("NETWORK_ERROR","Request timed out"):r("NETWORK_ERROR",`Failed to fetch recorded image: ${String(s)}`)}finally{clearTimeout(o)}}async function L(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch{t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);case 503:return r("SERVICE_UNAVAILABLE",`Service unavailable: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function ae(){const e=f();if(!e.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!e.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const n=`${e.baseUrl}/api/v3.0/media/session`;c("Fetching media session:",n);const{controller:t,timeoutId:i}=m();try{const a=await fetch(n,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${e.token}`},signal:t.signal});if(!a.ok)return L(a);const o=await a.json();return c("Media session URL received:",o.url),l(o)}catch(a){return a instanceof Error&&a.name==="AbortError"?r("NETWORK_ERROR","Request timed out"):r("NETWORK_ERROR",`Failed to fetch media session: ${String(a)}`)}finally{clearTimeout(i)}}async function He(){const e=f();if(!e.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");const n=await ae();if(n.error)return r(n.error.code,`Failed to get media session: ${n.error.message}`,n.error.status);if(!n.data?.url)return r("API_ERROR","No session URL returned from media session endpoint");const t=n.data.url;c("Calling session URL to set cookie:",t);const{controller:i,timeoutId:a}=m();try{const o=await fetch(t,{method:"GET",credentials:"include",headers:{Accept:"*/*",Authorization:`Bearer ${e.token}`},signal:i.signal});if(!o.ok&&o.status!==204){const s=o.status;let d;try{const h=await o.json();d=h.message??h.error??o.statusText}catch{d=o.statusText||"Unknown error"}return r("API_ERROR",`Failed to set media session cookie: ${d}`,s)}return c("Media session cookie set successfully"),l({success:!0,sessionUrl:t})}catch(o){return o instanceof Error&&o.name==="AbortError"?r("NETWORK_ERROR","Request timed out while setting session cookie"):r("NETWORK_ERROR",`Failed to set media session cookie: ${String(o)}`)}finally{clearTimeout(a)}}async function xe(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;typeof e?.pageSize=="number"&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.deviceId&&t.append("deviceId",e.deviceId),e?.deviceId__in&&e.deviceId__in.length>0&&t.append("deviceId__in",e.deviceId__in.join(",")),e?.type&&t.append("type",e.type),e?.include&&e.include.length>0&&t.append("include",e.include.join(","));const i=t.toString(),a=`${n.baseUrl}/api/v3.0/feeds${i?`?${i}`:""}`;c("Fetching feeds:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`},signal:e?.signal});if(!o.ok)return ze(o);const s=await o.json();return c("Feeds fetched:",s.results?.length??0,"feeds"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch feeds: ${String(o)}`)}}async function ze(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error}catch(i){c("Failed to parse error response JSON:",i)}switch(n){case 401:return r("AUTH_REQUIRED",t||"Authentication failed",n);case 403:return r("FORBIDDEN",t||"Access denied",n);case 404:return r("NOT_FOUND",t||"Not found",n);case 429:return r("RATE_LIMITED",t||"Rate limited",n);case 503:return r("SERVICE_UNAVAILABLE",t||"Service unavailable",n);default:return r("API_ERROR",t||e.statusText||"API error",n)}}async function Ce(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.actor)return r("VALIDATION_ERROR","actor parameter is required");if(!e.type__in||e.type__in.length===0)return r("VALIDATION_ERROR","type__in parameter is required and must not be empty");if(!e.startTimestamp__gte)return r("VALIDATION_ERROR","startTimestamp__gte parameter is required");const t=new URLSearchParams;t.append("actor",e.actor),t.append("type__in",e.type__in.join(",")),t.append("startTimestamp__gte",T(e.startTimestamp__gte)),e.pageSize&&t.append("pageSize",String(e.pageSize)),e.pageToken&&t.append("pageToken",e.pageToken),e.startTimestamp__lte&&t.append("startTimestamp__lte",T(e.startTimestamp__lte)),e.endTimestamp__gte&&t.append("endTimestamp__gte",T(e.endTimestamp__gte)),e.endTimestamp__lte&&t.append("endTimestamp__lte",T(e.endTimestamp__lte)),e.sort&&t.append("sort",e.sort),e.include&&e.include.length>0&&t.append("include",e.include.join(","));const i=t.toString(),a=`${n.baseUrl}/api/v3.0/events${i?`?${i}`:""}`;c("Fetching events:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return j(o);const s=await o.json();return c("Events fetched:",s.results?.length??0,"events"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch events: ${String(o)}`)}}async function Qe(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Event ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/events/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching event:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return j(s);const d=await s.json();return c("Event fetched:",d.id),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch event: ${String(s)}`)}}async function Ve(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.language&&t.append("language",e.language);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/eventTypes${i?`?${i}`:""}`;c("Fetching event types:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return j(o);const s=await o.json();return c("Event types fetched:",s.results?.length??0,"types"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch event types: ${String(o)}`)}}async function Me(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.actor)return r("VALIDATION_ERROR","actor parameter is required");const t=new URLSearchParams;t.append("actor",e.actor);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/events:listFieldValues${i?`?${i}`:""}`;c("Fetching event field values:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return j(o);const s=await o.json();return c("Event field values fetched:",s.type?.length??0,"types"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch event field values: ${String(o)}`)}}async function j(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function We(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.actor)return r("VALIDATION_ERROR","actor parameter is required");if(!e.eventType)return r("VALIDATION_ERROR","eventType parameter is required");const t=new URLSearchParams;t.append("actor",e.actor),t.append("eventType",e.eventType),e.timestamp__gte&&t.append("timestamp__gte",T(e.timestamp__gte)),e.timestamp__lte&&t.append("timestamp__lte",T(e.timestamp__lte)),e.aggregateByMinutes!==void 0&&t.append("aggregateByMinutes",String(e.aggregateByMinutes));const i=t.toString(),a=`${n.baseUrl}/api/v3.0/eventMetrics${i?`?${i}`:""}`;c("Fetching event metrics:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return Ke(o);const s=await o.json();return c("Event metrics fetched:",s.length,"metrics"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch event metrics: ${String(o)}`)}}async function Ke(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function Ge(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.timestamp__lte&&t.append("timestamp__lte",T(e.timestamp__lte)),e?.timestamp__gte&&t.append("timestamp__gte",T(e.timestamp__gte)),e?.creatorId&&t.append("creatorId",e.creatorId),e?.alertType__in&&e.alertType__in.length>0&&t.append("alertType__in",e.alertType__in.join(",")),e?.actorId__in&&e.actorId__in.length>0&&t.append("actorId__in",e.actorId__in.join(",")),e?.actorType__in&&e.actorType__in.length>0&&t.append("actorType__in",e.actorType__in.join(",")),e?.actorAccountId&&t.append("actorAccountId",e.actorAccountId),e?.ruleId&&t.append("ruleId",e.ruleId),e?.ruleId__in&&e.ruleId__in.length>0&&t.append("ruleId__in",e.ruleId__in.join(",")),e?.eventId&&t.append("eventId",e.eventId),e?.locationId__in&&e.locationId__in.length>0&&t.append("locationId__in",e.locationId__in.join(",")),e?.priority__gte!==void 0&&t.append("priority__gte",String(e.priority__gte)),e?.priority__lte!==void 0&&t.append("priority__lte",String(e.priority__lte)),e?.showInvalidAlerts!==void 0&&t.append("showInvalidAlerts",String(e.showInvalidAlerts)),e?.alertActionId__in&&e.alertActionId__in.length>0&&t.append("alertActionId__in",e.alertActionId__in.join(",")),e?.alertActionStatus__in&&e.alertActionStatus__in.length>0&&t.append("alertActionStatus__in",e.alertActionStatus__in.join(",")),e?.include&&e.include.length>0&&t.append("include",e.include.join(",")),e?.sort&&e.sort.length>0&&t.append("sort",e.sort.join(",")),e?.language&&t.append("language",e.language);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/alerts${i?`?${i}`:""}`;c("Fetching alerts:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return K(o);const s=await o.json();return c("Alerts fetched:",s.results?.length??0,"alerts"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch alerts: ${String(o)}`)}}async function Je(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Alert ID is required");const i=new URLSearchParams;n?.include&&n.include.length>0&&i.append("include",n.include.join(","));const a=i.toString(),o=`${t.baseUrl}/api/v3.0/alerts/${encodeURIComponent(e)}${a?`?${a}`:""}`;c("Fetching alert:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return K(s);const d=await s.json();return c("Alert fetched:",d.id),l(d)}catch(s){return r("NETWORK_ERROR",`Failed to fetch alert: ${String(s)}`)}}async function Xe(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/alertTypes${i?`?${i}`:""}`;c("Fetching alert types:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return K(o);const s=await o.json();return c("Alert types fetched:",s.results?.length??0,"types"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch alert types: ${String(o)}`)}}async function K(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function Ye(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken),e?.timestamp__lte&&t.append("timestamp__lte",T(e.timestamp__lte)),e?.timestamp__gte&&t.append("timestamp__gte",T(e.timestamp__gte)),e?.alertId&&t.append("alertId",e.alertId),e?.alertType&&t.append("alertType",e.alertType),e?.actorId&&t.append("actorId",e.actorId),e?.actorType&&t.append("actorType",e.actorType),e?.actorAccountId&&t.append("actorAccountId",e.actorAccountId),e?.category&&t.append("category",e.category),e?.userId&&t.append("userId",e.userId),e?.read!==void 0&&t.append("read",String(e.read)),e?.status&&t.append("status",e.status),e?.includeV1Notifications!==void 0&&t.append("includeV1Notifications",String(e.includeV1Notifications)),e?.sort&&e.sort.length>0&&t.append("sort",e.sort.join(",")),e?.language&&t.append("language",e.language);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/notifications${i?`?${i}`:""}`;c("Fetching notifications:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return se(o);const s=await o.json();return c("Notifications fetched:",s.results?.length??0,"notifications"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch notifications: ${String(o)}`)}}async function Ze(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Notification ID is required");const t=`${n.baseUrl}/api/v3.0/notifications/${encodeURIComponent(e)}`;c("Fetching notification:",t);try{const i=await fetch(t,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!i.ok)return se(i);const a=await i.json();return c("Notification fetched:",a.id),l(a)}catch(i){return r("NETWORK_ERROR",`Failed to fetch notification: ${String(i)}`)}}async function se(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return r("FORBIDDEN",`Access denied: ${t}`,n);case 404:return r("NOT_FOUND",`Not found: ${t}`,n);case 429:return r("RATE_LIMITED",`Rate limited: ${t}`,n);default:return r("API_ERROR",`API error: ${t}`,n)}}async function et(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");const t=new URLSearchParams;e?.pageSize&&t.append("pageSize",String(e.pageSize)),e?.pageToken&&t.append("pageToken",e.pageToken);const i=t.toString(),a=`${n.baseUrl}/api/v3.0/eventSubscriptions${i?`?${i}`:""}`;c("Fetching event subscriptions:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return F(o);const s=await o.json();return c("Event subscriptions fetched:",s.results?.length??0,"subscriptions"),l(s)}catch(o){return r("NETWORK_ERROR",`Failed to fetch event subscriptions: ${String(o)}`)}}async function tt(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Subscription ID is required");const t=`${n.baseUrl}/api/v3.0/eventSubscriptions/${encodeURIComponent(e)}`;c("Fetching event subscription:",t);try{const i=await fetch(t,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!i.ok)return F(i);const a=await i.json();return c("Event subscription fetched:",a.id),l(a)}catch(i){return r("NETWORK_ERROR",`Failed to fetch event subscription: ${String(i)}`)}}async function nt(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e.deliveryConfig)return r("VALIDATION_ERROR","deliveryConfig is required");if(!e.filters||e.filters.length===0)return r("VALIDATION_ERROR","At least one filter is required");for(const i of e.filters){if(!i.actors||i.actors.length===0)return r("VALIDATION_ERROR","Each filter must have at least one actor");if(!i.types||i.types.length===0)return r("VALIDATION_ERROR","Each filter must have at least one event type")}const t=`${n.baseUrl}/api/v3.0/eventSubscriptions`;c("Creating event subscription:",t);try{const i=await fetch(t,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json",Authorization:`Bearer ${n.token}`},body:JSON.stringify(e)});if(!i.ok)return F(i);const a=await i.json();return c("Event subscription created:",a.id),l(a)}catch(i){return r("NETWORK_ERROR",`Failed to create event subscription: ${String(i)}`)}}async function rt(e){const n=f();if(!n.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return r("AUTH_REQUIRED","Base URL not configured");if(!e)return r("VALIDATION_ERROR","Subscription ID is required");const t=`${n.baseUrl}/api/v3.0/eventSubscriptions/${encodeURIComponent(e)}`;c("Deleting event subscription:",t);try{const i=await fetch(t,{method:"DELETE",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});return i.ok?(c("Event subscription deleted:",e),l(void 0)):F(i)}catch(i){return r("NETWORK_ERROR",`Failed to delete event subscription: ${String(i)}`)}}function it(e,n){const t=f();if(!t.isAuthenticated)return r("AUTH_REQUIRED","Authentication required");if(!t.token)return r("AUTH_REQUIRED","Access token not available");if(!e)return r("VALIDATION_ERROR","SSE URL is required");try{const g=new URL(e);if(![".eagleeyenetworks.com",".een.cloud"].some(p=>g.hostname===p.substring(1)||g.hostname.endsWith(p)))return r("VALIDATION_ERROR",`SSE URL domain not allowed: ${g.hostname}`)}catch{return r("VALIDATION_ERROR","Invalid SSE URL format")}const i=1024*1024;let a="connecting",o=new AbortController,s=!1;const d=g=>{a=g,n.onStatusChange?.(a)},h=()=>{s||(s=!0,c("Closing SSE connection"),o?.abort(),o=null,d("disconnected"))};return(async()=>{if(!(s||!o)){d("connecting"),c("Connecting to SSE:",e);try{const g=await fetch(e,{method:"GET",headers:{Accept:"text/event-stream",Authorization:`Bearer ${t.token}`},signal:o.signal});if(!g.ok)throw new Error(`HTTP ${g.status}: ${g.statusText}`);if(!g.body)throw new Error("Response body is not available");d("connected"),c("SSE connected");const S=g.body.getReader(),y=new TextDecoder;let p="";for(;!s;){const{done:q,value:B}=await S.read();if(q){c("SSE stream ended");break}if(p+=y.decode(B,{stream:!0}),p.length>i){c("SSE buffer exceeded maximum size, resetting"),p="";continue}const b=p.split(`
|
|
2
|
+
`);p=b.pop()||"";let U="";for(const k of b)if(k.startsWith("data:")){const A=k.substring(5).trimStart();U=U?`${U}
|
|
3
|
+
${A}`:A}else if(k===""&&U){try{const A=JSON.parse(U);c("SSE event received:",A.type,A.actorId),n.onEvent(A)}catch(A){c("Failed to parse SSE event:",A)}U=""}}}catch(g){if(s||g instanceof Error&&g.name==="AbortError")return;c("SSE error:",g),d("error"),n.onError?.(g instanceof Error?g:new Error(String(g)))}}})(),l({close:h,get status(){return a}})}async function F(e){const n=e.status;let t;try{const i=await e.json();t=i.message??i.error??e.statusText}catch(i){c("Failed to parse error response JSON:",i),t=e.statusText||"Unknown error"}switch(n){case 401:return r("AUTH_REQUIRED",t,n);case 403:return r("FORBIDDEN",t,n);case 404:return r("NOT_FOUND",t,n);case 429:return r("RATE_LIMITED",t,n);default:return r("API_ERROR",t,n)}}exports.STORAGE_STRATEGY_DESCRIPTIONS=Te;exports.connectToEventSubscription=it;exports.createEventSubscription=nt;exports.deleteEventSubscription=rt;exports.failure=r;exports.formatTimestamp=T;exports.getAccessToken=M;exports.getAlert=Je;exports.getAuthUrl=Z;exports.getBridge=je;exports.getBridges=Le;exports.getCamera=Ne;exports.getCameras=we;exports.getClientId=Y;exports.getConfig=ye;exports.getCurrentUser=De;exports.getEvent=Qe;exports.getEventMetrics=We;exports.getEventSubscription=tt;exports.getLiveImage=Be;exports.getMediaSession=ae;exports.getNotification=Ze;exports.getProxyUrl=N;exports.getRecordedImage=Pe;exports.getRedirectUri=V;exports.getStorageStrategy=Ue;exports.getUser=be;exports.getUsers=me;exports.handleAuthCallback=ne;exports.initEenToolkit=Se;exports.initMediaSession=He;exports.listAlertTypes=Xe;exports.listAlerts=Ge;exports.listEventFieldValues=Me;exports.listEventSubscriptions=et;exports.listEventTypes=Ve;exports.listEvents=Ce;exports.listFeeds=xe;exports.listMedia=qe;exports.listNotifications=Ye;exports.refreshToken=ee;exports.revokeToken=te;exports.success=l;exports.useAuthStore=f;
|
|
2
4
|
//# sourceMappingURL=index.cjs.map
|