@busy-app/busy-lib 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var G=Object.defineProperty;var L=(n,t,e)=>t in n?G(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var c=(n,t,e)=>L(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("openapi-fetch"),O=(n,t)=>{if(typeof FormData<"u"&&n instanceof FormData||typeof Buffer<"u"&&typeof Buffer.isBuffer=="function"&&Buffer.isBuffer(n)||typeof File<"u"&&n instanceof File||typeof Blob<"u"&&n instanceof Blob||typeof ArrayBuffer<"u"&&n instanceof ArrayBuffer||typeof ArrayBuffer<"u"&&ArrayBuffer.isView&&ArrayBuffer.isView(n))return n;let e;return t&&(t instanceof Headers?e=t.get("Content-Type")??t.get("content-type")??void 0:typeof t=="object"&&(e=t["Content-Type"]??t["content-type"]),e==="application/x-www-form-urlencoded")?n&&typeof n=="object"&&!(n instanceof URLSearchParams)?new URLSearchParams(n).toString():String(n):JSON.stringify(n)};async function p(n){const i=(n.headers.get("content-type")||"").includes("application/json")?await n.clone().json():await n.clone().text(),r=typeof i=="object"&&i!==null?i.error||i.message:typeof i=="string"?i:void 0;return Object.assign(new Error(r||`HTTP ${n.status} ${n.statusText}`),{status:n.status,statusText:n.statusText,body:i})}async function s(n,t=3e3){if(t<=0)return await n();const e=new AbortController,i=setTimeout(()=>e.abort(),t);try{return await n(e.signal)}catch(r){throw r instanceof DOMException&&r.name==="AbortError"?new Error(`Request timed out after ${t}ms`):r}finally{clearTimeout(i)}}function D(n,t,e){let i,r=e??void 0,o,a=null;const d=async()=>{i||(a||(a=(async()=>{const u=await t();if(!u.api_semver)throw new Error("Empty API version");i=u.api_semver})().finally(()=>{a=null})),await a)},f={async onRequest({request:u,schemaPath:l}){return r&&u.headers.set("Authorization",`Bearer ${r}`),l!=="/version"&&(await d(),i&&u.headers.set("X-API-Sem-Ver",i),o&&u.headers.set("X-API-Token",o)),u},async onResponse({request:u,response:l,options:v,schemaPath:P}){if(l.ok)return l;if(P==="/version")throw await p(l);if(l.status!==405)throw await p(l);i=void 0,await d(),i&&u.headers.set("X-API-Sem-Ver",i),r&&u.headers.set("Authorization",`Bearer ${r}`);const y=await(v.fetch??fetch)(u);if(y.ok)return y;throw await p(y)}},h=m({baseUrl:n,bodySerializer:O});return h.use(f),{client:h,setApiKey:u=>{o=u},setToken:u=>{r=u}}}async function B(n,t){const{data:e,error:i}=await s(r=>n.GET("/version",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function U(n,t){const{data:e,error:i}=await s(r=>n.GET("/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function $(n,t){const{data:e,error:i}=await s(r=>n.GET("/status/system",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function I(n,t){const{data:e,error:i}=await s(r=>n.GET("/status/power",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class K{async SystemVersionGet(t){const e=await B(this.apiClient,t);return this.apiSemver=e.api_semver,e}async SystemStatusGet(t){return await U(this.apiClient,t)}async SystemInfoGet(t){return await $(this.apiClient,t)}async SystemStatusPowerGet(t){return await I(this.apiClient,t)}}async function R(n,t){const{file:e}=t,{data:i,error:r}=await s(o=>n.POST("/update",{headers:{"Content-Type":"application/octet-stream"},body:e,signal:o}),t.timeout);if(r)throw r;return i}async function F(n,t){const{data:e,error:i}=await s(r=>n.POST("/update/check",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function W(n,t){const{data:e,error:i}=await s(r=>n.GET("/update/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function M(n,t){const{version:e}=t,{data:i,error:r}=await s(o=>n.GET("/update/changelog",{params:{query:{version:e}},signal:o}),t.timeout);if(r)throw r;return i}async function N(n,t){const{version:e}=t,{data:i,error:r}=await s(o=>n.POST("/update/install",{params:{query:{version:e}},signal:o}),t.timeout);if(r)throw r;return i}async function _(n,t){const{data:e,error:i}=await s(r=>n.POST("/update/abort_download",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class x{async UpdateFromFile(t){return await R(this.apiClient,t)}async UpdateCheck(t){return await F(this.apiClient,t)}async UpdateStatusGet(t){return await W(this.apiClient,t)}async UpdateChangelogGet(t){return await M(this.apiClient,t)}async UpdateInstall(t){return await N(this.apiClient,t)}async UpdateAbort(t){return await _(this.apiClient,t)}}async function q(n,t){const{data:e,error:i}=await s(r=>n.GET("/time",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function j(n,t){const{data:e,error:i}=await s(r=>n.POST("/time/timestamp",{params:{query:{...t,timeout:void 0}},signal:r}),t.timeout);if(i)throw i;return e}async function V(n,t){const{data:e,error:i}=await s(r=>n.GET("/time/timezone",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function z(n,t){const{data:e,error:i}=await s(r=>n.POST("/time/timezone",{params:{query:{...t,timeout:void 0}},signal:r}),t.timeout);if(i)throw i;return e}async function H(n,t){const{data:e,error:i}=await s(r=>n.GET("/time/tzlist",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class J{async TimeGet(t){return await q(this.apiClient,t)}async TimeTimestampSet(t){return await j(this.apiClient,t)}async TimeTimezoneGet(t){return await V(this.apiClient,t)}async TimeTimezoneSet(t){return await z(this.apiClient,t)}async TimeTzListGet(t){return await H(this.apiClient,t)}}async function X(n,t){const{data:e,error:i}=await s(r=>n.GET("/account/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Q(n,t){const{data:e,error:i}=await s(r=>n.GET("/account/info",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Y(n,t){const{data:e,error:i}=await s(r=>n.GET("/account/profile",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Z(n,t){const{profile:e}=t,{data:i,error:r}=await s(o=>n.POST("/account/profile",{params:{query:{profile:e}},signal:o}),t.timeout);if(r)throw r;return i}async function tt(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/account",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function et(n,t){const{data:e,error:i}=await s(r=>n.POST("/account/link",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class it{async AccountInfoGet(t){return await Q(this.apiClient,t)}async AccountStateGet(t){return await X(this.apiClient,t)}async AccountProfileGet(t){return await Y(this.apiClient,t)}async AccountProfileSet(t){return await Z(this.apiClient,t)}async AccountUnlink(t){return await tt(this.apiClient,t)}async AccountLink(t){return await et(this.apiClient,t)}}async function nt(n,t){const{appId:e,elements:i}=t,{data:r,error:o}=await s(a=>n.POST("/display/draw",{body:{app_id:e,elements:i},signal:a}),t.timeout);if(o)throw o;return r}async function rt(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/display/draw",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function ot(n,t){const{display:e}=t,{data:i,error:r}=await s(o=>n.GET("/screen",{params:{query:{display:e}},parseAs:"blob",signal:o}),t.timeout);if(r)throw r;return i}async function st(n,t){const{data:e,error:i}=await s(r=>n.GET("/display/brightness",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function at(n,t){const{front:e,back:i}=t,r=h=>{if(typeof h=="number"){if(h<0||h>100)throw new Error("Brightness value must be between 0 and 100 or 'auto'");return String(h)}if(h==="auto")return"auto"},o=r(e),a=r(i),{data:d,error:f}=await s(h=>n.POST("/display/brightness",{params:{query:{front:o,back:a}},signal:h}),t.timeout);if(f)throw f;return d}class ct{async DisplayDraw(t){return await nt(this.apiClient,t)}async DisplayClear(t){return await rt(this.apiClient,t)}async DisplayScreenFrameGet(t){return await ot(this.apiClient,t)}async DisplayBrightnessGet(t){return await st(this.apiClient,t)}async DisplayBrightnessSet(t){return await at(this.apiClient,t)}}async function ut(n,t){const{appId:e,path:i}=t,{data:r,error:o}=await s(a=>n.POST("/audio/play",{params:{query:{app_id:e,path:i}},signal:a}),t.timeout);if(o)throw o;return r}async function ht(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/audio/play",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function dt(n,t){const{data:e,error:i}=await s(r=>n.GET("/audio/volume",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function ft(n,t){const{volume:e}=t;if(typeof e!="number"||e<0||e>100)throw new Error("Volume must be a number between 0 and 100");const{data:i,error:r}=await s(o=>n.POST("/audio/volume",{params:{query:{volume:e}},signal:o}),t.timeout);if(r)throw r;return i}class lt{async AudioPlay(t){return await ut(this.apiClient,t)}async AudioStop(t){return await ht(this.apiClient,t)}async AudioVolumeGet(t){return await dt(this.apiClient,t)}async AudioVolumeSet(t){return await ft(this.apiClient,t)}}async function wt(n,t){const{data:e,error:i}=await s(r=>n.GET("/wifi/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function yt(n,t){const{data:e,error:i}=await s(r=>n.POST("/wifi/connect",{body:{ssid:t.ssid,password:t.password,security:t.security,ip_config:{ip_method:t.ipConfig.ipMethod,address:t.ipConfig.address,mask:t.ipConfig.mask,gateway:t.ipConfig.gateway}},signal:r}),t.timeout);if(i)throw i;return e}async function pt(n,t){const{data:e,error:i}=await s(r=>n.POST("/wifi/disconnect",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function St(n,t){const{data:e,error:i}=await s(r=>n.GET("/wifi/networks",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class Tt{async WifiStatusGet(t){return await wt(this.apiClient,t)}async WifiConnect(t){return await yt(this.apiClient,t)}async WifiDisconnect(t){return await pt(this.apiClient,t)}async WifiNetworksGet(t){return await St(this.apiClient,t)}}async function Et(n,t){const{path:e,file:i}=t,{data:r,error:o}=await s(a=>n.POST("/storage/write",{params:{query:{path:e}},headers:{"Content-Type":"application/octet-stream"},body:i,signal:a}),t.timeout);if(o)throw o;return r}async function mt(n,t){const{path:e,asArrayBuffer:i}=t,{data:r,error:o}=await s(a=>n.GET("/storage/read",{params:{query:{path:e}},parseAs:i?"arrayBuffer":"blob",signal:a}),t.timeout);if(o)throw o;return r}async function kt(n,t){const{path:e}=t,{data:i,error:r}=await s(o=>n.GET("/storage/list",{params:{query:{path:e}},signal:o}),t.timeout);if(r)throw r;return i}async function Ct(n,t){const{path:e}=t,{data:i,error:r}=await s(o=>n.DELETE("/storage/remove",{params:{query:{path:e}},signal:o}),t.timeout);if(r)throw r;return i}async function gt(n,t){const{path:e}=t,{data:i,error:r}=await s(o=>n.POST("/storage/mkdir",{params:{query:{path:e}},signal:o}),t.timeout);if(r)throw r;return i}async function bt(n,t){const{data:e,error:i}=await s(r=>n.GET("/storage/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class At{async StorageWrite(t){return await Et(this.apiClient,t)}async StorageRead(t){return await mt(this.apiClient,t)}async StorageListGet(t){return await kt(this.apiClient,t)}async StorageRemove(t){return await Ct(this.apiClient,t)}async StorageMkdir(t){return await gt(this.apiClient,t)}async StorageStatusGet(t){return await bt(this.apiClient,t)}}async function vt(n,t){const{data:e,error:i}=await s(r=>n.GET("/access",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Pt(n,t){let{mode:e,key:i}=t;if(i=i??"",String(i).trim()&&!/^\d{4,10}$/.test(String(i)))throw new Error("Key must be a string of 4 to 10 digits");const{data:r,error:o}=await s(a=>n.POST("/access",{params:{query:{mode:e,key:i}},signal:a}),t.timeout);if(o)throw o;return r}async function Gt(n,t){const{data:e,error:i}=await s(r=>n.GET("/name",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Lt(n,t){const{data:e,error:i}=await s(r=>n.POST("/name",{body:t,signal:r}),t.timeout);if(i)throw i;return e}class Ot{async SettingsAccessGet(t){return await vt(this.apiClient,t)}async SettingsAccessSet(t){const e=await Pt(this.apiClient,t);return t.mode==="key"&&t.key&&this.setApiKey(t.key),e}async SettingsNameGet(t){return await Gt(this.apiClient,t)}async SettingsNameSet(t){return await Lt(this.apiClient,t)}}async function Dt(n,t){const{data:e,error:i}=await s(r=>n.POST("/ble/enable",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Bt(n,t){const{data:e,error:i}=await s(r=>n.POST("/ble/disable",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Ut(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/ble/pairing",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function $t(n,t){const{data:e,error:i}=await s(r=>n.GET("/ble/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class It{async BleEnable(t){return await Dt(this.apiClient,t)}async BleDisable(t){return await Bt(this.apiClient,t)}async BleUnpair(t){return await Ut(this.apiClient,t)}async BleStatusGet(t){return await $t(this.apiClient,t)}}async function Kt(n,t){const{keyName:e}=t,{data:i,error:r}=await s(o=>n.POST("/input",{params:{query:{key:e}},signal:o}),t.timeout);if(r)throw r;return i}class Rt{async InputSend(t){return await Kt(this.apiClient,t)}}async function Ft(n,t){const{data:e,error:i}=await s(r=>n.GET("/matter/commissioning",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Wt(n,t){const{data:e,error:i}=await s(r=>n.POST("/matter/commissioning",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Mt(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/matter/commissioning",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class Nt{async MatterStatusGet(t){return await Ft(this.apiClient,t)}async MatterPair(t){return await Wt(this.apiClient,t)}async MatterErase(t){return await Mt(this.apiClient,t)}}const S="http://10.0.4.20",_t="https://proxy.busy.app",xt=/^https?:\/\/proxy(?:\.(?:dev|test|stage))?\.busy\.app$/i;function T(n){const t=n.split(".");if(t.length!==4)return!1;for(const e of t){if(e.length===0||e.length>1&&e[0]==="0"||!/^\d+$/.test(e))return!1;const i=Number(e);if(i<0||i>255)return!1}return!0}function E(n){return/\.local$/i.test(n)}class k{constructor(t){c(this,"addr");c(this,"apiSemver");c(this,"apiClient");c(this,"setApiKeyFn");c(this,"setTokenFn");c(this,"connectionType","unknown");if(!t||!t.addr&&!t.token)this.addr=S;else if(!t.addr)this.addr=_t;else{let o=t.addr.trim();if(/^https?:\/\//i.test(o)||(o=`http://${o}`),xt.test(o)&&!t.token)throw new Error("Token is required. Please provide it.");this.addr=o}this.apiSemver="";const{client:e,setApiKey:i,setToken:r}=D(`${this.addr}/api/`,this.SystemVersionGet.bind(this),t==null?void 0:t.token);this.apiClient=e,this.setApiKeyFn=i,this.setTokenFn=r,this.detectConnectionType()}async detectConnectionType(){const t=new URL(this.addr).hostname;if(!T(t)&&!E(t)){this.connectionType="wifi";return}const e=m({baseUrl:`${this.addr}/api/`});try{const{response:i}=await e.GET("/name");if(i.status===401||i.status===403)this.connectionType="wifi";else if(i.ok)this.connectionType="usb";else throw new Error(`Failed to detect connection type. Status: ${i.status}`)}catch(i){throw i}}setApiKey(t){this.setApiKeyFn(t)}setToken(t){this.setTokenFn(t)}}function qt(n,t){t.forEach(e=>{Object.getOwnPropertyNames(e.prototype).forEach(i=>{Object.defineProperty(n.prototype,i,Object.getOwnPropertyDescriptor(e.prototype,i)||Object.create(null))})})}qt(k,[K,x,J,it,ct,lt,Tt,At,Ot,It,Rt,Nt]);var w=(n=>(n[n.FRONT=0]="FRONT",n[n.BACK=1]="BACK",n))(w||{});const C=3e3,g=new Set([1001,1006,1012,1013,1014,3008]);function b(n,t){if(t<0||t>=n.length)throw new Error(`Index ${t} is out of bounds (0…${n.length-1})`);const e=n[t];if(e===void 0)throw new Error(`Unexpected undefined at index ${t}`);return e}function jt(n,t){let e=0;const i=n.length,r=[];for(;e<i;){const o=b(n,e);if(e+=1,(o&128)!==0){const a=o&127;for(let d=0;d<a*t;d++)r.push(n[e+d]);e+=a*t}else{const a=o,d=n.slice(e,e+t);for(let f=0;f<a;f++)for(let h=0;h<t;h++)r.push(d[h]);e+=t}}return new Uint8Array(r)}function Vt(n){const t=new Uint8Array(n.length*2);let e=0,i=0;for(;e<n.length;){const r=b(n,e),o=r&15,a=r>>4&15;t[i]=o,t[i+1]=a,e+=1,i+=2}return t}const A=()=>typeof window<"u"&&typeof window.document<"u";class zt{constructor(t){c(this,"addr");c(this,"connected",!1);c(this,"apiKey");c(this,"apiSemver");c(this,"dataListeners",[]);c(this,"stopListeners",[]);c(this,"errorListeners",[]);c(this,"socket",null);if(this.config=t,!A())throw new Error("not browser");if(t.apiKey&&(this.apiKey=t.apiKey),t.apiSemver&&(this.apiSemver=t.apiSemver),!t||!t.addr)this.addr=S;else{let e=t.addr.trim();/^https?:\/\//i.test(e)||(e=`http://${e}`);try{const r=new URL(e).hostname;if(!T(r)&&!E(r))throw new Error(`Invalid address: "${t.addr}". Only IP addresses and mDNS names (ending in .local) are supported.`)}catch(i){throw i instanceof Error&&i.message.startsWith("Invalid address")?i:new Error(`Invalid URL format: "${t.addr}"`)}this.addr=e}}onData(t){this.dataListeners.push(t)}onStop(t){this.stopListeners.push(t)}onError(t){this.errorListeners.push(t)}emitData(t){for(const e of this.dataListeners)e(t)}emitStop(){for(const t of this.stopListeners)t()}emitError(t){for(const e of this.errorListeners)e(t)}async openWebsocket(){this.socket&&await this.closeWebsocket();const t=new URL(`${this.addr}/api/screen/ws`);if(this.apiKey&&t.searchParams.append("x-api-token",this.apiKey),this.apiSemver&&t.searchParams.append("x-api-sem-ver",this.apiSemver),!t)throw new Error("The WebSocket URL is not specified");this.socket=new WebSocket(t),this.socket.onopen=()=>{this.socket&&(this.socket.send(JSON.stringify({display:this.config.deviceScreen})),this.connected=!0)},this.socket.binaryType="arraybuffer",this.socket.onmessage=e=>{try{if(typeof e.data=="string")return;const i=new Uint8Array(e.data);let r;const o=this.config.deviceScreen===w.FRONT?3:2;try{const a=jt(i,o);this.config.deviceScreen===w.BACK?r=Vt(a):r=a,this.emitData(r)}catch{this.emitData(i)}}catch{this.connected=!1,this.emitStop()}},this.socket.onerror=e=>{this.connected=!1,this.emitError({code:1006,message:"WebSocket error occurred",raw:e}),this.emitStop()},this.socket.onclose=async e=>{if(this.socket=null,this.connected=!1,e.code===C||g.has(e.code)){this.emitError({code:e.code,message:e.reason,raw:e});return}this.emitStop()}}closeWebsocket(){return this.connected=!1,new Promise(t=>{this.socket?(this.socket.onclose=()=>{t()},this.socket.close(),this.socket=null):t(),this.emitStop()})}}class Ht{constructor(t){c(this,"addr");c(this,"connected",!1);c(this,"apiKey");c(this,"apiSemver");c(this,"inputEvent");c(this,"dataListeners",[]);c(this,"stopListeners",[]);c(this,"errorListeners",[]);c(this,"socket",null);if(!A())throw new Error("not browser");if(t!=null&&t.apiKey&&(this.apiKey=t.apiKey),t!=null&&t.apiSemver&&(this.apiSemver=t.apiSemver),!t||!t.addr)this.addr=S;else{let e=t.addr.trim();/^https?:\/\//i.test(e)||(e=`http://${e}`);try{const r=new URL(e).hostname;if(!T(r)&&!E(r))throw new Error(`Invalid address: "${t.addr}". Only IP addresses and mDNS names (ending in .local) are supported.`)}catch(i){throw i instanceof Error&&i.message.startsWith("Invalid address")?i:new Error(`Invalid URL format: "${t.addr}"`)}this.addr=e}this.inputEvent={}}onData(t){this.dataListeners.push(t)}onStop(t){this.stopListeners.push(t)}onError(t){this.errorListeners.push(t)}emitData(t){for(const e of this.dataListeners)e(t)}emitStop(){for(const t of this.stopListeners)t()}emitError(t){for(const e of this.errorListeners)e(t)}async openWebsocket(){this.socket&&await this.closeWebsocket();const t=new URL(`${this.addr}/api/input`);if(this.apiKey&&t.searchParams.append("x-api-token",this.apiKey),this.apiSemver&&t.searchParams.append("x-api-sem-ver",this.apiSemver),!t)throw new Error("The WebSocket URL is not specified");this.socket=new WebSocket(t),this.socket.onopen=()=>{this.socket&&(this.connected=!0)},this.socket.binaryType="arraybuffer",this.socket.onmessage=e=>{try{if(typeof e.data=="string")return;const i=new Uint8Array(e.data);this.emitData(i)}catch{this.connected=!1,this.emitStop()}},this.socket.onerror=e=>{this.connected=!1,this.emitError({code:1006,message:"WebSocket error occurred",raw:e}),this.emitStop()},this.socket.onclose=async e=>{if(this.socket=null,this.connected=!1,e.code===C||g.has(e.code)){this.emitError({code:e.code,message:e.reason,raw:e});return}this.emitStop()}}sendInput({keyName:t,value:e}){if(!this.socket||!this.connected)throw new Error("WebSocket: Not connected");this.inputEvent[t]=e,this.socket.send(JSON.stringify(this.inputEvent)),e===0&&delete this.inputEvent[t]}closeWebsocket(){return this.connected=!1,new Promise(t=>{this.socket?(this.socket.onclose=()=>{t()},this.socket.close(),this.socket=null):t(),this.emitStop()})}}exports.BusyBar=k;exports.DeviceScreen=w;exports.Input=Ht;exports.ScreenStream=zt;
1
+ "use strict";var G=Object.defineProperty;var L=(n,t,e)=>t in n?G(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var c=(n,t,e)=>L(n,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("openapi-fetch"),O=(n,t)=>{if(typeof FormData<"u"&&n instanceof FormData||typeof Buffer<"u"&&typeof Buffer.isBuffer=="function"&&Buffer.isBuffer(n)||typeof File<"u"&&n instanceof File||typeof Blob<"u"&&n instanceof Blob||typeof ArrayBuffer<"u"&&n instanceof ArrayBuffer||typeof ArrayBuffer<"u"&&ArrayBuffer.isView&&ArrayBuffer.isView(n))return n;let e;return t&&(t instanceof Headers?e=t.get("Content-Type")??t.get("content-type")??void 0:typeof t=="object"&&(e=t["Content-Type"]??t["content-type"]),e==="application/x-www-form-urlencoded")?n&&typeof n=="object"&&!(n instanceof URLSearchParams)?new URLSearchParams(n).toString():String(n):JSON.stringify(n)};async function p(n){const i=(n.headers.get("content-type")||"").includes("application/json")?await n.clone().json():await n.clone().text(),r=typeof i=="object"&&i!==null?i.error||i.message:typeof i=="string"?i:void 0;return Object.assign(new Error(r||`HTTP ${n.status} ${n.statusText}`),{status:n.status,statusText:n.statusText,body:i})}async function s(n,t=3e3){if(t<=0)return await n();const e=new AbortController,i=setTimeout(()=>e.abort(),t);try{return await n(e.signal)}catch(r){throw r instanceof DOMException&&r.name==="AbortError"?new Error(`Request timed out after ${t}ms`):r}finally{clearTimeout(i)}}function D(n,t,e){let i,r=e??void 0,o,a=null;const u=async()=>{i||(a||(a=(async()=>{const h=await t();if(!h.api_semver)throw new Error("Empty API version");i=h.api_semver})().finally(()=>{a=null})),await a)},l={async onRequest({request:h,schemaPath:d}){return r&&h.headers.set("Authorization",`Bearer ${r}`),d!=="/version"&&(await u(),i&&h.headers.set("X-API-Sem-Ver",i),o&&h.headers.set("X-API-Token",o)),h},async onResponse({request:h,response:d,options:v,schemaPath:P}){if(d.ok)return d;if(P==="/version")throw await p(d);if(d.status!==405)throw await p(d);i=void 0,await u(),i&&h.headers.set("X-API-Sem-Ver",i),r&&h.headers.set("Authorization",`Bearer ${r}`);const y=await(v.fetch??fetch)(h);if(y.ok)return y;throw await p(y)}},f=m({baseUrl:n,bodySerializer:O});return f.use(l),{client:f,setApiKey:h=>{o=h},setToken:h=>{r=h}}}async function B(n,t){const{data:e,error:i}=await s(r=>n.GET("/version",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function U(n,t){const{data:e,error:i}=await s(r=>n.GET("/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function I(n,t){const{data:e,error:i}=await s(r=>n.GET("/status/system",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function $(n,t){const{data:e,error:i}=await s(r=>n.GET("/status/power",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class K{async SystemVersionGet(t){const e=await B(this.apiClient,t);return this.apiSemver=e.api_semver,e}async SystemStatusGet(t){return await U(this.apiClient,t)}async SystemInfoGet(t){return await I(this.apiClient,t)}async SystemStatusPowerGet(t){return await $(this.apiClient,t)}}async function R(n,t){const{file:e}=t,{data:i,error:r}=await s(o=>n.POST("/update",{headers:{"Content-Type":"application/octet-stream"},body:e,signal:o}),t.timeout);if(r)throw r;return i}async function F(n,t){const{data:e,error:i}=await s(r=>n.POST("/update/check",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function M(n,t){const{data:e,error:i}=await s(r=>n.GET("/update/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function W(n,t){const{version:e}=t,{data:i,error:r}=await s(o=>n.GET("/update/changelog",{params:{query:{version:e}},signal:o}),t.timeout);if(r)throw r;return i}async function N(n,t){const{version:e}=t,{data:i,error:r}=await s(o=>n.POST("/update/install",{params:{query:{version:e}},signal:o}),t.timeout);if(r)throw r;return i}async function _(n,t){const{data:e,error:i}=await s(r=>n.POST("/update/abort_download",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class q{async UpdateFromFile(t){return await R(this.apiClient,t)}async UpdateCheck(t){return await F(this.apiClient,t)}async UpdateStatusGet(t){return await M(this.apiClient,t)}async UpdateChangelogGet(t){return await W(this.apiClient,t)}async UpdateInstall(t){return await N(this.apiClient,t)}async UpdateAbort(t){return await _(this.apiClient,t)}}async function x(n,t){const{data:e,error:i}=await s(r=>n.GET("/time",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function j(n,t){const{data:e,error:i}=await s(r=>n.POST("/time/timestamp",{params:{query:{...t,timeout:void 0}},signal:r}),t.timeout);if(i)throw i;return e}async function V(n,t){const{data:e,error:i}=await s(r=>n.GET("/time/timezone",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function z(n,t){const{data:e,error:i}=await s(r=>n.POST("/time/timezone",{params:{query:{...t,timeout:void 0}},signal:r}),t.timeout);if(i)throw i;return e}async function H(n,t){const{data:e,error:i}=await s(r=>n.GET("/time/tzlist",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class J{async TimeGet(t){return await x(this.apiClient,t)}async TimeTimestampSet(t){return await j(this.apiClient,t)}async TimeTimezoneGet(t){return await V(this.apiClient,t)}async TimeTimezoneSet(t){return await z(this.apiClient,t)}async TimeTzListGet(t){return await H(this.apiClient,t)}}async function X(n,t){const{data:e,error:i}=await s(r=>n.GET("/account/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Y(n,t){const{data:e,error:i}=await s(r=>n.GET("/account/info",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Q(n,t){const{data:e,error:i}=await s(r=>n.GET("/account/profile",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Z(n,t){const{profile:e}=t,{data:i,error:r}=await s(o=>n.POST("/account/profile",{params:{query:{profile:e}},signal:o}),t.timeout);if(r)throw r;return i}async function tt(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/account",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function et(n,t){const{data:e,error:i}=await s(r=>n.POST("/account/link",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class it{async AccountInfoGet(t){return await Y(this.apiClient,t)}async AccountStateGet(t){return await X(this.apiClient,t)}async AccountProfileGet(t){return await Q(this.apiClient,t)}async AccountProfileSet(t){return await Z(this.apiClient,t)}async AccountUnlink(t){return await tt(this.apiClient,t)}async AccountLink(t){return await et(this.apiClient,t)}}async function nt(n,t){const{appId:e,elements:i,priority:r=6}=t,{data:o,error:a}=await s(u=>n.POST("/display/draw",{body:{app_id:e,priority:r,elements:i},signal:u}),t.timeout);if(a)throw a;return o}async function rt(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/display/draw",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function ot(n,t){const{display:e}=t,{data:i,error:r}=await s(o=>n.GET("/screen",{params:{query:{display:e}},parseAs:"blob",signal:o}),t.timeout);if(r)throw r;return i}async function st(n,t){const{data:e,error:i}=await s(r=>n.GET("/display/brightness",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function at(n,t){const{value:e}=t,r=(u=>{if(typeof u=="number"){if(u<0||u>100)throw new Error("Brightness value must be between 0 and 100 or 'auto'");return String(u)}if(u==="auto")return"auto"})(e),{data:o,error:a}=await s(u=>n.POST("/display/brightness",{params:{query:{value:r}},signal:u}),t.timeout);if(a)throw a;return o}class ct{async DisplayDraw(t){return await nt(this.apiClient,t)}async DisplayClear(t){return await rt(this.apiClient,t)}async DisplayScreenFrameGet(t){return await ot(this.apiClient,t)}async DisplayBrightnessGet(t){return await st(this.apiClient,t)}async DisplayBrightnessSet(t){return await at(this.apiClient,t)}}async function ut(n,t){const{appId:e,path:i}=t,{data:r,error:o}=await s(a=>n.POST("/audio/play",{params:{query:{app_id:e,path:i}},signal:a}),t.timeout);if(o)throw o;return r}async function ht(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/audio/play",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function dt(n,t){const{data:e,error:i}=await s(r=>n.GET("/audio/volume",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function ft(n,t){const{volume:e}=t;if(typeof e!="number"||e<0||e>100)throw new Error("Volume must be a number between 0 and 100");const{data:i,error:r}=await s(o=>n.POST("/audio/volume",{params:{query:{volume:e}},signal:o}),t.timeout);if(r)throw r;return i}class lt{async AudioPlay(t){return await ut(this.apiClient,t)}async AudioStop(t){return await ht(this.apiClient,t)}async AudioVolumeGet(t){return await dt(this.apiClient,t)}async AudioVolumeSet(t){return await ft(this.apiClient,t)}}async function wt(n,t){const{data:e,error:i}=await s(r=>n.GET("/wifi/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function yt(n,t){const{data:e,error:i}=await s(r=>n.POST("/wifi/connect",{body:{ssid:t.ssid,password:t.password,security:t.security,ip_config:{ip_method:t.ipConfig.ipMethod,address:t.ipConfig.address,mask:t.ipConfig.mask,gateway:t.ipConfig.gateway}},signal:r}),t.timeout);if(i)throw i;return e}async function pt(n,t){const{data:e,error:i}=await s(r=>n.POST("/wifi/disconnect",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function St(n,t){const{data:e,error:i}=await s(r=>n.GET("/wifi/networks",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class Tt{async WifiStatusGet(t){return await wt(this.apiClient,t)}async WifiConnect(t){return await yt(this.apiClient,t)}async WifiDisconnect(t){return await pt(this.apiClient,t)}async WifiNetworksGet(t){return await St(this.apiClient,t)}}async function Et(n,t){const{path:e,file:i}=t,{data:r,error:o}=await s(a=>n.POST("/storage/write",{params:{query:{path:e}},headers:{"Content-Type":"application/octet-stream"},body:i,signal:a}),t.timeout);if(o)throw o;return r}async function mt(n,t){const{path:e,asArrayBuffer:i}=t,{data:r,error:o}=await s(a=>n.GET("/storage/read",{params:{query:{path:e}},parseAs:i?"arrayBuffer":"blob",signal:a}),t.timeout);if(o)throw o;return r}async function Ct(n,t){const{path:e}=t,{data:i,error:r}=await s(o=>n.GET("/storage/list",{params:{query:{path:e}},signal:o}),t.timeout);if(r)throw r;return i}async function kt(n,t){const{path:e}=t,{data:i,error:r}=await s(o=>n.DELETE("/storage/remove",{params:{query:{path:e}},signal:o}),t.timeout);if(r)throw r;return i}async function gt(n,t){const{path:e}=t,{data:i,error:r}=await s(o=>n.POST("/storage/mkdir",{params:{query:{path:e}},signal:o}),t.timeout);if(r)throw r;return i}async function bt(n,t){const{data:e,error:i}=await s(r=>n.GET("/storage/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class At{async StorageWrite(t){return await Et(this.apiClient,t)}async StorageRead(t){return await mt(this.apiClient,t)}async StorageListGet(t){return await Ct(this.apiClient,t)}async StorageRemove(t){return await kt(this.apiClient,t)}async StorageMkdir(t){return await gt(this.apiClient,t)}async StorageStatusGet(t){return await bt(this.apiClient,t)}}async function vt(n,t){const{data:e,error:i}=await s(r=>n.GET("/access",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Pt(n,t){let{mode:e,key:i}=t;if(i=i??"",String(i).trim()&&!/^\d{4,10}$/.test(String(i)))throw new Error("Key must be a string of 4 to 10 digits");const{data:r,error:o}=await s(a=>n.POST("/access",{params:{query:{mode:e,key:i}},signal:a}),t.timeout);if(o)throw o;return r}async function Gt(n,t){const{data:e,error:i}=await s(r=>n.GET("/name",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Lt(n,t){const{data:e,error:i}=await s(r=>n.POST("/name",{body:t,signal:r}),t.timeout);if(i)throw i;return e}class Ot{async SettingsAccessGet(t){return await vt(this.apiClient,t)}async SettingsAccessSet(t){const e=await Pt(this.apiClient,t);return t.mode==="key"&&t.key&&this.setApiKey(t.key),e}async SettingsNameGet(t){return await Gt(this.apiClient,t)}async SettingsNameSet(t){return await Lt(this.apiClient,t)}}async function Dt(n,t){const{data:e,error:i}=await s(r=>n.POST("/ble/enable",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Bt(n,t){const{data:e,error:i}=await s(r=>n.POST("/ble/disable",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Ut(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/ble/pairing",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function It(n,t){const{data:e,error:i}=await s(r=>n.GET("/ble/status",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class $t{async BleEnable(t){return await Dt(this.apiClient,t)}async BleDisable(t){return await Bt(this.apiClient,t)}async BleUnpair(t){return await Ut(this.apiClient,t)}async BleStatusGet(t){return await It(this.apiClient,t)}}async function Kt(n,t){const{keyName:e}=t,{data:i,error:r}=await s(o=>n.POST("/input",{params:{query:{key:e}},signal:o}),t.timeout);if(r)throw r;return i}class Rt{async InputSend(t){return await Kt(this.apiClient,t)}}async function Ft(n,t){const{data:e,error:i}=await s(r=>n.GET("/matter/commissioning",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Mt(n,t){const{data:e,error:i}=await s(r=>n.POST("/matter/commissioning",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}async function Wt(n,t){const{data:e,error:i}=await s(r=>n.DELETE("/matter/commissioning",{signal:r}),t==null?void 0:t.timeout);if(i)throw i;return e}class Nt{async MatterStatusGet(t){return await Ft(this.apiClient,t)}async MatterPair(t){return await Mt(this.apiClient,t)}async MatterErase(t){return await Wt(this.apiClient,t)}}async function _t(n,t){const{appId:e,fileName:i,file:r}=t,{data:o,error:a}=await s(u=>n.POST("/assets/upload",{params:{query:{app_id:e,file:i}},headers:{"Content-Type":"application/octet-stream"},body:r,signal:u}),t.timeout);if(a)throw a;return o}async function qt(n,t){const{appId:e}=t,{data:i,error:r}=await s(o=>n.DELETE("/assets/upload",{params:{query:{app_id:e}},signal:o}),t.timeout);if(r)throw r;return i}class xt{async AssetsUpload(t){return await _t(this.apiClient,t)}async AssetsDelete(t){return await qt(this.apiClient,t)}}const S="http://10.0.4.20",jt="https://proxy.busy.app",Vt=/^https?:\/\/proxy(?:\.(?:dev|test|stage))?\.busy\.app$/i;function T(n){const t=n.split(".");if(t.length!==4)return!1;for(const e of t){if(e.length===0||e.length>1&&e[0]==="0"||!/^\d+$/.test(e))return!1;const i=Number(e);if(i<0||i>255)return!1}return!0}function E(n){return/\.local$/i.test(n)}class C{constructor(t){c(this,"addr");c(this,"apiSemver");c(this,"apiClient");c(this,"setApiKeyFn");c(this,"setTokenFn");c(this,"connectionType","unknown");if(!t||!t.addr&&!t.token)this.addr=S;else if(!t.addr)this.addr=jt;else{let o=t.addr.trim();if(/^https?:\/\//i.test(o)||(o=`http://${o}`),Vt.test(o)&&!t.token)throw new Error("Token is required. Please provide it.");this.addr=o}this.apiSemver="";const{client:e,setApiKey:i,setToken:r}=D(`${this.addr}/api/`,this.SystemVersionGet.bind(this),t==null?void 0:t.token);this.apiClient=e,this.setApiKeyFn=i,this.setTokenFn=r,this.detectConnectionType()}async detectConnectionType(){const t=new URL(this.addr).hostname;if(!T(t)&&!E(t)){this.connectionType="wifi";return}const e=m({baseUrl:`${this.addr}/api/`});try{const{response:i}=await e.GET("/name");if(i.status===401||i.status===403)this.connectionType="wifi";else if(i.ok)this.connectionType="usb";else throw new Error(`Failed to detect connection type. Status: ${i.status}`)}catch(i){throw i}}setApiKey(t){this.setApiKeyFn(t)}setToken(t){this.setTokenFn(t)}}function zt(n,t){t.forEach(e=>{Object.getOwnPropertyNames(e.prototype).forEach(i=>{Object.defineProperty(n.prototype,i,Object.getOwnPropertyDescriptor(e.prototype,i)||Object.create(null))})})}zt(C,[K,q,J,it,ct,lt,Tt,At,Ot,$t,Rt,Nt,xt]);var w=(n=>(n[n.FRONT=0]="FRONT",n[n.BACK=1]="BACK",n))(w||{});const k=3e3,g=new Set([1001,1006,1012,1013,1014,3008]);function b(n,t){if(t<0||t>=n.length)throw new Error(`Index ${t} is out of bounds (0…${n.length-1})`);const e=n[t];if(e===void 0)throw new Error(`Unexpected undefined at index ${t}`);return e}function Ht(n,t){let e=0;const i=n.length,r=[];for(;e<i;){const o=b(n,e);if(e+=1,(o&128)!==0){const a=o&127;for(let u=0;u<a*t;u++)r.push(n[e+u]);e+=a*t}else{const a=o,u=n.slice(e,e+t);for(let l=0;l<a;l++)for(let f=0;f<t;f++)r.push(u[f]);e+=t}}return new Uint8Array(r)}function Jt(n){const t=new Uint8Array(n.length*2);let e=0,i=0;for(;e<n.length;){const r=b(n,e),o=r&15,a=r>>4&15;t[i]=o,t[i+1]=a,e+=1,i+=2}return t}const A=()=>typeof window<"u"&&typeof window.document<"u";class Xt{constructor(t){c(this,"addr");c(this,"connected",!1);c(this,"apiKey");c(this,"apiSemver");c(this,"dataListeners",[]);c(this,"stopListeners",[]);c(this,"errorListeners",[]);c(this,"socket",null);if(this.config=t,!A())throw new Error("not browser");if(t.apiKey&&(this.apiKey=t.apiKey),t.apiSemver&&(this.apiSemver=t.apiSemver),!t||!t.addr)this.addr=S;else{let e=t.addr.trim();/^https?:\/\//i.test(e)||(e=`http://${e}`);try{const r=new URL(e).hostname;if(!T(r)&&!E(r))throw new Error(`Invalid address: "${t.addr}". Only IP addresses and mDNS names (ending in .local) are supported.`)}catch(i){throw i instanceof Error&&i.message.startsWith("Invalid address")?i:new Error(`Invalid URL format: "${t.addr}"`)}this.addr=e}}onData(t){this.dataListeners.push(t)}onStop(t){this.stopListeners.push(t)}onError(t){this.errorListeners.push(t)}emitData(t){for(const e of this.dataListeners)e(t)}emitStop(){for(const t of this.stopListeners)t()}emitError(t){for(const e of this.errorListeners)e(t)}async openWebsocket(){this.socket&&await this.closeWebsocket();const t=new URL(`${this.addr}/api/screen/ws`);if(this.apiKey&&t.searchParams.append("x-api-token",this.apiKey),this.apiSemver&&t.searchParams.append("x-api-sem-ver",this.apiSemver),!t)throw new Error("The WebSocket URL is not specified");this.socket=new WebSocket(t),this.socket.onopen=()=>{this.socket&&(this.socket.send(JSON.stringify({display:this.config.deviceScreen})),this.connected=!0)},this.socket.binaryType="arraybuffer",this.socket.onmessage=e=>{try{if(typeof e.data=="string")return;const i=new Uint8Array(e.data);let r;const o=this.config.deviceScreen===w.FRONT?3:2;try{const a=Ht(i,o);this.config.deviceScreen===w.BACK?r=Jt(a):r=a,this.emitData(r)}catch{this.emitData(i)}}catch{this.connected=!1,this.emitStop()}},this.socket.onerror=e=>{this.connected=!1,this.emitError({code:1006,message:"WebSocket error occurred",raw:e}),this.emitStop()},this.socket.onclose=async e=>{if(this.socket=null,this.connected=!1,e.code===k||g.has(e.code)){this.emitError({code:e.code,message:e.reason,raw:e});return}this.emitStop()}}closeWebsocket(){return this.connected=!1,new Promise(t=>{this.socket?(this.socket.onclose=()=>{t()},this.socket.close(),this.socket=null):t(),this.emitStop()})}}class Yt{constructor(t){c(this,"addr");c(this,"connected",!1);c(this,"apiKey");c(this,"apiSemver");c(this,"inputEvent");c(this,"dataListeners",[]);c(this,"stopListeners",[]);c(this,"errorListeners",[]);c(this,"socket",null);if(!A())throw new Error("not browser");if(t!=null&&t.apiKey&&(this.apiKey=t.apiKey),t!=null&&t.apiSemver&&(this.apiSemver=t.apiSemver),!t||!t.addr)this.addr=S;else{let e=t.addr.trim();/^https?:\/\//i.test(e)||(e=`http://${e}`);try{const r=new URL(e).hostname;if(!T(r)&&!E(r))throw new Error(`Invalid address: "${t.addr}". Only IP addresses and mDNS names (ending in .local) are supported.`)}catch(i){throw i instanceof Error&&i.message.startsWith("Invalid address")?i:new Error(`Invalid URL format: "${t.addr}"`)}this.addr=e}this.inputEvent={}}onData(t){this.dataListeners.push(t)}onStop(t){this.stopListeners.push(t)}onError(t){this.errorListeners.push(t)}emitData(t){for(const e of this.dataListeners)e(t)}emitStop(){for(const t of this.stopListeners)t()}emitError(t){for(const e of this.errorListeners)e(t)}async openWebsocket(){this.socket&&await this.closeWebsocket();const t=new URL(`${this.addr}/api/input`);if(this.apiKey&&t.searchParams.append("x-api-token",this.apiKey),this.apiSemver&&t.searchParams.append("x-api-sem-ver",this.apiSemver),!t)throw new Error("The WebSocket URL is not specified");this.socket=new WebSocket(t),this.socket.onopen=()=>{this.socket&&(this.connected=!0)},this.socket.binaryType="arraybuffer",this.socket.onmessage=e=>{try{if(typeof e.data=="string")return;const i=new Uint8Array(e.data);this.emitData(i)}catch{this.connected=!1,this.emitStop()}},this.socket.onerror=e=>{this.connected=!1,this.emitError({code:1006,message:"WebSocket error occurred",raw:e}),this.emitStop()},this.socket.onclose=async e=>{if(this.socket=null,this.connected=!1,e.code===k||g.has(e.code)){this.emitError({code:e.code,message:e.reason,raw:e});return}this.emitStop()}}sendInput({keyName:t,value:e}){if(!this.socket||!this.connected)throw new Error("WebSocket: Not connected");this.inputEvent[t]=e,this.socket.send(JSON.stringify(this.inputEvent)),e===0&&delete this.inputEvent[t]}closeWebsocket(){return this.connected=!1,new Promise(t=>{this.socket?(this.socket.onclose=()=>{t()},this.socket.close(),this.socket=null):t(),this.emitStop()})}}exports.BusyBar=C;exports.DeviceScreen=w;exports.Input=Yt;exports.ScreenStream=Xt;
package/dist/index.d.ts CHANGED
@@ -72,6 +72,29 @@ export declare interface AssetsDeleteParams extends TimeoutOptions {
72
72
  appId: paths["/assets/upload"]["delete"]["parameters"]["query"]["app_id"];
73
73
  }
74
74
 
75
+ declare class AssetsMethods {
76
+ /**
77
+ * Upload asset file with app ID. Uploads a file to a specific app's assets directory.
78
+ *
79
+ * @param {UploadParams} params - Parameters for the upload.
80
+ * @param {UploadParams['appId']} params.appId - Application ID for organizing assets.
81
+ * @param {UploadParams['fileName']} params.fileName - Filename for the uploaded asset.
82
+ * @param {UploadParams['file']} params.file - File data to upload.
83
+ * @param {UploadParams['timeout']} [params.timeout] - Request timeout in milliseconds.
84
+ * @returns {Promise<SuccessResponse>} Result of the upload operation.
85
+ */
86
+ AssetsUpload(this: BusyBar, params: AssetsUploadParams): Promise<SuccessResponse>;
87
+ /**
88
+ * Delete app assets. Deletes all assets for a specific app ID.
89
+ *
90
+ * @param {DeleteParams} params - Parameters for the delete.
91
+ * @param {DeleteParams['appId']} params.appId - Application ID whose assets should be deleted.
92
+ * @param {DeleteParams['timeout']} [params.timeout] - Request timeout in milliseconds.
93
+ * @returns {Promise<SuccessResponse>} Result of the delete operation.
94
+ */
95
+ AssetsDelete(this: BusyBar, params: AssetsDeleteParams): Promise<SuccessResponse>;
96
+ }
97
+
75
98
  export declare interface AssetsUploadParams extends TimeoutOptions {
76
99
  appId: paths["/assets/upload"]["post"]["parameters"]["query"]["app_id"];
77
100
  fileName: paths["/assets/upload"]["post"]["parameters"]["query"]["file"];
@@ -166,7 +189,7 @@ export declare type BleStatusResponse = components["schemas"]["BleStatusResponse
166
189
 
167
190
  declare type Brightness = number | "auto";
168
191
 
169
- export declare interface BusyBar extends SystemMethods, UpdateMethods, TimeMethods, AccountMethods, DisplayMethods, AudioMethods, WifiMethods, StorageMethods, SettingsMethods, BleMethods, InputMethods, MatterMethods {
192
+ export declare interface BusyBar extends SystemMethods, UpdateMethods, TimeMethods, AccountMethods, DisplayMethods, AudioMethods, WifiMethods, StorageMethods, SettingsMethods, BleMethods, InputMethods, AssetsMethods, MatterMethods {
170
193
  }
171
194
 
172
195
  /**
@@ -490,6 +513,11 @@ declare interface components {
490
513
  * @example my_app
491
514
  */
492
515
  app_id: string;
516
+ /**
517
+ * @description Draw requests with a lower priority than the currently active draw request will be ignored. Value is 1 through 10, inclusive, higher number means higher priority. Any built-in app is treated as priority level 5.
518
+ * @default 6
519
+ */
520
+ priority: number;
493
521
  /** @description Array of elements to display */
494
522
  elements: components["schemas"]["DisplayElement"][];
495
523
  };
@@ -612,15 +640,10 @@ declare interface components {
612
640
  };
613
641
  DisplayBrightnessInfo: {
614
642
  /**
615
- * @description Front display brightness (0-100/auto)
643
+ * @description Displays brightness (0-100/auto)
616
644
  * @example auto
617
645
  */
618
- front?: string;
619
- /**
620
- * @description Back display brightness (0-100/auto)
621
- * @example 50
622
- */
623
- back?: string;
646
+ value?: string;
624
647
  };
625
648
  AudioVolumeInfo: {
626
649
  /**
@@ -649,15 +672,25 @@ declare interface components {
649
672
  };
650
673
  StatusSystem: {
651
674
  /**
652
- * @description Git branch name
653
- * @example main
675
+ * @description Device serial number
676
+ * @example 203638485431500400123456
654
677
  */
655
- branch?: string;
678
+ serial_number?: string;
679
+ /**
680
+ * @description API SemVer
681
+ * @example 0.0.0
682
+ */
683
+ api_semver?: string;
656
684
  /**
657
685
  * @description Firmware version
658
686
  * @example 1.0.0
659
687
  */
660
688
  version?: string;
689
+ /**
690
+ * @description Git branch name
691
+ * @example main
692
+ */
693
+ branch?: string;
661
694
  /**
662
695
  * @description Build date
663
696
  * @example 2024-01-01
@@ -673,6 +706,11 @@ declare interface components {
673
706
  * @example 00d 00h 04m 13s
674
707
  */
675
708
  uptime?: string;
709
+ /**
710
+ * @description System boot timestamp
711
+ * @example 1767225600
712
+ */
713
+ boot_time?: number;
676
714
  };
677
715
  StatusPower: {
678
716
  /**
@@ -754,6 +792,11 @@ declare interface components {
754
792
  security?: components["schemas"]["WifiSecurityMethod"];
755
793
  ip_config?: {
756
794
  ip_method?: components["schemas"]["WifiIpMethod"];
795
+ /**
796
+ * @example ipv4
797
+ * @enum {string}
798
+ */
799
+ ip_type?: "ipv4" | "ipv6";
757
800
  /** @example 192.168.50.5 */
758
801
  address?: string;
759
802
  /** @example 255.255.255.0 */
@@ -961,6 +1004,7 @@ declare interface components {
961
1004
  };
962
1005
  };
963
1006
  responses: never;
1007
+ parameters: never;
964
1008
  requestBodies: never;
965
1009
  headers: never;
966
1010
  pathItems: never;
@@ -980,13 +1024,14 @@ export declare enum DeviceScreen {
980
1024
  export declare type DisplayBrightnessInfo = components["schemas"]["DisplayBrightnessInfo"];
981
1025
 
982
1026
  export declare interface DisplayBrightnessParams extends TimeoutOptions {
983
- front?: Brightness;
984
- back?: Brightness;
1027
+ value?: Brightness;
985
1028
  }
986
1029
 
987
1030
  export declare interface DisplayDrawParams extends TimeoutOptions {
988
1031
  appId: components["schemas"]["DisplayElements"]["app_id"];
989
1032
  elements: components["schemas"]["DisplayElements"]["elements"];
1033
+ /** @default 6 */
1034
+ priority?: components["schemas"]["DisplayElements"]["priority"];
990
1035
  }
991
1036
 
992
1037
  declare class DisplayMethods {
@@ -994,8 +1039,9 @@ declare class DisplayMethods {
994
1039
  * Draw on display. Starts the Canvas application if not running.
995
1040
  *
996
1041
  * @param {DrawParams} params - Parameters for the draw operation.
997
- * @param {string} params.appId - Application ID.
998
- * @param {any} params.elements - Display elements to draw.
1042
+ * @param {DrawParams['appId']} params.appId - Application ID.
1043
+ * @param {DrawParams['elements']} params.elements - Display elements to draw.
1044
+ * @param {DrawParams['priority']} [params.priority=6] - Priority for the draw request (1-10).
999
1045
  * @param {TimeoutOptions['timeout']} [params.timeout] - Request timeout in milliseconds.
1000
1046
  * @returns {Promise<SuccessResponse>} A promise that resolves on successful draw command.
1001
1047
  */
@@ -1029,8 +1075,7 @@ declare class DisplayMethods {
1029
1075
  * Set display brightness.
1030
1076
  *
1031
1077
  * @param {BrightnessParams} params - Brightness parameters:
1032
- * @param {number|"auto"} [params.front] - Front brightness (0-100 or "auto").
1033
- * @param {number|"auto"} [params.back] - Back brightness (0-100 or "auto").
1078
+ * @param {BrightnessParams['value']} [params.value] - Brightness (0-100 or "auto").
1034
1079
  * @param {TimeoutOptions['timeout']} [params.timeout] - Request timeout in milliseconds.
1035
1080
  * @returns {Promise<SuccessResponse>} A promise that resolves on success.
1036
1081
  */
@@ -1539,7 +1584,7 @@ declare interface operations {
1539
1584
  "application/json": components["schemas"]["SuccessResponse"];
1540
1585
  };
1541
1586
  };
1542
- /** @description Invalid app_id or deletion failed */
1587
+ /** @description Invalid request parameters */
1543
1588
  400: {
1544
1589
  headers: {
1545
1590
  [name: string]: unknown;
@@ -1548,6 +1593,15 @@ declare interface operations {
1548
1593
  "application/json": components["schemas"]["Error"];
1549
1594
  };
1550
1595
  };
1596
+ /** @description Delete failed */
1597
+ 500: {
1598
+ headers: {
1599
+ [name: string]: unknown;
1600
+ };
1601
+ content: {
1602
+ "application/json": components["schemas"]["Error"];
1603
+ };
1604
+ };
1551
1605
  };
1552
1606
  };
1553
1607
  writeStorageFile: {
@@ -1798,6 +1852,15 @@ declare interface operations {
1798
1852
  "application/json": components["schemas"]["Error"];
1799
1853
  };
1800
1854
  };
1855
+ /** @description Requested priority level is below that of currently active app */
1856
+ 409: {
1857
+ headers: {
1858
+ [name: string]: unknown;
1859
+ };
1860
+ content: {
1861
+ "application/json": components["schemas"]["Error"];
1862
+ };
1863
+ };
1801
1864
  /** @description Display error */
1802
1865
  500: {
1803
1866
  headers: {
@@ -1868,15 +1931,10 @@ declare interface operations {
1868
1931
  parameters: {
1869
1932
  query?: {
1870
1933
  /**
1871
- * @description Front display brightness (0-100/auto)
1872
- * @example auto
1873
- */
1874
- front?: string;
1875
- /**
1876
- * @description Back display brightness (0-100/auto)
1934
+ * @description Displays brightness (0-100/auto)
1877
1935
  * @example 50
1878
1936
  */
1879
- back?: string;
1937
+ value?: string;
1880
1938
  };
1881
1939
  header?: never;
1882
1940
  path?: never;
@@ -3870,6 +3928,84 @@ declare interface paths {
3870
3928
  patch?: never;
3871
3929
  trace?: never;
3872
3930
  };
3931
+ "/matter/endpoint/1": {
3932
+ parameters: {
3933
+ query?: never;
3934
+ header?: never;
3935
+ path?: never;
3936
+ cookie?: never;
3937
+ };
3938
+ /** Get Matter endpoint 1 state */
3939
+ get: {
3940
+ parameters: {
3941
+ query?: never;
3942
+ header?: never;
3943
+ path?: never;
3944
+ cookie?: never;
3945
+ };
3946
+ requestBody?: never;
3947
+ responses: {
3948
+ /** @description Successfully got Matter endpoint 1 state */
3949
+ 200: {
3950
+ headers: {
3951
+ [name: string]: unknown;
3952
+ };
3953
+ content: {
3954
+ "application/json": components["schemas"]["MatterEndpointState"];
3955
+ };
3956
+ };
3957
+ /** @description Internal Matter service is broken */
3958
+ 503: {
3959
+ headers: {
3960
+ [name: string]: unknown;
3961
+ };
3962
+ content: {
3963
+ "application/json": components["schemas"]["Error"];
3964
+ };
3965
+ };
3966
+ };
3967
+ };
3968
+ put?: never;
3969
+ /** Set Matter endpoint 1 state */
3970
+ post: {
3971
+ parameters: {
3972
+ query?: never;
3973
+ header?: never;
3974
+ path?: never;
3975
+ cookie?: never;
3976
+ };
3977
+ requestBody: {
3978
+ content: {
3979
+ "application/json": components["schemas"]["MatterEndpointState"];
3980
+ };
3981
+ };
3982
+ responses: {
3983
+ /** @description Successfully set Matter endpoint 1 state */
3984
+ 200: {
3985
+ headers: {
3986
+ [name: string]: unknown;
3987
+ };
3988
+ content: {
3989
+ "application/json": components["schemas"]["SuccessResponse"];
3990
+ };
3991
+ };
3992
+ /** @description Internal Matter service is broken */
3993
+ 503: {
3994
+ headers: {
3995
+ [name: string]: unknown;
3996
+ };
3997
+ content: {
3998
+ "application/json": components["schemas"]["Error"];
3999
+ };
4000
+ };
4001
+ };
4002
+ };
4003
+ delete?: never;
4004
+ options?: never;
4005
+ head?: never;
4006
+ patch?: never;
4007
+ trace?: never;
4008
+ };
3873
4009
  }
3874
4010
 
3875
4011
  declare type RequiredIpConfig = RequireKeys<NonNullable<CamelizedRequest["ipConfig"]>, "ipMethod">;
package/dist/index.js CHANGED
@@ -33,43 +33,43 @@ async function s(n, t = 3e3) {
33
33
  }
34
34
  function O(n, t, e) {
35
35
  let i, r = e ?? void 0, o, a = null;
36
- const d = async () => {
36
+ const u = async () => {
37
37
  i || (a || (a = (async () => {
38
- const u = await t();
39
- if (!u.api_semver)
38
+ const h = await t();
39
+ if (!h.api_semver)
40
40
  throw new Error("Empty API version");
41
- i = u.api_semver;
41
+ i = h.api_semver;
42
42
  })().finally(() => {
43
43
  a = null;
44
44
  })), await a);
45
- }, f = {
46
- async onRequest({ request: u, schemaPath: w }) {
47
- return r && u.headers.set("Authorization", `Bearer ${r}`), w !== "/version" && (await d(), i && u.headers.set("X-API-Sem-Ver", i), o && u.headers.set("X-API-Token", o)), u;
45
+ }, l = {
46
+ async onRequest({ request: h, schemaPath: d }) {
47
+ return r && h.headers.set("Authorization", `Bearer ${r}`), d !== "/version" && (await u(), i && h.headers.set("X-API-Sem-Ver", i), o && h.headers.set("X-API-Token", o)), h;
48
48
  },
49
- async onResponse({ request: u, response: w, options: A, schemaPath: v }) {
49
+ async onResponse({ request: h, response: d, options: b, schemaPath: v }) {
50
+ if (d.ok)
51
+ return d;
52
+ if (v === "/version")
53
+ throw await y(d);
54
+ if (d.status !== 405)
55
+ throw await y(d);
56
+ i = void 0, await u(), i && h.headers.set("X-API-Sem-Ver", i), r && h.headers.set("Authorization", `Bearer ${r}`);
57
+ const w = await (b.fetch ?? fetch)(h);
50
58
  if (w.ok)
51
59
  return w;
52
- if (v === "/version")
53
- throw await y(w);
54
- if (w.status !== 405)
55
- throw await y(w);
56
- i = void 0, await d(), i && u.headers.set("X-API-Sem-Ver", i), r && u.headers.set("Authorization", `Bearer ${r}`);
57
- const l = await (A.fetch ?? fetch)(u);
58
- if (l.ok)
59
- return l;
60
- throw await y(l);
60
+ throw await y(w);
61
61
  }
62
- }, h = m({
62
+ }, f = m({
63
63
  baseUrl: n,
64
64
  bodySerializer: L
65
65
  });
66
- return h.use(f), {
67
- client: h,
68
- setApiKey: (u) => {
69
- o = u;
66
+ return f.use(l), {
67
+ client: f,
68
+ setApiKey: (h) => {
69
+ o = h;
70
70
  },
71
- setToken: (u) => {
72
- r = u;
71
+ setToken: (h) => {
72
+ r = h;
73
73
  }
74
74
  };
75
75
  }
@@ -100,7 +100,7 @@ async function U(n, t) {
100
100
  throw i;
101
101
  return e;
102
102
  }
103
- async function $(n, t) {
103
+ async function I(n, t) {
104
104
  const { data: e, error: i } = await s(
105
105
  (r) => n.GET("/status/power", { signal: r }),
106
106
  t == null ? void 0 : t.timeout
@@ -109,7 +109,7 @@ async function $(n, t) {
109
109
  throw i;
110
110
  return e;
111
111
  }
112
- class I {
112
+ class $ {
113
113
  /**
114
114
  * Get API version information.
115
115
  *
@@ -149,7 +149,7 @@ class I {
149
149
  * @returns {Promise<StatusPower>} Current power status.
150
150
  */
151
151
  async SystemStatusPowerGet(t) {
152
- return await $(this.apiClient, t);
152
+ return await I(this.apiClient, t);
153
153
  }
154
154
  }
155
155
  async function K(n, t) {
@@ -226,7 +226,7 @@ async function N(n, t) {
226
226
  throw i;
227
227
  return e;
228
228
  }
229
- class x {
229
+ class _ {
230
230
  /**
231
231
  * Upload firmware update package.
232
232
  *
@@ -291,7 +291,7 @@ class x {
291
291
  return await N(this.apiClient, t);
292
292
  }
293
293
  }
294
- async function _(n, t) {
294
+ async function x(n, t) {
295
295
  const { data: e, error: i } = await s(
296
296
  (r) => n.GET("/time", { signal: r }),
297
297
  t == null ? void 0 : t.timeout
@@ -355,7 +355,7 @@ class H {
355
355
  * @returns {Promise<TimestampInfo>} A promise that resolves to the timestamp information.
356
356
  */
357
357
  async TimeGet(t) {
358
- return await _(this.apiClient, t);
358
+ return await x(this.apiClient, t);
359
359
  }
360
360
  /**
361
361
  * Set system timestamp.
@@ -418,7 +418,7 @@ async function X(n, t) {
418
418
  throw i;
419
419
  return e;
420
420
  }
421
- async function Q(n, t) {
421
+ async function Y(n, t) {
422
422
  const { data: e, error: i } = await s(
423
423
  (r) => n.GET("/account/profile", { signal: r }),
424
424
  t == null ? void 0 : t.timeout
@@ -427,7 +427,7 @@ async function Q(n, t) {
427
427
  throw i;
428
428
  return e;
429
429
  }
430
- async function Y(n, t) {
430
+ async function Q(n, t) {
431
431
  const { profile: e } = t, { data: i, error: r } = await s(
432
432
  (o) => n.POST("/account/profile", {
433
433
  params: {
@@ -490,7 +490,7 @@ class et {
490
490
  * @returns {Promise<AccountProfile>} A promise that resolves to the account profile.
491
491
  */
492
492
  async AccountProfileGet(t) {
493
- return await Q(this.apiClient, t);
493
+ return await Y(this.apiClient, t);
494
494
  }
495
495
  /**
496
496
  * Set account profile.
@@ -501,7 +501,7 @@ class et {
501
501
  * @returns {Promise<SuccessResponse>} A promise that resolves on success.
502
502
  */
503
503
  async AccountProfileSet(t) {
504
- return await Y(this.apiClient, t);
504
+ return await Q(this.apiClient, t);
505
505
  }
506
506
  /**
507
507
  * Unlink device from account. Removes association with the current account.
@@ -525,19 +525,20 @@ class et {
525
525
  }
526
526
  }
527
527
  async function it(n, t) {
528
- const { appId: e, elements: i } = t, { data: r, error: o } = await s(
529
- (a) => n.POST("/display/draw", {
528
+ const { appId: e, elements: i, priority: r = 6 } = t, { data: o, error: a } = await s(
529
+ (u) => n.POST("/display/draw", {
530
530
  body: {
531
531
  app_id: e,
532
+ priority: r,
532
533
  elements: i
533
534
  },
534
- signal: a
535
+ signal: u
535
536
  }),
536
537
  t.timeout
537
538
  );
538
- if (o)
539
- throw o;
540
- return r;
539
+ if (a)
540
+ throw a;
541
+ return o;
541
542
  }
542
543
  async function nt(n, t) {
543
544
  const { data: e, error: i } = await s(
@@ -575,37 +576,37 @@ async function ot(n, t) {
575
576
  return e;
576
577
  }
577
578
  async function st(n, t) {
578
- const { front: e, back: i } = t, r = (h) => {
579
- if (typeof h == "number") {
580
- if (h < 0 || h > 100)
579
+ const { value: e } = t, r = ((u) => {
580
+ if (typeof u == "number") {
581
+ if (u < 0 || u > 100)
581
582
  throw new Error("Brightness value must be between 0 and 100 or 'auto'");
582
- return String(h);
583
+ return String(u);
583
584
  }
584
- if (h === "auto")
585
+ if (u === "auto")
585
586
  return "auto";
586
- }, o = r(e), a = r(i), { data: d, error: f } = await s(
587
- (h) => n.POST("/display/brightness", {
587
+ })(e), { data: o, error: a } = await s(
588
+ (u) => n.POST("/display/brightness", {
588
589
  params: {
589
590
  query: {
590
- front: o,
591
- back: a
591
+ value: r
592
592
  }
593
593
  },
594
- signal: h
594
+ signal: u
595
595
  }),
596
596
  t.timeout
597
597
  );
598
- if (f)
599
- throw f;
600
- return d;
598
+ if (a)
599
+ throw a;
600
+ return o;
601
601
  }
602
602
  class at {
603
603
  /**
604
604
  * Draw on display. Starts the Canvas application if not running.
605
605
  *
606
606
  * @param {DrawParams} params - Parameters for the draw operation.
607
- * @param {string} params.appId - Application ID.
608
- * @param {any} params.elements - Display elements to draw.
607
+ * @param {DrawParams['appId']} params.appId - Application ID.
608
+ * @param {DrawParams['elements']} params.elements - Display elements to draw.
609
+ * @param {DrawParams['priority']} [params.priority=6] - Priority for the draw request (1-10).
609
610
  * @param {TimeoutOptions['timeout']} [params.timeout] - Request timeout in milliseconds.
610
611
  * @returns {Promise<SuccessResponse>} A promise that resolves on successful draw command.
611
612
  */
@@ -647,8 +648,7 @@ class at {
647
648
  * Set display brightness.
648
649
  *
649
650
  * @param {BrightnessParams} params - Brightness parameters:
650
- * @param {number|"auto"} [params.front] - Front brightness (0-100 or "auto").
651
- * @param {number|"auto"} [params.back] - Back brightness (0-100 or "auto").
651
+ * @param {BrightnessParams['value']} [params.value] - Brightness (0-100 or "auto").
652
652
  * @param {TimeoutOptions['timeout']} [params.timeout] - Request timeout in milliseconds.
653
653
  * @returns {Promise<SuccessResponse>} A promise that resolves on success.
654
654
  */
@@ -755,7 +755,7 @@ class ft {
755
755
  return await dt(this.apiClient, t);
756
756
  }
757
757
  }
758
- async function wt(n, t) {
758
+ async function lt(n, t) {
759
759
  const { data: e, error: i } = await s(
760
760
  (r) => n.GET("/wifi/status", { signal: r }),
761
761
  t == null ? void 0 : t.timeout
@@ -764,7 +764,7 @@ async function wt(n, t) {
764
764
  throw i;
765
765
  return e;
766
766
  }
767
- async function lt(n, t) {
767
+ async function wt(n, t) {
768
768
  const { data: e, error: i } = await s(
769
769
  (r) => n.POST("/wifi/connect", {
770
770
  body: {
@@ -813,7 +813,7 @@ class St {
813
813
  * @returns {Promise<WifiStatusResponse>} A promise that resolves to the Wi-Fi status.
814
814
  */
815
815
  async WifiStatusGet(t) {
816
- return await wt(this.apiClient, t);
816
+ return await lt(this.apiClient, t);
817
817
  }
818
818
  /**
819
819
  * Connects to Wi-Fi network.
@@ -827,7 +827,7 @@ class St {
827
827
  * @returns {Promise<SuccessResponse>} A promise that resolves on successful connection initiation.
828
828
  */
829
829
  async WifiConnect(t) {
830
- return await lt(this.apiClient, t);
830
+ return await wt(this.apiClient, t);
831
831
  }
832
832
  /**
833
833
  * Disconnects from Wi-Fi.
@@ -903,7 +903,7 @@ async function mt(n, t) {
903
903
  throw r;
904
904
  return i;
905
905
  }
906
- async function kt(n, t) {
906
+ async function Ct(n, t) {
907
907
  const { path: e } = t, { data: i, error: r } = await s(
908
908
  (o) => n.DELETE("/storage/remove", {
909
909
  params: {
@@ -919,7 +919,7 @@ async function kt(n, t) {
919
919
  throw r;
920
920
  return i;
921
921
  }
922
- async function Ct(n, t) {
922
+ async function kt(n, t) {
923
923
  const { path: e } = t, { data: i, error: r } = await s(
924
924
  (o) => n.POST("/storage/mkdir", {
925
925
  params: {
@@ -944,7 +944,7 @@ async function gt(n, t) {
944
944
  throw i;
945
945
  return e;
946
946
  }
947
- class bt {
947
+ class At {
948
948
  /**
949
949
  * Upload file to internal storage. Uploads a file to a specified path.
950
950
  *
@@ -989,7 +989,7 @@ class bt {
989
989
  * @returns {Promise<SuccessResponse>} A promise that resolves on successful removal.
990
990
  */
991
991
  async StorageRemove(t) {
992
- return await kt(this.apiClient, t);
992
+ return await Ct(this.apiClient, t);
993
993
  }
994
994
  /**
995
995
  * Create a directory on internal storage. Creates a new directory with a specified path.
@@ -1000,7 +1000,7 @@ class bt {
1000
1000
  * @returns {Promise<SuccessResponse>} A promise that resolves on successful creation.
1001
1001
  */
1002
1002
  async StorageMkdir(t) {
1003
- return await Ct(this.apiClient, t);
1003
+ return await kt(this.apiClient, t);
1004
1004
  }
1005
1005
  /**
1006
1006
  * Show storage usage.
@@ -1013,7 +1013,7 @@ class bt {
1013
1013
  return await gt(this.apiClient, t);
1014
1014
  }
1015
1015
  }
1016
- async function At(n, t) {
1016
+ async function bt(n, t) {
1017
1017
  const { data: e, error: i } = await s(
1018
1018
  (r) => n.GET("/access", { signal: r }),
1019
1019
  t == null ? void 0 : t.timeout
@@ -1072,7 +1072,7 @@ class Lt {
1072
1072
  * @returns {Promise<HttpAccessInfo>} A promise that resolves to the access configuration.
1073
1073
  */
1074
1074
  async SettingsAccessGet(t) {
1075
- return await At(this.apiClient, t);
1075
+ return await bt(this.apiClient, t);
1076
1076
  }
1077
1077
  /**
1078
1078
  * Set HTTP API access over Wi-Fi configuration.
@@ -1145,7 +1145,7 @@ async function Ut(n, t) {
1145
1145
  throw i;
1146
1146
  return e;
1147
1147
  }
1148
- class $t {
1148
+ class It {
1149
1149
  /**
1150
1150
  * Enable BLE. Starts advertising.
1151
1151
  *
@@ -1187,7 +1187,7 @@ class $t {
1187
1187
  return await Ut(this.apiClient, t);
1188
1188
  }
1189
1189
  }
1190
- async function It(n, t) {
1190
+ async function $t(n, t) {
1191
1191
  const { keyName: e } = t, { data: i, error: r } = await s(
1192
1192
  (o) => n.POST("/input", {
1193
1193
  params: {
@@ -1213,7 +1213,7 @@ class Kt {
1213
1213
  * @returns {Promise<SuccessResponse>} A promise that resolves on success.
1214
1214
  */
1215
1215
  async InputSend(t) {
1216
- return await It(this.apiClient, t);
1216
+ return await $t(this.apiClient, t);
1217
1217
  }
1218
1218
  }
1219
1219
  async function Rt(n, t) {
@@ -1275,7 +1275,70 @@ class Mt {
1275
1275
  return await Wt(this.apiClient, t);
1276
1276
  }
1277
1277
  }
1278
- const S = "http://10.0.4.20", Nt = "https://proxy.busy.app", xt = /^https?:\/\/proxy(?:\.(?:dev|test|stage))?\.busy\.app$/i;
1278
+ async function Nt(n, t) {
1279
+ const { appId: e, fileName: i, file: r } = t, { data: o, error: a } = await s(
1280
+ (u) => n.POST("/assets/upload", {
1281
+ params: {
1282
+ query: {
1283
+ app_id: e,
1284
+ file: i
1285
+ }
1286
+ },
1287
+ headers: {
1288
+ "Content-Type": "application/octet-stream"
1289
+ },
1290
+ body: r,
1291
+ signal: u
1292
+ }),
1293
+ t.timeout
1294
+ );
1295
+ if (a)
1296
+ throw a;
1297
+ return o;
1298
+ }
1299
+ async function _t(n, t) {
1300
+ const { appId: e } = t, { data: i, error: r } = await s(
1301
+ (o) => n.DELETE("/assets/upload", {
1302
+ params: {
1303
+ query: {
1304
+ app_id: e
1305
+ }
1306
+ },
1307
+ signal: o
1308
+ }),
1309
+ t.timeout
1310
+ );
1311
+ if (r)
1312
+ throw r;
1313
+ return i;
1314
+ }
1315
+ class xt {
1316
+ /**
1317
+ * Upload asset file with app ID. Uploads a file to a specific app's assets directory.
1318
+ *
1319
+ * @param {UploadParams} params - Parameters for the upload.
1320
+ * @param {UploadParams['appId']} params.appId - Application ID for organizing assets.
1321
+ * @param {UploadParams['fileName']} params.fileName - Filename for the uploaded asset.
1322
+ * @param {UploadParams['file']} params.file - File data to upload.
1323
+ * @param {UploadParams['timeout']} [params.timeout] - Request timeout in milliseconds.
1324
+ * @returns {Promise<SuccessResponse>} Result of the upload operation.
1325
+ */
1326
+ async AssetsUpload(t) {
1327
+ return await Nt(this.apiClient, t);
1328
+ }
1329
+ /**
1330
+ * Delete app assets. Deletes all assets for a specific app ID.
1331
+ *
1332
+ * @param {DeleteParams} params - Parameters for the delete.
1333
+ * @param {DeleteParams['appId']} params.appId - Application ID whose assets should be deleted.
1334
+ * @param {DeleteParams['timeout']} [params.timeout] - Request timeout in milliseconds.
1335
+ * @returns {Promise<SuccessResponse>} Result of the delete operation.
1336
+ */
1337
+ async AssetsDelete(t) {
1338
+ return await _t(this.apiClient, t);
1339
+ }
1340
+ }
1341
+ const S = "http://10.0.4.20", qt = "https://proxy.busy.app", Vt = /^https?:\/\/proxy(?:\.(?:dev|test|stage))?\.busy\.app$/i;
1279
1342
  function T(n) {
1280
1343
  const t = n.split(".");
1281
1344
  if (t.length !== 4)
@@ -1292,7 +1355,7 @@ function T(n) {
1292
1355
  function E(n) {
1293
1356
  return /\.local$/i.test(n);
1294
1357
  }
1295
- class _t {
1358
+ class jt {
1296
1359
  /**
1297
1360
  * Creates an instance of BUSY Bar.
1298
1361
  * Initializes the API client with the provided host address.
@@ -1343,10 +1406,10 @@ class _t {
1343
1406
  if (!t || !t.addr && !t.token)
1344
1407
  this.addr = S;
1345
1408
  else if (!t.addr)
1346
- this.addr = Nt;
1409
+ this.addr = qt;
1347
1410
  else {
1348
1411
  let o = t.addr.trim();
1349
- if (/^https?:\/\//i.test(o) || (o = `http://${o}`), xt.test(o) && !t.token)
1412
+ if (/^https?:\/\//i.test(o) || (o = `http://${o}`), Vt.test(o) && !t.token)
1350
1413
  throw new Error("Token is required. Please provide it.");
1351
1414
  this.addr = o;
1352
1415
  }
@@ -1400,7 +1463,7 @@ class _t {
1400
1463
  this.setTokenFn(t);
1401
1464
  }
1402
1465
  }
1403
- function qt(n, t) {
1466
+ function zt(n, t) {
1404
1467
  t.forEach((e) => {
1405
1468
  Object.getOwnPropertyNames(e.prototype).forEach((i) => {
1406
1469
  Object.defineProperty(
@@ -1411,22 +1474,23 @@ function qt(n, t) {
1411
1474
  });
1412
1475
  });
1413
1476
  }
1414
- qt(_t, [
1415
- I,
1416
- x,
1477
+ zt(jt, [
1478
+ $,
1479
+ _,
1417
1480
  H,
1418
1481
  et,
1419
1482
  at,
1420
1483
  ft,
1421
1484
  St,
1422
- bt,
1485
+ At,
1423
1486
  Lt,
1424
- $t,
1487
+ It,
1425
1488
  Kt,
1426
- Mt
1489
+ Mt,
1490
+ xt
1427
1491
  ]);
1428
1492
  var p = /* @__PURE__ */ ((n) => (n[n.FRONT = 0] = "FRONT", n[n.BACK = 1] = "BACK", n))(p || {});
1429
- const k = 3e3, C = /* @__PURE__ */ new Set([1001, 1006, 1012, 1013, 1014, 3008]);
1493
+ const C = 3e3, k = /* @__PURE__ */ new Set([1001, 1006, 1012, 1013, 1014, 3008]);
1430
1494
  function g(n, t) {
1431
1495
  if (t < 0 || t >= n.length)
1432
1496
  throw new Error(`Index ${t} is out of bounds (0…${n.length - 1})`);
@@ -1435,27 +1499,27 @@ function g(n, t) {
1435
1499
  throw new Error(`Unexpected undefined at index ${t}`);
1436
1500
  return e;
1437
1501
  }
1438
- function Vt(n, t) {
1502
+ function Ht(n, t) {
1439
1503
  let e = 0;
1440
1504
  const i = n.length, r = [];
1441
1505
  for (; e < i; ) {
1442
1506
  const o = g(n, e);
1443
1507
  if (e += 1, (o & 128) !== 0) {
1444
1508
  const a = o & 127;
1445
- for (let d = 0; d < a * t; d++)
1446
- r.push(n[e + d]);
1509
+ for (let u = 0; u < a * t; u++)
1510
+ r.push(n[e + u]);
1447
1511
  e += a * t;
1448
1512
  } else {
1449
- const a = o, d = n.slice(e, e + t);
1450
- for (let f = 0; f < a; f++)
1451
- for (let h = 0; h < t; h++)
1452
- r.push(d[h]);
1513
+ const a = o, u = n.slice(e, e + t);
1514
+ for (let l = 0; l < a; l++)
1515
+ for (let f = 0; f < t; f++)
1516
+ r.push(u[f]);
1453
1517
  e += t;
1454
1518
  }
1455
1519
  }
1456
1520
  return new Uint8Array(r);
1457
1521
  }
1458
- function jt(n) {
1522
+ function Jt(n) {
1459
1523
  const t = new Uint8Array(n.length * 2);
1460
1524
  let e = 0, i = 0;
1461
1525
  for (; e < n.length; ) {
@@ -1464,8 +1528,8 @@ function jt(n) {
1464
1528
  }
1465
1529
  return t;
1466
1530
  }
1467
- const b = () => typeof window < "u" && typeof window.document < "u";
1468
- class Jt {
1531
+ const A = () => typeof window < "u" && typeof window.document < "u";
1532
+ class Qt {
1469
1533
  constructor(t) {
1470
1534
  c(this, "addr");
1471
1535
  c(this, "connected", !1);
@@ -1477,7 +1541,7 @@ class Jt {
1477
1541
  c(this, "stopListeners", []);
1478
1542
  c(this, "errorListeners", []);
1479
1543
  c(this, "socket", null);
1480
- if (this.config = t, !b())
1544
+ if (this.config = t, !A())
1481
1545
  throw new Error("not browser");
1482
1546
  if (t.apiKey && (this.apiKey = t.apiKey), t.apiSemver && (this.apiSemver = t.apiSemver), !t || !t.addr)
1483
1547
  this.addr = S;
@@ -1532,8 +1596,8 @@ class Jt {
1532
1596
  let r;
1533
1597
  const o = this.config.deviceScreen === p.FRONT ? 3 : 2;
1534
1598
  try {
1535
- const a = Vt(i, o);
1536
- this.config.deviceScreen === p.BACK ? r = jt(a) : r = a, this.emitData(r);
1599
+ const a = Ht(i, o);
1600
+ this.config.deviceScreen === p.BACK ? r = Jt(a) : r = a, this.emitData(r);
1537
1601
  } catch {
1538
1602
  this.emitData(i);
1539
1603
  }
@@ -1548,7 +1612,7 @@ class Jt {
1548
1612
  raw: e
1549
1613
  }), this.emitStop();
1550
1614
  }, this.socket.onclose = async (e) => {
1551
- if (this.socket = null, this.connected = !1, e.code === k || C.has(e.code)) {
1615
+ if (this.socket = null, this.connected = !1, e.code === C || k.has(e.code)) {
1552
1616
  this.emitError({
1553
1617
  code: e.code,
1554
1618
  message: e.reason,
@@ -1567,7 +1631,7 @@ class Jt {
1567
1631
  });
1568
1632
  }
1569
1633
  }
1570
- class Xt {
1634
+ class Zt {
1571
1635
  constructor(t) {
1572
1636
  c(this, "addr");
1573
1637
  c(this, "connected", !1);
@@ -1580,7 +1644,7 @@ class Xt {
1580
1644
  c(this, "stopListeners", []);
1581
1645
  c(this, "errorListeners", []);
1582
1646
  c(this, "socket", null);
1583
- if (!b())
1647
+ if (!A())
1584
1648
  throw new Error("not browser");
1585
1649
  if (t != null && t.apiKey && (this.apiKey = t.apiKey), t != null && t.apiSemver && (this.apiSemver = t.apiSemver), !t || !t.addr)
1586
1650
  this.addr = S;
@@ -1645,7 +1709,7 @@ class Xt {
1645
1709
  raw: e
1646
1710
  }), this.emitStop();
1647
1711
  }, this.socket.onclose = async (e) => {
1648
- if (this.socket = null, this.connected = !1, e.code === k || C.has(e.code)) {
1712
+ if (this.socket = null, this.connected = !1, e.code === C || k.has(e.code)) {
1649
1713
  this.emitError({
1650
1714
  code: e.code,
1651
1715
  message: e.reason,
@@ -1670,8 +1734,8 @@ class Xt {
1670
1734
  }
1671
1735
  }
1672
1736
  export {
1673
- _t as BusyBar,
1737
+ jt as BusyBar,
1674
1738
  p as DeviceScreen,
1675
- Xt as Input,
1676
- Jt as ScreenStream
1739
+ Zt as Input,
1740
+ Qt as ScreenStream
1677
1741
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@busy-app/busy-lib",
3
3
  "private": false,
4
4
  "description": "A library for interacting with the BUSY Bar API",
5
- "version": "0.9.0",
5
+ "version": "0.10.0",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },