@busy-app/busy-lib 0.4.0 → 0.5.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 k=Object.defineProperty;var P=(e,t,i)=>t in e?k(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i;var o=(e,t,i)=>P(e,typeof t!="symbol"?t+"":t,i);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("openapi-fetch"),b=(e,t)=>{if(typeof FormData<"u"&&e instanceof FormData||typeof Buffer<"u"&&typeof Buffer.isBuffer=="function"&&Buffer.isBuffer(e)||typeof File<"u"&&e instanceof File||typeof Blob<"u"&&e instanceof Blob||typeof ArrayBuffer<"u"&&e instanceof ArrayBuffer||typeof ArrayBuffer<"u"&&ArrayBuffer.isView&&ArrayBuffer.isView(e))return e;let i;return t&&(t instanceof Headers?i=t.get("Content-Type")??t.get("content-type")??void 0:typeof t=="object"&&(i=t["Content-Type"]??t["content-type"]),i==="application/x-www-form-urlencoded")?e&&typeof e=="object"&&!(e instanceof URLSearchParams)?new URLSearchParams(e).toString():String(e):JSON.stringify(e)};let y,w,h=null;async function E(){if(!w){if(!y)throw new Error("getApiVersionFn is not set");h||(h=(async()=>{const e=await y();if(!e.api_semver)throw new Error("Empty API version");w=e.api_semver})().finally(()=>{h=null})),await h}}async function p(e){const n=(e.headers.get("content-type")||"").includes("application/json")?await e.clone().json():await e.clone().text(),s=typeof n=="object"&&n!==null?n.error||n.message:typeof n=="string"?n:void 0;return Object.assign(new Error(s||`HTTP ${e.status} ${e.statusText}`),{status:e.status,statusText:e.statusText,body:n})}let m;function I(e){m=e}const v={async onRequest({request:e,schemaPath:t}){if(t!=="/version"){if(await E(),w)return e.headers.set("X-API-Sem-Ver",w);m&&e.headers.set("X-API-Token",m)}return e},async onResponse({request:e,response:t,options:i,schemaPath:n}){if(t.ok)return t;if(n==="/version")throw await p(t);if(t.status!==405)throw await p(t);w=void 0,await E(),w&&e.headers.set("X-API-Sem-Ver",w);const s=await(i.fetch??fetch)(e);if(s.ok)return s;throw await p(s)}};let r=null;function B(e,t){y=t,r=T({baseUrl:e,bodySerializer:b}),r.use(v)}async function L(e){const{appId:t,fileName:i,file:n}=e;if(!r)throw new Error("API client is not initialized");const{data:s,error:a}=await r.POST("/assets/upload",{params:{query:{app_id:t,file:i}},headers:{"Content-Type":"application/octet-stream"},body:n});if(a)throw a;return s}async function z(e){const{appId:t}=e;if(!r)throw new Error("API client is not initialized");const{data:i,error:n}=await r.DELETE("/assets/upload",{params:{query:{app_id:t}}});if(n)throw n;return i}const D={timeout:5,x:0,y:0,display:"front"};function O(e){return{...D,...e}}async function K(e){const{appId:t,elements:i}=e;if(!r)throw new Error("API client is not initialized");const n=i.map(O),{data:s,error:a}=await r.POST("/display/draw",{body:{app_id:t,elements:n}});if(a)throw a;return s}async function U(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.DELETE("/display/draw");if(t)throw t;return e}async function C(e){const{appId:t,path:i}=e;if(!r)throw new Error("API client is not initialized");const{data:n,error:s}=await r.POST("/audio/play",{params:{query:{app_id:t,path:i}}});if(s)throw s;return n}async function W(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.DELETE("/audio/play");if(t)throw t;return e}async function $(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/wifi/enable");if(t)throw t;return e}async function F(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/wifi/disable");if(t)throw t;return e}async function R(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/wifi/status");if(t)throw t;return e}async function V(e){if(!r)throw new Error("API client is not initialized");const{data:t,error:i}=await r.POST("/wifi/connect",{body:{ssid:e.ssid,password:e.password,security:e.security,ip_config:{ip_method:e.ipConfig.ipMethod,ip_type:e.ipConfig.ipType,address:e.ipConfig.address,mask:e.ipConfig.mask,gateway:e.ipConfig.gateway}}});if(i)throw i;return t}async function _(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/wifi/disconnect");if(t)throw t;return e}async function q(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/wifi/networks");if(t)throw t;return e}async function x(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/wifi/forget");if(t)throw t;return e}async function G(e){if(!r)throw new Error("API client is not initialized");const{path:t,file:i}=e,{data:n,error:s}=await r.POST("/storage/write",{params:{query:{path:t}},headers:{"Content-Type":"application/octet-stream"},body:i});if(s)throw s;return n}async function N(e){if(!r)throw new Error("API client is not initialized");const{path:t,asArrayBuffer:i}=e,{data:n,error:s}=await r.GET("/storage/read",{params:{query:{path:t}},parseAs:i?"arrayBuffer":"blob"});if(s)throw s;return n}async function j(e){if(!r)throw new Error("API client is not initialized");const{path:t}=e,{data:i,error:n}=await r.GET("/storage/list",{params:{query:{path:t}}});if(n)throw n;return i}async function H(e){if(!r)throw new Error("API client is not initialized");const{path:t}=e,{data:i,error:n}=await r.DELETE("/storage/remove",{params:{query:{path:t}}});if(n)throw n;return i}async function J(e){if(!r)throw new Error("API client is not initialized");const{path:t}=e,{data:i,error:n}=await r.POST("/storage/mkdir",{params:{query:{path:t}}});if(n)throw n;return i}async function X(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/version");if(t)throw t;return e}async function M(e){if(!r)throw new Error("API client is not initialized");const{name:t,file:i}=e,{data:n,error:s}=await r.POST("/update",{params:{query:{name:t}},headers:{"Content-Type":"application/octet-stream"},body:i});if(s)throw s;return n}async function Q(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/status");if(t)throw t;return e}async function Y(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/status/system");if(t)throw t;return e}async function Z(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/status/power");if(t)throw t;return e}async function tt(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/display/brightness");if(t)throw t;return e}async function et(e){if(!r)throw new Error("API client is not initialized");const{front:t,back:i}=e,n=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"},s=n(t),a=n(i),{data:c,error:f}=await r.POST("/display/brightness",{params:{query:{front:s,back:a}}});if(f)throw f;return c}async function it(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/audio/volume");if(t)throw t;return e}async function rt(e){if(!r)throw new Error("API client is not initialized");const{volume:t}=e;if(typeof t!="number"||t<0||t>100)throw new Error("Volume must be a number between 0 and 100");const{data:i,error:n}=await r.POST("/audio/volume",{params:{query:{volume:t}}});if(n)throw n;return i}async function nt(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/access");if(t)throw t;return e}async function st(e){if(!r)throw new Error("API client is not initialized");const{mode:t,key:i}=e;if(!/^\d{4,10}$/.test(String(i)))throw new Error("Key must be a string of 4 to 10 digits");const{data:n,error:s}=await r.POST("/access",{params:{query:{mode:t,key:i}}});if(s)throw s;return n}async function ot(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/ble/enable");if(t)throw t;return e}async function at(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/ble/disable");if(t)throw t;return e}async function ct(e){if(!r)throw new Error("API client is not initialized");const{keyName:t}=e,{data:i,error:n}=await r.POST("/input",{params:{query:{key:t}}});if(n)throw n;return i}class ft{constructor(t){o(this,"host");o(this,"apiSemver");this.host=t.host,this.apiSemver="",B(`http://${this.host}/api/`,this.getApiVersion.bind(this))}async getApiVersion(){const t=await X();return this.apiSemver=t.api_semver,t}async updateFirmware(t){return await M(t)}async deviceStatus(){return await Q()}async systemStatus(){return await Y()}async powerStatus(){return await Z()}async uploadAsset(t){return await L(t)}async deleteAssets(t){return await z(t)}async drawDisplay(t){return await K(t)}async clearDisplay(){return await U()}async playSound(t){return await C(t)}async stopSound(){return await W()}async enableWifi(){return await $()}async disableWifi(){return await F()}async statusWifi(){return await R()}async connectWifi(t){return await V(t)}async disconnectWifi(){return await _()}async networksWifi(){return await q()}async forgetWifi(){return await x()}async uploadFile(t){return await G(t)}async downloadFile(t){return await N(t)}async readDirectory(t){return await j(t)}async removeResource(t){return await H(t)}async createDirectory(t){return await J(t)}async getDisplayBrightness(){return await tt()}async setDisplayBrightness(t){return await et(t)}async getAudioVolume(){return await it()}async setAudioVolume(t){return await rt(t)}async getHttpAccess(){return await nt()}async setHttpAccess(t){const i=await st(t);return t.mode==="key"&&t.key&&this.setApiKey(t.key),i}setApiKey(t){I(t)}async enableBle(){return await ot()}async disableBle(){return await at()}async pressButton(t){return await ct(t)}}var l=(e=>(e[e.FRONT=0]="FRONT",e[e.BACK=1]="BACK",e))(l||{});const g=3e3,S=new Set([1001,1006,1012,1013,1014,3008]);function A(e,t){if(t<0||t>=e.length)throw new Error(`Index ${t} is out of bounds (0…${e.length-1})`);const i=e[t];if(i===void 0)throw new Error(`Unexpected undefined at index ${t}`);return i}function ut(e,t){let i=0;const n=e.length,s=[];for(;i<n;){const a=A(e,i);if(i+=1,(a&128)!==0){const c=a&127;for(let f=0;f<c*t;f++)s.push(e[i+f]);i+=c*t}else{const c=a,f=e.slice(i,i+t);for(let u=0;u<c;u++)for(let d=0;d<t;d++)s.push(f[d]);i+=t}}return new Uint8Array(s)}function wt(e){const t=new Uint8Array(e.length*2);let i=0,n=0;for(;i<e.length;){const s=A(e,i),a=s&15,c=s>>4&15;t[n]=a,t[n+1]=c,i+=1,n+=2}return t}class ht{constructor(t){o(this,"connected",!1);o(this,"apiKey");o(this,"apiSemver");o(this,"dataListeners",[]);o(this,"stopListeners",[]);o(this,"errorListeners",[]);o(this,"socket",null);if(this.config=t,!(()=>typeof window<"u"&&typeof window.document<"u"))throw new Error("not browser");t.apiKey&&(this.apiKey=t.apiKey),t.apiSemver&&(this.apiSemver=t.apiSemver)}onData(t){this.dataListeners.push(t)}onStop(t){this.stopListeners.push(t)}onError(t){this.errorListeners.push(t)}emitData(t){for(const i of this.dataListeners)i(t)}emitStop(){for(const t of this.stopListeners)t()}emitError(t){for(const i of this.errorListeners)i(t)}async openWebsocket(){this.socket&&await this.closeWebsocket();let t;if(this.config.mode==="cloud"?t=new URL(`${this.config.domain}/bars/${this.config.idDevice}/ws`):this.config.mode==="local"&&(t=new URL(`${this.config.barUrl}/api/screen/ws`),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.config.mode==="cloud"?this.socket.send(JSON.stringify({token:this.config.token,display:this.config.deviceScreen})):this.config.mode==="local"&&this.socket.send(JSON.stringify({display:this.config.deviceScreen})),this.connected=!0)},this.socket.binaryType="arraybuffer",this.socket.onmessage=i=>{try{if(typeof i.data=="string")return;const n=new Uint8Array(i.data);if(this.config.mode==="cloud")this.emitData(n);else if(this.config.mode==="local"){let s;const a=this.config.deviceScreen===l.FRONT?3:2;try{const c=ut(n,a);this.config.deviceScreen===l.BACK?s=wt(c):s=c,this.emitData(s)}catch{this.emitData(n)}}}catch{this.connected=!1,this.emitStop()}},this.socket.onerror=i=>{this.connected=!1,this.emitError({code:1006,message:"WebSocket error occurred",raw:i}),this.emitStop()},this.socket.onclose=async i=>{if(this.socket=null,this.connected=!1,i.code===g||S.has(i.code)){this.emitError({code:i.code,message:i.reason,raw:i});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 lt{constructor(t){o(this,"connected",!1);o(this,"apiKey");o(this,"apiSemver");o(this,"inputEvent");o(this,"dataListeners",[]);o(this,"stopListeners",[]);o(this,"errorListeners",[]);o(this,"socket",null);if(this.config=t,!(()=>typeof window<"u"&&typeof window.document<"u"))throw new Error("not browser");t.apiKey&&(this.apiKey=t.apiKey),t.apiSemver&&(this.apiSemver=t.apiSemver),this.inputEvent={}}onData(t){this.dataListeners.push(t)}onStop(t){this.stopListeners.push(t)}onError(t){this.errorListeners.push(t)}emitData(t){for(const i of this.dataListeners)i(t)}emitStop(){for(const t of this.stopListeners)t()}emitError(t){for(const i of this.errorListeners)i(t)}async openWebsocket(){this.socket&&await this.closeWebsocket();let t;if(this.config.mode==="cloud"?t=new URL(`${this.config.domain}/bars/${this.config.idDevice}/ws`):this.config.mode==="local"&&(t=new URL(`${this.config.barUrl}/api/input`),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=i=>{try{if(typeof i.data=="string")return;const n=new Uint8Array(i.data);this.emitData(n)}catch{this.connected=!1,this.emitStop()}},this.socket.onerror=i=>{this.connected=!1,this.emitError({code:1006,message:"WebSocket error occurred",raw:i}),this.emitStop()},this.socket.onclose=async i=>{if(this.socket=null,this.connected=!1,i.code===g||S.has(i.code)){this.emitError({code:i.code,message:i.reason,raw:i});return}this.emitStop()}}sendInput({keyName:t,value:i}){if(!this.socket||!this.connected)throw new Error("WebSocket: Not connected");this.inputEvent[t]=i,this.socket.send(JSON.stringify(this.inputEvent)),i===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=ft;exports.DeviceScreen=l;exports.Input=lt;exports.ScreenStream=ht;
1
+ "use strict";var P=Object.defineProperty;var T=(e,t,i)=>t in e?P(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i;var o=(e,t,i)=>T(e,typeof t!="symbol"?t+"":t,i);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("openapi-fetch"),v=(e,t)=>{if(typeof FormData<"u"&&e instanceof FormData||typeof Buffer<"u"&&typeof Buffer.isBuffer=="function"&&Buffer.isBuffer(e)||typeof File<"u"&&e instanceof File||typeof Blob<"u"&&e instanceof Blob||typeof ArrayBuffer<"u"&&e instanceof ArrayBuffer||typeof ArrayBuffer<"u"&&ArrayBuffer.isView&&ArrayBuffer.isView(e))return e;let i;return t&&(t instanceof Headers?i=t.get("Content-Type")??t.get("content-type")??void 0:typeof t=="object"&&(i=t["Content-Type"]??t["content-type"]),i==="application/x-www-form-urlencoded")?e&&typeof e=="object"&&!(e instanceof URLSearchParams)?new URLSearchParams(e).toString():String(e):JSON.stringify(e)};let m,w,h=null;async function S(){if(!w){if(!m)throw new Error("getApiVersionFn is not set");h||(h=(async()=>{const e=await m();if(!e.api_semver)throw new Error("Empty API version");w=e.api_semver})().finally(()=>{h=null})),await h}}async function y(e){const n=(e.headers.get("content-type")||"").includes("application/json")?await e.clone().json():await e.clone().text(),s=typeof n=="object"&&n!==null?n.error||n.message:typeof n=="string"?n:void 0;return Object.assign(new Error(s||`HTTP ${e.status} ${e.statusText}`),{status:e.status,statusText:e.statusText,body:n})}let E;function I(e){E=e}let d;const B={async onRequest({request:e,schemaPath:t}){return d&&e.headers.set("Authorization",`Bearer ${d}`),t!=="/version"&&(await S(),w&&e.headers.set("X-API-Sem-Ver",w),E&&e.headers.set("X-API-Token",E)),e},async onResponse({request:e,response:t,options:i,schemaPath:n}){if(t.ok)return t;if(n==="/version")throw await y(t);if(t.status!==405)throw await y(t);w=void 0,await S(),w&&e.headers.set("X-API-Sem-Ver",w),d&&e.headers.set("Authorization",`Bearer ${d}`);const s=await(i.fetch??fetch)(e);if(s.ok)return s;throw await y(s)}};let r=null;function L(e,t,i){m=t,d=i??void 0,r=b({baseUrl:e,bodySerializer:v}),r.use(B)}async function z(e){const{appId:t,fileName:i,file:n}=e;if(!r)throw new Error("API client is not initialized");const{data:s,error:a}=await r.POST("/assets/upload",{params:{query:{app_id:t,file:i}},headers:{"Content-Type":"application/octet-stream"},body:n});if(a)throw a;return s}async function D(e){const{appId:t}=e;if(!r)throw new Error("API client is not initialized");const{data:i,error:n}=await r.DELETE("/assets/upload",{params:{query:{app_id:t}}});if(n)throw n;return i}const O={timeout:5,x:0,y:0,display:"front"};function U(e){return{...O,...e}}async function C(e){const{appId:t,elements:i}=e;if(!r)throw new Error("API client is not initialized");const n=i.map(U),{data:s,error:a}=await r.POST("/display/draw",{body:{app_id:t,elements:n}});if(a)throw a;return s}async function K(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.DELETE("/display/draw");if(t)throw t;return e}async function R(e){const{appId:t,path:i}=e;if(!r)throw new Error("API client is not initialized");const{data:n,error:s}=await r.POST("/audio/play",{params:{query:{app_id:t,path:i}}});if(s)throw s;return n}async function W(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.DELETE("/audio/play");if(t)throw t;return e}async function $(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/wifi/enable");if(t)throw t;return e}async function _(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/wifi/disable");if(t)throw t;return e}async function F(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/wifi/status");if(t)throw t;return e}async function V(e){if(!r)throw new Error("API client is not initialized");const{data:t,error:i}=await r.POST("/wifi/connect",{body:{ssid:e.ssid,password:e.password,security:e.security,ip_config:{ip_method:e.ipConfig.ipMethod,ip_type:e.ipConfig.ipType,address:e.ipConfig.address,mask:e.ipConfig.mask,gateway:e.ipConfig.gateway}}});if(i)throw i;return t}async function x(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/wifi/disconnect");if(t)throw t;return e}async function q(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/wifi/networks");if(t)throw t;return e}async function G(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/wifi/forget");if(t)throw t;return e}async function N(e){if(!r)throw new Error("API client is not initialized");const{path:t,file:i}=e,{data:n,error:s}=await r.POST("/storage/write",{params:{query:{path:t}},headers:{"Content-Type":"application/octet-stream"},body:i});if(s)throw s;return n}async function j(e){if(!r)throw new Error("API client is not initialized");const{path:t,asArrayBuffer:i}=e,{data:n,error:s}=await r.GET("/storage/read",{params:{query:{path:t}},parseAs:i?"arrayBuffer":"blob"});if(s)throw s;return n}async function H(e){if(!r)throw new Error("API client is not initialized");const{path:t}=e,{data:i,error:n}=await r.GET("/storage/list",{params:{query:{path:t}}});if(n)throw n;return i}async function J(e){if(!r)throw new Error("API client is not initialized");const{path:t}=e,{data:i,error:n}=await r.DELETE("/storage/remove",{params:{query:{path:t}}});if(n)throw n;return i}async function X(e){if(!r)throw new Error("API client is not initialized");const{path:t}=e,{data:i,error:n}=await r.POST("/storage/mkdir",{params:{query:{path:t}}});if(n)throw n;return i}async function M(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/version");if(t)throw t;return e}async function Q(e){if(!r)throw new Error("API client is not initialized");const{name:t,file:i}=e,{data:n,error:s}=await r.POST("/update",{params:{query:{name:t}},headers:{"Content-Type":"application/octet-stream"},body:i});if(s)throw s;return n}async function Y(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/status");if(t)throw t;return e}async function Z(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/status/system");if(t)throw t;return e}async function tt(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/status/power");if(t)throw t;return e}async function et(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/display/brightness");if(t)throw t;return e}async function it(e){if(!r)throw new Error("API client is not initialized");const{front:t,back:i}=e,n=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"},s=n(t),a=n(i),{data:c,error:f}=await r.POST("/display/brightness",{params:{query:{front:s,back:a}}});if(f)throw f;return c}async function rt(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/audio/volume");if(t)throw t;return e}async function nt(e){if(!r)throw new Error("API client is not initialized");const{volume:t}=e;if(typeof t!="number"||t<0||t>100)throw new Error("Volume must be a number between 0 and 100");const{data:i,error:n}=await r.POST("/audio/volume",{params:{query:{volume:t}}});if(n)throw n;return i}async function st(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.GET("/access");if(t)throw t;return e}async function ot(e){if(!r)throw new Error("API client is not initialized");const{mode:t,key:i}=e;if(!/^\d{4,10}$/.test(String(i)))throw new Error("Key must be a string of 4 to 10 digits");const{data:n,error:s}=await r.POST("/access",{params:{query:{mode:t,key:i}}});if(s)throw s;return n}async function at(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/ble/enable");if(t)throw t;return e}async function ct(){if(!r)throw new Error("API client is not initialized");const{data:e,error:t}=await r.POST("/ble/disable");if(t)throw t;return e}async function ft(e){if(!r)throw new Error("API client is not initialized");const{keyName:t}=e,{data:i,error:n}=await r.POST("/input",{params:{query:{key:t}}});if(n)throw n;return i}const ut="http://10.0.4.20",wt="https://proxy.busy.app",dt=/^https?:\/\/proxy(?:\.(?:dev|test|stage))?\.busy\.app$/i;class ht{constructor(t){o(this,"addr");o(this,"apiSemver");if(!t||!t.addr&&!t.token)this.addr=ut;else if(!t.addr)this.addr=wt;else{let i=t.addr.trim();if(/^https?:\/\//i.test(i)||(i=`http://${i}`),dt.test(i)&&!t.token)throw new Error("Token is required. Please provide it.");this.addr=i}this.apiSemver="",L(`${this.addr}/api/`,this.getApiVersion.bind(this),t==null?void 0:t.token)}async getApiVersion(){const t=await M();return this.apiSemver=t.api_semver,t}async updateFirmware(t){return await Q(t)}async deviceStatus(){return await Y()}async systemStatus(){return await Z()}async powerStatus(){return await tt()}async uploadAsset(t){return await z(t)}async deleteAssets(t){return await D(t)}async drawDisplay(t){return await C(t)}async clearDisplay(){return await K()}async playSound(t){return await R(t)}async stopSound(){return await W()}async enableWifi(){return await $()}async disableWifi(){return await _()}async statusWifi(){return await F()}async connectWifi(t){return await V(t)}async disconnectWifi(){return await x()}async networksWifi(){return await q()}async forgetWifi(){return await G()}async uploadFile(t){return await N(t)}async downloadFile(t){return await j(t)}async readDirectory(t){return await H(t)}async removeResource(t){return await J(t)}async createDirectory(t){return await X(t)}async getDisplayBrightness(){return await et()}async setDisplayBrightness(t){return await it(t)}async getAudioVolume(){return await rt()}async setAudioVolume(t){return await nt(t)}async getHttpAccess(){return await st()}async setHttpAccess(t){const i=await ot(t);return t.mode==="key"&&t.key&&this.setApiKey(t.key),i}setApiKey(t){I(t)}async enableBle(){return await at()}async disableBle(){return await ct()}async pressButton(t){return await ft(t)}}var l=(e=>(e[e.FRONT=0]="FRONT",e[e.BACK=1]="BACK",e))(l||{});const A=3e3,g=new Set([1001,1006,1012,1013,1014,3008]);function k(e,t){if(t<0||t>=e.length)throw new Error(`Index ${t} is out of bounds (0…${e.length-1})`);const i=e[t];if(i===void 0)throw new Error(`Unexpected undefined at index ${t}`);return i}function lt(e,t){let i=0;const n=e.length,s=[];for(;i<n;){const a=k(e,i);if(i+=1,(a&128)!==0){const c=a&127;for(let f=0;f<c*t;f++)s.push(e[i+f]);i+=c*t}else{const c=a,f=e.slice(i,i+t);for(let u=0;u<c;u++)for(let p=0;p<t;p++)s.push(f[p]);i+=t}}return new Uint8Array(s)}function pt(e){const t=new Uint8Array(e.length*2);let i=0,n=0;for(;i<e.length;){const s=k(e,i),a=s&15,c=s>>4&15;t[n]=a,t[n+1]=c,i+=1,n+=2}return t}class yt{constructor(t){o(this,"connected",!1);o(this,"apiKey");o(this,"apiSemver");o(this,"dataListeners",[]);o(this,"stopListeners",[]);o(this,"errorListeners",[]);o(this,"socket",null);if(this.config=t,!(()=>typeof window<"u"&&typeof window.document<"u"))throw new Error("not browser");t.apiKey&&(this.apiKey=t.apiKey),t.apiSemver&&(this.apiSemver=t.apiSemver)}onData(t){this.dataListeners.push(t)}onStop(t){this.stopListeners.push(t)}onError(t){this.errorListeners.push(t)}emitData(t){for(const i of this.dataListeners)i(t)}emitStop(){for(const t of this.stopListeners)t()}emitError(t){for(const i of this.errorListeners)i(t)}async openWebsocket(){this.socket&&await this.closeWebsocket();let t;if(this.config.mode==="cloud"?t=new URL(`${this.config.domain}/bars/${this.config.idDevice}/ws`):this.config.mode==="local"&&(t=new URL(`${this.config.barUrl}/api/screen/ws`),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.config.mode==="cloud"?this.socket.send(JSON.stringify({token:this.config.token,display:this.config.deviceScreen})):this.config.mode==="local"&&this.socket.send(JSON.stringify({display:this.config.deviceScreen})),this.connected=!0)},this.socket.binaryType="arraybuffer",this.socket.onmessage=i=>{try{if(typeof i.data=="string")return;const n=new Uint8Array(i.data);if(this.config.mode==="cloud")this.emitData(n);else if(this.config.mode==="local"){let s;const a=this.config.deviceScreen===l.FRONT?3:2;try{const c=lt(n,a);this.config.deviceScreen===l.BACK?s=pt(c):s=c,this.emitData(s)}catch{this.emitData(n)}}}catch{this.connected=!1,this.emitStop()}},this.socket.onerror=i=>{this.connected=!1,this.emitError({code:1006,message:"WebSocket error occurred",raw:i}),this.emitStop()},this.socket.onclose=async i=>{if(this.socket=null,this.connected=!1,i.code===A||g.has(i.code)){this.emitError({code:i.code,message:i.reason,raw:i});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 mt{constructor(t){o(this,"connected",!1);o(this,"apiKey");o(this,"apiSemver");o(this,"inputEvent");o(this,"dataListeners",[]);o(this,"stopListeners",[]);o(this,"errorListeners",[]);o(this,"socket",null);if(this.config=t,!(()=>typeof window<"u"&&typeof window.document<"u"))throw new Error("not browser");t.apiKey&&(this.apiKey=t.apiKey),t.apiSemver&&(this.apiSemver=t.apiSemver),this.inputEvent={}}onData(t){this.dataListeners.push(t)}onStop(t){this.stopListeners.push(t)}onError(t){this.errorListeners.push(t)}emitData(t){for(const i of this.dataListeners)i(t)}emitStop(){for(const t of this.stopListeners)t()}emitError(t){for(const i of this.errorListeners)i(t)}async openWebsocket(){this.socket&&await this.closeWebsocket();let t;if(this.config.mode==="cloud"?t=new URL(`${this.config.domain}/bars/${this.config.idDevice}/ws`):this.config.mode==="local"&&(t=new URL(`${this.config.barUrl}/api/input`),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=i=>{try{if(typeof i.data=="string")return;const n=new Uint8Array(i.data);this.emitData(n)}catch{this.connected=!1,this.emitStop()}},this.socket.onerror=i=>{this.connected=!1,this.emitError({code:1006,message:"WebSocket error occurred",raw:i}),this.emitStop()},this.socket.onclose=async i=>{if(this.socket=null,this.connected=!1,i.code===A||g.has(i.code)){this.emitError({code:i.code,message:i.reason,raw:i});return}this.emitStop()}}sendInput({keyName:t,value:i}){if(!this.socket||!this.connected)throw new Error("WebSocket: Not connected");this.inputEvent[t]=i,this.socket.send(JSON.stringify(this.inputEvent)),i===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=ht;exports.DeviceScreen=l;exports.Input=mt;exports.ScreenStream=yt;
package/dist/index.d.ts CHANGED
@@ -47,7 +47,7 @@ export declare class BusyBar {
47
47
  * @type {BusyBarConfig['host']}
48
48
  * @readonly
49
49
  */
50
- readonly host: BusyBarConfig["host"];
50
+ readonly addr: BusyBarConfig["addr"];
51
51
  /**
52
52
  * Current API semantic version.
53
53
  * @type {ApiSemver}
@@ -57,9 +57,25 @@ export declare class BusyBar {
57
57
  * Creates an instance of BUSY Bar.
58
58
  * Initializes the API client with the provided host address.
59
59
  *
60
- * @param {BusyBarConfig} config - The host address of the device (IP or mDNS).
60
+ * @param {BusyBarConfig} config - BUSY Bar connection configuration
61
+ * @param {BusyBarConfig['addr']} config.addr -
62
+ * The device address or proxy endpoint.
63
+ *
64
+ * Can be:
65
+ * - An IP address (e.g. `192.168.0.10`)
66
+ * - An mDNS hostname (e.g. `busybar.local`)
67
+ * - A domain name
68
+ * - A full URL (`http://` or `https://`)
69
+ *
70
+ * If no protocol is specified, `http://` will be automatically added.
71
+ *
72
+ * @param {BusyBarConfig['token']} config.token -
73
+ * Optional authentication token.
74
+ *
75
+ * Must be provided when `addr` points to a secured proxy endpoint
76
+ * such as `https://proxy.busy.app`.
61
77
  */
62
- constructor(config: BusyBarConfig);
78
+ constructor(config?: BusyBarConfig);
63
79
  /**
64
80
  * Retrieves the API semantic version.
65
81
  *
@@ -310,9 +326,10 @@ export declare class BusyBar {
310
326
  pressButton(params: InputKeyParams): Promise<SuccessResponse>;
311
327
  }
312
328
 
313
- declare interface BusyBarConfig {
314
- host: string;
315
- }
329
+ declare type BusyBarConfig = {
330
+ addr?: string;
331
+ token?: string;
332
+ };
316
333
 
317
334
  declare type BusyFile = Buffer | Blob | File | ArrayBuffer;
318
335
 
package/dist/index.js CHANGED
@@ -1,20 +1,20 @@
1
- var k = Object.defineProperty;
2
- var P = (e, t, i) => t in e ? k(e, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[t] = i;
3
- var o = (e, t, i) => P(e, typeof t != "symbol" ? t + "" : t, i);
4
- import T from "openapi-fetch";
5
- const b = (e, t) => {
1
+ var P = Object.defineProperty;
2
+ var T = (e, t, i) => t in e ? P(e, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : e[t] = i;
3
+ var o = (e, t, i) => T(e, typeof t != "symbol" ? t + "" : t, i);
4
+ import b from "openapi-fetch";
5
+ const v = (e, t) => {
6
6
  if (typeof FormData < "u" && e instanceof FormData || typeof Buffer < "u" && typeof Buffer.isBuffer == "function" && Buffer.isBuffer(e) || typeof File < "u" && e instanceof File || typeof Blob < "u" && e instanceof Blob || typeof ArrayBuffer < "u" && e instanceof ArrayBuffer || typeof ArrayBuffer < "u" && ArrayBuffer.isView && ArrayBuffer.isView(e))
7
7
  return e;
8
8
  let i;
9
9
  return t && (t instanceof Headers ? i = t.get("Content-Type") ?? t.get("content-type") ?? void 0 : typeof t == "object" && (i = t["Content-Type"] ?? t["content-type"]), i === "application/x-www-form-urlencoded") ? e && typeof e == "object" && !(e instanceof URLSearchParams) ? new URLSearchParams(e).toString() : String(e) : JSON.stringify(e);
10
10
  };
11
- let p, w, h = null;
12
- async function E() {
11
+ let y, w, h = null;
12
+ async function A() {
13
13
  if (!w) {
14
- if (!p)
14
+ if (!y)
15
15
  throw new Error("getApiVersionFn is not set");
16
16
  h || (h = (async () => {
17
- const e = await p();
17
+ const e = await y();
18
18
  if (!e.api_semver)
19
19
  throw new Error("Empty API version");
20
20
  w = e.api_semver;
@@ -23,7 +23,7 @@ async function E() {
23
23
  })), await h;
24
24
  }
25
25
  }
26
- async function d(e) {
26
+ async function p(e) {
27
27
  const n = (e.headers.get("content-type") || "").includes("application/json") ? await e.clone().json() : await e.clone().text(), s = typeof n == "object" && n !== null ? n.error || n.message : typeof n == "string" ? n : void 0;
28
28
  return Object.assign(
29
29
  new Error(s || `HTTP ${e.status} ${e.statusText}`),
@@ -34,41 +34,37 @@ async function d(e) {
34
34
  }
35
35
  );
36
36
  }
37
- let y;
37
+ let m;
38
38
  function I(e) {
39
- y = e;
39
+ m = e;
40
40
  }
41
- const v = {
41
+ let d;
42
+ const L = {
42
43
  async onRequest({ request: e, schemaPath: t }) {
43
- if (t !== "/version") {
44
- if (await E(), w)
45
- return e.headers.set("X-API-Sem-Ver", w);
46
- y && e.headers.set("X-API-Token", y);
47
- }
48
- return e;
44
+ return d && e.headers.set("Authorization", `Bearer ${d}`), t !== "/version" && (await A(), w && e.headers.set("X-API-Sem-Ver", w), m && e.headers.set("X-API-Token", m)), e;
49
45
  },
50
46
  async onResponse({ request: e, response: t, options: i, schemaPath: n }) {
51
47
  if (t.ok)
52
48
  return t;
53
49
  if (n === "/version")
54
- throw await d(t);
50
+ throw await p(t);
55
51
  if (t.status !== 405)
56
- throw await d(t);
57
- w = void 0, await E(), w && e.headers.set("X-API-Sem-Ver", w);
52
+ throw await p(t);
53
+ w = void 0, await A(), w && e.headers.set("X-API-Sem-Ver", w), d && e.headers.set("Authorization", `Bearer ${d}`);
58
54
  const s = await (i.fetch ?? fetch)(e);
59
55
  if (s.ok)
60
56
  return s;
61
- throw await d(s);
57
+ throw await p(s);
62
58
  }
63
59
  };
64
60
  let r = null;
65
- function B(e, t) {
66
- p = t, r = T({
61
+ function B(e, t, i) {
62
+ y = t, d = i ?? void 0, r = b({
67
63
  baseUrl: e,
68
- bodySerializer: b
69
- }), r.use(v);
64
+ bodySerializer: v
65
+ }), r.use(L);
70
66
  }
71
- async function L(e) {
67
+ async function z(e) {
72
68
  const { appId: t, fileName: i, file: n } = e;
73
69
  if (!r)
74
70
  throw new Error("API client is not initialized");
@@ -88,7 +84,7 @@ async function L(e) {
88
84
  throw a;
89
85
  return s;
90
86
  }
91
- async function z(e) {
87
+ async function D(e) {
92
88
  const { appId: t } = e;
93
89
  if (!r)
94
90
  throw new Error("API client is not initialized");
@@ -103,15 +99,15 @@ async function z(e) {
103
99
  throw n;
104
100
  return i;
105
101
  }
106
- const D = { timeout: 5, x: 0, y: 0, display: "front" };
107
- function O(e) {
108
- return { ...D, ...e };
102
+ const O = { timeout: 5, x: 0, y: 0, display: "front" };
103
+ function U(e) {
104
+ return { ...O, ...e };
109
105
  }
110
- async function K(e) {
106
+ async function C(e) {
111
107
  const { appId: t, elements: i } = e;
112
108
  if (!r)
113
109
  throw new Error("API client is not initialized");
114
- const n = i.map(O), { data: s, error: a } = await r.POST("/display/draw", {
110
+ const n = i.map(U), { data: s, error: a } = await r.POST("/display/draw", {
115
111
  body: {
116
112
  app_id: t,
117
113
  elements: n
@@ -121,7 +117,7 @@ async function K(e) {
121
117
  throw a;
122
118
  return s;
123
119
  }
124
- async function U() {
120
+ async function K() {
125
121
  if (!r)
126
122
  throw new Error("API client is not initialized");
127
123
  const { data: e, error: t } = await r.DELETE("/display/draw");
@@ -129,7 +125,7 @@ async function U() {
129
125
  throw t;
130
126
  return e;
131
127
  }
132
- async function C(e) {
128
+ async function R(e) {
133
129
  const { appId: t, path: i } = e;
134
130
  if (!r)
135
131
  throw new Error("API client is not initialized");
@@ -161,7 +157,7 @@ async function $() {
161
157
  throw t;
162
158
  return e;
163
159
  }
164
- async function F() {
160
+ async function _() {
165
161
  if (!r)
166
162
  throw new Error("API client is not initialized");
167
163
  const { data: e, error: t } = await r.POST("/wifi/disable");
@@ -169,7 +165,7 @@ async function F() {
169
165
  throw t;
170
166
  return e;
171
167
  }
172
- async function R() {
168
+ async function F() {
173
169
  if (!r)
174
170
  throw new Error("API client is not initialized");
175
171
  const { data: e, error: t } = await r.GET("/wifi/status");
@@ -206,7 +202,7 @@ async function x() {
206
202
  throw t;
207
203
  return e;
208
204
  }
209
- async function _() {
205
+ async function G() {
210
206
  if (!r)
211
207
  throw new Error("API client is not initialized");
212
208
  const { data: e, error: t } = await r.GET("/wifi/networks");
@@ -214,7 +210,7 @@ async function _() {
214
210
  throw t;
215
211
  return e;
216
212
  }
217
- async function q() {
213
+ async function N() {
218
214
  if (!r)
219
215
  throw new Error("API client is not initialized");
220
216
  const { data: e, error: t } = await r.POST("/wifi/forget");
@@ -222,7 +218,7 @@ async function q() {
222
218
  throw t;
223
219
  return e;
224
220
  }
225
- async function G(e) {
221
+ async function q(e) {
226
222
  if (!r)
227
223
  throw new Error("API client is not initialized");
228
224
  const { path: t, file: i } = e, { data: n, error: s } = await r.POST("/storage/write", {
@@ -240,7 +236,7 @@ async function G(e) {
240
236
  throw s;
241
237
  return n;
242
238
  }
243
- async function N(e) {
239
+ async function j(e) {
244
240
  if (!r)
245
241
  throw new Error("API client is not initialized");
246
242
  const { path: t, asArrayBuffer: i } = e, { data: n, error: s } = await r.GET("/storage/read", {
@@ -255,7 +251,7 @@ async function N(e) {
255
251
  throw s;
256
252
  return n;
257
253
  }
258
- async function j(e) {
254
+ async function H(e) {
259
255
  if (!r)
260
256
  throw new Error("API client is not initialized");
261
257
  const { path: t } = e, { data: i, error: n } = await r.GET("/storage/list", {
@@ -269,7 +265,7 @@ async function j(e) {
269
265
  throw n;
270
266
  return i;
271
267
  }
272
- async function H(e) {
268
+ async function J(e) {
273
269
  if (!r)
274
270
  throw new Error("API client is not initialized");
275
271
  const { path: t } = e, { data: i, error: n } = await r.DELETE("/storage/remove", {
@@ -283,7 +279,7 @@ async function H(e) {
283
279
  throw n;
284
280
  return i;
285
281
  }
286
- async function J(e) {
282
+ async function X(e) {
287
283
  if (!r)
288
284
  throw new Error("API client is not initialized");
289
285
  const { path: t } = e, { data: i, error: n } = await r.POST("/storage/mkdir", {
@@ -297,7 +293,7 @@ async function J(e) {
297
293
  throw n;
298
294
  return i;
299
295
  }
300
- async function X() {
296
+ async function Q() {
301
297
  if (!r)
302
298
  throw new Error("API client is not initialized");
303
299
  const { data: e, error: t } = await r.GET("/version");
@@ -305,7 +301,7 @@ async function X() {
305
301
  throw t;
306
302
  return e;
307
303
  }
308
- async function Q(e) {
304
+ async function Y(e) {
309
305
  if (!r)
310
306
  throw new Error("API client is not initialized");
311
307
  const { name: t, file: i } = e, { data: n, error: s } = await r.POST("/update", {
@@ -331,7 +327,7 @@ async function M() {
331
327
  throw t;
332
328
  return e;
333
329
  }
334
- async function Y() {
330
+ async function Z() {
335
331
  if (!r)
336
332
  throw new Error("API client is not initialized");
337
333
  const { data: e, error: t } = await r.GET("/status/system");
@@ -339,7 +335,7 @@ async function Y() {
339
335
  throw t;
340
336
  return e;
341
337
  }
342
- async function Z() {
338
+ async function tt() {
343
339
  if (!r)
344
340
  throw new Error("API client is not initialized");
345
341
  const { data: e, error: t } = await r.GET("/status/power");
@@ -347,7 +343,7 @@ async function Z() {
347
343
  throw t;
348
344
  return e;
349
345
  }
350
- async function tt() {
346
+ async function et() {
351
347
  if (!r)
352
348
  throw new Error("API client is not initialized");
353
349
  const { data: e, error: t } = await r.GET("/display/brightness");
@@ -355,7 +351,7 @@ async function tt() {
355
351
  throw t;
356
352
  return e;
357
353
  }
358
- async function et(e) {
354
+ async function it(e) {
359
355
  if (!r)
360
356
  throw new Error("API client is not initialized");
361
357
  const { front: t, back: i } = e, n = (u) => {
@@ -378,7 +374,7 @@ async function et(e) {
378
374
  throw f;
379
375
  return c;
380
376
  }
381
- async function it() {
377
+ async function rt() {
382
378
  if (!r)
383
379
  throw new Error("API client is not initialized");
384
380
  const { data: e, error: t } = await r.GET("/audio/volume");
@@ -386,7 +382,7 @@ async function it() {
386
382
  throw t;
387
383
  return e;
388
384
  }
389
- async function rt(e) {
385
+ async function nt(e) {
390
386
  if (!r)
391
387
  throw new Error("API client is not initialized");
392
388
  const { volume: t } = e;
@@ -403,7 +399,7 @@ async function rt(e) {
403
399
  throw n;
404
400
  return i;
405
401
  }
406
- async function nt() {
402
+ async function st() {
407
403
  if (!r)
408
404
  throw new Error("API client is not initialized");
409
405
  const { data: e, error: t } = await r.GET("/access");
@@ -411,7 +407,7 @@ async function nt() {
411
407
  throw t;
412
408
  return e;
413
409
  }
414
- async function st(e) {
410
+ async function ot(e) {
415
411
  if (!r)
416
412
  throw new Error("API client is not initialized");
417
413
  const { mode: t, key: i } = e;
@@ -429,7 +425,7 @@ async function st(e) {
429
425
  throw s;
430
426
  return n;
431
427
  }
432
- async function ot() {
428
+ async function at() {
433
429
  if (!r)
434
430
  throw new Error("API client is not initialized");
435
431
  const { data: e, error: t } = await r.POST("/ble/enable");
@@ -437,7 +433,7 @@ async function ot() {
437
433
  throw t;
438
434
  return e;
439
435
  }
440
- async function at() {
436
+ async function ct() {
441
437
  if (!r)
442
438
  throw new Error("API client is not initialized");
443
439
  const { data: e, error: t } = await r.POST("/ble/disable");
@@ -445,7 +441,7 @@ async function at() {
445
441
  throw t;
446
442
  return e;
447
443
  }
448
- async function ct(e) {
444
+ async function ft(e) {
449
445
  if (!r)
450
446
  throw new Error("API client is not initialized");
451
447
  const { keyName: t } = e, { data: i, error: n } = await r.POST("/input", {
@@ -459,12 +455,29 @@ async function ct(e) {
459
455
  throw n;
460
456
  return i;
461
457
  }
462
- class lt {
458
+ const ut = "http://10.0.4.20", wt = "https://proxy.busy.app", dt = /^https?:\/\/proxy(?:\.(?:dev|test|stage))?\.busy\.app$/i;
459
+ class mt {
463
460
  /**
464
461
  * Creates an instance of BUSY Bar.
465
462
  * Initializes the API client with the provided host address.
466
463
  *
467
- * @param {BusyBarConfig} config - The host address of the device (IP or mDNS).
464
+ * @param {BusyBarConfig} config - BUSY Bar connection configuration
465
+ * @param {BusyBarConfig['addr']} config.addr -
466
+ * The device address or proxy endpoint.
467
+ *
468
+ * Can be:
469
+ * - An IP address (e.g. `192.168.0.10`)
470
+ * - An mDNS hostname (e.g. `busybar.local`)
471
+ * - A domain name
472
+ * - A full URL (`http://` or `https://`)
473
+ *
474
+ * If no protocol is specified, `http://` will be automatically added.
475
+ *
476
+ * @param {BusyBarConfig['token']} config.token -
477
+ * Optional authentication token.
478
+ *
479
+ * Must be provided when `addr` points to a secured proxy endpoint
480
+ * such as `https://proxy.busy.app`.
468
481
  */
469
482
  constructor(t) {
470
483
  /**
@@ -472,13 +485,27 @@ class lt {
472
485
  * @type {BusyBarConfig['host']}
473
486
  * @readonly
474
487
  */
475
- o(this, "host");
488
+ o(this, "addr");
476
489
  /**
477
490
  * Current API semantic version.
478
491
  * @type {ApiSemver}
479
492
  */
480
493
  o(this, "apiSemver");
481
- this.host = t.host, this.apiSemver = "", B(`http://${this.host}/api/`, this.getApiVersion.bind(this));
494
+ if (!t || !t.addr && !t.token)
495
+ this.addr = ut;
496
+ else if (!t.addr)
497
+ this.addr = wt;
498
+ else {
499
+ let i = t.addr.trim();
500
+ if (/^https?:\/\//i.test(i) || (i = `http://${i}`), dt.test(i) && !t.token)
501
+ throw new Error("Token is required. Please provide it.");
502
+ this.addr = i;
503
+ }
504
+ this.apiSemver = "", B(
505
+ `${this.addr}/api/`,
506
+ this.getApiVersion.bind(this),
507
+ t == null ? void 0 : t.token
508
+ );
482
509
  }
483
510
  /**
484
511
  * Retrieves the API semantic version.
@@ -486,7 +513,7 @@ class lt {
486
513
  * @returns {Promise<VersionInfo>} A promise that resolves to an object containing the `api_semver` string.
487
514
  */
488
515
  async getApiVersion() {
489
- const t = await X();
516
+ const t = await Q();
490
517
  return this.apiSemver = t.api_semver, t;
491
518
  }
492
519
  /**
@@ -498,7 +525,7 @@ class lt {
498
525
  * @returns {Promise<SuccessResponse>} Result of the update operation.
499
526
  */
500
527
  async updateFirmware(t) {
501
- return await Q(t);
528
+ return await Y(t);
502
529
  }
503
530
  /**
504
531
  * Gets the current status of the device, including system and power information.
@@ -514,7 +541,7 @@ class lt {
514
541
  * @returns {Promise<StatusSystem>} Current system status.
515
542
  */
516
543
  async systemStatus() {
517
- return await Y();
544
+ return await Z();
518
545
  }
519
546
  /**
520
547
  * Gets the current power status.
@@ -522,7 +549,7 @@ class lt {
522
549
  * @returns {Promise<StatusPower>} Current power status.
523
550
  */
524
551
  async powerStatus() {
525
- return await Z();
552
+ return await tt();
526
553
  }
527
554
  /**
528
555
  * Uploads an asset to the device.
@@ -534,7 +561,7 @@ class lt {
534
561
  * @returns {Promise<SuccessResponse>} Result of the upload operation.
535
562
  */
536
563
  async uploadAsset(t) {
537
- return await L(t);
564
+ return await z(t);
538
565
  }
539
566
  /**
540
567
  * Deletes all assets for a specific application from the device.
@@ -544,7 +571,7 @@ class lt {
544
571
  * @returns {Promise<SuccessResponse>} Result of the delete operation.
545
572
  */
546
573
  async deleteAssets(t) {
547
- return await z(t);
574
+ return await D(t);
548
575
  }
549
576
  /**
550
577
  * Draws elements on the device display.
@@ -555,7 +582,7 @@ class lt {
555
582
  * @returns {Promise<SuccessResponse>} Result of the draw operation.
556
583
  */
557
584
  async drawDisplay(t) {
558
- return await K(t);
585
+ return await C(t);
559
586
  }
560
587
  /**
561
588
  * Clears the device display and stops the Canvas application if running.
@@ -563,7 +590,7 @@ class lt {
563
590
  * @returns {Promise<SuccessResponse>} Result of the clear operation.
564
591
  */
565
592
  async clearDisplay() {
566
- return await U();
593
+ return await K();
567
594
  }
568
595
  /**
569
596
  * Plays an audio file from the assets directory.
@@ -574,7 +601,7 @@ class lt {
574
601
  * @returns {Promise<SuccessResponse>} Result of the play operation.
575
602
  */
576
603
  async playSound(t) {
577
- return await C(t);
604
+ return await R(t);
578
605
  }
579
606
  /**
580
607
  * Stops any currently playing audio on the device.
@@ -598,7 +625,7 @@ class lt {
598
625
  * @returns {Promise<SuccessResponse>} Result of the disable operation.
599
626
  */
600
627
  async disableWifi() {
601
- return await F();
628
+ return await _();
602
629
  }
603
630
  /**
604
631
  * Gets the current status of the Wi-Fi module.
@@ -606,7 +633,7 @@ class lt {
606
633
  * @returns {Promise<WifiStatusResponse>} Current Wi-Fi status.
607
634
  */
608
635
  async statusWifi() {
609
- return await R();
636
+ return await F();
610
637
  }
611
638
  /**
612
639
  * Connects the device to a Wi-Fi network with the specified parameters.
@@ -640,7 +667,7 @@ class lt {
640
667
  * @returns {Promise<WifiNetworkResponse>} List of discovered networks.
641
668
  */
642
669
  async networksWifi() {
643
- return await _();
670
+ return await G();
644
671
  }
645
672
  /**
646
673
  * Removes the saved Wi-Fi configuration (forgets the network).
@@ -648,7 +675,7 @@ class lt {
648
675
  * @returns {Promise<never>} Result of the forget operation.
649
676
  */
650
677
  async forgetWifi() {
651
- return await q();
678
+ return await N();
652
679
  }
653
680
  /**
654
681
  * Uploads a file to the device's internal storage.
@@ -659,7 +686,7 @@ class lt {
659
686
  * @returns {Promise<SuccessResponse>} Result of the upload operation.
660
687
  */
661
688
  async uploadFile(t) {
662
- return await G(t);
689
+ return await q(t);
663
690
  }
664
691
  /**
665
692
  * Downloads a file from the device's internal storage.
@@ -670,7 +697,7 @@ class lt {
670
697
  * @returns {Promise<StorageReadResponse>} The file data.
671
698
  */
672
699
  async downloadFile(t) {
673
- return await N(t);
700
+ return await j(t);
674
701
  }
675
702
  /**
676
703
  * Reads the contents of a directory (files and subdirectories) at the specified path.
@@ -680,7 +707,7 @@ class lt {
680
707
  * @returns {Promise<StorageList>} List of files and directories.
681
708
  */
682
709
  async readDirectory(t) {
683
- return await j(t);
710
+ return await H(t);
684
711
  }
685
712
  /**
686
713
  * Removes a file or a directory from the device's internal storage.
@@ -690,7 +717,7 @@ class lt {
690
717
  * @returns {Promise<SuccessResponse>} Result of the remove operation.
691
718
  */
692
719
  async removeResource(t) {
693
- return await H(t);
720
+ return await J(t);
694
721
  }
695
722
  /**
696
723
  * Creates a new directory in the device's internal storage.
@@ -700,7 +727,7 @@ class lt {
700
727
  * @returns {Promise<SuccessResponse>} Result of the create operation.
701
728
  */
702
729
  async createDirectory(t) {
703
- return await J(t);
730
+ return await X(t);
704
731
  }
705
732
  /**
706
733
  * Gets the current display brightness settings for the device.
@@ -708,7 +735,7 @@ class lt {
708
735
  * @returns {Promise<DisplayBrightnessInfo>} Current brightness information for front and back panels.
709
736
  */
710
737
  async getDisplayBrightness() {
711
- return await tt();
738
+ return await et();
712
739
  }
713
740
  /**
714
741
  * Sets the display brightness for the device.
@@ -720,7 +747,7 @@ class lt {
720
747
  * @throws {Error} If brightness value is outside the range 0-100 or not "auto".
721
748
  */
722
749
  async setDisplayBrightness(t) {
723
- return await et(t);
750
+ return await it(t);
724
751
  }
725
752
  /**
726
753
  * Gets the current audio volume value.
@@ -728,7 +755,7 @@ class lt {
728
755
  * @returns {Promise<AudioVolumeInfo>} Current audio volume (0-100).
729
756
  */
730
757
  async getAudioVolume() {
731
- return await it();
758
+ return await rt();
732
759
  }
733
760
  /**
734
761
  * Sets the audio volume value.
@@ -739,7 +766,7 @@ class lt {
739
766
  * @throws {Error} If volume is outside the range 0-100 or request fails.
740
767
  */
741
768
  async setAudioVolume(t) {
742
- return await rt(t);
769
+ return await nt(t);
743
770
  }
744
771
  /**
745
772
  * Gets the current HTTP API access configuration.
@@ -747,7 +774,7 @@ class lt {
747
774
  * @returns {Promise<HttpAccessInfo>} Current HTTP access info.
748
775
  */
749
776
  async getHttpAccess() {
750
- return await nt();
777
+ return await st();
751
778
  }
752
779
  /**
753
780
  * Sets the HTTP API access configuration.
@@ -758,7 +785,7 @@ class lt {
758
785
  * @returns {Promise<SuccessResponse>} Result of the set operation.
759
786
  */
760
787
  async setHttpAccess(t) {
761
- const i = await st(t);
788
+ const i = await ot(t);
762
789
  return t.mode === "key" && t.key && this.setApiKey(t.key), i;
763
790
  }
764
791
  /**
@@ -773,14 +800,14 @@ class lt {
773
800
  * @returns {Promise<SuccessResponse>} Result of the enable operation.
774
801
  */
775
802
  async enableBle() {
776
- return await ot();
803
+ return await at();
777
804
  }
778
805
  /**
779
806
  * Disables BLE module.
780
807
  * @returns {Promise<SuccessResponse>} Result of the disable operation.
781
808
  */
782
809
  async disableBle() {
783
- return await at();
810
+ return await ct();
784
811
  }
785
812
  /**
786
813
  * Sends a button press.
@@ -794,12 +821,12 @@ class lt {
794
821
  * @returns {Promise<SuccessResponse>} Result of pressing the button.
795
822
  */
796
823
  async pressButton(t) {
797
- return await ct(t);
824
+ return await ft(t);
798
825
  }
799
826
  }
800
- var m = /* @__PURE__ */ ((e) => (e[e.FRONT = 0] = "FRONT", e[e.BACK = 1] = "BACK", e))(m || {});
801
- const g = 3e3, S = /* @__PURE__ */ new Set([1001, 1006, 1012, 1013, 1014, 3008]);
802
- function A(e, t) {
827
+ var E = /* @__PURE__ */ ((e) => (e[e.FRONT = 0] = "FRONT", e[e.BACK = 1] = "BACK", e))(E || {});
828
+ const S = 3e3, k = /* @__PURE__ */ new Set([1001, 1006, 1012, 1013, 1014, 3008]);
829
+ function g(e, t) {
803
830
  if (t < 0 || t >= e.length)
804
831
  throw new Error(`Index ${t} is out of bounds (0…${e.length - 1})`);
805
832
  const i = e[t];
@@ -807,11 +834,11 @@ function A(e, t) {
807
834
  throw new Error(`Unexpected undefined at index ${t}`);
808
835
  return i;
809
836
  }
810
- function ft(e, t) {
837
+ function ht(e, t) {
811
838
  let i = 0;
812
839
  const n = e.length, s = [];
813
840
  for (; i < n; ) {
814
- const a = A(e, i);
841
+ const a = g(e, i);
815
842
  if (i += 1, (a & 128) !== 0) {
816
843
  const c = a & 127;
817
844
  for (let f = 0; f < c * t; f++)
@@ -827,16 +854,16 @@ function ft(e, t) {
827
854
  }
828
855
  return new Uint8Array(s);
829
856
  }
830
- function ut(e) {
857
+ function lt(e) {
831
858
  const t = new Uint8Array(e.length * 2);
832
859
  let i = 0, n = 0;
833
860
  for (; i < e.length; ) {
834
- const s = A(e, i), a = s & 15, c = s >> 4 & 15;
861
+ const s = g(e, i), a = s & 15, c = s >> 4 & 15;
835
862
  t[n] = a, t[n + 1] = c, i += 1, n += 2;
836
863
  }
837
864
  return t;
838
865
  }
839
- class dt {
866
+ class Et {
840
867
  constructor(t) {
841
868
  o(this, "connected", !1);
842
869
  // @ts-ignore
@@ -893,10 +920,10 @@ class dt {
893
920
  this.emitData(n);
894
921
  else if (this.config.mode === "local") {
895
922
  let s;
896
- const a = this.config.deviceScreen === m.FRONT ? 3 : 2;
923
+ const a = this.config.deviceScreen === E.FRONT ? 3 : 2;
897
924
  try {
898
- const c = ft(n, a);
899
- this.config.deviceScreen === m.BACK ? s = ut(c) : s = c, this.emitData(s);
925
+ const c = ht(n, a);
926
+ this.config.deviceScreen === E.BACK ? s = lt(c) : s = c, this.emitData(s);
900
927
  } catch {
901
928
  this.emitData(n);
902
929
  }
@@ -912,7 +939,7 @@ class dt {
912
939
  raw: i
913
940
  }), this.emitStop();
914
941
  }, this.socket.onclose = async (i) => {
915
- if (this.socket = null, this.connected = !1, i.code === g || S.has(i.code)) {
942
+ if (this.socket = null, this.connected = !1, i.code === S || k.has(i.code)) {
916
943
  this.emitError({
917
944
  code: i.code,
918
945
  message: i.reason,
@@ -931,7 +958,7 @@ class dt {
931
958
  });
932
959
  }
933
960
  }
934
- class pt {
961
+ class At {
935
962
  constructor(t) {
936
963
  o(this, "connected", !1);
937
964
  // @ts-ignore
@@ -992,7 +1019,7 @@ class pt {
992
1019
  raw: i
993
1020
  }), this.emitStop();
994
1021
  }, this.socket.onclose = async (i) => {
995
- if (this.socket = null, this.connected = !1, i.code === g || S.has(i.code)) {
1022
+ if (this.socket = null, this.connected = !1, i.code === S || k.has(i.code)) {
996
1023
  this.emitError({
997
1024
  code: i.code,
998
1025
  message: i.reason,
@@ -1017,8 +1044,8 @@ class pt {
1017
1044
  }
1018
1045
  }
1019
1046
  export {
1020
- lt as BusyBar,
1021
- m as DeviceScreen,
1022
- pt as Input,
1023
- dt as ScreenStream
1047
+ mt as BusyBar,
1048
+ E as DeviceScreen,
1049
+ At as Input,
1050
+ Et as ScreenStream
1024
1051
  };
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.4.0",
5
+ "version": "0.5.0",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },