een-api-toolkit 0.3.8 → 0.3.11
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 +125 -7
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +17 -0
- package/dist/index.js +70 -64
- package/dist/index.js.map +1 -1
- package/docs/AI-CONTEXT.md +20 -1
- package/examples/vue-bridges/src/views/Home.vue +15 -1
- package/examples/vue-cameras/src/views/Home.vue +15 -1
- package/examples/vue-feeds/src/views/Home.vue +15 -1
- package/examples/vue-media/README.md +154 -85
- package/examples/vue-media/e2e/app.spec.ts +8 -0
- package/examples/vue-media/e2e/auth.spec.ts +154 -2
- package/examples/vue-media/media-screenshot.png +0 -0
- package/examples/vue-media/package-lock.json +8 -1
- package/examples/vue-media/package.json +1 -0
- package/examples/vue-media/src/App.vue +3 -2
- package/examples/vue-media/src/composables/useSelectedDateTime.ts +102 -0
- package/examples/vue-media/src/router/index.ts +7 -0
- package/examples/vue-media/src/utils/timestamp.ts +263 -0
- package/examples/vue-media/src/views/HLS.vue +645 -0
- package/examples/vue-media/src/views/Home.vue +21 -3
- package/examples/vue-media/src/views/LiveCamera.vue +8 -27
- package/examples/vue-media/src/views/RecordedImage.vue +214 -77
- package/examples/vue-users/e2e/auth.spec.ts +3 -3
- package/examples/vue-users/package-lock.json +2 -2
- package/examples/vue-users/package.json +1 -1
- package/examples/vue-users/src/views/Home.vue +67 -1
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,26 +2,144 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## [0.3.
|
|
5
|
+
## [0.3.11] - 2026-01-12
|
|
6
6
|
|
|
7
7
|
### Release Summary
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
#### PR #52: Release v0.3.10: Vue-media improvements and agent definitions
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
This release includes improvements to the vue-media example and adds Claude Code agent definitions.
|
|
13
|
+
|
|
14
|
+
### Changes
|
|
15
|
+
|
|
16
|
+
- **feat(vue-media)**: Add seconds precision and Now button to recorded images
|
|
17
|
+
- Add seconds precision to datetime picker (`step="1"`)
|
|
18
|
+
- Add "Now" button to reset datetime picker to current time
|
|
19
|
+
- Update page titles to indicate "(Preview)" image quality
|
|
20
|
+
- Update README documentation with current API examples
|
|
21
|
+
|
|
22
|
+
- **chore**: Add Claude Code agent definitions
|
|
23
|
+
- `docs-accuracy-reviewer`: Verifies documentation accuracy
|
|
24
|
+
- `test-runner`: Runs unit and E2E test suites
|
|
25
|
+
|
|
26
|
+
### Commits
|
|
27
|
+
|
|
28
|
+
- 172ea1c chore: Add Claude Code agent definitions
|
|
29
|
+
- 142999e feat(vue-media): Add seconds precision and Now button to recorded images
|
|
30
|
+
|
|
31
|
+
## Test Results
|
|
32
|
+
|
|
33
|
+
- **Lint**: ✅ Passed (1 warning)
|
|
34
|
+
- **Unit Tests**: ✅ 188 passed
|
|
35
|
+
- **Build**: ✅ Successful
|
|
36
|
+
|
|
37
|
+
## Version
|
|
38
|
+
|
|
39
|
+
`0.3.10`
|
|
40
|
+
|
|
41
|
+
#### PR #53: feat(vue-media): Add HLS video streaming and improve media pages
|
|
42
|
+
## Summary
|
|
43
|
+
|
|
44
|
+
This PR adds HLS video streaming capability to the vue-media example and improves the existing media pages with better UX features.
|
|
45
|
+
|
|
46
|
+
### New Features
|
|
47
|
+
- **HLS Video page** - Stream recorded video using HLS protocol with adaptive bitrate support
|
|
48
|
+
- **Shared datetime state** - Datetime selection persists across Recorded Image and HLS Video pages
|
|
49
|
+
- **Clip Time button** - Quickly set datetime picker to the clip's start time
|
|
50
|
+
- **Time position indicator** - Shows whether selected time is before, inside, or after the segment
|
|
51
|
+
- **Image resolution display** - Shows dimensions for preview and main images on Recorded Image page
|
|
52
|
+
|
|
53
|
+
### Changes
|
|
54
|
+
- Add HLS.vue page for HLS video streaming
|
|
55
|
+
- Add useSelectedDateTime composable for shared datetime state
|
|
56
|
+
- Display segment start/end times with duration on HLS page
|
|
57
|
+
- Use YYYY-MM-DD date format and AM/PM time notation
|
|
58
|
+
- Remove MP4 playback page (simplified to HLS only)
|
|
59
|
+
- Update README with comprehensive documentation of all pages and APIs
|
|
60
|
+
- Add E2E tests for HLS video page
|
|
61
|
+
|
|
62
|
+
### Commits
|
|
63
|
+
- e374bd6 feat(vue-media): Add HLS video streaming and improve media pages
|
|
64
|
+
- 14b8d71 fix(vue-media): Now button triggers image fetch like Go button
|
|
65
|
+
- f3bb8bf Merge pull request #52 from klaushofrichter/develop
|
|
66
|
+
- 6368e35 fix: Address code review feedback and test timeout issue
|
|
67
|
+
- 172ea1c chore: Add Claude Code agent definitions
|
|
68
|
+
- 142999e feat(vue-media): Add seconds precision and Now button to recorded images
|
|
69
|
+
|
|
70
|
+
## Test Results
|
|
71
|
+
- **Lint**: Passed (1 warning)
|
|
72
|
+
- **Unit Tests**: 188 passed
|
|
73
|
+
- **Build**: Success
|
|
74
|
+
|
|
75
|
+
## Version
|
|
76
|
+
`0.3.10`
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
🤖 Generated with [Claude Code](https://claude.ai/code)
|
|
80
|
+
|
|
81
|
+
#### PR #54: chore: Audit and upgrade dependencies
|
|
82
|
+
## Summary
|
|
83
|
+
|
|
84
|
+
- Adds `@eslint/js` package for ESLint v9 flat config compatibility
|
|
85
|
+
- Merges latest develop changes (conflict resolution)
|
|
86
|
+
- Removes accidentally committed non-code files
|
|
87
|
+
|
|
88
|
+
## Changes
|
|
89
|
+
|
|
90
|
+
This branch was originally created to audit dependencies but diverged from develop. The main contribution is:
|
|
91
|
+
|
|
92
|
+
- **ESLint v9 compatibility**: Added `@eslint/js` package required for the flat config format
|
|
93
|
+
|
|
94
|
+
## Conflict Resolution
|
|
95
|
+
|
|
96
|
+
Resolved merge conflicts with develop:
|
|
97
|
+
- `eslint.config.js`: Adopted develop's `commonRules` pattern
|
|
98
|
+
- `package.json`: Merged dependencies
|
|
99
|
+
- `vite.config.ts`: Used develop's test exclude pattern
|
|
100
|
+
- Removed obsolete `examples/vue-basic/` (renamed to `vue-users` in develop)
|
|
101
|
+
|
|
102
|
+
## Test Results
|
|
103
|
+
|
|
104
|
+
- Linting: Passed (1 warning - existing console statement)
|
|
105
|
+
- Unit tests: 188/188 passed
|
|
106
|
+
- Build: Successful
|
|
107
|
+
|
|
108
|
+
## Version
|
|
109
|
+
|
|
110
|
+
`0.3.11`
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
Generated with [Claude Code](https://claude.ai/code)
|
|
114
|
+
|
|
10
115
|
|
|
11
116
|
### Detailed Changes
|
|
12
117
|
|
|
13
118
|
#### Features
|
|
14
|
-
- feat:
|
|
119
|
+
- feat(vue-media): Add 60 second loading timeout for HLS video streams
|
|
120
|
+
- feat(vue-media): Add HLS video streaming and improve media pages
|
|
121
|
+
- feat(vue-media): Add seconds precision and Now button to recorded images
|
|
15
122
|
|
|
16
123
|
#### Bug Fixes
|
|
17
|
-
- fix:
|
|
124
|
+
- fix(vue-media): Improve UI labels and layout
|
|
125
|
+
- fix(vue-media): Address remaining code review issues
|
|
126
|
+
- fix(vue-media): Address code review high/medium priority issues
|
|
127
|
+
- fix(vue-media): Now button triggers image fetch like Go button
|
|
128
|
+
- fix: Address code review feedback and test timeout issue
|
|
18
129
|
|
|
19
130
|
#### Other Changes
|
|
20
|
-
-
|
|
131
|
+
- chore: Address code review recommendations
|
|
132
|
+
- chore: Consolidate .gitignore presentation patterns
|
|
133
|
+
- chore: Add presentation artifacts to .gitignore
|
|
134
|
+
- chore: Remove accidentally committed non-code files
|
|
135
|
+
- chore: Update example dependencies and fix test configuration
|
|
136
|
+
- refactor(vue-media): Extract timestamp utilities and fix code review issues
|
|
137
|
+
- chore: Add Claude Code agent definitions
|
|
138
|
+
- chore: Upgrade all optional dependencies to latest major versions
|
|
21
139
|
|
|
22
140
|
### Links
|
|
23
141
|
- [npm package](https://www.npmjs.com/package/een-api-toolkit)
|
|
24
|
-
- [Full Changelog](https://github.com/klaushofrichter/een-api-toolkit/compare/v0.3.
|
|
142
|
+
- [Full Changelog](https://github.com/klaushofrichter/een-api-toolkit/compare/v0.3.10...v0.3.11)
|
|
25
143
|
|
|
26
144
|
---
|
|
27
|
-
*Released: 2026-01-
|
|
145
|
+
*Released: 2026-01-12 17:56:08 CST*
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const de=require("pinia"),h=require("vue");class fe{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 C{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 N="localStorage",w=null;function b(){return w||(w=new fe),w}function ge(e){N=e}function _e(){return N}function L(){switch(N){case"memory":return b();case"sessionStorage":return typeof sessionStorage<"u"?new C(sessionStorage):b();default:return typeof localStorage<"u"?new C(localStorage):b()}}const E={};let U={};function he(e={}){const n=e.storageStrategy??"localStorage";ge(n),U={proxyUrl:e.proxyUrl??E?.VITE_PROXY_URL,clientId:e.clientId??E?.VITE_EEN_CLIENT_ID,redirectUri:e.redirectUri??E?.VITE_REDIRECT_URI,storageStrategy:n,debug:e.debug??E?.VITE_DEBUG==="true"}}function Re(){return U}function k(){return U.proxyUrl??E?.VITE_PROXY_URL}function H(){return U.clientId??E?.VITE_EEN_CLIENT_ID}function F(){return U.redirectUri??E?.VITE_REDIRECT_URI??"http://127.0.0.1:3333"}function f(e){return{data:e,error:null}}function i(e,n,t,r){return{data:null,error:{code:e,message:n,status:t,details:r}}}const Ie={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1},pe=()=>{try{return Ie?.VITE_DEBUG==="true"}catch{return!1}};function u(...e){pe()&&console.log("[een-api-toolkit]",...e)}let j=null;function Ee(){return j||(j=Promise.resolve().then(()=>Ue).then(e=>e.refreshToken)),j}const g=de.defineStore("een-auth",()=>{const e=h.ref(null),n=h.ref(null),t=h.ref(null),r=h.ref(null),a=h.ref(null),o=h.ref(443),s=h.ref(null),l=h.ref(null),_=h.ref(!1);let I=null;const R=h.ref(!1),p=h.ref(null),y=h.computed(()=>!!e.value),S=h.computed(()=>a.value?o.value===443?`https://${a.value}`:`https://${a.value}:${o.value}`:null),$=h.computed(()=>n.value?Date.now()>=n.value:!0),J=h.computed(()=>n.value?Math.max(0,n.value-Date.now()):0);function Y(c,d){e.value=c,n.value=Date.now()+d*1e3,T(),D(),u("Token set, expires in",d,"seconds")}function Z(c){t.value=c,T()}function ee(c){r.value=c,T()}function te(c){if(typeof c=="string")try{const d=new URL(c.startsWith("http")?c:`https://${c}`);a.value=d.hostname,o.value=d.port?parseInt(d.port,10):443}catch(d){u("Failed to parse URL, using as hostname:",d instanceof Error?d.message:String(d)),a.value=c,o.value=443}else a.value=c.hostname,o.value=c.port??443;T(),u("Base URL set:",S.value)}function ne(c){s.value=c,T()}function D(){if(l.value&&(clearTimeout(l.value),l.value=null),!n.value||!e.value)return;const c=Date.now(),A=n.value-c,m=300*1e3,ce=A/2,ue=Math.min(m,ce),le=Math.max(A-ue,60*1e3),B=Math.max(le,5e3);u("Auto-refresh scheduled in",Math.round(B/1e3),"seconds"),l.value=setTimeout(async()=>{await re()},B)}async function re(){return I?(u("Refresh already in progress, waiting for existing refresh"),I):(_.value=!0,u("Performing auto-refresh"),I=(async()=>{try{const d=await(await Ee())();d.error?(R.value=!0,p.value=d.error.message,u("Auto-refresh failed:",d.error.message)):(R.value=!1,p.value=null,u("Auto-refresh successful"))}catch(c){R.value=!0,p.value=c instanceof Error?c.message:String(c),u("Auto-refresh error:",c)}finally{_.value=!1,I=null}})(),I)}function ie(){R.value=!1,p.value=null}function x(){l.value&&(clearTimeout(l.value),l.value=null),e.value=null,n.value=null,t.value=null,r.value=null,a.value=null,o.value=443,s.value=null,R.value=!1,p.value=null,se(),u("Logged out")}function oe(){ae(),e.value&&!$.value?(D(),u("Initialized from storage")):e.value&&$.value&&(u("Stored token expired, clearing"),x())}function T(){try{const c=L();e.value&&c.setItem("een_token",e.value),n.value&&c.setItem("een_tokenExpiration",String(n.value)),t.value&&c.setItem("een_refreshTokenMarker",t.value),r.value&&c.setItem("een_sessionId",r.value),a.value&&c.setItem("een_hostname",a.value),o.value!==443&&c.setItem("een_port",String(o.value)),s.value&&c.setItem("een_userProfile",JSON.stringify(s.value))}catch(c){u("Failed to save to storage:",c instanceof Error?c.message:String(c))}}function ae(){try{const c=L();e.value=c.getItem("een_token");const d=c.getItem("een_tokenExpiration");n.value=d?parseInt(d,10):null,t.value=c.getItem("een_refreshTokenMarker"),r.value=c.getItem("een_sessionId"),a.value=c.getItem("een_hostname");const A=c.getItem("een_port");o.value=A?parseInt(A,10):443;const m=c.getItem("een_userProfile");s.value=m?JSON.parse(m):null}catch(c){u("Failed to load from storage:",c instanceof Error?c.message:String(c))}}function se(){try{const c=L();c.removeItem("een_token"),c.removeItem("een_tokenExpiration"),c.removeItem("een_refreshTokenMarker"),c.removeItem("een_sessionId"),c.removeItem("een_hostname"),c.removeItem("een_port"),c.removeItem("een_userProfile")}catch(c){u("Failed to clear storage:",c instanceof Error?c.message:String(c))}}return{token:e,tokenExpiration:n,refreshTokenMarker:t,sessionId:r,hostname:a,port:o,userProfile:s,isRefreshing:_,refreshFailed:R,refreshFailedMessage:p,isAuthenticated:y,baseUrl:S,isTokenExpired:$,tokenExpiresIn:J,setToken:Y,setRefreshTokenMarker:Z,setSessionId:ee,setBaseUrl:te,setUserProfile:ne,setupAutoRefresh:D,clearRefreshFailed:ie,logout:x,initialize:oe}}),Te="https://auth.eagleeyenetworks.com/oauth2/authorize";function M(){const e=H();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:F(),state:n});return u("Generated auth URL with state:",n),`${Te}?${t.toString()}`}async function P(e){const n=k();if(!n)return i("AUTH_FAILED","Proxy URL not configured. Call initEenToolkit() or set VITE_PROXY_URL");const t=new URLSearchParams({code:e,redirect_uri:F()});try{const r=await fetch(`${n}/proxy/getAccessToken?${t.toString()}`,{method:"POST",credentials:"include",headers:{Accept:"application/json"}});if(!r.ok){const o=await r.text().catch(()=>"Unknown error");return i("AUTH_FAILED",`Token exchange failed: ${o}`,r.status)}const a=await r.json();return u("Token received, expires in:",a.expiresIn),f(a)}catch(r){return i("NETWORK_ERROR",`Failed to exchange code: ${String(r)}`)}}async function z(){const e=k();if(!e)return i("AUTH_FAILED","Proxy URL not configured");const n=g();try{const t={Accept:"application/json"};n.sessionId&&(t.Authorization=`Bearer ${n.sessionId}`);const r=await fetch(`${e}/proxy/refreshAccessToken`,{method:"POST",credentials:"include",headers:t});if(!r.ok){const o=await r.text().catch(()=>"Unknown error");return i("AUTH_FAILED",`Token refresh failed: ${o}`,r.status)}const a=await r.json();return n.setToken(a.accessToken,a.expiresIn),u("Token refreshed, expires in:",a.expiresIn),f(a)}catch(t){return i("NETWORK_ERROR",`Failed to refresh token: ${String(t)}`)}}async function Q(){const e=k();if(!e)return i("AUTH_FAILED","Proxy URL not configured");const n=g();try{const t={Accept:"application/json"};n.sessionId&&(t.Authorization=`Bearer ${n.sessionId}`);const r=await fetch(`${e}/proxy/revoke`,{method:"POST",credentials:"include",headers:t});if(n.logout(),!r.ok){const a=await r.text().catch(()=>"Unknown error");return i("AUTH_FAILED",`Token revocation failed: ${a}`,r.status)}return u("Token revoked"),f(void 0)}catch(t){return n.logout(),i("NETWORK_ERROR",`Failed to revoke token: ${String(t)}`)}}async function V(e,n){let t=null;try{t=sessionStorage.getItem("een_oauth_state"),sessionStorage.removeItem("een_oauth_state")}catch{}if(!t)return i("AUTH_FAILED","No OAuth state found. Please restart the login process.");if(!Ae(n,t))return i("AUTH_FAILED","Invalid OAuth state. Possible CSRF attack.");u("State validated, exchanging code for token");const r=await P(e);if(r.error)return r;const a=g(),o=r.data;return a.setToken(o.accessToken,o.expiresIn),a.setRefreshTokenMarker("present"),a.setSessionId(o.sessionId),a.setBaseUrl(o.httpsBaseUrl),u("Auth callback complete, user:",o.userEmail),f(o)}function Ae(e,n){if(e.length!==n.length)return!1;let t=0;for(let r=0;r<e.length;r++)t|=e.charCodeAt(r)^n.charCodeAt(r);return t===0}const Ue=Object.freeze(Object.defineProperty({__proto__:null,getAccessToken:P,getAuthUrl:M,handleAuthCallback:V,refreshToken:z,revokeToken:Q},Symbol.toStringTag,{value:"Module"}));async function ve(){const e=g();if(!e.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!e.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");const n=`${e.baseUrl}/api/v3.0/users/self`;u("Fetching current user:",n);try{const t=await fetch(n,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${e.token}`}});if(!t.ok)return q(t);const r=await t.json();return u("Current user fetched:",r.email),e.setUserProfile(r),f(r)}catch(t){return i("NETWORK_ERROR",`Failed to fetch current user: ${String(t)}`)}}async function ye(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("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 r=t.toString(),a=`${n.baseUrl}/api/v3.0/users${r?`?${r}`:""}`;u("Fetching users:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return q(o);const s=await o.json();return u("Users fetched:",s.results?.length??0,"users"),f(s)}catch(o){return i("NETWORK_ERROR",`Failed to fetch users: ${String(o)}`)}}async function Se(e,n){const t=g();if(!t.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e)return i("VALIDATION_ERROR","User ID is required");const r=new URLSearchParams;n?.include&&n.include.length>0&&r.append("include",n.include.join(","));const a=r.toString(),o=`${t.baseUrl}/api/v3.0/users/${encodeURIComponent(e)}${a?`?${a}`:""}`;u("Fetching user:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return q(s);const l=await s.json();return u("User fetched:",l.email),f(l)}catch(s){return i("NETWORK_ERROR",`Failed to fetch user: ${String(s)}`)}}async function q(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error??e.statusText}catch{t=e.statusText||"Unknown error"}switch(n){case 401:return i("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return i("FORBIDDEN",`Access denied: ${t}`,n);case 404:return i("NOT_FOUND",`Not found: ${t}`,n);case 429:return i("RATE_LIMITED",`Rate limited: ${t}`,n);default:return i("API_ERROR",`API error: ${t}`,n)}}async function me(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("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 r=t.toString(),a=`${n.baseUrl}/api/v3.0/cameras${r?`?${r}`:""}`;u("Fetching cameras:",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 u("Cameras fetched:",s.results?.length??0,"cameras"),f(s)}catch(o){return i("NETWORK_ERROR",`Failed to fetch cameras: ${String(o)}`)}}async function ke(e,n){const t=g();if(!t.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e)return i("VALIDATION_ERROR","Camera ID is required");const r=new URLSearchParams;n?.include&&n.include.length>0&&r.append("include",n.include.join(","));const a=r.toString(),o=`${t.baseUrl}/api/v3.0/cameras/${encodeURIComponent(e)}${a?`?${a}`:""}`;u("Fetching camera:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return W(s);const l=await s.json();return u("Camera fetched:",l.name),f(l)}catch(s){return i("NETWORK_ERROR",`Failed to fetch camera: ${String(s)}`)}}async function W(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error??e.statusText}catch(r){u("Failed to parse error response JSON:",r),t=e.statusText||"Unknown error"}switch(n){case 401:return i("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return i("FORBIDDEN",`Access denied: ${t}`,n);case 404:return i("NOT_FOUND",`Not found: ${t}`,n);case 429:return i("RATE_LIMITED",`Rate limited: ${t}`,n);default:return i("API_ERROR",`API error: ${t}`,n)}}async function Oe(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("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 r=t.toString(),a=`${n.baseUrl}/api/v3.0/bridges${r?`?${r}`:""}`;u("Fetching bridges:",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 u("Bridges fetched:",s.results?.length??0,"bridges"),f(s)}catch(o){return i("NETWORK_ERROR",`Failed to fetch bridges: ${String(o)}`)}}async function $e(e,n){const t=g();if(!t.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e)return i("VALIDATION_ERROR","Bridge ID is required");const r=new URLSearchParams;n?.include&&n.include.length>0&&r.append("include",n.include.join(","));const a=r.toString(),o=`${t.baseUrl}/api/v3.0/bridges/${encodeURIComponent(e)}${a?`?${a}`:""}`;u("Fetching bridge:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return K(s);const l=await s.json();return u("Bridge fetched:",l.name),f(l)}catch(s){return i("NETWORK_ERROR",`Failed to fetch bridge: ${String(s)}`)}}async function K(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error??e.statusText}catch(r){u("Failed to parse error response JSON:",r),t=e.statusText||"Unknown error"}switch(n){case 401:return i("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return i("FORBIDDEN",`Access denied: ${t}`,n);case 404:return i("NOT_FOUND",`Not found: ${t}`,n);case 429:return i("RATE_LIMITED",`Rate limited: ${t}`,n);default:return i("API_ERROR",`API error: ${t}`,n)}}const De=3e4;function v(e=De){const n=new AbortController,t=setTimeout(()=>n.abort(),e);return{controller:n,timeoutId:t}}function G(e){const n=new Uint8Array(e),t=8192,r=[];for(let o=0;o<n.byteLength;o+=t){const s=n.subarray(o,Math.min(o+t,n.byteLength));let l="";for(let _=0;_<s.length;_++)l+=String.fromCharCode(s[_]);r.push(l)}const a=r.join("");return typeof btoa=="function"?btoa(a):Buffer.from(a,"binary").toString("base64")}async function we(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId)return i("VALIDATION_ERROR","Device ID is required");if(!e.type)return i("VALIDATION_ERROR","Stream type is required (preview or main)");if(!e.mediaType)return i("VALIDATION_ERROR","Media type is required (video or image)");if(!e.startTimestamp)return i("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 r=`${n.baseUrl}/api/v3.0/media?${t.toString()}`;u("Fetching media intervals:",r);const{controller:a,timeoutId:o}=v();try{const s=await fetch(r,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`},signal:a.signal});if(!s.ok)return O(s);const l=await s.json();return u("Media intervals fetched:",l.results?.length??0,"intervals"),f(l)}catch(s){return s instanceof Error&&s.name==="AbortError"?i("NETWORK_ERROR","Request timed out"):i("NETWORK_ERROR",`Failed to fetch media intervals: ${String(s)}`)}finally{clearTimeout(o)}}async function be(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId)return i("VALIDATION_ERROR","Device ID is required");const t=e.type??"preview",r=new URLSearchParams;r.append("deviceId",e.deviceId),r.append("type",t);const a=`${n.baseUrl}/api/v3.0/media/liveImage.jpeg?${r.toString()}`;u("Fetching live image:",a);const{controller:o,timeoutId:s}=v();try{const l=await fetch(a,{method:"GET",headers:{Accept:"image/jpeg",Authorization:`Bearer ${n.token}`},signal:o.signal}),_=l.headers.get("X-Een-Timestamp"),I=l.headers.get("X-Een-PrevToken");if(!l.ok)return O(l);const R=await l.arrayBuffer(),y=`data:image/jpeg;base64,${G(R)}`;return u("Live image fetched, timestamp:",_),f({imageData:y,timestamp:_,prevToken:I})}catch(l){return l instanceof Error&&l.name==="AbortError"?i("NETWORK_ERROR","Request timed out"):i("NETWORK_ERROR",`Failed to fetch live image: ${String(l)}`)}finally{clearTimeout(s)}}async function Le(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId&&!e.pageToken)return i("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 i("VALIDATION_ERROR","At least one timestamp parameter is required");if(e.include?.includes("overlaySvgHeader")&&(!e.overlayId__in||e.overlayId__in.length===0))return i("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 r=`${n.baseUrl}/api/v3.0/media/recordedImage.jpeg?${t.toString()}`;u("Fetching recorded image:",r);const{controller:a,timeoutId:o}=v();try{const s=await fetch(r,{method:"GET",headers:{Accept:"image/jpeg",Authorization:`Bearer ${n.token}`},signal:a.signal}),l=s.headers.get("X-Een-Timestamp"),_=s.headers.get("X-Een-NextToken"),I=s.headers.get("X-Een-PrevToken"),R=s.headers.get("X-Een-OverlaySvg");if(!s.ok)return O(s);const p=await s.arrayBuffer(),S=`data:image/jpeg;base64,${G(p)}`;return u("Recorded image fetched, timestamp:",l),f({imageData:S,timestamp:l,nextToken:_,prevToken:I,overlaySvg:R})}catch(s){return s instanceof Error&&s.name==="AbortError"?i("NETWORK_ERROR","Request timed out"):i("NETWORK_ERROR",`Failed to fetch recorded image: ${String(s)}`)}finally{clearTimeout(o)}}async function O(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error??e.statusText}catch{t=e.statusText||"Unknown error"}switch(n){case 401:return i("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return i("FORBIDDEN",`Access denied: ${t}`,n);case 404:return i("NOT_FOUND",`Not found: ${t}`,n);case 429:return i("RATE_LIMITED",`Rate limited: ${t}`,n);case 503:return i("SERVICE_UNAVAILABLE",`Service unavailable: ${t}`,n);default:return i("API_ERROR",`API error: ${t}`,n)}}async function X(){const e=g();if(!e.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!e.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");const n=`${e.baseUrl}/api/v3.0/media/session`;u("Fetching media session:",n);const{controller:t,timeoutId:r}=v();try{const a=await fetch(n,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${e.token}`},signal:t.signal});if(!a.ok)return O(a);const o=await a.json();return u("Media session URL received:",o.url),f(o)}catch(a){return a instanceof Error&&a.name==="AbortError"?i("NETWORK_ERROR","Request timed out"):i("NETWORK_ERROR",`Failed to fetch media session: ${String(a)}`)}finally{clearTimeout(r)}}async function je(){const e=g();if(!e.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");const n=await X();if(n.error)return i(n.error.code,`Failed to get media session: ${n.error.message}`,n.error.status);if(!n.data?.url)return i("API_ERROR","No session URL returned from media session endpoint");const t=n.data.url;u("Calling session URL to set cookie:",t);const{controller:r,timeoutId:a}=v();try{const o=await fetch(t,{method:"GET",credentials:"include",headers:{Accept:"*/*",Authorization:`Bearer ${e.token}`},signal:r.signal});if(!o.ok&&o.status!==204){const s=o.status;let l;try{const _=await o.json();l=_.message??_.error??o.statusText}catch{l=o.statusText||"Unknown error"}return i("API_ERROR",`Failed to set media session cookie: ${l}`,s)}return u("Media session cookie set successfully"),f({success:!0,sessionUrl:t})}catch(o){return o instanceof Error&&o.name==="AbortError"?i("NETWORK_ERROR","Request timed out while setting session cookie"):i("NETWORK_ERROR",`Failed to set media session cookie: ${String(o)}`)}finally{clearTimeout(a)}}async function Ne(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("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 r=t.toString(),a=`${n.baseUrl}/api/v3.0/feeds${r?`?${r}`:""}`;u("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 Fe(o);const s=await o.json();return u("Feeds fetched:",s.results?.length??0,"feeds"),f(s)}catch(o){return i("NETWORK_ERROR",`Failed to fetch feeds: ${String(o)}`)}}async function Fe(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error}catch(r){u("Failed to parse error response JSON:",r)}switch(n){case 401:return i("AUTH_REQUIRED",t||"Authentication failed",n);case 403:return i("FORBIDDEN",t||"Access denied",n);case 404:return i("NOT_FOUND",t||"Not found",n);case 429:return i("RATE_LIMITED",t||"Rate limited",n);case 503:return i("SERVICE_UNAVAILABLE",t||"Service unavailable",n);default:return i("API_ERROR",t||e.statusText||"API error",n)}}exports.failure=i;exports.getAccessToken=P;exports.getAuthUrl=M;exports.getBridge=$e;exports.getBridges=Oe;exports.getCamera=ke;exports.getCameras=me;exports.getClientId=H;exports.getConfig=Re;exports.getCurrentUser=ve;exports.getLiveImage=be;exports.getMediaSession=X;exports.getProxyUrl=k;exports.getRecordedImage=Le;exports.getRedirectUri=F;exports.getStorageStrategy=_e;exports.getUser=Se;exports.getUsers=ye;exports.handleAuthCallback=V;exports.initEenToolkit=he;exports.initMediaSession=je;exports.listFeeds=Ne;exports.listMedia=we;exports.refreshToken=z;exports.revokeToken=Q;exports.success=f;exports.useAuthStore=g;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const de=require("pinia"),h=require("vue"),fe={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1},ge=()=>{try{return fe?.VITE_DEBUG==="true"}catch{return!1}};function u(...e){ge()&&console.log("[een-api-toolkit]",...e)}const _e={localStorage:"persists across sessions",sessionStorage:"per-tab, cleared on tab close",memory:"tokens lost on page refresh"};class he{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 C{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 N="localStorage",b=null;function w(){return b||(b=new he),b}function Re(e){N=e}function Ie(){return N}function L(){switch(N){case"memory":return w();case"sessionStorage":return typeof sessionStorage<"u"?new C(sessionStorage):(u("sessionStorage unavailable, falling back to memory storage"),w());default:return typeof localStorage<"u"?new C(localStorage):(u("localStorage unavailable, falling back to memory storage"),w())}}const p={};let U={};function Ee(e={}){const n=e.storageStrategy??"localStorage";Re(n),U={proxyUrl:e.proxyUrl??p?.VITE_PROXY_URL,clientId:e.clientId??p?.VITE_EEN_CLIENT_ID,redirectUri:e.redirectUri??p?.VITE_REDIRECT_URI,storageStrategy:n,debug:e.debug??p?.VITE_DEBUG==="true"}}function pe(){return U}function k(){return U.proxyUrl??p?.VITE_PROXY_URL}function H(){return U.clientId??p?.VITE_EEN_CLIENT_ID}function F(){return U.redirectUri??p?.VITE_REDIRECT_URI??"http://127.0.0.1:3333"}function f(e){return{data:e,error:null}}function i(e,n,t,r){return{data:null,error:{code:e,message:n,status:t,details:r}}}let j=null;function Te(){return j||(j=Promise.resolve().then(()=>ve).then(e=>e.refreshToken)),j}const g=de.defineStore("een-auth",()=>{const e=h.ref(null),n=h.ref(null),t=h.ref(null),r=h.ref(null),a=h.ref(null),o=h.ref(443),s=h.ref(null),l=h.ref(null),_=h.ref(!1);let I=null;const R=h.ref(!1),E=h.ref(null),y=h.computed(()=>!!e.value),S=h.computed(()=>a.value?o.value===443?`https://${a.value}`:`https://${a.value}:${o.value}`:null),D=h.computed(()=>n.value?Date.now()>=n.value:!0),J=h.computed(()=>n.value?Math.max(0,n.value-Date.now()):0);function Y(c,d){e.value=c,n.value=Date.now()+d*1e3,T(),$(),u("Token set, expires in",d,"seconds")}function Z(c){t.value=c,T()}function ee(c){r.value=c,T()}function te(c){if(typeof c=="string")try{const d=new URL(c.startsWith("http")?c:`https://${c}`);a.value=d.hostname,o.value=d.port?parseInt(d.port,10):443}catch(d){u("Failed to parse URL, using as hostname:",d instanceof Error?d.message:String(d)),a.value=c,o.value=443}else a.value=c.hostname,o.value=c.port??443;T(),u("Base URL set:",S.value)}function ne(c){s.value=c,T()}function $(){if(l.value&&(clearTimeout(l.value),l.value=null),!n.value||!e.value)return;const c=Date.now(),A=n.value-c,m=300*1e3,ce=A/2,ue=Math.min(m,ce),le=Math.max(A-ue,60*1e3),B=Math.max(le,5e3);u("Auto-refresh scheduled in",Math.round(B/1e3),"seconds"),l.value=setTimeout(async()=>{await re()},B)}async function re(){return I?(u("Refresh already in progress, waiting for existing refresh"),I):(_.value=!0,u("Performing auto-refresh"),I=(async()=>{try{const d=await(await Te())();d.error?(R.value=!0,E.value=d.error.message,u("Auto-refresh failed:",d.error.message)):(R.value=!1,E.value=null,u("Auto-refresh successful"))}catch(c){R.value=!0,E.value=c instanceof Error?c.message:String(c),u("Auto-refresh error:",c)}finally{_.value=!1,I=null}})(),I)}function ie(){R.value=!1,E.value=null}function x(){l.value&&(clearTimeout(l.value),l.value=null),e.value=null,n.value=null,t.value=null,r.value=null,a.value=null,o.value=443,s.value=null,R.value=!1,E.value=null,se(),u("Logged out")}function oe(){ae(),e.value&&!D.value?($(),u("Initialized from storage")):e.value&&D.value&&(u("Stored token expired, clearing"),x())}function T(){try{const c=L();e.value&&c.setItem("een_token",e.value),n.value&&c.setItem("een_tokenExpiration",String(n.value)),t.value&&c.setItem("een_refreshTokenMarker",t.value),r.value&&c.setItem("een_sessionId",r.value),a.value&&c.setItem("een_hostname",a.value),o.value!==443&&c.setItem("een_port",String(o.value)),s.value&&c.setItem("een_userProfile",JSON.stringify(s.value))}catch(c){u("Failed to save to storage:",c instanceof Error?c.message:String(c))}}function ae(){try{const c=L();e.value=c.getItem("een_token");const d=c.getItem("een_tokenExpiration");n.value=d?parseInt(d,10):null,t.value=c.getItem("een_refreshTokenMarker"),r.value=c.getItem("een_sessionId"),a.value=c.getItem("een_hostname");const A=c.getItem("een_port");o.value=A?parseInt(A,10):443;const m=c.getItem("een_userProfile");s.value=m?JSON.parse(m):null}catch(c){u("Failed to load from storage:",c instanceof Error?c.message:String(c))}}function se(){try{const c=L();c.removeItem("een_token"),c.removeItem("een_tokenExpiration"),c.removeItem("een_refreshTokenMarker"),c.removeItem("een_sessionId"),c.removeItem("een_hostname"),c.removeItem("een_port"),c.removeItem("een_userProfile")}catch(c){u("Failed to clear storage:",c instanceof Error?c.message:String(c))}}return{token:e,tokenExpiration:n,refreshTokenMarker:t,sessionId:r,hostname:a,port:o,userProfile:s,isRefreshing:_,refreshFailed:R,refreshFailedMessage:E,isAuthenticated:y,baseUrl:S,isTokenExpired:D,tokenExpiresIn:J,setToken:Y,setRefreshTokenMarker:Z,setSessionId:ee,setBaseUrl:te,setUserProfile:ne,setupAutoRefresh:$,clearRefreshFailed:ie,logout:x,initialize:oe}}),Ae="https://auth.eagleeyenetworks.com/oauth2/authorize";function M(){const e=H();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:F(),state:n});return u("Generated auth URL with state:",n),`${Ae}?${t.toString()}`}async function P(e){const n=k();if(!n)return i("AUTH_FAILED","Proxy URL not configured. Call initEenToolkit() or set VITE_PROXY_URL");const t=new URLSearchParams({code:e,redirect_uri:F()});try{const r=await fetch(`${n}/proxy/getAccessToken?${t.toString()}`,{method:"POST",credentials:"include",headers:{Accept:"application/json"}});if(!r.ok){const o=await r.text().catch(()=>"Unknown error");return i("AUTH_FAILED",`Token exchange failed: ${o}`,r.status)}const a=await r.json();return u("Token received, expires in:",a.expiresIn),f(a)}catch(r){return i("NETWORK_ERROR",`Failed to exchange code: ${String(r)}`)}}async function z(){const e=k();if(!e)return i("AUTH_FAILED","Proxy URL not configured");const n=g();try{const t={Accept:"application/json"};n.sessionId&&(t.Authorization=`Bearer ${n.sessionId}`);const r=await fetch(`${e}/proxy/refreshAccessToken`,{method:"POST",credentials:"include",headers:t});if(!r.ok){const o=await r.text().catch(()=>"Unknown error");return i("AUTH_FAILED",`Token refresh failed: ${o}`,r.status)}const a=await r.json();return n.setToken(a.accessToken,a.expiresIn),u("Token refreshed, expires in:",a.expiresIn),f(a)}catch(t){return i("NETWORK_ERROR",`Failed to refresh token: ${String(t)}`)}}async function Q(){const e=k();if(!e)return i("AUTH_FAILED","Proxy URL not configured");const n=g();try{const t={Accept:"application/json"};n.sessionId&&(t.Authorization=`Bearer ${n.sessionId}`);const r=await fetch(`${e}/proxy/revoke`,{method:"POST",credentials:"include",headers:t});if(n.logout(),!r.ok){const a=await r.text().catch(()=>"Unknown error");return i("AUTH_FAILED",`Token revocation failed: ${a}`,r.status)}return u("Token revoked"),f(void 0)}catch(t){return n.logout(),i("NETWORK_ERROR",`Failed to revoke token: ${String(t)}`)}}async function V(e,n){let t=null;try{t=sessionStorage.getItem("een_oauth_state"),sessionStorage.removeItem("een_oauth_state")}catch{}if(!t)return i("AUTH_FAILED","No OAuth state found. Please restart the login process.");if(!Ue(n,t))return i("AUTH_FAILED","Invalid OAuth state. Possible CSRF attack.");u("State validated, exchanging code for token");const r=await P(e);if(r.error)return r;const a=g(),o=r.data;return a.setToken(o.accessToken,o.expiresIn),a.setRefreshTokenMarker("present"),a.setSessionId(o.sessionId),a.setBaseUrl(o.httpsBaseUrl),u("Auth callback complete, user:",o.userEmail),f(o)}function Ue(e,n){if(e.length!==n.length)return!1;let t=0;for(let r=0;r<e.length;r++)t|=e.charCodeAt(r)^n.charCodeAt(r);return t===0}const ve=Object.freeze(Object.defineProperty({__proto__:null,getAccessToken:P,getAuthUrl:M,handleAuthCallback:V,refreshToken:z,revokeToken:Q},Symbol.toStringTag,{value:"Module"}));async function ye(){const e=g();if(!e.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!e.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");const n=`${e.baseUrl}/api/v3.0/users/self`;u("Fetching current user:",n);try{const t=await fetch(n,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${e.token}`}});if(!t.ok)return q(t);const r=await t.json();return u("Current user fetched:",r.email),e.setUserProfile(r),f(r)}catch(t){return i("NETWORK_ERROR",`Failed to fetch current user: ${String(t)}`)}}async function Se(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("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 r=t.toString(),a=`${n.baseUrl}/api/v3.0/users${r?`?${r}`:""}`;u("Fetching users:",a);try{const o=await fetch(a,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`}});if(!o.ok)return q(o);const s=await o.json();return u("Users fetched:",s.results?.length??0,"users"),f(s)}catch(o){return i("NETWORK_ERROR",`Failed to fetch users: ${String(o)}`)}}async function me(e,n){const t=g();if(!t.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e)return i("VALIDATION_ERROR","User ID is required");const r=new URLSearchParams;n?.include&&n.include.length>0&&r.append("include",n.include.join(","));const a=r.toString(),o=`${t.baseUrl}/api/v3.0/users/${encodeURIComponent(e)}${a?`?${a}`:""}`;u("Fetching user:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return q(s);const l=await s.json();return u("User fetched:",l.email),f(l)}catch(s){return i("NETWORK_ERROR",`Failed to fetch user: ${String(s)}`)}}async function q(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error??e.statusText}catch{t=e.statusText||"Unknown error"}switch(n){case 401:return i("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return i("FORBIDDEN",`Access denied: ${t}`,n);case 404:return i("NOT_FOUND",`Not found: ${t}`,n);case 429:return i("RATE_LIMITED",`Rate limited: ${t}`,n);default:return i("API_ERROR",`API error: ${t}`,n)}}async function ke(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("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 r=t.toString(),a=`${n.baseUrl}/api/v3.0/cameras${r?`?${r}`:""}`;u("Fetching cameras:",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 u("Cameras fetched:",s.results?.length??0,"cameras"),f(s)}catch(o){return i("NETWORK_ERROR",`Failed to fetch cameras: ${String(o)}`)}}async function Oe(e,n){const t=g();if(!t.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e)return i("VALIDATION_ERROR","Camera ID is required");const r=new URLSearchParams;n?.include&&n.include.length>0&&r.append("include",n.include.join(","));const a=r.toString(),o=`${t.baseUrl}/api/v3.0/cameras/${encodeURIComponent(e)}${a?`?${a}`:""}`;u("Fetching camera:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return W(s);const l=await s.json();return u("Camera fetched:",l.name),f(l)}catch(s){return i("NETWORK_ERROR",`Failed to fetch camera: ${String(s)}`)}}async function W(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error??e.statusText}catch(r){u("Failed to parse error response JSON:",r),t=e.statusText||"Unknown error"}switch(n){case 401:return i("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return i("FORBIDDEN",`Access denied: ${t}`,n);case 404:return i("NOT_FOUND",`Not found: ${t}`,n);case 429:return i("RATE_LIMITED",`Rate limited: ${t}`,n);default:return i("API_ERROR",`API error: ${t}`,n)}}async function De(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("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 r=t.toString(),a=`${n.baseUrl}/api/v3.0/bridges${r?`?${r}`:""}`;u("Fetching bridges:",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 u("Bridges fetched:",s.results?.length??0,"bridges"),f(s)}catch(o){return i("NETWORK_ERROR",`Failed to fetch bridges: ${String(o)}`)}}async function $e(e,n){const t=g();if(!t.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!t.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e)return i("VALIDATION_ERROR","Bridge ID is required");const r=new URLSearchParams;n?.include&&n.include.length>0&&r.append("include",n.include.join(","));const a=r.toString(),o=`${t.baseUrl}/api/v3.0/bridges/${encodeURIComponent(e)}${a?`?${a}`:""}`;u("Fetching bridge:",o);try{const s=await fetch(o,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${t.token}`}});if(!s.ok)return K(s);const l=await s.json();return u("Bridge fetched:",l.name),f(l)}catch(s){return i("NETWORK_ERROR",`Failed to fetch bridge: ${String(s)}`)}}async function K(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error??e.statusText}catch(r){u("Failed to parse error response JSON:",r),t=e.statusText||"Unknown error"}switch(n){case 401:return i("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return i("FORBIDDEN",`Access denied: ${t}`,n);case 404:return i("NOT_FOUND",`Not found: ${t}`,n);case 429:return i("RATE_LIMITED",`Rate limited: ${t}`,n);default:return i("API_ERROR",`API error: ${t}`,n)}}const be=3e4;function v(e=be){const n=new AbortController,t=setTimeout(()=>n.abort(),e);return{controller:n,timeoutId:t}}function G(e){const n=new Uint8Array(e),t=8192,r=[];for(let o=0;o<n.byteLength;o+=t){const s=n.subarray(o,Math.min(o+t,n.byteLength));let l="";for(let _=0;_<s.length;_++)l+=String.fromCharCode(s[_]);r.push(l)}const a=r.join("");return typeof btoa=="function"?btoa(a):Buffer.from(a,"binary").toString("base64")}async function we(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId)return i("VALIDATION_ERROR","Device ID is required");if(!e.type)return i("VALIDATION_ERROR","Stream type is required (preview or main)");if(!e.mediaType)return i("VALIDATION_ERROR","Media type is required (video or image)");if(!e.startTimestamp)return i("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 r=`${n.baseUrl}/api/v3.0/media?${t.toString()}`;u("Fetching media intervals:",r);const{controller:a,timeoutId:o}=v();try{const s=await fetch(r,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${n.token}`},signal:a.signal});if(!s.ok)return O(s);const l=await s.json();return u("Media intervals fetched:",l.results?.length??0,"intervals"),f(l)}catch(s){return s instanceof Error&&s.name==="AbortError"?i("NETWORK_ERROR","Request timed out"):i("NETWORK_ERROR",`Failed to fetch media intervals: ${String(s)}`)}finally{clearTimeout(o)}}async function Le(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId)return i("VALIDATION_ERROR","Device ID is required");const t=e.type??"preview",r=new URLSearchParams;r.append("deviceId",e.deviceId),r.append("type",t);const a=`${n.baseUrl}/api/v3.0/media/liveImage.jpeg?${r.toString()}`;u("Fetching live image:",a);const{controller:o,timeoutId:s}=v();try{const l=await fetch(a,{method:"GET",headers:{Accept:"image/jpeg",Authorization:`Bearer ${n.token}`},signal:o.signal}),_=l.headers.get("X-Een-Timestamp"),I=l.headers.get("X-Een-PrevToken");if(!l.ok)return O(l);const R=await l.arrayBuffer(),y=`data:image/jpeg;base64,${G(R)}`;return u("Live image fetched, timestamp:",_),f({imageData:y,timestamp:_,prevToken:I})}catch(l){return l instanceof Error&&l.name==="AbortError"?i("NETWORK_ERROR","Request timed out"):i("NETWORK_ERROR",`Failed to fetch live image: ${String(l)}`)}finally{clearTimeout(s)}}async function je(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");if(!e.deviceId&&!e.pageToken)return i("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 i("VALIDATION_ERROR","At least one timestamp parameter is required");if(e.include?.includes("overlaySvgHeader")&&(!e.overlayId__in||e.overlayId__in.length===0))return i("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 r=`${n.baseUrl}/api/v3.0/media/recordedImage.jpeg?${t.toString()}`;u("Fetching recorded image:",r);const{controller:a,timeoutId:o}=v();try{const s=await fetch(r,{method:"GET",headers:{Accept:"image/jpeg",Authorization:`Bearer ${n.token}`},signal:a.signal}),l=s.headers.get("X-Een-Timestamp"),_=s.headers.get("X-Een-NextToken"),I=s.headers.get("X-Een-PrevToken"),R=s.headers.get("X-Een-OverlaySvg");if(!s.ok)return O(s);const E=await s.arrayBuffer(),S=`data:image/jpeg;base64,${G(E)}`;return u("Recorded image fetched, timestamp:",l),f({imageData:S,timestamp:l,nextToken:_,prevToken:I,overlaySvg:R})}catch(s){return s instanceof Error&&s.name==="AbortError"?i("NETWORK_ERROR","Request timed out"):i("NETWORK_ERROR",`Failed to fetch recorded image: ${String(s)}`)}finally{clearTimeout(o)}}async function O(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error??e.statusText}catch{t=e.statusText||"Unknown error"}switch(n){case 401:return i("AUTH_REQUIRED",`Authentication failed: ${t}`,n);case 403:return i("FORBIDDEN",`Access denied: ${t}`,n);case 404:return i("NOT_FOUND",`Not found: ${t}`,n);case 429:return i("RATE_LIMITED",`Rate limited: ${t}`,n);case 503:return i("SERVICE_UNAVAILABLE",`Service unavailable: ${t}`,n);default:return i("API_ERROR",`API error: ${t}`,n)}}async function X(){const e=g();if(!e.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!e.baseUrl)return i("AUTH_REQUIRED","Base URL not configured");const n=`${e.baseUrl}/api/v3.0/media/session`;u("Fetching media session:",n);const{controller:t,timeoutId:r}=v();try{const a=await fetch(n,{method:"GET",headers:{Accept:"application/json",Authorization:`Bearer ${e.token}`},signal:t.signal});if(!a.ok)return O(a);const o=await a.json();return u("Media session URL received:",o.url),f(o)}catch(a){return a instanceof Error&&a.name==="AbortError"?i("NETWORK_ERROR","Request timed out"):i("NETWORK_ERROR",`Failed to fetch media session: ${String(a)}`)}finally{clearTimeout(r)}}async function Ne(){const e=g();if(!e.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");const n=await X();if(n.error)return i(n.error.code,`Failed to get media session: ${n.error.message}`,n.error.status);if(!n.data?.url)return i("API_ERROR","No session URL returned from media session endpoint");const t=n.data.url;u("Calling session URL to set cookie:",t);const{controller:r,timeoutId:a}=v();try{const o=await fetch(t,{method:"GET",credentials:"include",headers:{Accept:"*/*",Authorization:`Bearer ${e.token}`},signal:r.signal});if(!o.ok&&o.status!==204){const s=o.status;let l;try{const _=await o.json();l=_.message??_.error??o.statusText}catch{l=o.statusText||"Unknown error"}return i("API_ERROR",`Failed to set media session cookie: ${l}`,s)}return u("Media session cookie set successfully"),f({success:!0,sessionUrl:t})}catch(o){return o instanceof Error&&o.name==="AbortError"?i("NETWORK_ERROR","Request timed out while setting session cookie"):i("NETWORK_ERROR",`Failed to set media session cookie: ${String(o)}`)}finally{clearTimeout(a)}}async function Fe(e){const n=g();if(!n.isAuthenticated)return i("AUTH_REQUIRED","Authentication required");if(!n.baseUrl)return i("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 r=t.toString(),a=`${n.baseUrl}/api/v3.0/feeds${r?`?${r}`:""}`;u("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 Pe(o);const s=await o.json();return u("Feeds fetched:",s.results?.length??0,"feeds"),f(s)}catch(o){return i("NETWORK_ERROR",`Failed to fetch feeds: ${String(o)}`)}}async function Pe(e){const n=e.status;let t;try{const r=await e.json();t=r.message??r.error}catch(r){u("Failed to parse error response JSON:",r)}switch(n){case 401:return i("AUTH_REQUIRED",t||"Authentication failed",n);case 403:return i("FORBIDDEN",t||"Access denied",n);case 404:return i("NOT_FOUND",t||"Not found",n);case 429:return i("RATE_LIMITED",t||"Rate limited",n);case 503:return i("SERVICE_UNAVAILABLE",t||"Service unavailable",n);default:return i("API_ERROR",t||e.statusText||"API error",n)}}exports.STORAGE_STRATEGY_DESCRIPTIONS=_e;exports.failure=i;exports.getAccessToken=P;exports.getAuthUrl=M;exports.getBridge=$e;exports.getBridges=De;exports.getCamera=Oe;exports.getCameras=ke;exports.getClientId=H;exports.getConfig=pe;exports.getCurrentUser=ye;exports.getLiveImage=Le;exports.getMediaSession=X;exports.getProxyUrl=k;exports.getRecordedImage=je;exports.getRedirectUri=F;exports.getStorageStrategy=Ie;exports.getUser=me;exports.getUsers=Se;exports.handleAuthCallback=V;exports.initEenToolkit=Ee;exports.initMediaSession=Ne;exports.listFeeds=Fe;exports.listMedia=we;exports.refreshToken=z;exports.revokeToken=Q;exports.success=f;exports.useAuthStore=g;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|