@ikalogic/at1000 0.1.27 → 0.1.28
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/build/{at1000-Drc2Gwwh.cjs → at1000-Buk_qSPK.cjs} +3 -3
- package/build/at1000-Buk_qSPK.cjs.map +1 -0
- package/build/{at1000-CbtCnc9k.d.mts → at1000-C4BduTvM.d.mts} +2 -2
- package/build/at1000-C4BduTvM.d.mts.map +1 -0
- package/build/{at1000-COqCU7HR.mjs → at1000-D2141F9Y.mjs} +3 -3
- package/build/at1000-D2141F9Y.mjs.map +1 -0
- package/build/{at1000-iknorBtT.d.cts → at1000-LlkehOWj.d.cts} +2 -2
- package/build/at1000-LlkehOWj.d.cts.map +1 -0
- package/build/browser.cjs +1 -1
- package/build/browser.d.cts +1 -1
- package/build/browser.d.mts +1 -1
- package/build/browser.mjs +1 -1
- package/build/{hmi-BVhaUdzh.d.cts → hmi-BdkiKYEE.d.mts} +9 -4
- package/build/{hmi-BVhaUdzh.d.cts.map → hmi-BdkiKYEE.d.mts.map} +1 -1
- package/build/{hmi-CiHf34mI.d.mts → hmi-DkO4bd8B.d.cts} +9 -4
- package/build/{hmi-CiHf34mI.d.mts.map → hmi-DkO4bd8B.d.cts.map} +1 -1
- package/build/hmi.cjs +1 -1
- package/build/hmi.cjs.map +1 -1
- package/build/hmi.d.cts +1 -1
- package/build/hmi.d.mts +1 -1
- package/build/hmi.mjs +1 -1
- package/build/hmi.mjs.map +1 -1
- package/build/node.cjs +1 -1
- package/build/node.cjs.map +1 -1
- package/build/node.d.cts +1 -1
- package/build/node.d.mts +1 -1
- package/build/node.mjs +1 -1
- package/build/node.mjs.map +1 -1
- package/package.json +1 -1
- package/build/at1000-COqCU7HR.mjs.map +0 -1
- package/build/at1000-CbtCnc9k.d.mts.map +0 -1
- package/build/at1000-Drc2Gwwh.cjs.map +0 -1
- package/build/at1000-iknorBtT.d.cts.map +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
require(`./chunk-Bmb41Sf3.cjs`);const e=require(`./com.cjs`),t=require(`./gpio.cjs`),n=require(`./hmi.cjs`),r=require(`./management.cjs`),i=require(`./power.cjs`),a=require(`./relays.cjs`);let o=require(`up-fetch`);var s=`0.1.
|
|
2
|
-
`);throw Error(`${n.message} (${n.code})\n Suggestion: ${e}\n Path: ${n.path}`)}throw Error(`API request to ${t.method} ${e.url} failed with status ${e.status}: ${typeof n==`string`?n:JSON.stringify(n)}`)}})),this.com=new e.ComApi(this.fetch),this.hmi=new n.HmiApi(this.fetch),this.gpio=new t.GpioApi(this.fetch,this.info),this.management=new r.ManagementApi(this.fetch),this.power=new i.PowerApi(this.fetch,this.info),this.relays=new a.RelaysApi(this.fetch)}async reset(){await this.com.reset(),await this.hmi.reset(),await this.gpio.reset(),await this.power.reset(),await this.relays.reset()}static create=async e=>new s(e,await new r.ManagementApi((0,o.up)(fetch,()=>({baseUrl:`http://${e}/v0`,timeout:1e3}))).info())};Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return
|
|
3
|
-
//# sourceMappingURL=at1000-
|
|
1
|
+
require(`./chunk-Bmb41Sf3.cjs`);const e=require(`./com.cjs`),t=require(`./gpio.cjs`),n=require(`./hmi.cjs`),r=require(`./management.cjs`),i=require(`./power.cjs`),a=require(`./relays.cjs`);let o=require(`up-fetch`);var s=`0.1.28`;function c(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}var l=class s{host;info;fetch;com;hmi;gpio;management;power;relays;constructor(s,l){this.host=s,this.info=l,this.fetch=(0,o.up)(fetch,()=>({baseUrl:`http://${c(this.host)}/v0`,timeout:1e3,parseRejected:async(e,t)=>{let n,r=e.headers.get(`content-type`);try{n=r?.includes(`application/json`)?await e.json():await e.text()}catch{n=`Failed to parse response body`}if(typeof n==`object`&&[`code`,`message`,`suggestion`,`path`].every(e=>e in n)){let e=n.suggestion.replace(/\n/g,`
|
|
2
|
+
`);throw Error(`${n.message} (${n.code})\n Suggestion: ${e}\n Path: ${n.path}`)}throw Error(`API request to ${t.method} ${e.url} failed with status ${e.status}: ${typeof n==`string`?n:JSON.stringify(n)}`)}})),this.com=new e.ComApi(this.fetch),this.hmi=new n.HmiApi(this.fetch),this.gpio=new t.GpioApi(this.fetch,this.info),this.management=new r.ManagementApi(this.fetch),this.power=new i.PowerApi(this.fetch,this.info),this.relays=new a.RelaysApi(this.fetch)}async reset(){await this.com.reset(),await this.hmi.reset(),await this.gpio.reset(),await this.power.reset(),await this.relays.reset()}static create=async e=>new s(e,await new r.ManagementApi((0,o.up)(fetch,()=>({baseUrl:`http://${c(e)}/v0`,timeout:1e3}))).info())};Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return l}});
|
|
3
|
+
//# sourceMappingURL=at1000-Buk_qSPK.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"at1000-Buk_qSPK.cjs","names":["ComApi","HmiApi","GpioApi","ManagementApi","PowerApi","RelaysApi"],"sources":["../package.json","../src/at1000.ts"],"sourcesContent":["","import { up, type UpFetch } from 'up-fetch';\n\nimport { ComApi } from './api/com';\nimport { GpioApi } from './api/gpio';\nimport { HmiApi } from './api/hmi';\nimport { type Information, ManagementApi } from './api/management';\nimport { PowerApi } from './api/power';\nimport { RelaysApi } from './api/relays';\n\n/** Wraps IPv6 literal addresses in brackets for use in URLs (RFC 3986). */\nfunction format_host_for_url(host: string): string {\n if (host.includes(':') && !host.startsWith('[')) {\n return `[${host}]`;\n }\n return host;\n}\n\n/** @hideconstructor */\nexport class AT1000Base {\n /**\n * IP address or hostname of the AT1000 device\n */\n public readonly host: string;\n /**\n * Device information\n */\n public readonly info: Information;\n\n private fetch: UpFetch;\n /**\n * COM API\n */\n public readonly com: ComApi;\n /**\n * HMI API\n */\n public readonly hmi: HmiApi;\n /**\n * GPIO API\n */\n public readonly gpio: GpioApi;\n /**\n * Management API\n */\n public readonly management: ManagementApi;\n /**\n * Power management API\n */\n public readonly power: PowerApi;\n /**\n * Relays API\n */\n public readonly relays: RelaysApi;\n\n constructor(host: string, info: Information) {\n this.host = host;\n this.info = info;\n\n this.fetch = up(\n fetch,\n () => ({\n baseUrl: `http://${format_host_for_url(this.host)}/v0`,\n timeout: 1000,\n parseRejected: async (response, request) => {\n let errorData: any;\n const contentType = response.headers.get('content-type');\n try {\n if (contentType?.includes('application/json')) {\n errorData = await response.json();\n } else {\n errorData = await response.text();\n }\n } catch {\n errorData = 'Failed to parse response body';\n }\n\n if (\n typeof errorData === 'object'\n && ['code', 'message', 'suggestion', 'path'].every((key) => key in errorData)\n ) {\n const formattedSuggestion = errorData.suggestion.replace(/\\n/g, '\\n ');\n throw new Error(\n `${errorData.message} (${errorData.code})\\n Suggestion: ${formattedSuggestion}\\n Path: ${errorData.path}`,\n );\n }\n\n throw new Error(\n `API request to ${request.method} ${response.url} failed with status ${response.status}: ${\n typeof errorData === 'string' ? errorData : JSON.stringify(errorData)\n }`,\n );\n },\n }),\n );\n\n this.com = new ComApi(this.fetch);\n this.hmi = new HmiApi(this.fetch);\n this.gpio = new GpioApi(this.fetch, this.info);\n this.management = new ManagementApi(this.fetch);\n this.power = new PowerApi(this.fetch, this.info);\n this.relays = new RelaysApi(this.fetch);\n }\n\n async reset() {\n await this.com.reset();\n await this.hmi.reset();\n await this.gpio.reset();\n await this.power.reset();\n await this.relays.reset();\n }\n\n public static create = async (host: string): Promise<AT1000Base> => {\n // Create a temporary client to fetch device info\n const management = new ManagementApi(\n up(fetch, () => ({ baseUrl: `http://${format_host_for_url(host)}/v0`, timeout: 1000 })),\n );\n const info = await management.info();\n\n return new AT1000Base(host, info);\n };\n}\n"],"mappings":"sOCUA,SAAS,EAAoB,EAAsB,CAIjD,OAHI,EAAK,SAAS,IAAI,EAAI,CAAC,EAAK,WAAW,IAAI,CACtC,IAAI,EAAK,GAEX,EAIT,IAAa,EAAb,MAAa,CAAW,CAItB,KAIA,KAEA,MAIA,IAIA,IAIA,KAIA,WAIA,MAIA,OAEA,YAAY,EAAc,EAAmB,CAC3C,KAAK,KAAO,EACZ,KAAK,KAAO,EAEZ,KAAK,OAAA,EAAA,EAAA,IACH,WACO,CACL,QAAS,UAAU,EAAoB,KAAK,KAAK,CAAC,KAClD,QAAS,IACT,cAAe,MAAO,EAAU,IAAY,CAC1C,IAAI,EACE,EAAc,EAAS,QAAQ,IAAI,eAAe,CACxD,GAAI,CACF,AAGE,EAHE,GAAa,SAAS,mBAAmB,CAC/B,MAAM,EAAS,MAAM,CAErB,MAAM,EAAS,MAAM,MAE7B,CACN,EAAY,gCAGd,GACE,OAAO,GAAc,UAClB,CAAC,OAAQ,UAAW,aAAc,OAAO,CAAC,MAAO,GAAQ,KAAO,EAAU,CAC7E,CACA,IAAM,EAAsB,EAAU,WAAW,QAAQ,MAAO;kBAAqB,CACrF,MAAU,MACR,GAAG,EAAU,QAAQ,IAAI,EAAU,KAAK,qBAAqB,EAAoB,cAAc,EAAU,OAC1G,CAGH,MAAU,MACR,kBAAkB,EAAQ,OAAO,GAAG,EAAS,IAAI,sBAAsB,EAAS,OAAO,IACrF,OAAO,GAAc,SAAW,EAAY,KAAK,UAAU,EAAU,GAExE,EAEJ,EACF,CAED,KAAK,IAAM,IAAIA,EAAAA,OAAO,KAAK,MAAM,CACjC,KAAK,IAAM,IAAIC,EAAAA,OAAO,KAAK,MAAM,CACjC,KAAK,KAAO,IAAIC,EAAAA,QAAQ,KAAK,MAAO,KAAK,KAAK,CAC9C,KAAK,WAAa,IAAIC,EAAAA,cAAc,KAAK,MAAM,CAC/C,KAAK,MAAQ,IAAIC,EAAAA,SAAS,KAAK,MAAO,KAAK,KAAK,CAChD,KAAK,OAAS,IAAIC,EAAAA,UAAU,KAAK,MAAM,CAGzC,MAAM,OAAQ,CACZ,MAAM,KAAK,IAAI,OAAO,CACtB,MAAM,KAAK,IAAI,OAAO,CACtB,MAAM,KAAK,KAAK,OAAO,CACvB,MAAM,KAAK,MAAM,OAAO,CACxB,MAAM,KAAK,OAAO,OAAO,CAG3B,OAAc,OAAS,KAAO,IAOrB,IAAI,EAAW,EAFT,MAHM,IAAIF,EAAAA,eAAAA,EAAAA,EAAAA,IAClB,WAAc,CAAE,QAAS,UAAU,EAAoB,EAAK,CAAC,KAAM,QAAS,IAAM,EAAE,CACxF,CAC6B,MAAM,CAEH"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { o as ComApi } from "./com-BKy7zoOg.mjs";
|
|
2
2
|
import { n as Information, r as ManagementApi } from "./management-ra61-qUr.mjs";
|
|
3
3
|
import { s as GpioApi } from "./gpio-B2EhZKM8.mjs";
|
|
4
|
-
import { r as HmiApi } from "./hmi-
|
|
4
|
+
import { r as HmiApi } from "./hmi-BdkiKYEE.mjs";
|
|
5
5
|
import { i as PowerApi } from "./power-Bi9cbP8g.mjs";
|
|
6
6
|
import { n as RelaysApi } from "./relays-CbyqFtJP.mjs";
|
|
7
7
|
|
|
@@ -47,4 +47,4 @@ declare class AT1000Base {
|
|
|
47
47
|
}
|
|
48
48
|
//#endregion
|
|
49
49
|
export { AT1000Base as t };
|
|
50
|
-
//# sourceMappingURL=at1000-
|
|
50
|
+
//# sourceMappingURL=at1000-C4BduTvM.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"at1000-C4BduTvM.d.mts","names":[],"sources":["../src/at1000.ts"],"mappings":";;;;;;;;;cAkBa,UAAA;EAAA;;;EAAA,SAIK,IAAA;EAUK;;;EAAA,SANL,IAAA,EAAM,WAAA;EAAA,QAEd,KAAA;EAwBgB;;;EAAA,SApBR,GAAA,EAAK,MAAA;EA+EwB;;;EAAA,SA3E7B,GAAA,EAAK,MAAA;EAVL;;;EAAA,SAcA,IAAA,EAAM,OAAA;EARD;;;EAAA,SAYL,UAAA,EAAY,aAAA;EAJN;;;EAAA,SAQN,KAAA,EAAO,QAAA;EAAA;;;EAAA,SAIP,MAAA,EAAQ,SAAA;cAEZ,IAAA,UAAc,IAAA,EAAM,WAAA;EAiD1B,KAAA,CAAA,GAAK,OAAA;EAAA,OAQG,MAAA,GAAgB,IAAA,aAAe,OAAA,CAAQ,UAAA;AAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{ComApi as e}from"./com.mjs";import{GpioApi as t}from"./gpio.mjs";import{HmiApi as n}from"./hmi.mjs";import{ManagementApi as r}from"./management.mjs";import{PowerApi as i}from"./power.mjs";import{RelaysApi as a}from"./relays.mjs";import{up as o}from"up-fetch";var s=`0.1.
|
|
2
|
-
`);throw Error(`${n.message} (${n.code})\n Suggestion: ${e}\n Path: ${n.path}`)}throw Error(`API request to ${t.method} ${e.url} failed with status ${e.status}: ${typeof n==`string`?n:JSON.stringify(n)}`)}})),this.com=new e(this.fetch),this.hmi=new n(this.fetch),this.gpio=new t(this.fetch,this.info),this.management=new r(this.fetch),this.power=new i(this.fetch,this.info),this.relays=new a(this.fetch)}async reset(){await this.com.reset(),await this.hmi.reset(),await this.gpio.reset(),await this.power.reset(),await this.relays.reset()}static create=async e=>new s(e,await new r(o(fetch,()=>({baseUrl:`http://${e}/v0`,timeout:1e3}))).info())};export{s as n,
|
|
3
|
-
//# sourceMappingURL=at1000-
|
|
1
|
+
import{ComApi as e}from"./com.mjs";import{GpioApi as t}from"./gpio.mjs";import{HmiApi as n}from"./hmi.mjs";import{ManagementApi as r}from"./management.mjs";import{PowerApi as i}from"./power.mjs";import{RelaysApi as a}from"./relays.mjs";import{up as o}from"up-fetch";var s=`0.1.28`;function c(e){return e.includes(`:`)&&!e.startsWith(`[`)?`[${e}]`:e}var l=class s{host;info;fetch;com;hmi;gpio;management;power;relays;constructor(s,l){this.host=s,this.info=l,this.fetch=o(fetch,()=>({baseUrl:`http://${c(this.host)}/v0`,timeout:1e3,parseRejected:async(e,t)=>{let n,r=e.headers.get(`content-type`);try{n=r?.includes(`application/json`)?await e.json():await e.text()}catch{n=`Failed to parse response body`}if(typeof n==`object`&&[`code`,`message`,`suggestion`,`path`].every(e=>e in n)){let e=n.suggestion.replace(/\n/g,`
|
|
2
|
+
`);throw Error(`${n.message} (${n.code})\n Suggestion: ${e}\n Path: ${n.path}`)}throw Error(`API request to ${t.method} ${e.url} failed with status ${e.status}: ${typeof n==`string`?n:JSON.stringify(n)}`)}})),this.com=new e(this.fetch),this.hmi=new n(this.fetch),this.gpio=new t(this.fetch,this.info),this.management=new r(this.fetch),this.power=new i(this.fetch,this.info),this.relays=new a(this.fetch)}async reset(){await this.com.reset(),await this.hmi.reset(),await this.gpio.reset(),await this.power.reset(),await this.relays.reset()}static create=async e=>new s(e,await new r(o(fetch,()=>({baseUrl:`http://${c(e)}/v0`,timeout:1e3}))).info())};export{s as n,l as t};
|
|
3
|
+
//# sourceMappingURL=at1000-D2141F9Y.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"at1000-D2141F9Y.mjs","names":[],"sources":["../package.json","../src/at1000.ts"],"sourcesContent":["","import { up, type UpFetch } from 'up-fetch';\n\nimport { ComApi } from './api/com';\nimport { GpioApi } from './api/gpio';\nimport { HmiApi } from './api/hmi';\nimport { type Information, ManagementApi } from './api/management';\nimport { PowerApi } from './api/power';\nimport { RelaysApi } from './api/relays';\n\n/** Wraps IPv6 literal addresses in brackets for use in URLs (RFC 3986). */\nfunction format_host_for_url(host: string): string {\n if (host.includes(':') && !host.startsWith('[')) {\n return `[${host}]`;\n }\n return host;\n}\n\n/** @hideconstructor */\nexport class AT1000Base {\n /**\n * IP address or hostname of the AT1000 device\n */\n public readonly host: string;\n /**\n * Device information\n */\n public readonly info: Information;\n\n private fetch: UpFetch;\n /**\n * COM API\n */\n public readonly com: ComApi;\n /**\n * HMI API\n */\n public readonly hmi: HmiApi;\n /**\n * GPIO API\n */\n public readonly gpio: GpioApi;\n /**\n * Management API\n */\n public readonly management: ManagementApi;\n /**\n * Power management API\n */\n public readonly power: PowerApi;\n /**\n * Relays API\n */\n public readonly relays: RelaysApi;\n\n constructor(host: string, info: Information) {\n this.host = host;\n this.info = info;\n\n this.fetch = up(\n fetch,\n () => ({\n baseUrl: `http://${format_host_for_url(this.host)}/v0`,\n timeout: 1000,\n parseRejected: async (response, request) => {\n let errorData: any;\n const contentType = response.headers.get('content-type');\n try {\n if (contentType?.includes('application/json')) {\n errorData = await response.json();\n } else {\n errorData = await response.text();\n }\n } catch {\n errorData = 'Failed to parse response body';\n }\n\n if (\n typeof errorData === 'object'\n && ['code', 'message', 'suggestion', 'path'].every((key) => key in errorData)\n ) {\n const formattedSuggestion = errorData.suggestion.replace(/\\n/g, '\\n ');\n throw new Error(\n `${errorData.message} (${errorData.code})\\n Suggestion: ${formattedSuggestion}\\n Path: ${errorData.path}`,\n );\n }\n\n throw new Error(\n `API request to ${request.method} ${response.url} failed with status ${response.status}: ${\n typeof errorData === 'string' ? errorData : JSON.stringify(errorData)\n }`,\n );\n },\n }),\n );\n\n this.com = new ComApi(this.fetch);\n this.hmi = new HmiApi(this.fetch);\n this.gpio = new GpioApi(this.fetch, this.info);\n this.management = new ManagementApi(this.fetch);\n this.power = new PowerApi(this.fetch, this.info);\n this.relays = new RelaysApi(this.fetch);\n }\n\n async reset() {\n await this.com.reset();\n await this.hmi.reset();\n await this.gpio.reset();\n await this.power.reset();\n await this.relays.reset();\n }\n\n public static create = async (host: string): Promise<AT1000Base> => {\n // Create a temporary client to fetch device info\n const management = new ManagementApi(\n up(fetch, () => ({ baseUrl: `http://${format_host_for_url(host)}/v0`, timeout: 1000 })),\n );\n const info = await management.info();\n\n return new AT1000Base(host, info);\n };\n}\n"],"mappings":"yRCUA,SAAS,EAAoB,EAAsB,CAIjD,OAHI,EAAK,SAAS,IAAI,EAAI,CAAC,EAAK,WAAW,IAAI,CACtC,IAAI,EAAK,GAEX,EAIT,IAAa,EAAb,MAAa,CAAW,CAItB,KAIA,KAEA,MAIA,IAIA,IAIA,KAIA,WAIA,MAIA,OAEA,YAAY,EAAc,EAAmB,CAC3C,KAAK,KAAO,EACZ,KAAK,KAAO,EAEZ,KAAK,MAAQ,EACX,WACO,CACL,QAAS,UAAU,EAAoB,KAAK,KAAK,CAAC,KAClD,QAAS,IACT,cAAe,MAAO,EAAU,IAAY,CAC1C,IAAI,EACE,EAAc,EAAS,QAAQ,IAAI,eAAe,CACxD,GAAI,CACF,AAGE,EAHE,GAAa,SAAS,mBAAmB,CAC/B,MAAM,EAAS,MAAM,CAErB,MAAM,EAAS,MAAM,MAE7B,CACN,EAAY,gCAGd,GACE,OAAO,GAAc,UAClB,CAAC,OAAQ,UAAW,aAAc,OAAO,CAAC,MAAO,GAAQ,KAAO,EAAU,CAC7E,CACA,IAAM,EAAsB,EAAU,WAAW,QAAQ,MAAO;kBAAqB,CACrF,MAAU,MACR,GAAG,EAAU,QAAQ,IAAI,EAAU,KAAK,qBAAqB,EAAoB,cAAc,EAAU,OAC1G,CAGH,MAAU,MACR,kBAAkB,EAAQ,OAAO,GAAG,EAAS,IAAI,sBAAsB,EAAS,OAAO,IACrF,OAAO,GAAc,SAAW,EAAY,KAAK,UAAU,EAAU,GAExE,EAEJ,EACF,CAED,KAAK,IAAM,IAAI,EAAO,KAAK,MAAM,CACjC,KAAK,IAAM,IAAI,EAAO,KAAK,MAAM,CACjC,KAAK,KAAO,IAAI,EAAQ,KAAK,MAAO,KAAK,KAAK,CAC9C,KAAK,WAAa,IAAI,EAAc,KAAK,MAAM,CAC/C,KAAK,MAAQ,IAAI,EAAS,KAAK,MAAO,KAAK,KAAK,CAChD,KAAK,OAAS,IAAI,EAAU,KAAK,MAAM,CAGzC,MAAM,OAAQ,CACZ,MAAM,KAAK,IAAI,OAAO,CACtB,MAAM,KAAK,IAAI,OAAO,CACtB,MAAM,KAAK,KAAK,OAAO,CACvB,MAAM,KAAK,MAAM,OAAO,CACxB,MAAM,KAAK,OAAO,OAAO,CAG3B,OAAc,OAAS,KAAO,IAOrB,IAAI,EAAW,EAFT,MAHM,IAAI,EACrB,EAAG,WAAc,CAAE,QAAS,UAAU,EAAoB,EAAK,CAAC,KAAM,QAAS,IAAM,EAAE,CACxF,CAC6B,MAAM,CAEH"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { o as ComApi } from "./com-lqsVrnqO.cjs";
|
|
2
2
|
import { n as Information, r as ManagementApi } from "./management-wQgti8p7.cjs";
|
|
3
3
|
import { s as GpioApi } from "./gpio-C4wCa4wG.cjs";
|
|
4
|
-
import { r as HmiApi } from "./hmi-
|
|
4
|
+
import { r as HmiApi } from "./hmi-DkO4bd8B.cjs";
|
|
5
5
|
import { i as PowerApi } from "./power-Dv21KxFx.cjs";
|
|
6
6
|
import { n as RelaysApi } from "./relays-C-vNqDM-.cjs";
|
|
7
7
|
|
|
@@ -47,4 +47,4 @@ declare class AT1000Base {
|
|
|
47
47
|
}
|
|
48
48
|
//#endregion
|
|
49
49
|
export { AT1000Base as t };
|
|
50
|
-
//# sourceMappingURL=at1000-
|
|
50
|
+
//# sourceMappingURL=at1000-LlkehOWj.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"at1000-LlkehOWj.d.cts","names":[],"sources":["../src/at1000.ts"],"mappings":";;;;;;;;;cAkBa,UAAA;EAAA;;;EAAA,SAIK,IAAA;EAUK;;;EAAA,SANL,IAAA,EAAM,WAAA;EAAA,QAEd,KAAA;EAwBgB;;;EAAA,SApBR,GAAA,EAAK,MAAA;EA+EwB;;;EAAA,SA3E7B,GAAA,EAAK,MAAA;EAVL;;;EAAA,SAcA,IAAA,EAAM,OAAA;EARD;;;EAAA,SAYL,UAAA,EAAY,aAAA;EAJN;;;EAAA,SAQN,KAAA,EAAO,QAAA;EAAA;;;EAAA,SAIP,MAAA,EAAQ,SAAA;cAEZ,IAAA,UAAc,IAAA,EAAM,WAAA;EAiD1B,KAAA,CAAA,GAAK,OAAA;EAAA,OAQG,MAAA,GAAgB,IAAA,aAAe,OAAA,CAAQ,UAAA;AAAA"}
|
package/build/browser.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./at1000-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./at1000-Buk_qSPK.cjs`);require(`./common-PXzrB8CC.cjs`);var t=class extends e.t{static apiVersion=e.n};exports.AT1000=t;
|
|
2
2
|
//# sourceMappingURL=browser.cjs.map
|
package/build/browser.d.cts
CHANGED
package/build/browser.d.mts
CHANGED
package/build/browser.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e,t}from"./at1000-
|
|
1
|
+
import{n as e,t}from"./at1000-D2141F9Y.mjs";import"./common-DzTRbz1N.mjs";var n=class extends t{static apiVersion=e};export{n as AT1000};
|
|
2
2
|
//# sourceMappingURL=browser.mjs.map
|
|
@@ -121,15 +121,20 @@ declare class Audio {
|
|
|
121
121
|
declare class Knob {
|
|
122
122
|
private readonly fetch;
|
|
123
123
|
constructor(fetch: UpFetch);
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
read_event: () => Promise<{
|
|
125
|
+
button_pressed: boolean;
|
|
126
|
+
button_held: boolean;
|
|
127
|
+
rotation_delta: number;
|
|
128
|
+
}>;
|
|
129
|
+
is_button_held: () => Promise<boolean>;
|
|
130
|
+
is_knob_turned: () => Promise<boolean>;
|
|
126
131
|
/**
|
|
127
132
|
* Waits for a knob event and returns it.
|
|
128
133
|
* @param timeout_ms The timeout in milliseconds.
|
|
129
134
|
* @returns The knob event or null if the timeout was reached.
|
|
130
135
|
*/
|
|
131
|
-
wait_event(timeout_ms
|
|
136
|
+
wait_event(timeout_ms?: number): Promise<KnobEvent | null>;
|
|
132
137
|
}
|
|
133
138
|
//#endregion
|
|
134
139
|
export { KnobEvent as a, ProgressValue as c, Knob as i, Screen as l, Color as n, PlaybackConfiguration as o, HmiApi as r, Progress as s, Audio as t, ScreenText as u };
|
|
135
|
-
//# sourceMappingURL=hmi-
|
|
140
|
+
//# sourceMappingURL=hmi-BdkiKYEE.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmi-
|
|
1
|
+
{"version":3,"file":"hmi-BdkiKYEE.d.mts","names":[],"sources":["../src/api/hmi.ts"],"mappings":";;;;cAGM,UAAA,EAAU,CAAA,CAAA,cAAA,WAAA,CAAA,CAAA,YAAA,aAAA,CAAA,CAAA,eAAA;AAAA,KACJ,UAAA,GAAa,CAAA,CAAE,WAAA,QAAmB,UAAA;AAAA,cAMxC,KAAA,EAAK,CAAA,CAAA,YAAA;EAAA;;;;KAKC,KAAA,GAAQ,CAAA,CAAE,WAAA,QAAmB,KAAA;AAAA,cAEnC,aAAA,EAAa,CAAA,CAAA,cAAA,WAAA,CAAA,CAAA,YAAA,aAAA,CAAA,CAAA,cAAA,wBAAA,CAAA,CAAA,cAAA;AAAA,KACP,aAAA,GAAgB,CAAA,CAAE,WAAA,QAAmB,aAAA;AAAA,cAC3C,QAAA,EAAQ,CAAA,CAAA,YAAA;EAAA;;KACF,QAAA,GAAW,CAAA,CAAE,WAAA,QAAmB,QAAA;AAAA,cAEtC,qBAAA,EAAqB,CAAA,CAAA,YAAA;EAAA;;;KAOf,qBAAA,GAAwB,CAAA,CAAE,WAAA,QAAmB,qBAAA;AAAA,cAOnD,SAAA,EAAS,IAAA,CAAA,CAAA,CAAA,YAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KACH,SAAA,GAAY,CAAA,CAAE,WAAA,QAAmB,SAAA;;cAGhC,MAAA;EAAA,iBACkB,KAAA;cAAA,KAAA,EAAO,OAAA;;;;EAKpC,KAAA,CAAA,GAAS,OAAA;;;;;EAQT,MAAA,CAAA,GAAU,MAAA;;;;;EAQV,KAAA,CAAA,GAAS,KAAA;;;;;EAQT,IAAA,CAAA,GAAQ,IAAA;AAAA;;cAMG,MAAA;EAAA,iBACkB,KAAA;cAAA,KAAA,EAAO,OAAA;;;;;AA9DtC;EAqEQ,KAAA,CAAM,IAAA,EAAM,UAAA,GAAa,OAAA;;;;;;EAc/B,MAAA,CAAO,MAAA,EAAQ,KAAA,GAAQ,OAAA,CAAQ,KAAA;EAnFa;AAAE;;;;EAgGxC,QAAA,CAAS,IAAA,EAAM,aAAA,GAAgB,OAAA,CAAQ,QAAA;EA9F5B;;;EAgHjB,KAAA,CAAA,GAAS,OAAA;AAAA;;cAME,KAAA;EAAA,iBACkB,KAAA;cAAA,KAAA,EAAO,OAAA;EAvHnB;;;;;EA8HX,IAAA,CAAK,MAAA,EAAQ,qBAAA,GAAwB,OAAA,CAAQ,qBAAA;AAAA;;cAUxC,IAAA;EAAA,iBACkB,KAAA;cAAA,KAAA,EAAO,OAAA;EAEpC,UAAA,QAAU,OAAA;;;;;EAEV,cAAA,QAAc,OAAA;EACd,cAAA,QAAc,OAAA;;;;;;EAOR,UAAA,CAAW,UAAA,YAAsB,OAAA,CAAQ,SAAA;AAAA"}
|
|
@@ -121,15 +121,20 @@ declare class Audio {
|
|
|
121
121
|
declare class Knob {
|
|
122
122
|
private readonly fetch;
|
|
123
123
|
constructor(fetch: UpFetch);
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
read_event: () => Promise<{
|
|
125
|
+
button_pressed: boolean;
|
|
126
|
+
button_held: boolean;
|
|
127
|
+
rotation_delta: number;
|
|
128
|
+
}>;
|
|
129
|
+
is_button_held: () => Promise<boolean>;
|
|
130
|
+
is_knob_turned: () => Promise<boolean>;
|
|
126
131
|
/**
|
|
127
132
|
* Waits for a knob event and returns it.
|
|
128
133
|
* @param timeout_ms The timeout in milliseconds.
|
|
129
134
|
* @returns The knob event or null if the timeout was reached.
|
|
130
135
|
*/
|
|
131
|
-
wait_event(timeout_ms
|
|
136
|
+
wait_event(timeout_ms?: number): Promise<KnobEvent | null>;
|
|
132
137
|
}
|
|
133
138
|
//#endregion
|
|
134
139
|
export { KnobEvent as a, ProgressValue as c, Knob as i, Screen as l, Color as n, PlaybackConfiguration as o, HmiApi as r, Progress as s, Audio as t, ScreenText as u };
|
|
135
|
-
//# sourceMappingURL=hmi-
|
|
140
|
+
//# sourceMappingURL=hmi-DkO4bd8B.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmi-
|
|
1
|
+
{"version":3,"file":"hmi-DkO4bd8B.d.cts","names":[],"sources":["../src/api/hmi.ts"],"mappings":";;;;cAGM,UAAA,EAAU,CAAA,CAAA,cAAA,WAAA,CAAA,CAAA,YAAA,aAAA,CAAA,CAAA,eAAA;AAAA,KACJ,UAAA,GAAa,CAAA,CAAE,WAAA,QAAmB,UAAA;AAAA,cAMxC,KAAA,EAAK,CAAA,CAAA,YAAA;EAAA;;;;KAKC,KAAA,GAAQ,CAAA,CAAE,WAAA,QAAmB,KAAA;AAAA,cAEnC,aAAA,EAAa,CAAA,CAAA,cAAA,WAAA,CAAA,CAAA,YAAA,aAAA,CAAA,CAAA,cAAA,wBAAA,CAAA,CAAA,cAAA;AAAA,KACP,aAAA,GAAgB,CAAA,CAAE,WAAA,QAAmB,aAAA;AAAA,cAC3C,QAAA,EAAQ,CAAA,CAAA,YAAA;EAAA;;KACF,QAAA,GAAW,CAAA,CAAE,WAAA,QAAmB,QAAA;AAAA,cAEtC,qBAAA,EAAqB,CAAA,CAAA,YAAA;EAAA;;;KAOf,qBAAA,GAAwB,CAAA,CAAE,WAAA,QAAmB,qBAAA;AAAA,cAOnD,SAAA,EAAS,IAAA,CAAA,CAAA,CAAA,YAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KACH,SAAA,GAAY,CAAA,CAAE,WAAA,QAAmB,SAAA;;cAGhC,MAAA;EAAA,iBACkB,KAAA;cAAA,KAAA,EAAO,OAAA;;;;EAKpC,KAAA,CAAA,GAAS,OAAA;;;;;EAQT,MAAA,CAAA,GAAU,MAAA;;;;;EAQV,KAAA,CAAA,GAAS,KAAA;;;;;EAQT,IAAA,CAAA,GAAQ,IAAA;AAAA;;cAMG,MAAA;EAAA,iBACkB,KAAA;cAAA,KAAA,EAAO,OAAA;;;;;AA9DtC;EAqEQ,KAAA,CAAM,IAAA,EAAM,UAAA,GAAa,OAAA;;;;;;EAc/B,MAAA,CAAO,MAAA,EAAQ,KAAA,GAAQ,OAAA,CAAQ,KAAA;EAnFa;AAAE;;;;EAgGxC,QAAA,CAAS,IAAA,EAAM,aAAA,GAAgB,OAAA,CAAQ,QAAA;EA9F5B;;;EAgHjB,KAAA,CAAA,GAAS,OAAA;AAAA;;cAME,KAAA;EAAA,iBACkB,KAAA;cAAA,KAAA,EAAO,OAAA;EAvHnB;;;;;EA8HX,IAAA,CAAK,MAAA,EAAQ,qBAAA,GAAwB,OAAA,CAAQ,qBAAA;AAAA;;cAUxC,IAAA;EAAA,iBACkB,KAAA;cAAA,KAAA,EAAO,OAAA;EAEpC,UAAA,QAAU,OAAA;;;;;EAEV,cAAA,QAAc,OAAA;EACd,cAAA,QAAc,OAAA;;;;;;EAOR,UAAA,CAAW,UAAA,YAAsB,OAAA,CAAQ,SAAA;AAAA"}
|
package/build/hmi.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-Bmb41Sf3.cjs`);let t=require(`valibot`);t=e.t(t);const n=t.pipe(t.string(),t.maxLength(1024)),r=t.object({text:n}),i=t.optional(t.pipe(t.string(),t.length(7),t.hexColor())),a=t.object({text:i,progress:i,background:i}),o=t.pipe(t.number(),t.minValue(0),t.maxValue(100)),s=t.object({progress:o}),c=t.object({sound_id:t.picklist([`success`,`warning`,`failure`,`notification_1`,`notification_2`,`imperial_march`]),volume:t.pipe(t.number(),t.minValue(0),t.maxValue(100))}),l=t.object({button_pressed:t.boolean(),button_held:t.boolean(),rotation_delta:t.number()});t.omit(l,[`button_held`]);var u=class{constructor(e){this.fetch=e}reset(){return this.fetch(`/hmi/reset`,{method:`POST`,parseResponse:()=>{}})}screen(){return new d(this.fetch)}audio(){return new f(this.fetch)}knob(){return new p(this.fetch)}},d=class{constructor(e){this.fetch=e}async print(e){return(await this.fetch(`/hmi/screen/text`,{method:`POST`,body:t.parse(r,{text:e}),schema:r})).text}colors(e){return this.fetch(`/hmi/screen/colors`,{method:`PATCH`,body:t.parse(a,e),schema:a})}async progress(e){return e==0?await this.fetch(`/hmi/screen/progress`,{method:`DELETE`,parseResponse:()=>({progress:0})}):this.fetch(`/hmi/screen/progress`,{method:`PUT`,body:t.parse(s,{progress:e}),schema:s})}clear(){return this.fetch(`/hmi/screen/clear`,{method:`POST`,parseResponse:()=>{}})}},f=class{constructor(e){this.fetch=e}async play(e){return this.fetch(`/hmi/speaker/play`,{method:`POST`,body:t.parse(c,e),schema:c})}},p=class{constructor(e){this.fetch=e}
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-Bmb41Sf3.cjs`);let t=require(`valibot`);t=e.t(t);const n=t.pipe(t.string(),t.maxLength(1024)),r=t.object({text:n}),i=t.optional(t.pipe(t.string(),t.length(7),t.hexColor())),a=t.object({text:i,progress:i,background:i}),o=t.pipe(t.number(),t.minValue(0),t.maxValue(100)),s=t.object({progress:o}),c=t.object({sound_id:t.picklist([`success`,`warning`,`failure`,`notification_1`,`notification_2`,`imperial_march`]),volume:t.pipe(t.number(),t.minValue(0),t.maxValue(100))}),l=t.object({button_pressed:t.boolean(),button_held:t.boolean(),rotation_delta:t.number()});t.omit(l,[`button_held`]);var u=class{constructor(e){this.fetch=e}reset(){return this.fetch(`/hmi/reset`,{method:`POST`,parseResponse:()=>{}})}screen(){return new d(this.fetch)}audio(){return new f(this.fetch)}knob(){return new p(this.fetch)}},d=class{constructor(e){this.fetch=e}async print(e){return(await this.fetch(`/hmi/screen/text`,{method:`POST`,body:t.parse(r,{text:e}),schema:r})).text}colors(e){return this.fetch(`/hmi/screen/colors`,{method:`PATCH`,body:t.parse(a,e),schema:a})}async progress(e){return e==0?await this.fetch(`/hmi/screen/progress`,{method:`DELETE`,parseResponse:()=>({progress:0})}):this.fetch(`/hmi/screen/progress`,{method:`PUT`,body:t.parse(s,{progress:e}),schema:s})}clear(){return this.fetch(`/hmi/screen/clear`,{method:`POST`,parseResponse:()=>{}})}},f=class{constructor(e){this.fetch=e}async play(e){return this.fetch(`/hmi/speaker/play`,{method:`POST`,body:t.parse(c,e),schema:c})}},p=class{constructor(e){this.fetch=e}read_event=()=>this.fetch(`/hmi/knob/get_knob_event`,{schema:l});is_button_held=async()=>(await this.read_event()).button_held;is_knob_turned=async()=>Math.abs((await this.read_event()).rotation_delta)>=4;async wait_event(e){await this.read_event();let t=0,n=Math.min(50,(e??500)/10),r=Date.now();for(;!e||Date.now()-r<e;){let e=await this.read_event();if(t+=e.rotation_delta,e.button_pressed||Math.abs(t)>=4)return{button_pressed:e.button_pressed,rotation_delta:Math.sign(t)};await new Promise(e=>setTimeout(e,n))}return null}};exports.Audio=f,exports.HmiApi=u,exports.Knob=p,exports.Screen=d;
|
|
2
2
|
//# sourceMappingURL=hmi.cjs.map
|
package/build/hmi.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmi.cjs","names":["v"],"sources":["../src/api/hmi.ts"],"sourcesContent":["import type { UpFetch } from 'up-fetch';\nimport * as v from 'valibot';\n\nconst screenText = v.pipe(v.string(), v.maxLength(1024));\nexport type ScreenText = v.InferOutput<typeof screenText>;\n\nconst text = v.object({ text: screenText });\ntype Text = v.InferOutput<typeof text>;\n\nconst optionalHexColor = v.optional(v.pipe(v.string(), v.length(7), v.hexColor()));\nconst color = v.object({\n text: optionalHexColor,\n progress: optionalHexColor,\n background: optionalHexColor,\n});\nexport type Color = v.InferOutput<typeof color>;\n\nconst progressValue = v.pipe(v.number(), v.minValue(0), v.maxValue(100));\nexport type ProgressValue = v.InferOutput<typeof progressValue>;\nconst progress = v.object({ progress: progressValue });\nexport type Progress = v.InferOutput<typeof progress>;\n\nconst playbackConfiguration = v.object({\n sound_id: v.picklist(\n ['success', 'warning', 'failure', 'notification_1', 'notification_2',\n 'imperial_march'] as const,\n ),\n volume: v.pipe(v.number(), v.minValue(0), v.maxValue(100)),\n});\nexport type PlaybackConfiguration = v.InferOutput<typeof playbackConfiguration>;\n\nconst internalKnobEvent = v.object({\n button_pressed: v.boolean(),\n button_held: v.boolean(),\n rotation_delta: v.number(),\n});\nconst knobEvent = v.omit(internalKnobEvent, ['button_held']);\nexport type KnobEvent = v.InferOutput<typeof knobEvent>;\n\n/** @hideconstructor */\nexport class HmiApi {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Resets the HMI.\n */\n reset(): Promise<void> {\n return this.fetch('/hmi/reset', { method: 'POST', parseResponse: () => {} });\n }\n\n /**\n * Access the screen API.\n * @returns The screen instance.\n */\n screen(): Screen {\n return new Screen(this.fetch);\n }\n\n /**\n * Access the audio API.\n * @returns The audio instance.\n */\n audio(): Audio {\n return new Audio(this.fetch);\n }\n\n /**\n * Access the knob API.\n * @returns The knob instance.\n */\n knob(): Knob {\n return new Knob(this.fetch);\n }\n}\n\n/** @hideconstructor */\nexport class Screen {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Prints text to the screen.\n * @param data The text to print.\n * @returns The printed text.\n */\n async print(data: ScreenText): Promise<string> {\n return (await this.fetch('/hmi/screen/text', {\n method: 'POST',\n body: v.parse(text, { text: data } satisfies Text),\n schema: text,\n }))\n .text;\n }\n\n /**\n * Sets the screen colors.\n * @param colors The colors to set.\n * @returns The updated colors.\n */\n colors(colors: Color): Promise<Color> {\n return this.fetch('/hmi/screen/colors', {\n method: 'PATCH',\n body: v.parse(color, colors satisfies Color),\n schema: color,\n });\n }\n\n /**\n * Sets the screen progress.\n * @param data The progress value to set.\n * @returns The updated progress.\n */\n async progress(data: ProgressValue): Promise<Progress> {\n if (data == 0) {\n return await this.fetch('/hmi/screen/progress', {\n method: 'DELETE',\n parseResponse: () => ({ progress: 0 }),\n });\n }\n\n return this.fetch('/hmi/screen/progress', {\n method: 'PUT',\n body: v.parse(progress, { progress: data } satisfies Progress),\n schema: progress,\n });\n }\n\n /**\n * Clears the screen.\n */\n clear(): Promise<void> {\n return this.fetch('/hmi/screen/clear', { method: 'POST', parseResponse: () => {} });\n }\n}\n\n/** @hideconstructor */\nexport class Audio {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Plays a sound.\n * @param config The configuration (sound_id, volume).\n * @returns The play configuration.\n */\n async play(config: PlaybackConfiguration): Promise<PlaybackConfiguration> {\n return this.fetch('/hmi/speaker/play', {\n method: 'POST',\n body: v.parse(playbackConfiguration, config),\n schema: playbackConfiguration,\n });\n }\n}\n\n/** @hideconstructor */\nexport class Knob {\n constructor(private readonly fetch: UpFetch) {}\n\n
|
|
1
|
+
{"version":3,"file":"hmi.cjs","names":["v"],"sources":["../src/api/hmi.ts"],"sourcesContent":["import type { UpFetch } from 'up-fetch';\nimport * as v from 'valibot';\n\nconst screenText = v.pipe(v.string(), v.maxLength(1024));\nexport type ScreenText = v.InferOutput<typeof screenText>;\n\nconst text = v.object({ text: screenText });\ntype Text = v.InferOutput<typeof text>;\n\nconst optionalHexColor = v.optional(v.pipe(v.string(), v.length(7), v.hexColor()));\nconst color = v.object({\n text: optionalHexColor,\n progress: optionalHexColor,\n background: optionalHexColor,\n});\nexport type Color = v.InferOutput<typeof color>;\n\nconst progressValue = v.pipe(v.number(), v.minValue(0), v.maxValue(100));\nexport type ProgressValue = v.InferOutput<typeof progressValue>;\nconst progress = v.object({ progress: progressValue });\nexport type Progress = v.InferOutput<typeof progress>;\n\nconst playbackConfiguration = v.object({\n sound_id: v.picklist(\n ['success', 'warning', 'failure', 'notification_1', 'notification_2',\n 'imperial_march'] as const,\n ),\n volume: v.pipe(v.number(), v.minValue(0), v.maxValue(100)),\n});\nexport type PlaybackConfiguration = v.InferOutput<typeof playbackConfiguration>;\n\nconst internalKnobEvent = v.object({\n button_pressed: v.boolean(),\n button_held: v.boolean(),\n rotation_delta: v.number(),\n});\nconst knobEvent = v.omit(internalKnobEvent, ['button_held']);\nexport type KnobEvent = v.InferOutput<typeof knobEvent>;\n\n/** @hideconstructor */\nexport class HmiApi {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Resets the HMI.\n */\n reset(): Promise<void> {\n return this.fetch('/hmi/reset', { method: 'POST', parseResponse: () => {} });\n }\n\n /**\n * Access the screen API.\n * @returns The screen instance.\n */\n screen(): Screen {\n return new Screen(this.fetch);\n }\n\n /**\n * Access the audio API.\n * @returns The audio instance.\n */\n audio(): Audio {\n return new Audio(this.fetch);\n }\n\n /**\n * Access the knob API.\n * @returns The knob instance.\n */\n knob(): Knob {\n return new Knob(this.fetch);\n }\n}\n\n/** @hideconstructor */\nexport class Screen {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Prints text to the screen.\n * @param data The text to print.\n * @returns The printed text.\n */\n async print(data: ScreenText): Promise<string> {\n return (await this.fetch('/hmi/screen/text', {\n method: 'POST',\n body: v.parse(text, { text: data } satisfies Text),\n schema: text,\n }))\n .text;\n }\n\n /**\n * Sets the screen colors.\n * @param colors The colors to set.\n * @returns The updated colors.\n */\n colors(colors: Color): Promise<Color> {\n return this.fetch('/hmi/screen/colors', {\n method: 'PATCH',\n body: v.parse(color, colors satisfies Color),\n schema: color,\n });\n }\n\n /**\n * Sets the screen progress.\n * @param data The progress value to set.\n * @returns The updated progress.\n */\n async progress(data: ProgressValue): Promise<Progress> {\n if (data == 0) {\n return await this.fetch('/hmi/screen/progress', {\n method: 'DELETE',\n parseResponse: () => ({ progress: 0 }),\n });\n }\n\n return this.fetch('/hmi/screen/progress', {\n method: 'PUT',\n body: v.parse(progress, { progress: data } satisfies Progress),\n schema: progress,\n });\n }\n\n /**\n * Clears the screen.\n */\n clear(): Promise<void> {\n return this.fetch('/hmi/screen/clear', { method: 'POST', parseResponse: () => {} });\n }\n}\n\n/** @hideconstructor */\nexport class Audio {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Plays a sound.\n * @param config The configuration (sound_id, volume).\n * @returns The play configuration.\n */\n async play(config: PlaybackConfiguration): Promise<PlaybackConfiguration> {\n return this.fetch('/hmi/speaker/play', {\n method: 'POST',\n body: v.parse(playbackConfiguration, config),\n schema: playbackConfiguration,\n });\n }\n}\n\n/** @hideconstructor */\nexport class Knob {\n constructor(private readonly fetch: UpFetch) {}\n\n read_event = () => this.fetch('/hmi/knob/get_knob_event', { schema: internalKnobEvent });\n\n is_button_held = async () => (await this.read_event()).button_held;\n is_knob_turned = async () => Math.abs((await this.read_event()).rotation_delta) >= 4;\n\n /**\n * Waits for a knob event and returns it.\n * @param timeout_ms The timeout in milliseconds.\n * @returns The knob event or null if the timeout was reached.\n */\n async wait_event(timeout_ms?: number): Promise<KnobEvent | null> {\n await this.read_event(); // Discard any previous events\n let delta = 0;\n\n const interval = Math.min(50, (timeout_ms ?? 500) / 10);\n\n const startTime = Date.now();\n while (timeout_ms ? Date.now() - startTime < timeout_ms : true) {\n const knobEvent = await this.read_event();\n delta += knobEvent.rotation_delta;\n\n if (knobEvent.button_pressed || Math.abs(delta) >= 4) {\n return { button_pressed: knobEvent.button_pressed, rotation_delta: Math.sign(delta) };\n }\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n\n return null;\n }\n}\n"],"mappings":"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"}
|
package/build/hmi.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as KnobEvent, c as ProgressValue, i as Knob, l as Screen, n as Color, o as PlaybackConfiguration, r as HmiApi, s as Progress, t as Audio, u as ScreenText } from "./hmi-
|
|
1
|
+
import { a as KnobEvent, c as ProgressValue, i as Knob, l as Screen, n as Color, o as PlaybackConfiguration, r as HmiApi, s as Progress, t as Audio, u as ScreenText } from "./hmi-DkO4bd8B.cjs";
|
|
2
2
|
export { Audio, Color, HmiApi, Knob, KnobEvent, PlaybackConfiguration, Progress, ProgressValue, Screen, ScreenText };
|
package/build/hmi.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as KnobEvent, c as ProgressValue, i as Knob, l as Screen, n as Color, o as PlaybackConfiguration, r as HmiApi, s as Progress, t as Audio, u as ScreenText } from "./hmi-
|
|
1
|
+
import { a as KnobEvent, c as ProgressValue, i as Knob, l as Screen, n as Color, o as PlaybackConfiguration, r as HmiApi, s as Progress, t as Audio, u as ScreenText } from "./hmi-BdkiKYEE.mjs";
|
|
2
2
|
export { Audio, Color, HmiApi, Knob, KnobEvent, PlaybackConfiguration, Progress, ProgressValue, Screen, ScreenText };
|
package/build/hmi.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import*as e from"valibot";const t=e.pipe(e.string(),e.maxLength(1024)),n=e.object({text:t}),r=e.optional(e.pipe(e.string(),e.length(7),e.hexColor())),i=e.object({text:r,progress:r,background:r}),a=e.pipe(e.number(),e.minValue(0),e.maxValue(100)),o=e.object({progress:a}),s=e.object({sound_id:e.picklist([`success`,`warning`,`failure`,`notification_1`,`notification_2`,`imperial_march`]),volume:e.pipe(e.number(),e.minValue(0),e.maxValue(100))}),c=e.object({button_pressed:e.boolean(),button_held:e.boolean(),rotation_delta:e.number()});e.omit(c,[`button_held`]);var l=class{constructor(e){this.fetch=e}reset(){return this.fetch(`/hmi/reset`,{method:`POST`,parseResponse:()=>{}})}screen(){return new u(this.fetch)}audio(){return new d(this.fetch)}knob(){return new f(this.fetch)}},u=class{constructor(e){this.fetch=e}async print(t){return(await this.fetch(`/hmi/screen/text`,{method:`POST`,body:e.parse(n,{text:t}),schema:n})).text}colors(t){return this.fetch(`/hmi/screen/colors`,{method:`PATCH`,body:e.parse(i,t),schema:i})}async progress(t){return t==0?await this.fetch(`/hmi/screen/progress`,{method:`DELETE`,parseResponse:()=>({progress:0})}):this.fetch(`/hmi/screen/progress`,{method:`PUT`,body:e.parse(o,{progress:t}),schema:o})}clear(){return this.fetch(`/hmi/screen/clear`,{method:`POST`,parseResponse:()=>{}})}},d=class{constructor(e){this.fetch=e}async play(t){return this.fetch(`/hmi/speaker/play`,{method:`POST`,body:e.parse(s,t),schema:s})}},f=class{constructor(e){this.fetch=e}
|
|
1
|
+
import*as e from"valibot";const t=e.pipe(e.string(),e.maxLength(1024)),n=e.object({text:t}),r=e.optional(e.pipe(e.string(),e.length(7),e.hexColor())),i=e.object({text:r,progress:r,background:r}),a=e.pipe(e.number(),e.minValue(0),e.maxValue(100)),o=e.object({progress:a}),s=e.object({sound_id:e.picklist([`success`,`warning`,`failure`,`notification_1`,`notification_2`,`imperial_march`]),volume:e.pipe(e.number(),e.minValue(0),e.maxValue(100))}),c=e.object({button_pressed:e.boolean(),button_held:e.boolean(),rotation_delta:e.number()});e.omit(c,[`button_held`]);var l=class{constructor(e){this.fetch=e}reset(){return this.fetch(`/hmi/reset`,{method:`POST`,parseResponse:()=>{}})}screen(){return new u(this.fetch)}audio(){return new d(this.fetch)}knob(){return new f(this.fetch)}},u=class{constructor(e){this.fetch=e}async print(t){return(await this.fetch(`/hmi/screen/text`,{method:`POST`,body:e.parse(n,{text:t}),schema:n})).text}colors(t){return this.fetch(`/hmi/screen/colors`,{method:`PATCH`,body:e.parse(i,t),schema:i})}async progress(t){return t==0?await this.fetch(`/hmi/screen/progress`,{method:`DELETE`,parseResponse:()=>({progress:0})}):this.fetch(`/hmi/screen/progress`,{method:`PUT`,body:e.parse(o,{progress:t}),schema:o})}clear(){return this.fetch(`/hmi/screen/clear`,{method:`POST`,parseResponse:()=>{}})}},d=class{constructor(e){this.fetch=e}async play(t){return this.fetch(`/hmi/speaker/play`,{method:`POST`,body:e.parse(s,t),schema:s})}},f=class{constructor(e){this.fetch=e}read_event=()=>this.fetch(`/hmi/knob/get_knob_event`,{schema:c});is_button_held=async()=>(await this.read_event()).button_held;is_knob_turned=async()=>Math.abs((await this.read_event()).rotation_delta)>=4;async wait_event(e){await this.read_event();let t=0,n=Math.min(50,(e??500)/10),r=Date.now();for(;!e||Date.now()-r<e;){let e=await this.read_event();if(t+=e.rotation_delta,e.button_pressed||Math.abs(t)>=4)return{button_pressed:e.button_pressed,rotation_delta:Math.sign(t)};await new Promise(e=>setTimeout(e,n))}return null}};export{d as Audio,l as HmiApi,f as Knob,u as Screen};
|
|
2
2
|
//# sourceMappingURL=hmi.mjs.map
|
package/build/hmi.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hmi.mjs","names":[],"sources":["../src/api/hmi.ts"],"sourcesContent":["import type { UpFetch } from 'up-fetch';\nimport * as v from 'valibot';\n\nconst screenText = v.pipe(v.string(), v.maxLength(1024));\nexport type ScreenText = v.InferOutput<typeof screenText>;\n\nconst text = v.object({ text: screenText });\ntype Text = v.InferOutput<typeof text>;\n\nconst optionalHexColor = v.optional(v.pipe(v.string(), v.length(7), v.hexColor()));\nconst color = v.object({\n text: optionalHexColor,\n progress: optionalHexColor,\n background: optionalHexColor,\n});\nexport type Color = v.InferOutput<typeof color>;\n\nconst progressValue = v.pipe(v.number(), v.minValue(0), v.maxValue(100));\nexport type ProgressValue = v.InferOutput<typeof progressValue>;\nconst progress = v.object({ progress: progressValue });\nexport type Progress = v.InferOutput<typeof progress>;\n\nconst playbackConfiguration = v.object({\n sound_id: v.picklist(\n ['success', 'warning', 'failure', 'notification_1', 'notification_2',\n 'imperial_march'] as const,\n ),\n volume: v.pipe(v.number(), v.minValue(0), v.maxValue(100)),\n});\nexport type PlaybackConfiguration = v.InferOutput<typeof playbackConfiguration>;\n\nconst internalKnobEvent = v.object({\n button_pressed: v.boolean(),\n button_held: v.boolean(),\n rotation_delta: v.number(),\n});\nconst knobEvent = v.omit(internalKnobEvent, ['button_held']);\nexport type KnobEvent = v.InferOutput<typeof knobEvent>;\n\n/** @hideconstructor */\nexport class HmiApi {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Resets the HMI.\n */\n reset(): Promise<void> {\n return this.fetch('/hmi/reset', { method: 'POST', parseResponse: () => {} });\n }\n\n /**\n * Access the screen API.\n * @returns The screen instance.\n */\n screen(): Screen {\n return new Screen(this.fetch);\n }\n\n /**\n * Access the audio API.\n * @returns The audio instance.\n */\n audio(): Audio {\n return new Audio(this.fetch);\n }\n\n /**\n * Access the knob API.\n * @returns The knob instance.\n */\n knob(): Knob {\n return new Knob(this.fetch);\n }\n}\n\n/** @hideconstructor */\nexport class Screen {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Prints text to the screen.\n * @param data The text to print.\n * @returns The printed text.\n */\n async print(data: ScreenText): Promise<string> {\n return (await this.fetch('/hmi/screen/text', {\n method: 'POST',\n body: v.parse(text, { text: data } satisfies Text),\n schema: text,\n }))\n .text;\n }\n\n /**\n * Sets the screen colors.\n * @param colors The colors to set.\n * @returns The updated colors.\n */\n colors(colors: Color): Promise<Color> {\n return this.fetch('/hmi/screen/colors', {\n method: 'PATCH',\n body: v.parse(color, colors satisfies Color),\n schema: color,\n });\n }\n\n /**\n * Sets the screen progress.\n * @param data The progress value to set.\n * @returns The updated progress.\n */\n async progress(data: ProgressValue): Promise<Progress> {\n if (data == 0) {\n return await this.fetch('/hmi/screen/progress', {\n method: 'DELETE',\n parseResponse: () => ({ progress: 0 }),\n });\n }\n\n return this.fetch('/hmi/screen/progress', {\n method: 'PUT',\n body: v.parse(progress, { progress: data } satisfies Progress),\n schema: progress,\n });\n }\n\n /**\n * Clears the screen.\n */\n clear(): Promise<void> {\n return this.fetch('/hmi/screen/clear', { method: 'POST', parseResponse: () => {} });\n }\n}\n\n/** @hideconstructor */\nexport class Audio {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Plays a sound.\n * @param config The configuration (sound_id, volume).\n * @returns The play configuration.\n */\n async play(config: PlaybackConfiguration): Promise<PlaybackConfiguration> {\n return this.fetch('/hmi/speaker/play', {\n method: 'POST',\n body: v.parse(playbackConfiguration, config),\n schema: playbackConfiguration,\n });\n }\n}\n\n/** @hideconstructor */\nexport class Knob {\n constructor(private readonly fetch: UpFetch) {}\n\n
|
|
1
|
+
{"version":3,"file":"hmi.mjs","names":[],"sources":["../src/api/hmi.ts"],"sourcesContent":["import type { UpFetch } from 'up-fetch';\nimport * as v from 'valibot';\n\nconst screenText = v.pipe(v.string(), v.maxLength(1024));\nexport type ScreenText = v.InferOutput<typeof screenText>;\n\nconst text = v.object({ text: screenText });\ntype Text = v.InferOutput<typeof text>;\n\nconst optionalHexColor = v.optional(v.pipe(v.string(), v.length(7), v.hexColor()));\nconst color = v.object({\n text: optionalHexColor,\n progress: optionalHexColor,\n background: optionalHexColor,\n});\nexport type Color = v.InferOutput<typeof color>;\n\nconst progressValue = v.pipe(v.number(), v.minValue(0), v.maxValue(100));\nexport type ProgressValue = v.InferOutput<typeof progressValue>;\nconst progress = v.object({ progress: progressValue });\nexport type Progress = v.InferOutput<typeof progress>;\n\nconst playbackConfiguration = v.object({\n sound_id: v.picklist(\n ['success', 'warning', 'failure', 'notification_1', 'notification_2',\n 'imperial_march'] as const,\n ),\n volume: v.pipe(v.number(), v.minValue(0), v.maxValue(100)),\n});\nexport type PlaybackConfiguration = v.InferOutput<typeof playbackConfiguration>;\n\nconst internalKnobEvent = v.object({\n button_pressed: v.boolean(),\n button_held: v.boolean(),\n rotation_delta: v.number(),\n});\nconst knobEvent = v.omit(internalKnobEvent, ['button_held']);\nexport type KnobEvent = v.InferOutput<typeof knobEvent>;\n\n/** @hideconstructor */\nexport class HmiApi {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Resets the HMI.\n */\n reset(): Promise<void> {\n return this.fetch('/hmi/reset', { method: 'POST', parseResponse: () => {} });\n }\n\n /**\n * Access the screen API.\n * @returns The screen instance.\n */\n screen(): Screen {\n return new Screen(this.fetch);\n }\n\n /**\n * Access the audio API.\n * @returns The audio instance.\n */\n audio(): Audio {\n return new Audio(this.fetch);\n }\n\n /**\n * Access the knob API.\n * @returns The knob instance.\n */\n knob(): Knob {\n return new Knob(this.fetch);\n }\n}\n\n/** @hideconstructor */\nexport class Screen {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Prints text to the screen.\n * @param data The text to print.\n * @returns The printed text.\n */\n async print(data: ScreenText): Promise<string> {\n return (await this.fetch('/hmi/screen/text', {\n method: 'POST',\n body: v.parse(text, { text: data } satisfies Text),\n schema: text,\n }))\n .text;\n }\n\n /**\n * Sets the screen colors.\n * @param colors The colors to set.\n * @returns The updated colors.\n */\n colors(colors: Color): Promise<Color> {\n return this.fetch('/hmi/screen/colors', {\n method: 'PATCH',\n body: v.parse(color, colors satisfies Color),\n schema: color,\n });\n }\n\n /**\n * Sets the screen progress.\n * @param data The progress value to set.\n * @returns The updated progress.\n */\n async progress(data: ProgressValue): Promise<Progress> {\n if (data == 0) {\n return await this.fetch('/hmi/screen/progress', {\n method: 'DELETE',\n parseResponse: () => ({ progress: 0 }),\n });\n }\n\n return this.fetch('/hmi/screen/progress', {\n method: 'PUT',\n body: v.parse(progress, { progress: data } satisfies Progress),\n schema: progress,\n });\n }\n\n /**\n * Clears the screen.\n */\n clear(): Promise<void> {\n return this.fetch('/hmi/screen/clear', { method: 'POST', parseResponse: () => {} });\n }\n}\n\n/** @hideconstructor */\nexport class Audio {\n constructor(private readonly fetch: UpFetch) {}\n\n /**\n * Plays a sound.\n * @param config The configuration (sound_id, volume).\n * @returns The play configuration.\n */\n async play(config: PlaybackConfiguration): Promise<PlaybackConfiguration> {\n return this.fetch('/hmi/speaker/play', {\n method: 'POST',\n body: v.parse(playbackConfiguration, config),\n schema: playbackConfiguration,\n });\n }\n}\n\n/** @hideconstructor */\nexport class Knob {\n constructor(private readonly fetch: UpFetch) {}\n\n read_event = () => this.fetch('/hmi/knob/get_knob_event', { schema: internalKnobEvent });\n\n is_button_held = async () => (await this.read_event()).button_held;\n is_knob_turned = async () => Math.abs((await this.read_event()).rotation_delta) >= 4;\n\n /**\n * Waits for a knob event and returns it.\n * @param timeout_ms The timeout in milliseconds.\n * @returns The knob event or null if the timeout was reached.\n */\n async wait_event(timeout_ms?: number): Promise<KnobEvent | null> {\n await this.read_event(); // Discard any previous events\n let delta = 0;\n\n const interval = Math.min(50, (timeout_ms ?? 500) / 10);\n\n const startTime = Date.now();\n while (timeout_ms ? Date.now() - startTime < timeout_ms : true) {\n const knobEvent = await this.read_event();\n delta += knobEvent.rotation_delta;\n\n if (knobEvent.button_pressed || Math.abs(delta) >= 4) {\n return { button_pressed: knobEvent.button_pressed, rotation_delta: Math.sign(delta) };\n }\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n\n return null;\n }\n}\n"],"mappings":"0BAGA,MAAM,EAAa,EAAE,KAAK,EAAE,QAAQ,CAAE,EAAE,UAAU,KAAK,CAAC,CAGlD,EAAO,EAAE,OAAO,CAAE,KAAM,EAAY,CAAC,CAGrC,EAAmB,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAE,EAAE,OAAO,EAAE,CAAE,EAAE,UAAU,CAAC,CAAC,CAC5E,EAAQ,EAAE,OAAO,CACrB,KAAM,EACN,SAAU,EACV,WAAY,EACb,CAAC,CAGI,EAAgB,EAAE,KAAK,EAAE,QAAQ,CAAE,EAAE,SAAS,EAAE,CAAE,EAAE,SAAS,IAAI,CAAC,CAElE,EAAW,EAAE,OAAO,CAAE,SAAU,EAAe,CAAC,CAGhD,EAAwB,EAAE,OAAO,CACrC,SAAU,EAAE,SACV,CAAC,UAAW,UAAW,UAAW,iBAAkB,iBAClD,iBAAiB,CACpB,CACD,OAAQ,EAAE,KAAK,EAAE,QAAQ,CAAE,EAAE,SAAS,EAAE,CAAE,EAAE,SAAS,IAAI,CAAC,CAC3D,CAAC,CAGI,EAAoB,EAAE,OAAO,CACjC,eAAgB,EAAE,SAAS,CAC3B,YAAa,EAAE,SAAS,CACxB,eAAgB,EAAE,QAAQ,CAC3B,CAAC,CACgB,EAAE,KAAK,EAAmB,CAAC,cAAc,CAAC,CAI5D,IAAa,EAAb,KAAoB,CAClB,YAAY,EAAiC,CAAhB,KAAA,MAAA,EAK7B,OAAuB,CACrB,OAAO,KAAK,MAAM,aAAc,CAAE,OAAQ,OAAQ,kBAAqB,GAAI,CAAC,CAO9E,QAAiB,CACf,OAAO,IAAI,EAAO,KAAK,MAAM,CAO/B,OAAe,CACb,OAAO,IAAI,EAAM,KAAK,MAAM,CAO9B,MAAa,CACX,OAAO,IAAI,EAAK,KAAK,MAAM,GAKlB,EAAb,KAAoB,CAClB,YAAY,EAAiC,CAAhB,KAAA,MAAA,EAO7B,MAAM,MAAM,EAAmC,CAC7C,OAAQ,MAAM,KAAK,MAAM,mBAAoB,CAC3C,OAAQ,OACR,KAAM,EAAE,MAAM,EAAM,CAAE,KAAM,EAAM,CAAgB,CAClD,OAAQ,EACT,CAAC,EACC,KAQL,OAAO,EAA+B,CACpC,OAAO,KAAK,MAAM,qBAAsB,CACtC,OAAQ,QACR,KAAM,EAAE,MAAM,EAAO,EAAuB,CAC5C,OAAQ,EACT,CAAC,CAQJ,MAAM,SAAS,EAAwC,CAQrD,OAPI,GAAQ,EACH,MAAM,KAAK,MAAM,uBAAwB,CAC9C,OAAQ,SACR,mBAAsB,CAAE,SAAU,EAAG,EACtC,CAAC,CAGG,KAAK,MAAM,uBAAwB,CACxC,OAAQ,MACR,KAAM,EAAE,MAAM,EAAU,CAAE,SAAU,EAAM,CAAoB,CAC9D,OAAQ,EACT,CAAC,CAMJ,OAAuB,CACrB,OAAO,KAAK,MAAM,oBAAqB,CAAE,OAAQ,OAAQ,kBAAqB,GAAI,CAAC,GAK1E,EAAb,KAAmB,CACjB,YAAY,EAAiC,CAAhB,KAAA,MAAA,EAO7B,MAAM,KAAK,EAA+D,CACxE,OAAO,KAAK,MAAM,oBAAqB,CACrC,OAAQ,OACR,KAAM,EAAE,MAAM,EAAuB,EAAO,CAC5C,OAAQ,EACT,CAAC,GAKO,EAAb,KAAkB,CAChB,YAAY,EAAiC,CAAhB,KAAA,MAAA,EAE7B,eAAmB,KAAK,MAAM,2BAA4B,CAAE,OAAQ,EAAmB,CAAC,CAExF,eAAiB,UAAa,MAAM,KAAK,YAAY,EAAE,YACvD,eAAiB,SAAY,KAAK,KAAK,MAAM,KAAK,YAAY,EAAE,eAAe,EAAI,EAOnF,MAAM,WAAW,EAAgD,CAC/D,MAAM,KAAK,YAAY,CACvB,IAAI,EAAQ,EAEN,EAAW,KAAK,IAAI,IAAK,GAAc,KAAO,GAAG,CAEjD,EAAY,KAAK,KAAK,CAC5B,KAAO,IAAa,KAAK,KAAK,CAAG,EAAY,GAAmB,CAC9D,IAAM,EAAY,MAAM,KAAK,YAAY,CAGzC,GAFA,GAAS,EAAU,eAEf,EAAU,gBAAkB,KAAK,IAAI,EAAM,EAAI,EACjD,MAAO,CAAE,eAAgB,EAAU,eAAgB,eAAgB,KAAK,KAAK,EAAM,CAAE,CAEvF,MAAM,IAAI,QAAS,GAAY,WAAW,EAAS,EAAS,CAAC,CAG/D,OAAO"}
|
package/build/node.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./at1000-Drc2Gwwh.cjs`);require(`./common-PXzrB8CC.cjs`);let n=require(`dns-packet`);n=e.t(n);let r=require(`node:events`),i=require(`node:util`);i=e.t(i);let a=require(`ip-address`);a=e.t(a);let o=require(`node:os`);o=e.t(o);let s=require(`node:dgram`);s=e.t(s);const c=`224.0.0.251`,l=`FF02::FB`,u=5353,d=`IPv4`,f=`IPv6`,p=[d,4,f,6];var m=class e{static getInterfaces(t){return t?e.getInterfacesFromStrings(t):e.getAllInterfaces()}static getAllInterfaces(){let e=[],t=[],n=o.default.networkInterfaces();for(let[r,i]of Object.entries(n))t.includes(r)||(t.push(r),i?.forEach(t=>{t.internal||!p.includes(t.family)||/^(2002|2001):/gi.exec(t.address)||e.push({name:r,address:t.address,family:t.family,scopeid:t.scopeid})}));if(!e.length)throw Error(`No usable network interfaces returned by OS.`);return e}static getInterfacesFromStrings(t){let n=Array.isArray(t)?t:[t],r=this.getAllInterfaces().filter(t=>n.reduce((n,r)=>n||!!(e.stringMatchesAddress(r,t.address)||t.name===r),!1));if(!r||!r.length)throw Error(`No usable network interfaces returned by OS.`);return r}static stringMatchesAddress(e,t){let n,r;try{n=new a.default.Address4(e),r=new a.default.Address4(t)}catch{try{n=new a.default.Address6(e),r=new a.default.Address6(t)}catch{return!1}}return n.bigInt()===r.bigInt()}};const h={interfaces:[],reuseAddr:!0,ttl:255,loopback:!0,onMessage:(e,t)=>{console.log(`Message `+e.toString())},socketError:e=>{console.log(`Socket error `+e.message)}};var g=class e{static validateSettings(e){if(!e.multicastAddress)throw Error(`Socket settings require multicastAddress`);if(!e.multicastPort)throw Error(`Socket settings require multicastPort`)}static createMulticastSocket(t){return new Promise((n,r)=>{let i=Object.assign({},h,t);e.validateSettings(i);let o=s.default.createSocket({type:a.default.Address4.isValid(i.multicastAddress)?`udp4`:`udp6`,reuseAddr:i.reuseAddr}),c=!1;o.on(`error`,e=>{c?i.socketError(e):(o.close(),n({success:!1,error:e}))}).on(`listening`,()=>{c=!0,o.setMulticastTTL(i.ttl??255),o.setMulticastLoopback(i.loopback??!0);let t=e.addMulticastMemberships(o,i);if(!t.memberships.length){c=!1,o.close(),n({success:!1,error:Error(`No interface memberships for multicast address `+i.multicastAddress)});return}n(Object.assign({success:!0},t,{socket:o}))}).on(`message`,(e,t)=>{i.onMessage(e,t)}),o.bind({port:i.multicastPort,exclusive:!1})})}static addMulticastMemberships(t,n){let r=[],i=[],o=a.default.Address4.isValid(n.multicastAddress)?[d,4]:[f,6];return n.interfaces.forEach(a=>{if(o.includes(a.family))try{t.addMembership(n.multicastAddress,e.interfaceAddress(a)),r.push(a)}catch{i.push(a)}}),{memberships:r,failedMemberships:i}}static async createSendSocket(t,n,r,i){return new Promise((a,o)=>{let c=s.default.createSocket({type:[`IPv4`,4].includes(t.family)?`udp4`:`udp6`,reuseAddr:!!n.reuseAddr}),l=!1;c.on(`error`,e=>{l?i(e):(c.close(),a({success:!1,error:Error(e.message)}))}).on(`listening`,()=>{l=!0,a({success:!0,iface:t,socket:c,send:c.send.bind(c)})}).on(`message`,(e,n)=>{n.interface=t.name,r(e,n)}).bind(n.srcPort||0,e.interfaceAddress(t))})}static interfaceAddress(e){return[`IPv4`,4].includes(e.family)?e.address:e.scopeid?`${e.address}%${e.scopeid}`:e.address}};const _={reuseAddr:!0,srcPort:0,interfaces:null,ttl:255,loopback:!0,debug:!1};var v=class extends r.EventEmitter{Config;ready;receiveSockets;sendSockets;interfaces;destroyed;constructor(e){super(),this.Config=Object.assign({},_,e),this.ready=!1,this.receiveSockets=[],this.sendSockets=[]}async init(){try{this.interfaces=m.getInterfaces(this.Config.interfaces||void 0)}catch(e){throw this.emitError(e),e}return this.emitDebug(`Scanner interfaces: ${i.default.inspect(this.interfaces)}`),await this.createReceiveSockets(),await this.createSendSockets(),this.receiveSockets.length&&this.sendSockets.length&&(this.ready=!0),this.ready}async createReceiveSockets(){if(!this.interfaces)return[];let e=this.interfaces.filter(e=>[d,4].includes(e.family)),t=this.interfaces.filter(e=>[f,6].includes(e.family));if(this.emitDebug(`Create receive sockets for${e.length?` `+d:``}${e.length&&t.length?` and`:``}${t.length?` `+f:``}`),e.length){let t=await g.createMulticastSocket({multicastAddress:c,multicastPort:u,interfaces:e,onMessage:this.onMessage.bind(this),socketError:this.socketError.bind(this)});t.success?this.receiveSockets.push(t):t.error&&this.emitError(t.error.message)}if(t.length){let e=await g.createMulticastSocket({multicastAddress:l,multicastPort:u,interfaces:t,onMessage:this.onMessage.bind(this),socketError:this.socketError.bind(this)});e.success?this.receiveSockets.push(e):e.error&&this.emitError(e.error.message)}return this.receiveSockets}async createSendSockets(){if(this.interfaces){this.emitDebug(`Create send sockets on ${this.interfaces.length} interfaces/addresses.`);for(let e=0;e<this.interfaces.length;e++){let t=await g.createSendSocket(this.interfaces[e],this.Config,this.onMessage.bind(this),this.socketError.bind(this));t.success?this.sendSockets.push(t):t.error&&this.emitError(t.error.message)}}}onMessage(e,t){let r;try{r=n.default.decode(e)}catch(e){return this.emitWarn(e)}this.emit(`packet`,r,t)}socketError(e){e.code===`EACCES`||e.code===`EADDRINUSE`||e.code===`EADDRNOTAVAIL`?this.emitError(e):this.emitWarn(e)}query(e,t){let n;if(typeof e==`string`)n=[{name:e,type:t||`ANY`}];else if(Array.isArray(e))n=e;else throw Error(`Query questions must be an array of mDNS query questions.`);let r={type:`query`,questions:n};this.emitDebug(`Send mDNS query: ${i.default.inspect(r)}`),this.send(r)}send(e){if(this.destroyed)return;let t=n.default.encode(e);for(let e=0;e<this.sendSockets.length;e++){let n=this.sendSockets[e];if(n.send&&n.iface)try{n.send(t,0,t.length,u,[`IPv4`,4].includes(n.iface.family)?c:l+`%`+n.iface.name),this.emitDebug(`Send packet on ${n.iface.address}`)}catch{}}}destroy(){this.destroyed=!0,this.ready=!1,this.removeAllListeners(),this.sendSockets.forEach(e=>{try{e.socket?.close()}catch{}}),this.sendSockets=[],this.receiveSockets.forEach(e=>{try{e.socket?.close()}catch{}}),this.receiveSockets=[]}emitError(e){this.emit(`error`,e)}emitWarn(e){this.emit(`warn`,e)}emitDebug(e){this.Config.debug&&this.emit(`debug`,e)}};const y={debug:!1};var b=class extends r.EventEmitter{Config;scanner;types;namedServices;packetListener;constructor(e,t){super(),this.packetListener=this.onPacket.bind(this),this.scanner=e,this.Config=Object.assign({},y,t),this.types=[],this.namedServices={},this.forwardEvents(this.scanner),this.reset()}reset(){this.removeMDNSListener(this.scanner),this.types=[],this.namedServices={},this.listenMDNSEvents(this.scanner)}forwardEvents(e){e.on(`error`,e=>{this.emitError(e)}).on(`warn`,e=>{this.emitWarn(e)}).on(`debug`,e=>{this.emitDebug(e)})}listenMDNSEvents(e){e.on(`packet`,this.packetListener)}removeMDNSListener(e){e.removeListener(`packet`,this.packetListener)}onPacket(e,t){switch(this.emitDebug(`Received packet type ${e.type} from ${t.address}.`),e.type){case`query`:this.emit(`query`,e,t);break;case`response`:this.emitDebug(`Received response packet from ${t.address} with ${e.answers?e.answers.length:0} answers and ${e.additionals?e.additionals.length:0} additionals.`),e.answers&&this.processAnswers(e.answers,t),e.additionals&&this.processAnswers(e.additionals,t);break}}processAnswers(e,t){this.emitDebug(`Processing answers or additionals...`);let n=this.processSRVAnswers(e);this.processTXTAnswers(e),this.processAAnswers(e),this.processAAAAAnswers(e),this.processPTRAnswers(e,t),n.forEach(e=>{this.emit(`discovered`,{type:`service`,data:this.namedServices[e]})})}processSRVAnswers(e){let t=[];return e.forEach(e=>{if(e.type!==`SRV`)return;this.emitDebug(`Processing SRV answer.`);let n=e.name.toString();t.includes(n)||t.push(n),this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].service=e,this.namedServices[n].host=e.data.target.toString(),this.namedServices[n].port=e.data.port}),t}processTXTAnswers(e){e.forEach(e=>{if(e.type!==`TXT`)return;this.emitDebug(`Processing TXT answer.`);let t=e.data;if(Array.isArray(t)&&t.length>1){let n=e.name.toString();this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].txt=this.answerDataToKeyValues(Buffer.concat(t))}else if(Buffer.isBuffer(t)){let n=e.name.toString();this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].txt=this.answerDataToKeyValues(t)}})}processAAnswers(e){e.forEach(e=>{if(e.type!==`A`)return;this.emitDebug(`Processing A answer.`);let t=e.name.toString(),n=e.data.toString();for(let e in this.namedServices)this.namedServices[e].host===t&&(this.namedServices[e].addresses=this.namedServices[e].addresses||[],this.namedServices[e].addresses.reduce((e,t)=>e||t.address===n,!1)||this.namedServices[e].addresses.push({family:d,address:n}))})}processAAAAAnswers(e){e.forEach(e=>{if(e.type!==`AAAA`)return;this.emitDebug(`Processing AAAA answer.`);let t=e.name.toString(),n=e.data.toString();for(let e in this.namedServices)this.namedServices[e].host===t&&(this.namedServices[e].addresses=this.namedServices[e].addresses||[],this.namedServices[e].addresses.reduce((e,t)=>e||t.address===n,!1)||this.namedServices[e].addresses.push({family:f,address:n}))})}processPTRAnswers(e,t){e.forEach(e=>{if(e.type!==`PTR`)return;this.emitDebug(`Processing PTR answer.`);let n=this.serviceTypeFromPTR(e),r=e.data.toString();n!==r&&(this.namedServices[r]=this.namedServices[r]||{},this.namedServices[r].name=r.replace(`.`+n,``),this.namedServices[r].rinfo=t)})}serviceTypeFromPTR(e){let t=e.data,n=/(?:^|^.+?(?:\.))(_.*)$/gm.exec(t.toString()),r=n?n[1]:t.toString();return this.types.includes(r)||(this.types.push(r),this.emit(`discovered`,{type:`type`,data:r}),this.emitDebug(`Scanning service type ${r}.`),this.scanner.query(r,`ANY`)),r}answerDataToKeyValues(e){let t=[],n={},r=0,i=e[r];for(;i;){let a=e.slice(r+1,r+1+i);t.push(a.toString());let o=/^([^=]+)=([^=]*)$/.exec(a.toString());o&&(n[o[1]]=o[2]),r=r+1+i,i=e[r]}return{strings:t,keyValuePairs:n}}emitError(e){this.emit(`error`,e)}emitWarn(e){this.emit(`warn`,e)}emitDebug(e){this.Config.debug&&this.emit(`debug`,e)}};const x=async(e=500)=>{e<10&&(e=10);let n=new v({debug:!0}),r=new b(n);if(r.on(`error`,e=>{if(!e.includes(`bind ENOENT`))throw Error(e)}),!await n.init())throw Error(`Failed to initialize mDNS scanner`);n.query(`_at1000_server._tcp.local`),await new Promise(t=>setTimeout(t,e));let i=[...new Set(Object.values(r.namedServices).filter(e=>e!==void 0&&e.service!==void 0).filter(e=>e.service.name.endsWith(`_at1000_server._tcp.local`)).map(e=>e.addresses.filter(e=>e.family==`IPv4`).pop()?.address).filter(e=>e!==void 0))];return n.destroy(),(await Promise.allSettled(i.map(e=>t.t.create(e)))).filter(e=>e.status===`fulfilled`).map(e=>e.value)};var S=class extends t.t{static apiVersion=t.n;static findDevices(e=500){return x(e)}};exports.AT1000=S;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./at1000-Buk_qSPK.cjs`);require(`./common-PXzrB8CC.cjs`);let n=require(`dns-packet`);n=e.t(n);let r=require(`node:events`),i=require(`node:util`);i=e.t(i);let a=require(`ip-address`);a=e.t(a);let o=require(`node:os`);o=e.t(o);let s=require(`node:dgram`);s=e.t(s);const c=`224.0.0.251`,l=`FF02::FB`,u=5353,d=`IPv4`,f=`IPv6`,p=[d,4,f,6];var m=class e{static getInterfaces(t){return t?e.getInterfacesFromStrings(t):e.getAllInterfaces()}static getAllInterfaces(){let e=[],t=[],n=o.default.networkInterfaces();for(let[r,i]of Object.entries(n))t.includes(r)||(t.push(r),i?.forEach(t=>{t.internal||!p.includes(t.family)||/^(2002|2001):/gi.exec(t.address)||e.push({name:r,address:t.address,family:t.family,scopeid:t.scopeid})}));if(!e.length)throw Error(`No usable network interfaces returned by OS.`);return e}static getInterfacesFromStrings(t){let n=Array.isArray(t)?t:[t],r=this.getAllInterfaces().filter(t=>n.reduce((n,r)=>n||!!(e.stringMatchesAddress(r,t.address)||t.name===r),!1));if(!r||!r.length)throw Error(`No usable network interfaces returned by OS.`);return r}static stringMatchesAddress(e,t){let n,r;try{n=new a.default.Address4(e),r=new a.default.Address4(t)}catch{try{n=new a.default.Address6(e),r=new a.default.Address6(t)}catch{return!1}}return n.bigInt()===r.bigInt()}};const h={interfaces:[],reuseAddr:!0,ttl:255,loopback:!0,onMessage:(e,t)=>{console.log(`Message `+e.toString())},socketError:e=>{console.log(`Socket error `+e.message)}};var g=class e{static validateSettings(e){if(!e.multicastAddress)throw Error(`Socket settings require multicastAddress`);if(!e.multicastPort)throw Error(`Socket settings require multicastPort`)}static createMulticastSocket(t){return new Promise((n,r)=>{let i=Object.assign({},h,t);e.validateSettings(i);let o=s.default.createSocket({type:a.default.Address4.isValid(i.multicastAddress)?`udp4`:`udp6`,reuseAddr:i.reuseAddr}),c=!1;o.on(`error`,e=>{c?i.socketError(e):(o.close(),n({success:!1,error:e}))}).on(`listening`,()=>{c=!0,o.setMulticastTTL(i.ttl??255),o.setMulticastLoopback(i.loopback??!0);let t=e.addMulticastMemberships(o,i);if(!t.memberships.length){c=!1,o.close(),n({success:!1,error:Error(`No interface memberships for multicast address `+i.multicastAddress)});return}n(Object.assign({success:!0},t,{socket:o}))}).on(`message`,(e,t)=>{i.onMessage(e,t)}),o.bind({port:i.multicastPort,exclusive:!1})})}static addMulticastMemberships(t,n){let r=[],i=[],o=a.default.Address4.isValid(n.multicastAddress)?[d,4]:[f,6];return n.interfaces.forEach(a=>{if(o.includes(a.family))try{t.addMembership(n.multicastAddress,e.interfaceAddress(a)),r.push(a)}catch{i.push(a)}}),{memberships:r,failedMemberships:i}}static async createSendSocket(t,n,r,i){return new Promise((a,o)=>{let c=s.default.createSocket({type:[`IPv4`,4].includes(t.family)?`udp4`:`udp6`,reuseAddr:!!n.reuseAddr}),l=!1;c.on(`error`,e=>{l?i(e):(c.close(),a({success:!1,error:Error(e.message)}))}).on(`listening`,()=>{l=!0,a({success:!0,iface:t,socket:c,send:c.send.bind(c)})}).on(`message`,(e,n)=>{n.interface=t.name,r(e,n)}).bind(n.srcPort||0,e.interfaceAddress(t))})}static interfaceAddress(e){return[`IPv4`,4].includes(e.family)?e.address:e.scopeid?`${e.address}%${e.scopeid}`:e.address}};const _={reuseAddr:!0,srcPort:0,interfaces:null,ttl:255,loopback:!0,debug:!1};var v=class extends r.EventEmitter{Config;ready;receiveSockets;sendSockets;interfaces;destroyed;constructor(e){super(),this.Config=Object.assign({},_,e),this.ready=!1,this.receiveSockets=[],this.sendSockets=[]}async init(){try{this.interfaces=m.getInterfaces(this.Config.interfaces||void 0)}catch(e){throw this.emitError(e),e}return this.emitDebug(`Scanner interfaces: ${i.default.inspect(this.interfaces)}`),await this.createReceiveSockets(),await this.createSendSockets(),this.receiveSockets.length&&this.sendSockets.length&&(this.ready=!0),this.ready}async createReceiveSockets(){if(!this.interfaces)return[];let e=this.interfaces.filter(e=>[d,4].includes(e.family)),t=this.interfaces.filter(e=>[f,6].includes(e.family));if(this.emitDebug(`Create receive sockets for${e.length?` `+d:``}${e.length&&t.length?` and`:``}${t.length?` `+f:``}`),e.length){let t=await g.createMulticastSocket({multicastAddress:c,multicastPort:u,interfaces:e,onMessage:this.onMessage.bind(this),socketError:this.socketError.bind(this)});t.success?this.receiveSockets.push(t):t.error&&this.emitError(t.error.message)}if(t.length){let e=await g.createMulticastSocket({multicastAddress:l,multicastPort:u,interfaces:t,onMessage:this.onMessage.bind(this),socketError:this.socketError.bind(this)});e.success?this.receiveSockets.push(e):e.error&&this.emitError(e.error.message)}return this.receiveSockets}async createSendSockets(){if(this.interfaces){this.emitDebug(`Create send sockets on ${this.interfaces.length} interfaces/addresses.`);for(let e=0;e<this.interfaces.length;e++){let t=await g.createSendSocket(this.interfaces[e],this.Config,this.onMessage.bind(this),this.socketError.bind(this));t.success?this.sendSockets.push(t):t.error&&this.emitError(t.error.message)}}}onMessage(e,t){let r;try{r=n.default.decode(e)}catch(e){return this.emitWarn(e)}this.emit(`packet`,r,t)}socketError(e){e.code===`EACCES`||e.code===`EADDRINUSE`||e.code===`EADDRNOTAVAIL`?this.emitError(e):this.emitWarn(e)}query(e,t){let n;if(typeof e==`string`)n=[{name:e,type:t||`ANY`}];else if(Array.isArray(e))n=e;else throw Error(`Query questions must be an array of mDNS query questions.`);let r={type:`query`,questions:n};this.emitDebug(`Send mDNS query: ${i.default.inspect(r)}`),this.send(r)}send(e){if(this.destroyed)return;let t=n.default.encode(e);for(let e=0;e<this.sendSockets.length;e++){let n=this.sendSockets[e];if(n.send&&n.iface)try{n.send(t,0,t.length,u,[`IPv4`,4].includes(n.iface.family)?c:l+`%`+n.iface.name),this.emitDebug(`Send packet on ${n.iface.address}`)}catch{}}}destroy(){this.destroyed=!0,this.ready=!1,this.removeAllListeners(),this.sendSockets.forEach(e=>{try{e.socket?.close()}catch{}}),this.sendSockets=[],this.receiveSockets.forEach(e=>{try{e.socket?.close()}catch{}}),this.receiveSockets=[]}emitError(e){this.emit(`error`,e)}emitWarn(e){this.emit(`warn`,e)}emitDebug(e){this.Config.debug&&this.emit(`debug`,e)}};const y={debug:!1};var b=class extends r.EventEmitter{Config;scanner;types;namedServices;packetListener;constructor(e,t){super(),this.packetListener=this.onPacket.bind(this),this.scanner=e,this.Config=Object.assign({},y,t),this.types=[],this.namedServices={},this.forwardEvents(this.scanner),this.reset()}reset(){this.removeMDNSListener(this.scanner),this.types=[],this.namedServices={},this.listenMDNSEvents(this.scanner)}forwardEvents(e){e.on(`error`,e=>{this.emitError(e)}).on(`warn`,e=>{this.emitWarn(e)}).on(`debug`,e=>{this.emitDebug(e)})}listenMDNSEvents(e){e.on(`packet`,this.packetListener)}removeMDNSListener(e){e.removeListener(`packet`,this.packetListener)}onPacket(e,t){switch(this.emitDebug(`Received packet type ${e.type} from ${t.address}.`),e.type){case`query`:this.emit(`query`,e,t);break;case`response`:this.emitDebug(`Received response packet from ${t.address} with ${e.answers?e.answers.length:0} answers and ${e.additionals?e.additionals.length:0} additionals.`),e.answers&&this.processAnswers(e.answers,t),e.additionals&&this.processAnswers(e.additionals,t);break}}processAnswers(e,t){this.emitDebug(`Processing answers or additionals...`);let n=this.processSRVAnswers(e);this.processTXTAnswers(e),this.processAAnswers(e),this.processAAAAAnswers(e),this.processPTRAnswers(e,t),n.forEach(e=>{this.emit(`discovered`,{type:`service`,data:this.namedServices[e]})})}processSRVAnswers(e){let t=[];return e.forEach(e=>{if(e.type!==`SRV`)return;this.emitDebug(`Processing SRV answer.`);let n=e.name.toString();t.includes(n)||t.push(n),this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].service=e,this.namedServices[n].host=e.data.target.toString(),this.namedServices[n].port=e.data.port}),t}processTXTAnswers(e){e.forEach(e=>{if(e.type!==`TXT`)return;this.emitDebug(`Processing TXT answer.`);let t=e.data;if(Array.isArray(t)&&t.length>1){let n=e.name.toString();this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].txt=this.answerDataToKeyValues(Buffer.concat(t))}else if(Buffer.isBuffer(t)){let n=e.name.toString();this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].txt=this.answerDataToKeyValues(t)}})}processAAnswers(e){e.forEach(e=>{if(e.type!==`A`)return;this.emitDebug(`Processing A answer.`);let t=e.name.toString(),n=e.data.toString();for(let e in this.namedServices)this.namedServices[e].host===t&&(this.namedServices[e].addresses=this.namedServices[e].addresses||[],this.namedServices[e].addresses.reduce((e,t)=>e||t.address===n,!1)||this.namedServices[e].addresses.push({family:d,address:n}))})}processAAAAAnswers(e){e.forEach(e=>{if(e.type!==`AAAA`)return;this.emitDebug(`Processing AAAA answer.`);let t=e.name.toString(),n=e.data.toString();for(let e in this.namedServices)this.namedServices[e].host===t&&(this.namedServices[e].addresses=this.namedServices[e].addresses||[],this.namedServices[e].addresses.reduce((e,t)=>e||t.address===n,!1)||this.namedServices[e].addresses.push({family:f,address:n}))})}processPTRAnswers(e,t){e.forEach(e=>{if(e.type!==`PTR`)return;this.emitDebug(`Processing PTR answer.`);let n=this.serviceTypeFromPTR(e),r=e.data.toString();n!==r&&(this.namedServices[r]=this.namedServices[r]||{},this.namedServices[r].name=r.replace(`.`+n,``),this.namedServices[r].rinfo=t)})}serviceTypeFromPTR(e){let t=e.data,n=/(?:^|^.+?(?:\.))(_.*)$/gm.exec(t.toString()),r=n?n[1]:t.toString();return this.types.includes(r)||(this.types.push(r),this.emit(`discovered`,{type:`type`,data:r}),this.emitDebug(`Scanning service type ${r}.`),this.scanner.query(r,`ANY`)),r}answerDataToKeyValues(e){let t=[],n={},r=0,i=e[r];for(;i;){let a=e.slice(r+1,r+1+i);t.push(a.toString());let o=/^([^=]+)=([^=]*)$/.exec(a.toString());o&&(n[o[1]]=o[2]),r=r+1+i,i=e[r]}return{strings:t,keyValuePairs:n}}emitError(e){this.emit(`error`,e)}emitWarn(e){this.emit(`warn`,e)}emitDebug(e){this.Config.debug&&this.emit(`debug`,e)}};const x=async(e=500)=>{e<10&&(e=10);let n=new v({debug:!0}),r=new b(n);if(r.on(`error`,e=>{if(!e.includes(`bind ENOENT`))throw Error(e)}),!await n.init())throw Error(`Failed to initialize mDNS scanner`);n.query(`_at1000_server._tcp.local`),await new Promise(t=>setTimeout(t,e));let i=[...new Set(Object.values(r.namedServices).filter(e=>e!==void 0&&e.service!==void 0).filter(e=>e.service.name.endsWith(`_at1000_server._tcp.local`)).map(e=>{let t=e.addresses?.find(e=>e.family===`IPv4`),n=e.addresses?.find(e=>e.family===`IPv6`);return(t??n)?.address}).filter(e=>e!==void 0))];return n.destroy(),(await Promise.allSettled(i.map(e=>t.t.create(e)))).filter(e=>e.status===`fulfilled`).map(e=>e.value)};var S=class extends t.t{static apiVersion=t.n;static findDevices(e=500){return x(e)}};exports.AT1000=S;
|
|
2
2
|
//# sourceMappingURL=node.cjs.map
|
package/build/node.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.cjs","names":["Constants.IPv4","Constants.IPv6","OS","IP","DGram","IP","Constants.IPv4","Constants.IPv6","Defaults","EventEmitter","Util","Constants.IPv4","Constants.IPv6","Constants.MDNS_IPV4","Constants.MDNS_PORT","Constants.MDNS_IPV6","DNSPacket","EventEmitter","Constants.IPv4","Constants.IPv6","Scanner","Services","AT1000","AT1000Base","version"],"sources":["../src/mdns-scanner/constants.ts","../src/mdns-scanner/interfaces.ts","../src/mdns-scanner/sockets.ts","../src/mdns-scanner/scanner.ts","../src/mdns-scanner/services.ts","../src/discovery.ts","../src/node.ts"],"sourcesContent":["export const MDNS_IPV4 = '224.0.0.251';\nexport const MDNS_IPV6 = 'FF02::FB';\nexport const MDNS_PORT = 5353;\nexport const IPv4 = 'IPv4';\nexport const IPv4_INT = 4; // beginning in node 18 family is integer\nexport const IPv6 = 'IPv6';\nexport const IPv6_INT = 6; // beginning in node 18 family is integer\nexport const ANY_IPV4 = '0.0.0.0';\nexport const ANY_IPV6 = '::';\n\nexport const ErrorMessages = { NO_INTERFACES: 'No available interfaces.' };\n","import IP from 'ip-address';\nimport OS from 'node:os';\nimport * as Constants from './constants.js';\n\nconst SupportedFamilies = [Constants.IPv4, Constants.IPv4_INT, Constants.IPv6, Constants.IPv6_INT];\n\nexport interface NetworkInterface {\n name: string;\n address: string;\n family: string | number;\n scopeid?: number;\n}\n\nclass Interfaces {\n // select appropriate method based on argument\n static getInterfaces(interfaceStrings?: string | string[]): NetworkInterface[] {\n return (!interfaceStrings\n ? Interfaces.getAllInterfaces()\n : Interfaces.getInterfacesFromStrings(interfaceStrings));\n }\n\n // get all usable interfaces from OS\n static getAllInterfaces(): NetworkInterface[] {\n const interfaces: NetworkInterface[] = [];\n const names: string[] = [];\n const osInterfaces = OS.networkInterfaces();\n for (const [name, iface] of Object.entries(osInterfaces)) {\n if (names.includes(name)) {\n continue;\n }\n names.push(name);\n iface?.forEach((assignment) => {\n // check if interface is usable\n if (\n assignment.internal // cannot use internal\n || !SupportedFamilies.includes(assignment.family) // can only use IPv4 and IPv6 family\n || /^(2002|2001):/ig.exec(assignment.address) // cannot use IPv6 special prefix\n ) return;\n interfaces.push({\n name: name,\n address: assignment.address,\n family: assignment.family,\n scopeid: assignment.scopeid,\n });\n });\n }\n if (!interfaces.length) throw new Error('No usable network interfaces returned by OS.');\n return interfaces;\n }\n\n // get interfaces from configuration strings\n static getInterfacesFromStrings(interfaceStrings: string | string[]): NetworkInterface[] {\n const interfaceArray = Array.isArray(interfaceStrings) ? interfaceStrings : [interfaceStrings];\n const interfaces = this.getAllInterfaces().filter((iface) => {\n return interfaceArray.reduce((result, interfaceString) => {\n // return result || (((IP.isV4Format(interfaceString) || IP.isV6Format(interfaceString)) && IP.isEqual(iface.address, interfaceString)) || iface.name === interfaceString ? true : false);\n return result\n || (Interfaces.stringMatchesAddress(interfaceString, iface.address)\n || iface.name === interfaceString\n ? true\n : false);\n }, false);\n });\n if (!interfaces || !interfaces.length) {\n throw new Error('No usable network interfaces returned by OS.');\n }\n return interfaces;\n }\n\n // compare interface settings string to os interface address\n static stringMatchesAddress(ifaceString: string, address: string): boolean {\n // try to create address objects\n let stringAddress: IP.Address4 | IP.Address6;\n let addressAddress: IP.Address4 | IP.Address6;\n try {\n stringAddress = new IP.Address4(ifaceString);\n addressAddress = new IP.Address4(address);\n // oxlint-disable-next-line no-unused-vars\n } catch (e) {\n try {\n stringAddress = new IP.Address6(ifaceString);\n addressAddress = new IP.Address6(address);\n // oxlint-disable-next-line no-unused-vars\n } catch (e) {\n return false;\n }\n }\n // compare addresses\n return stringAddress.bigInt() === addressAddress.bigInt();\n }\n}\n\nexport default Interfaces;\n","import IP from 'ip-address';\nimport type { RemoteInfo, Socket as DgramSocket } from 'node:dgram';\nimport DGram from 'node:dgram';\nimport * as Constants from './constants.js';\nimport type { NetworkInterface } from './interfaces.js';\n\nexport interface MulticastSettings {\n multicastAddress: string;\n multicastPort: number;\n interfaces: NetworkInterface[];\n reuseAddr?: boolean;\n ttl?: number;\n loopback?: boolean;\n onMessage: (message: Buffer, rinfo: RemoteInfo) => void;\n socketError: (error: Error) => void;\n}\n\nexport interface SendSocketSettings {\n reuseAddr?: boolean;\n srcPort?: number;\n}\n\nexport interface SocketResult {\n success: boolean;\n socket?: DgramSocket;\n memberships?: NetworkInterface[];\n failedMemberships?: NetworkInterface[];\n error?: Error;\n iface?: NetworkInterface;\n send?: (...args: any[]) => void;\n}\n\nconst MulticastDefaults = {\n interfaces: [],\n reuseAddr: true,\n ttl: 255,\n loopback: true,\n onMessage: (message: Buffer, _rinfo: RemoteInfo) => {\n console.log('Message ' + message.toString());\n },\n socketError: (error: Error) => {\n console.log('Socket error ' + error.message);\n },\n};\n\nclass Sockets {\n static validateSettings(settings: Partial<MulticastSettings>): void {\n if (!settings.multicastAddress) {\n throw new Error('Socket settings require multicastAddress');\n }\n if (!settings.multicastPort) {\n throw new Error('Socket settings require multicastPort');\n }\n }\n\n // create a multicast socket and add interfaces to group membership\n static createMulticastSocket(settings: Partial<MulticastSettings>): Promise<SocketResult> {\n return new Promise((resolve, _reject) => {\n const mergedSettings = Object.assign({}, MulticastDefaults, settings) as MulticastSettings;\n Sockets.validateSettings(mergedSettings);\n // create multicast socket to listen for packets\n const socket = DGram.createSocket({\n type: IP.Address4.isValid(mergedSettings.multicastAddress) ? 'udp4' : 'udp6',\n reuseAddr: mergedSettings.reuseAddr,\n });\n // track bind status with local variable\n let isListening = false;\n // add event listeners to socket\n socket\n .on('error', (error) => {\n if (isListening) {\n mergedSettings.socketError(error);\n } else {\n socket.close();\n resolve({ success: false, error: error });\n }\n })\n .on('listening', () => {\n isListening = true;\n socket.setMulticastTTL(mergedSettings.ttl ?? 255);\n socket.setMulticastLoopback(mergedSettings.loopback ?? true);\n const result = Sockets.addMulticastMemberships(socket, mergedSettings);\n if (!result.memberships.length) {\n isListening = false;\n socket.close();\n resolve({\n success: false,\n error: new Error(\n 'No interface memberships for multicast address ' + mergedSettings.multicastAddress,\n ),\n });\n return;\n }\n resolve(Object.assign({ success: true }, result, { socket }));\n })\n .on('message', (msg, rinfo) => {\n mergedSettings.onMessage(msg, rinfo);\n });\n // bind socket\n socket.bind({ port: mergedSettings.multicastPort, exclusive: false });\n });\n }\n\n // add interfaces to multicast membership group on socket\n static addMulticastMemberships(\n socket: DgramSocket,\n settings: MulticastSettings,\n ): { memberships: NetworkInterface[]; failedMemberships: NetworkInterface[] } {\n const memberships: NetworkInterface[] = [];\n const failedMemberships: NetworkInterface[] = [];\n const family = IP.Address4.isValid(settings.multicastAddress)\n ? [Constants.IPv4, Constants.IPv4_INT]\n : [Constants.IPv6, Constants.IPv6_INT];\n settings.interfaces.forEach((iface) => {\n if (!family.includes(iface.family)) return; // unsupported family\n try {\n socket.addMembership(settings.multicastAddress, Sockets.interfaceAddress(iface));\n memberships.push(iface);\n // oxlint-disable-next-line no-unused-vars\n } catch (error) {\n failedMemberships.push(iface);\n }\n });\n return { memberships, failedMemberships };\n }\n\n // create a socket to be used when sending mDNS packets\n static async createSendSocket(\n iface: NetworkInterface,\n settings: SendSocketSettings,\n onMessage: (message: Buffer, rinfo: RemoteInfo) => void,\n socketError: (error: Error) => void,\n ): Promise<SocketResult> {\n return new Promise((resolve, _reject) => {\n const socket = DGram.createSocket({\n type: [Constants.IPv4, Constants.IPv4_INT].includes(iface.family) ? 'udp4' : 'udp6',\n reuseAddr: settings.reuseAddr ? true : false,\n });\n let bound = false;\n socket\n .on('error', (error) => {\n if (!bound) {\n socket.close();\n resolve({ success: false, error: new Error(error.message) });\n } else {\n socketError(error);\n }\n })\n .on('listening', () => {\n bound = true;\n resolve({ success: true, iface, socket, send: socket.send.bind(socket) });\n })\n .on('message', (msg, rinfo: RemoteInfo & { interface?: string }) => {\n // include interface name so we know where the message came in\n rinfo.interface = iface.name;\n onMessage(msg, rinfo);\n })\n .bind(settings.srcPort || 0, Sockets.interfaceAddress(iface));\n });\n }\n\n // format an interface address for mDNS socket\n static interfaceAddress(iface: NetworkInterface): string {\n // IPv4 addresses don't need scope\n if ([Constants.IPv4, Constants.IPv4_INT].includes(iface.family)) {\n return iface.address;\n }\n // For IPv6 link-local addresses (scopeid > 0), append the numeric scope ID\n // Global IPv6 addresses (scopeid = 0 or undefined) don't need a scope\n if (iface.scopeid) {\n return `${iface.address}%${iface.scopeid}`;\n }\n return iface.address;\n }\n}\n\nexport default Sockets;\n","import type { Packet, Question, RecordType } from 'dns-packet';\nimport DNSPacket from 'dns-packet';\nimport type { RemoteInfo } from 'node:dgram';\nimport { EventEmitter } from 'node:events';\nimport Util from 'node:util';\nimport * as Constants from './constants.js';\nimport type { NetworkInterface } from './interfaces.js';\nimport Interfaces from './interfaces.js';\nimport type { SocketResult } from './sockets.js';\nimport Sockets from './sockets.js';\n\nexport interface ScannerConfig {\n reuseAddr?: boolean;\n srcPort?: number;\n interfaces?: string | string[] | null;\n ttl?: number;\n loopback?: boolean;\n debug?: boolean;\n}\n\ntype Socket = SocketResult;\n\nconst Defaults: Required<ScannerConfig> = {\n reuseAddr: true,\n srcPort: 0,\n interfaces: null,\n ttl: 255,\n loopback: true,\n debug: false,\n};\n\nclass MDNSScanner extends EventEmitter {\n Config: Required<ScannerConfig>;\n ready: boolean;\n receiveSockets: Socket[];\n sendSockets: Socket[];\n interfaces?: NetworkInterface[];\n destroyed?: boolean;\n\n constructor(config?: ScannerConfig) {\n super();\n this.Config = Object.assign({}, Defaults, config);\n this.ready = false;\n this.receiveSockets = [];\n this.sendSockets = [];\n }\n\n // initialize the scanner\n async init(): Promise<boolean> {\n try {\n this.interfaces = Interfaces.getInterfaces(this.Config.interfaces || undefined);\n } catch (error) {\n this.emitError(error);\n throw error;\n }\n this.emitDebug(`Scanner interfaces: ${Util.inspect(this.interfaces)}`);\n await this.createReceiveSockets();\n await this.createSendSockets();\n if (this.receiveSockets.length && this.sendSockets.length) this.ready = true;\n return this.ready;\n }\n\n // create sockets that will receive mDNS packets\n async createReceiveSockets(): Promise<Socket[]> {\n if (!this.interfaces) return [];\n const ipv4 = this.interfaces.filter(i =>\n [Constants.IPv4, Constants.IPv4_INT].includes(i.family)\n );\n const ipv6 = this.interfaces.filter(i =>\n [Constants.IPv6, Constants.IPv6_INT].includes(i.family)\n );\n this.emitDebug(\n `Create receive sockets for${ipv4.length ? ' ' + Constants.IPv4 : ''}${\n ipv4.length && ipv6.length\n ? ' and'\n : ''\n }${ipv6.length ? ' ' + Constants.IPv6 : ''}`,\n );\n if (ipv4.length) {\n const ipv4Socket = await Sockets.createMulticastSocket({\n multicastAddress: Constants.MDNS_IPV4,\n multicastPort: Constants.MDNS_PORT,\n interfaces: ipv4,\n onMessage: this.onMessage.bind(this),\n socketError: this.socketError.bind(this),\n });\n if (ipv4Socket.success) this.receiveSockets.push(ipv4Socket);\n else if (ipv4Socket.error) this.emitError(ipv4Socket.error.message);\n }\n if (ipv6.length) {\n const ipv6Socket = await Sockets.createMulticastSocket({\n multicastAddress: Constants.MDNS_IPV6,\n multicastPort: Constants.MDNS_PORT,\n interfaces: ipv6,\n onMessage: this.onMessage.bind(this),\n socketError: this.socketError.bind(this),\n });\n if (ipv6Socket.success) this.receiveSockets.push(ipv6Socket);\n else if (ipv6Socket.error) this.emitError(ipv6Socket.error.message);\n }\n return this.receiveSockets;\n }\n\n // create sockets used to send out mDNS packets\n async createSendSockets(): Promise<void> {\n if (!this.interfaces) return;\n this.emitDebug(`Create send sockets on ${this.interfaces.length} interfaces/addresses.`);\n for (let i = 0; i < this.interfaces.length; i++) {\n const sendSocket = await Sockets.createSendSocket(\n this.interfaces[i],\n this.Config,\n this.onMessage.bind(this),\n this.socketError.bind(this),\n );\n if (sendSocket.success) this.sendSockets.push(sendSocket);\n else if (sendSocket.error) this.emitError(sendSocket.error.message);\n }\n }\n\n // handle receive socket message\n onMessage(message: Buffer, rinfo: RemoteInfo): void {\n let packet: Packet;\n try {\n packet = DNSPacket.decode(message);\n } catch (error) {\n return this.emitWarn(error);\n }\n this.emit('packet', packet, rinfo);\n }\n\n // handle socket errors\n socketError(error: any): void {\n if (error.code === 'EACCES' || error.code === 'EADDRINUSE' || error.code === 'EADDRNOTAVAIL') {\n this.emitError(error);\n } else {\n this.emitWarn(error);\n }\n }\n\n // send an mDNS query, questions can be an array of formatted questions or a single question name string, qtype is optionally used with name string\n // oxlint-disable-next-line no-redundant-type-constituents\n query(questions: string | Question[], qtype?: RecordType | string): void {\n let questionArray: Question[];\n if (typeof questions === 'string') {\n questionArray = [{ name: questions, type: (qtype || 'ANY') as RecordType }];\n } else if (Array.isArray(questions)) {\n questionArray = questions;\n } else {\n throw new Error('Query questions must be an array of mDNS query questions.');\n }\n const query = { type: 'query' as const, questions: questionArray };\n this.emitDebug(`Send mDNS query: ${Util.inspect(query)}`);\n this.send(query);\n }\n\n // send mDNS packet\n send(value: Packet): void {\n if (this.destroyed) return;\n const packet = DNSPacket.encode(value);\n for (let i = 0; i < this.sendSockets.length; i++) {\n const socket = this.sendSockets[i];\n if (socket.send && socket.iface) {\n try {\n socket.send(\n packet,\n 0,\n packet.length,\n Constants.MDNS_PORT,\n [Constants.IPv4, Constants.IPv4_INT].includes(socket.iface.family)\n ? Constants.MDNS_IPV4\n : Constants.MDNS_IPV6 + '%' + socket.iface.name,\n );\n this.emitDebug(`Send packet on ${socket.iface.address}`);\n } catch {\n // Socket was closed between check and send — skip silently\n }\n }\n }\n }\n\n // destroy this scanner\n destroy(): void {\n this.destroyed = true;\n this.ready = false;\n this.removeAllListeners();\n this.sendSockets.forEach(s => {\n try {\n s.socket?.close();\n } catch {}\n });\n this.sendSockets = [];\n this.receiveSockets.forEach(s => {\n try {\n s.socket?.close();\n } catch {}\n });\n this.receiveSockets = [];\n }\n\n ////////////////////////\n // emit event methods //\n ////////////////////////\n\n emitError(error: any): void {\n this.emit('error', error);\n }\n\n emitWarn(message: any): void {\n this.emit('warn', message);\n }\n\n emitDebug(message: string): void {\n if (this.Config.debug) this.emit('debug', message);\n }\n}\n\nexport default MDNSScanner;\n","import type { Answer, Packet } from 'dns-packet';\nimport type { RemoteInfo } from 'node:dgram';\nimport { EventEmitter } from 'node:events';\nimport * as Constants from './constants.js';\nimport type MDNSScanner from './scanner.js';\n\nexport interface ServicesConfig {\n debug?: boolean;\n}\n\nexport interface NamedService {\n service?: Answer;\n host?: string;\n port?: number;\n txt?: { strings: string[]; keyValuePairs: Record<string, string> };\n addresses?: Array<{ family: string; address: string }>;\n name?: string;\n rinfo?: RemoteInfo;\n}\n\nconst Defaults: Required<ServicesConfig> = { debug: false };\n\nclass MDNSServices extends EventEmitter {\n Config: Required<ServicesConfig>;\n scanner: MDNSScanner;\n types: string[];\n namedServices: Record<string, NamedService>;\n private packetListener: (packet: Packet, rinfo: RemoteInfo) => void;\n\n constructor(scanner: MDNSScanner, config?: ServicesConfig) {\n super();\n this.packetListener = this.onPacket.bind(this);\n this.scanner = scanner;\n this.Config = Object.assign({}, Defaults, config);\n this.types = [];\n this.namedServices = {};\n this.forwardEvents(this.scanner);\n this.reset();\n }\n\n // reset services\n reset(): void {\n this.removeMDNSListener(this.scanner);\n this.types = [];\n this.namedServices = {};\n this.listenMDNSEvents(this.scanner);\n }\n\n // forward events received from scanner\n forwardEvents(scanner: MDNSScanner): void {\n scanner\n .on('error', (error: any) => {\n this.emitError(error);\n })\n .on('warn', (message: any) => {\n this.emitWarn(message);\n })\n .on('debug', (message: string) => {\n this.emitDebug(message);\n });\n }\n\n // handle packets from scanner\n listenMDNSEvents(scanner: MDNSScanner): void {\n scanner.on('packet', this.packetListener);\n }\n\n // remove packet listener\n removeMDNSListener(scanner: MDNSScanner): void {\n scanner.removeListener('packet', this.packetListener);\n }\n\n // on scanner packet handler\n onPacket(packet: Packet, rinfo: RemoteInfo): void {\n this.emitDebug(`Received packet type ${packet.type} from ${rinfo.address}.`);\n switch (packet.type) {\n case 'query':\n this.emit('query', packet, rinfo);\n break;\n\n case 'response':\n this.emitDebug(\n `Received response packet from ${rinfo.address} with ${\n packet.answers\n ? packet.answers.length\n : 0\n } answers and ${packet.additionals ? packet.additionals.length : 0} additionals.`,\n );\n if (packet.answers) this.processAnswers(packet.answers, rinfo);\n if (packet.additionals) this.processAnswers(packet.additionals, rinfo);\n\n break;\n }\n }\n\n // process answers or additionals in a response type packet\n processAnswers(answers: Answer[], rinfo: RemoteInfo): void {\n this.emitDebug('Processing answers or additionals...');\n // process service answers\n const serviceNames = this.processSRVAnswers(answers);\n this.processTXTAnswers(answers);\n this.processAAnswers(answers);\n this.processAAAAAnswers(answers);\n this.processPTRAnswers(answers, rinfo);\n serviceNames.forEach(name => {\n this.emit('discovered', { type: 'service', data: this.namedServices[name] });\n });\n }\n\n processSRVAnswers(answers: Answer[]): string[] {\n const serviceNames: string[] = [];\n answers.forEach(answer => {\n if (answer.type !== 'SRV') return;\n this.emitDebug(`Processing SRV answer.`);\n const fullName = answer.name.toString();\n if (!serviceNames.includes(fullName)) serviceNames.push(fullName);\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].service = answer;\n this.namedServices[fullName].host = (answer.data as any).target.toString();\n this.namedServices[fullName].port = (answer.data as any).port;\n });\n return serviceNames;\n }\n\n processTXTAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'TXT') return;\n this.emitDebug(`Processing TXT answer.`);\n const data = answer.data as Buffer | Buffer[];\n if (Array.isArray(data) && data.length > 1) {\n const fullName = answer.name.toString();\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].txt = this.answerDataToKeyValues(Buffer.concat(data));\n } else if (Buffer.isBuffer(data)) {\n const fullName = answer.name.toString();\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].txt = this.answerDataToKeyValues(data);\n }\n });\n }\n\n processAAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'A') return;\n this.emitDebug(`Processing A answer.`);\n const hostName = answer.name.toString();\n const address = (answer as any).data.toString();\n for (const serviceName in this.namedServices) {\n if (this.namedServices[serviceName].host !== hostName) continue;\n this.namedServices[serviceName].addresses = this.namedServices[serviceName].addresses || [];\n const exists = this.namedServices[serviceName].addresses!.reduce((e, a) => {\n return e || a.address === address;\n }, false);\n if (!exists) {\n this.namedServices[serviceName].addresses!.push({ family: Constants.IPv4, address });\n }\n }\n });\n }\n\n processAAAAAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'AAAA') return;\n this.emitDebug(`Processing AAAA answer.`);\n const hostName = answer.name.toString();\n const address = (answer as any).data.toString();\n for (const serviceName in this.namedServices) {\n if (this.namedServices[serviceName].host !== hostName) continue;\n this.namedServices[serviceName].addresses = this.namedServices[serviceName].addresses || [];\n const exists = this.namedServices[serviceName].addresses!.reduce((e, a) => {\n return e || a.address === address;\n }, false);\n if (!exists) {\n this.namedServices[serviceName].addresses!.push({ family: Constants.IPv6, address });\n }\n }\n });\n }\n\n processPTRAnswers(answers: Answer[], rinfo: RemoteInfo): void {\n answers.forEach(answer => {\n if (answer.type !== 'PTR') return;\n this.emitDebug(`Processing PTR answer.`);\n const serviceType = this.serviceTypeFromPTR(answer);\n const fullName = (answer as any).data.toString();\n // build host service definition if fullName is a host service\n if (serviceType !== fullName) {\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].name = fullName.replace('.' + serviceType, '');\n this.namedServices[fullName].rinfo = rinfo;\n }\n });\n }\n\n // extract service type from answer data\n serviceTypeFromPTR(answer: Answer): string {\n const data = (answer as any).data;\n const match = /(?:^|^.+?(?:\\.))(_.*)$/mg.exec(data.toString()); // get service type without hostname\n const serviceType = match ? match[1] : data.toString();\n if (!this.types.includes(serviceType)) {\n this.types.push(serviceType);\n this.emit('discovered', { type: 'type', data: serviceType });\n this.emitDebug(`Scanning service type ${serviceType}.`);\n this.scanner.query(serviceType, 'ANY');\n }\n return serviceType;\n }\n\n // extract the key=value pairs from a TXT data buffer\n answerDataToKeyValues(\n data: Buffer,\n ): { strings: string[]; keyValuePairs: Record<string, string> } {\n const strings: string[] = [];\n const kvPairs: Record<string, string> = {};\n let kvPointer = 0;\n let kvLen = data[kvPointer];\n while (kvLen) {\n const pair = data.slice(kvPointer + 1, kvPointer + 1 + kvLen);\n strings.push(pair.toString());\n const kvMatch = /^([^=]+)=([^=]*)$/.exec(pair.toString());\n if (kvMatch) {\n kvPairs[kvMatch[1]] = kvMatch[2];\n }\n kvPointer = kvPointer + 1 + kvLen;\n kvLen = data[kvPointer];\n }\n return { strings: strings, keyValuePairs: kvPairs };\n }\n\n ////////////////////////\n // emit event methods //\n ////////////////////////\n\n emitError(error: any): void {\n this.emit('error', error);\n }\n\n emitWarn(message: any): void {\n this.emit('warn', message);\n }\n\n emitDebug(message: string): void {\n if (this.Config.debug) this.emit('debug', message);\n }\n}\n\nexport default MDNSServices;\n","import { AT1000Base as AT1000 } from './at1000';\n\nimport { Scanner, Services } from './mdns-scanner';\n\nexport const findDevices = async (timeout: number = 500): Promise<AT1000[]> => {\n if (timeout < 10) {\n timeout = 10;\n }\n\n let scanner = new Scanner({ debug: true });\n let services = new Services(scanner);\n\n services.on('error', (error: string) => {\n if (!error.includes('bind ENOENT')) {\n throw Error(error);\n }\n });\n\n let ready = await scanner.init();\n if (!ready) {\n throw new Error('Failed to initialize mDNS scanner');\n }\n scanner.query('_at1000_server._tcp.local');\n\n await new Promise((r) => setTimeout(r, timeout));\n\n // Extract unique IPv4 addresses from discovered services\n const addresses = [\n ...new Set(\n Object\n .values(services.namedServices)\n .filter((s: any) => s !== undefined && s.service !== undefined)\n .filter((s: any) => (s.service.name as string).endsWith('_at1000_server._tcp.local'))\n .map((s: any) => s.addresses.filter((a: any) => a.family == 'IPv4').pop()?.address)\n .filter((ipv4: string | undefined) => ipv4 !== undefined),\n ),\n ];\n\n scanner.destroy();\n\n const results = await Promise.allSettled(addresses.map((ipv4) => AT1000.create(ipv4)));\n return results.filter((r): r is PromiseFulfilledResult<AT1000> => r.status === 'fulfilled').map((\n r,\n ) => r.value);\n};\n","import { version } from '../package.json';\nimport { AT1000Base } from './at1000';\nimport { findDevices } from './discovery';\n\n/** @hideconstructor */\nexport class AT1000 extends AT1000Base {\n static readonly apiVersion = version;\n\n static findDevices(timeout: number = 500): Promise<AT1000[]> {\n return findDevices(timeout);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"node.cjs","names":["Constants.IPv4","Constants.IPv6","OS","IP","DGram","IP","Constants.IPv4","Constants.IPv6","Defaults","EventEmitter","Util","Constants.IPv4","Constants.IPv6","Constants.MDNS_IPV4","Constants.MDNS_PORT","Constants.MDNS_IPV6","DNSPacket","EventEmitter","Constants.IPv4","Constants.IPv6","Scanner","Services","AT1000","AT1000Base","version"],"sources":["../src/mdns-scanner/constants.ts","../src/mdns-scanner/interfaces.ts","../src/mdns-scanner/sockets.ts","../src/mdns-scanner/scanner.ts","../src/mdns-scanner/services.ts","../src/discovery.ts","../src/node.ts"],"sourcesContent":["export const MDNS_IPV4 = '224.0.0.251';\nexport const MDNS_IPV6 = 'FF02::FB';\nexport const MDNS_PORT = 5353;\nexport const IPv4 = 'IPv4';\nexport const IPv4_INT = 4; // beginning in node 18 family is integer\nexport const IPv6 = 'IPv6';\nexport const IPv6_INT = 6; // beginning in node 18 family is integer\nexport const ANY_IPV4 = '0.0.0.0';\nexport const ANY_IPV6 = '::';\n\nexport const ErrorMessages = { NO_INTERFACES: 'No available interfaces.' };\n","import IP from 'ip-address';\nimport OS from 'node:os';\nimport * as Constants from './constants.js';\n\nconst SupportedFamilies = [Constants.IPv4, Constants.IPv4_INT, Constants.IPv6, Constants.IPv6_INT];\n\nexport interface NetworkInterface {\n name: string;\n address: string;\n family: string | number;\n scopeid?: number;\n}\n\nclass Interfaces {\n // select appropriate method based on argument\n static getInterfaces(interfaceStrings?: string | string[]): NetworkInterface[] {\n return (!interfaceStrings\n ? Interfaces.getAllInterfaces()\n : Interfaces.getInterfacesFromStrings(interfaceStrings));\n }\n\n // get all usable interfaces from OS\n static getAllInterfaces(): NetworkInterface[] {\n const interfaces: NetworkInterface[] = [];\n const names: string[] = [];\n const osInterfaces = OS.networkInterfaces();\n for (const [name, iface] of Object.entries(osInterfaces)) {\n if (names.includes(name)) {\n continue;\n }\n names.push(name);\n iface?.forEach((assignment) => {\n // check if interface is usable\n if (\n assignment.internal // cannot use internal\n || !SupportedFamilies.includes(assignment.family) // can only use IPv4 and IPv6 family\n || /^(2002|2001):/ig.exec(assignment.address) // cannot use IPv6 special prefix\n ) return;\n interfaces.push({\n name: name,\n address: assignment.address,\n family: assignment.family,\n scopeid: assignment.scopeid,\n });\n });\n }\n if (!interfaces.length) throw new Error('No usable network interfaces returned by OS.');\n return interfaces;\n }\n\n // get interfaces from configuration strings\n static getInterfacesFromStrings(interfaceStrings: string | string[]): NetworkInterface[] {\n const interfaceArray = Array.isArray(interfaceStrings) ? interfaceStrings : [interfaceStrings];\n const interfaces = this.getAllInterfaces().filter((iface) => {\n return interfaceArray.reduce((result, interfaceString) => {\n // return result || (((IP.isV4Format(interfaceString) || IP.isV6Format(interfaceString)) && IP.isEqual(iface.address, interfaceString)) || iface.name === interfaceString ? true : false);\n return result\n || (Interfaces.stringMatchesAddress(interfaceString, iface.address)\n || iface.name === interfaceString\n ? true\n : false);\n }, false);\n });\n if (!interfaces || !interfaces.length) {\n throw new Error('No usable network interfaces returned by OS.');\n }\n return interfaces;\n }\n\n // compare interface settings string to os interface address\n static stringMatchesAddress(ifaceString: string, address: string): boolean {\n // try to create address objects\n let stringAddress: IP.Address4 | IP.Address6;\n let addressAddress: IP.Address4 | IP.Address6;\n try {\n stringAddress = new IP.Address4(ifaceString);\n addressAddress = new IP.Address4(address);\n // oxlint-disable-next-line no-unused-vars\n } catch (e) {\n try {\n stringAddress = new IP.Address6(ifaceString);\n addressAddress = new IP.Address6(address);\n // oxlint-disable-next-line no-unused-vars\n } catch (e) {\n return false;\n }\n }\n // compare addresses\n return stringAddress.bigInt() === addressAddress.bigInt();\n }\n}\n\nexport default Interfaces;\n","import IP from 'ip-address';\nimport type { RemoteInfo, Socket as DgramSocket } from 'node:dgram';\nimport DGram from 'node:dgram';\nimport * as Constants from './constants.js';\nimport type { NetworkInterface } from './interfaces.js';\n\nexport interface MulticastSettings {\n multicastAddress: string;\n multicastPort: number;\n interfaces: NetworkInterface[];\n reuseAddr?: boolean;\n ttl?: number;\n loopback?: boolean;\n onMessage: (message: Buffer, rinfo: RemoteInfo) => void;\n socketError: (error: Error) => void;\n}\n\nexport interface SendSocketSettings {\n reuseAddr?: boolean;\n srcPort?: number;\n}\n\nexport interface SocketResult {\n success: boolean;\n socket?: DgramSocket;\n memberships?: NetworkInterface[];\n failedMemberships?: NetworkInterface[];\n error?: Error;\n iface?: NetworkInterface;\n send?: (...args: any[]) => void;\n}\n\nconst MulticastDefaults = {\n interfaces: [],\n reuseAddr: true,\n ttl: 255,\n loopback: true,\n onMessage: (message: Buffer, _rinfo: RemoteInfo) => {\n console.log('Message ' + message.toString());\n },\n socketError: (error: Error) => {\n console.log('Socket error ' + error.message);\n },\n};\n\nclass Sockets {\n static validateSettings(settings: Partial<MulticastSettings>): void {\n if (!settings.multicastAddress) {\n throw new Error('Socket settings require multicastAddress');\n }\n if (!settings.multicastPort) {\n throw new Error('Socket settings require multicastPort');\n }\n }\n\n // create a multicast socket and add interfaces to group membership\n static createMulticastSocket(settings: Partial<MulticastSettings>): Promise<SocketResult> {\n return new Promise((resolve, _reject) => {\n const mergedSettings = Object.assign({}, MulticastDefaults, settings) as MulticastSettings;\n Sockets.validateSettings(mergedSettings);\n // create multicast socket to listen for packets\n const socket = DGram.createSocket({\n type: IP.Address4.isValid(mergedSettings.multicastAddress) ? 'udp4' : 'udp6',\n reuseAddr: mergedSettings.reuseAddr,\n });\n // track bind status with local variable\n let isListening = false;\n // add event listeners to socket\n socket\n .on('error', (error) => {\n if (isListening) {\n mergedSettings.socketError(error);\n } else {\n socket.close();\n resolve({ success: false, error: error });\n }\n })\n .on('listening', () => {\n isListening = true;\n socket.setMulticastTTL(mergedSettings.ttl ?? 255);\n socket.setMulticastLoopback(mergedSettings.loopback ?? true);\n const result = Sockets.addMulticastMemberships(socket, mergedSettings);\n if (!result.memberships.length) {\n isListening = false;\n socket.close();\n resolve({\n success: false,\n error: new Error(\n 'No interface memberships for multicast address ' + mergedSettings.multicastAddress,\n ),\n });\n return;\n }\n resolve(Object.assign({ success: true }, result, { socket }));\n })\n .on('message', (msg, rinfo) => {\n mergedSettings.onMessage(msg, rinfo);\n });\n // bind socket\n socket.bind({ port: mergedSettings.multicastPort, exclusive: false });\n });\n }\n\n // add interfaces to multicast membership group on socket\n static addMulticastMemberships(\n socket: DgramSocket,\n settings: MulticastSettings,\n ): { memberships: NetworkInterface[]; failedMemberships: NetworkInterface[] } {\n const memberships: NetworkInterface[] = [];\n const failedMemberships: NetworkInterface[] = [];\n const family = IP.Address4.isValid(settings.multicastAddress)\n ? [Constants.IPv4, Constants.IPv4_INT]\n : [Constants.IPv6, Constants.IPv6_INT];\n settings.interfaces.forEach((iface) => {\n if (!family.includes(iface.family)) return; // unsupported family\n try {\n socket.addMembership(settings.multicastAddress, Sockets.interfaceAddress(iface));\n memberships.push(iface);\n // oxlint-disable-next-line no-unused-vars\n } catch (error) {\n failedMemberships.push(iface);\n }\n });\n return { memberships, failedMemberships };\n }\n\n // create a socket to be used when sending mDNS packets\n static async createSendSocket(\n iface: NetworkInterface,\n settings: SendSocketSettings,\n onMessage: (message: Buffer, rinfo: RemoteInfo) => void,\n socketError: (error: Error) => void,\n ): Promise<SocketResult> {\n return new Promise((resolve, _reject) => {\n const socket = DGram.createSocket({\n type: [Constants.IPv4, Constants.IPv4_INT].includes(iface.family) ? 'udp4' : 'udp6',\n reuseAddr: settings.reuseAddr ? true : false,\n });\n let bound = false;\n socket\n .on('error', (error) => {\n if (!bound) {\n socket.close();\n resolve({ success: false, error: new Error(error.message) });\n } else {\n socketError(error);\n }\n })\n .on('listening', () => {\n bound = true;\n resolve({ success: true, iface, socket, send: socket.send.bind(socket) });\n })\n .on('message', (msg, rinfo: RemoteInfo & { interface?: string }) => {\n // include interface name so we know where the message came in\n rinfo.interface = iface.name;\n onMessage(msg, rinfo);\n })\n .bind(settings.srcPort || 0, Sockets.interfaceAddress(iface));\n });\n }\n\n // format an interface address for mDNS socket\n static interfaceAddress(iface: NetworkInterface): string {\n // IPv4 addresses don't need scope\n if ([Constants.IPv4, Constants.IPv4_INT].includes(iface.family)) {\n return iface.address;\n }\n // For IPv6 link-local addresses (scopeid > 0), append the numeric scope ID\n // Global IPv6 addresses (scopeid = 0 or undefined) don't need a scope\n if (iface.scopeid) {\n return `${iface.address}%${iface.scopeid}`;\n }\n return iface.address;\n }\n}\n\nexport default Sockets;\n","import type { Packet, Question, RecordType } from 'dns-packet';\nimport DNSPacket from 'dns-packet';\nimport type { RemoteInfo } from 'node:dgram';\nimport { EventEmitter } from 'node:events';\nimport Util from 'node:util';\nimport * as Constants from './constants.js';\nimport type { NetworkInterface } from './interfaces.js';\nimport Interfaces from './interfaces.js';\nimport type { SocketResult } from './sockets.js';\nimport Sockets from './sockets.js';\n\nexport interface ScannerConfig {\n reuseAddr?: boolean;\n srcPort?: number;\n interfaces?: string | string[] | null;\n ttl?: number;\n loopback?: boolean;\n debug?: boolean;\n}\n\ntype Socket = SocketResult;\n\nconst Defaults: Required<ScannerConfig> = {\n reuseAddr: true,\n srcPort: 0,\n interfaces: null,\n ttl: 255,\n loopback: true,\n debug: false,\n};\n\nclass MDNSScanner extends EventEmitter {\n Config: Required<ScannerConfig>;\n ready: boolean;\n receiveSockets: Socket[];\n sendSockets: Socket[];\n interfaces?: NetworkInterface[];\n destroyed?: boolean;\n\n constructor(config?: ScannerConfig) {\n super();\n this.Config = Object.assign({}, Defaults, config);\n this.ready = false;\n this.receiveSockets = [];\n this.sendSockets = [];\n }\n\n // initialize the scanner\n async init(): Promise<boolean> {\n try {\n this.interfaces = Interfaces.getInterfaces(this.Config.interfaces || undefined);\n } catch (error) {\n this.emitError(error);\n throw error;\n }\n this.emitDebug(`Scanner interfaces: ${Util.inspect(this.interfaces)}`);\n await this.createReceiveSockets();\n await this.createSendSockets();\n if (this.receiveSockets.length && this.sendSockets.length) this.ready = true;\n return this.ready;\n }\n\n // create sockets that will receive mDNS packets\n async createReceiveSockets(): Promise<Socket[]> {\n if (!this.interfaces) return [];\n const ipv4 = this.interfaces.filter(i =>\n [Constants.IPv4, Constants.IPv4_INT].includes(i.family)\n );\n const ipv6 = this.interfaces.filter(i =>\n [Constants.IPv6, Constants.IPv6_INT].includes(i.family)\n );\n this.emitDebug(\n `Create receive sockets for${ipv4.length ? ' ' + Constants.IPv4 : ''}${\n ipv4.length && ipv6.length\n ? ' and'\n : ''\n }${ipv6.length ? ' ' + Constants.IPv6 : ''}`,\n );\n if (ipv4.length) {\n const ipv4Socket = await Sockets.createMulticastSocket({\n multicastAddress: Constants.MDNS_IPV4,\n multicastPort: Constants.MDNS_PORT,\n interfaces: ipv4,\n onMessage: this.onMessage.bind(this),\n socketError: this.socketError.bind(this),\n });\n if (ipv4Socket.success) this.receiveSockets.push(ipv4Socket);\n else if (ipv4Socket.error) this.emitError(ipv4Socket.error.message);\n }\n if (ipv6.length) {\n const ipv6Socket = await Sockets.createMulticastSocket({\n multicastAddress: Constants.MDNS_IPV6,\n multicastPort: Constants.MDNS_PORT,\n interfaces: ipv6,\n onMessage: this.onMessage.bind(this),\n socketError: this.socketError.bind(this),\n });\n if (ipv6Socket.success) this.receiveSockets.push(ipv6Socket);\n else if (ipv6Socket.error) this.emitError(ipv6Socket.error.message);\n }\n return this.receiveSockets;\n }\n\n // create sockets used to send out mDNS packets\n async createSendSockets(): Promise<void> {\n if (!this.interfaces) return;\n this.emitDebug(`Create send sockets on ${this.interfaces.length} interfaces/addresses.`);\n for (let i = 0; i < this.interfaces.length; i++) {\n const sendSocket = await Sockets.createSendSocket(\n this.interfaces[i],\n this.Config,\n this.onMessage.bind(this),\n this.socketError.bind(this),\n );\n if (sendSocket.success) this.sendSockets.push(sendSocket);\n else if (sendSocket.error) this.emitError(sendSocket.error.message);\n }\n }\n\n // handle receive socket message\n onMessage(message: Buffer, rinfo: RemoteInfo): void {\n let packet: Packet;\n try {\n packet = DNSPacket.decode(message);\n } catch (error) {\n return this.emitWarn(error);\n }\n this.emit('packet', packet, rinfo);\n }\n\n // handle socket errors\n socketError(error: any): void {\n if (error.code === 'EACCES' || error.code === 'EADDRINUSE' || error.code === 'EADDRNOTAVAIL') {\n this.emitError(error);\n } else {\n this.emitWarn(error);\n }\n }\n\n // send an mDNS query, questions can be an array of formatted questions or a single question name string, qtype is optionally used with name string\n // oxlint-disable-next-line no-redundant-type-constituents\n query(questions: string | Question[], qtype?: RecordType | string): void {\n let questionArray: Question[];\n if (typeof questions === 'string') {\n questionArray = [{ name: questions, type: (qtype || 'ANY') as RecordType }];\n } else if (Array.isArray(questions)) {\n questionArray = questions;\n } else {\n throw new Error('Query questions must be an array of mDNS query questions.');\n }\n const query = { type: 'query' as const, questions: questionArray };\n this.emitDebug(`Send mDNS query: ${Util.inspect(query)}`);\n this.send(query);\n }\n\n // send mDNS packet\n send(value: Packet): void {\n if (this.destroyed) return;\n const packet = DNSPacket.encode(value);\n for (let i = 0; i < this.sendSockets.length; i++) {\n const socket = this.sendSockets[i];\n if (socket.send && socket.iface) {\n try {\n socket.send(\n packet,\n 0,\n packet.length,\n Constants.MDNS_PORT,\n [Constants.IPv4, Constants.IPv4_INT].includes(socket.iface.family)\n ? Constants.MDNS_IPV4\n : Constants.MDNS_IPV6 + '%' + socket.iface.name,\n );\n this.emitDebug(`Send packet on ${socket.iface.address}`);\n } catch {\n // Socket was closed between check and send — skip silently\n }\n }\n }\n }\n\n // destroy this scanner\n destroy(): void {\n this.destroyed = true;\n this.ready = false;\n this.removeAllListeners();\n this.sendSockets.forEach(s => {\n try {\n s.socket?.close();\n } catch {}\n });\n this.sendSockets = [];\n this.receiveSockets.forEach(s => {\n try {\n s.socket?.close();\n } catch {}\n });\n this.receiveSockets = [];\n }\n\n ////////////////////////\n // emit event methods //\n ////////////////////////\n\n emitError(error: any): void {\n this.emit('error', error);\n }\n\n emitWarn(message: any): void {\n this.emit('warn', message);\n }\n\n emitDebug(message: string): void {\n if (this.Config.debug) this.emit('debug', message);\n }\n}\n\nexport default MDNSScanner;\n","import type { Answer, Packet } from 'dns-packet';\nimport type { RemoteInfo } from 'node:dgram';\nimport { EventEmitter } from 'node:events';\nimport * as Constants from './constants.js';\nimport type MDNSScanner from './scanner.js';\n\nexport interface ServicesConfig {\n debug?: boolean;\n}\n\nexport interface NamedService {\n service?: Answer;\n host?: string;\n port?: number;\n txt?: { strings: string[]; keyValuePairs: Record<string, string> };\n addresses?: Array<{ family: string; address: string }>;\n name?: string;\n rinfo?: RemoteInfo;\n}\n\nconst Defaults: Required<ServicesConfig> = { debug: false };\n\nclass MDNSServices extends EventEmitter {\n Config: Required<ServicesConfig>;\n scanner: MDNSScanner;\n types: string[];\n namedServices: Record<string, NamedService>;\n private packetListener: (packet: Packet, rinfo: RemoteInfo) => void;\n\n constructor(scanner: MDNSScanner, config?: ServicesConfig) {\n super();\n this.packetListener = this.onPacket.bind(this);\n this.scanner = scanner;\n this.Config = Object.assign({}, Defaults, config);\n this.types = [];\n this.namedServices = {};\n this.forwardEvents(this.scanner);\n this.reset();\n }\n\n // reset services\n reset(): void {\n this.removeMDNSListener(this.scanner);\n this.types = [];\n this.namedServices = {};\n this.listenMDNSEvents(this.scanner);\n }\n\n // forward events received from scanner\n forwardEvents(scanner: MDNSScanner): void {\n scanner\n .on('error', (error: any) => {\n this.emitError(error);\n })\n .on('warn', (message: any) => {\n this.emitWarn(message);\n })\n .on('debug', (message: string) => {\n this.emitDebug(message);\n });\n }\n\n // handle packets from scanner\n listenMDNSEvents(scanner: MDNSScanner): void {\n scanner.on('packet', this.packetListener);\n }\n\n // remove packet listener\n removeMDNSListener(scanner: MDNSScanner): void {\n scanner.removeListener('packet', this.packetListener);\n }\n\n // on scanner packet handler\n onPacket(packet: Packet, rinfo: RemoteInfo): void {\n this.emitDebug(`Received packet type ${packet.type} from ${rinfo.address}.`);\n switch (packet.type) {\n case 'query':\n this.emit('query', packet, rinfo);\n break;\n\n case 'response':\n this.emitDebug(\n `Received response packet from ${rinfo.address} with ${\n packet.answers\n ? packet.answers.length\n : 0\n } answers and ${packet.additionals ? packet.additionals.length : 0} additionals.`,\n );\n if (packet.answers) this.processAnswers(packet.answers, rinfo);\n if (packet.additionals) this.processAnswers(packet.additionals, rinfo);\n\n break;\n }\n }\n\n // process answers or additionals in a response type packet\n processAnswers(answers: Answer[], rinfo: RemoteInfo): void {\n this.emitDebug('Processing answers or additionals...');\n // process service answers\n const serviceNames = this.processSRVAnswers(answers);\n this.processTXTAnswers(answers);\n this.processAAnswers(answers);\n this.processAAAAAnswers(answers);\n this.processPTRAnswers(answers, rinfo);\n serviceNames.forEach(name => {\n this.emit('discovered', { type: 'service', data: this.namedServices[name] });\n });\n }\n\n processSRVAnswers(answers: Answer[]): string[] {\n const serviceNames: string[] = [];\n answers.forEach(answer => {\n if (answer.type !== 'SRV') return;\n this.emitDebug(`Processing SRV answer.`);\n const fullName = answer.name.toString();\n if (!serviceNames.includes(fullName)) serviceNames.push(fullName);\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].service = answer;\n this.namedServices[fullName].host = (answer.data as any).target.toString();\n this.namedServices[fullName].port = (answer.data as any).port;\n });\n return serviceNames;\n }\n\n processTXTAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'TXT') return;\n this.emitDebug(`Processing TXT answer.`);\n const data = answer.data as Buffer | Buffer[];\n if (Array.isArray(data) && data.length > 1) {\n const fullName = answer.name.toString();\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].txt = this.answerDataToKeyValues(Buffer.concat(data));\n } else if (Buffer.isBuffer(data)) {\n const fullName = answer.name.toString();\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].txt = this.answerDataToKeyValues(data);\n }\n });\n }\n\n processAAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'A') return;\n this.emitDebug(`Processing A answer.`);\n const hostName = answer.name.toString();\n const address = (answer as any).data.toString();\n for (const serviceName in this.namedServices) {\n if (this.namedServices[serviceName].host !== hostName) continue;\n this.namedServices[serviceName].addresses = this.namedServices[serviceName].addresses || [];\n const exists = this.namedServices[serviceName].addresses!.reduce((e, a) => {\n return e || a.address === address;\n }, false);\n if (!exists) {\n this.namedServices[serviceName].addresses!.push({ family: Constants.IPv4, address });\n }\n }\n });\n }\n\n processAAAAAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'AAAA') return;\n this.emitDebug(`Processing AAAA answer.`);\n const hostName = answer.name.toString();\n const address = (answer as any).data.toString();\n for (const serviceName in this.namedServices) {\n if (this.namedServices[serviceName].host !== hostName) continue;\n this.namedServices[serviceName].addresses = this.namedServices[serviceName].addresses || [];\n const exists = this.namedServices[serviceName].addresses!.reduce((e, a) => {\n return e || a.address === address;\n }, false);\n if (!exists) {\n this.namedServices[serviceName].addresses!.push({ family: Constants.IPv6, address });\n }\n }\n });\n }\n\n processPTRAnswers(answers: Answer[], rinfo: RemoteInfo): void {\n answers.forEach(answer => {\n if (answer.type !== 'PTR') return;\n this.emitDebug(`Processing PTR answer.`);\n const serviceType = this.serviceTypeFromPTR(answer);\n const fullName = (answer as any).data.toString();\n // build host service definition if fullName is a host service\n if (serviceType !== fullName) {\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].name = fullName.replace('.' + serviceType, '');\n this.namedServices[fullName].rinfo = rinfo;\n }\n });\n }\n\n // extract service type from answer data\n serviceTypeFromPTR(answer: Answer): string {\n const data = (answer as any).data;\n const match = /(?:^|^.+?(?:\\.))(_.*)$/mg.exec(data.toString()); // get service type without hostname\n const serviceType = match ? match[1] : data.toString();\n if (!this.types.includes(serviceType)) {\n this.types.push(serviceType);\n this.emit('discovered', { type: 'type', data: serviceType });\n this.emitDebug(`Scanning service type ${serviceType}.`);\n this.scanner.query(serviceType, 'ANY');\n }\n return serviceType;\n }\n\n // extract the key=value pairs from a TXT data buffer\n answerDataToKeyValues(\n data: Buffer,\n ): { strings: string[]; keyValuePairs: Record<string, string> } {\n const strings: string[] = [];\n const kvPairs: Record<string, string> = {};\n let kvPointer = 0;\n let kvLen = data[kvPointer];\n while (kvLen) {\n const pair = data.slice(kvPointer + 1, kvPointer + 1 + kvLen);\n strings.push(pair.toString());\n const kvMatch = /^([^=]+)=([^=]*)$/.exec(pair.toString());\n if (kvMatch) {\n kvPairs[kvMatch[1]] = kvMatch[2];\n }\n kvPointer = kvPointer + 1 + kvLen;\n kvLen = data[kvPointer];\n }\n return { strings: strings, keyValuePairs: kvPairs };\n }\n\n ////////////////////////\n // emit event methods //\n ////////////////////////\n\n emitError(error: any): void {\n this.emit('error', error);\n }\n\n emitWarn(message: any): void {\n this.emit('warn', message);\n }\n\n emitDebug(message: string): void {\n if (this.Config.debug) this.emit('debug', message);\n }\n}\n\nexport default MDNSServices;\n","import { AT1000Base as AT1000 } from './at1000';\n\nimport { Scanner, Services } from './mdns-scanner';\n\nexport const findDevices = async (timeout: number = 500): Promise<AT1000[]> => {\n if (timeout < 10) {\n timeout = 10;\n }\n\n let scanner = new Scanner({ debug: true });\n let services = new Services(scanner);\n\n services.on('error', (error: string) => {\n if (!error.includes('bind ENOENT')) {\n throw Error(error);\n }\n });\n\n let ready = await scanner.init();\n if (!ready) {\n throw new Error('Failed to initialize mDNS scanner');\n }\n scanner.query('_at1000_server._tcp.local');\n\n await new Promise((r) => setTimeout(r, timeout));\n\n // Extract unique IP addresses from discovered services, preferring IPv4 over IPv6\n const addresses = [\n ...new Set(\n Object\n .values(services.namedServices)\n .filter((s: any) => s !== undefined && s.service !== undefined)\n .filter((s: any) => (s.service.name as string).endsWith('_at1000_server._tcp.local'))\n .map((s: any) => {\n const ipv4 = s.addresses?.find((a: any) => a.family === 'IPv4');\n const ipv6 = s.addresses?.find((a: any) => a.family === 'IPv6');\n return (ipv4 ?? ipv6)?.address;\n })\n .filter((address: string | undefined) => address !== undefined),\n ),\n ];\n\n scanner.destroy();\n\n const results = await Promise.allSettled(addresses.map((address) => AT1000.create(address)));\n return results.filter((r): r is PromiseFulfilledResult<AT1000> => r.status === 'fulfilled').map((\n r,\n ) => r.value);\n};\n","import { version } from '../package.json';\nimport { AT1000Base } from './at1000';\nimport { findDevices } from './discovery';\n\n/** @hideconstructor */\nexport class AT1000 extends AT1000Base {\n static readonly apiVersion = version;\n\n static findDevices(timeout: number = 500): Promise<AT1000[]> {\n return findDevices(timeout);\n }\n}\n"],"mappings":"6XAAA,MAAa,EAAY,cACZ,EAAY,WACZ,EAAY,KACZ,EAAO,OAEP,EAAO,OCDd,EAAoB,CAACA,EAAgB,EAAoBC,EAAgB,EAAmB,CASlG,IAAM,EAAN,MAAM,CAAW,CAEf,OAAO,cAAc,EAA0D,CAC7E,OAAS,EAEL,EAAW,yBAAyB,EAAiB,CADrD,EAAW,kBAAkB,CAKnC,OAAO,kBAAuC,CAC5C,IAAM,EAAiC,EAAE,CACnC,EAAkB,EAAE,CACpB,EAAeC,EAAAA,QAAG,mBAAmB,CAC3C,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,EAAa,CAClD,EAAM,SAAS,EAAK,GAGxB,EAAM,KAAK,EAAK,CAChB,GAAO,QAAS,GAAe,CAG3B,EAAW,UACR,CAAC,EAAkB,SAAS,EAAW,OAAO,EAC9C,kBAAkB,KAAK,EAAW,QAAQ,EAE/C,EAAW,KAAK,CACR,OACN,QAAS,EAAW,QACpB,OAAQ,EAAW,OACnB,QAAS,EAAW,QACrB,CAAC,EACF,EAEJ,GAAI,CAAC,EAAW,OAAQ,MAAU,MAAM,+CAA+C,CACvF,OAAO,EAIT,OAAO,yBAAyB,EAAyD,CACvF,IAAM,EAAiB,MAAM,QAAQ,EAAiB,CAAG,EAAmB,CAAC,EAAiB,CACxF,EAAa,KAAK,kBAAkB,CAAC,OAAQ,GAC1C,EAAe,QAAQ,EAAQ,IAE7B,GACD,KAAW,qBAAqB,EAAiB,EAAM,QAAQ,EAC5D,EAAM,OAAS,GAGvB,GAAM,CACT,CACF,GAAI,CAAC,GAAc,CAAC,EAAW,OAC7B,MAAU,MAAM,+CAA+C,CAEjE,OAAO,EAIT,OAAO,qBAAqB,EAAqB,EAA0B,CAEzE,IAAI,EACA,EACJ,GAAI,CACF,EAAgB,IAAIC,EAAAA,QAAG,SAAS,EAAY,CAC5C,EAAiB,IAAIA,EAAAA,QAAG,SAAS,EAAQ,MAE/B,CACV,GAAI,CACF,EAAgB,IAAIA,EAAAA,QAAG,SAAS,EAAY,CAC5C,EAAiB,IAAIA,EAAAA,QAAG,SAAS,EAAQ,MAE/B,CACV,MAAO,IAIX,OAAO,EAAc,QAAQ,GAAK,EAAe,QAAQ,GCxD7D,MAAM,EAAoB,CACxB,WAAY,EAAE,CACd,UAAW,GACX,IAAK,IACL,SAAU,GACV,WAAY,EAAiB,IAAuB,CAClD,QAAQ,IAAI,WAAa,EAAQ,UAAU,CAAC,EAE9C,YAAc,GAAiB,CAC7B,QAAQ,IAAI,gBAAkB,EAAM,QAAQ,EAE/C,CAED,IAAM,EAAN,MAAM,CAAQ,CACZ,OAAO,iBAAiB,EAA4C,CAClE,GAAI,CAAC,EAAS,iBACZ,MAAU,MAAM,2CAA2C,CAE7D,GAAI,CAAC,EAAS,cACZ,MAAU,MAAM,wCAAwC,CAK5D,OAAO,sBAAsB,EAA6D,CACxF,OAAO,IAAI,SAAS,EAAS,IAAY,CACvC,IAAM,EAAiB,OAAO,OAAO,EAAE,CAAE,EAAmB,EAAS,CACrE,EAAQ,iBAAiB,EAAe,CAExC,IAAM,EAASC,EAAAA,QAAM,aAAa,CAChC,KAAMC,EAAAA,QAAG,SAAS,QAAQ,EAAe,iBAAiB,CAAG,OAAS,OACtE,UAAW,EAAe,UAC3B,CAAC,CAEE,EAAc,GAElB,EACG,GAAG,QAAU,GAAU,CAClB,EACF,EAAe,YAAY,EAAM,EAEjC,EAAO,OAAO,CACd,EAAQ,CAAE,QAAS,GAAc,QAAO,CAAC,GAE3C,CACD,GAAG,gBAAmB,CACrB,EAAc,GACd,EAAO,gBAAgB,EAAe,KAAO,IAAI,CACjD,EAAO,qBAAqB,EAAe,UAAY,GAAK,CAC5D,IAAM,EAAS,EAAQ,wBAAwB,EAAQ,EAAe,CACtE,GAAI,CAAC,EAAO,YAAY,OAAQ,CAC9B,EAAc,GACd,EAAO,OAAO,CACd,EAAQ,CACN,QAAS,GACT,MAAW,MACT,kDAAoD,EAAe,iBACpE,CACF,CAAC,CACF,OAEF,EAAQ,OAAO,OAAO,CAAE,QAAS,GAAM,CAAE,EAAQ,CAAE,SAAQ,CAAC,CAAC,EAC7D,CACD,GAAG,WAAY,EAAK,IAAU,CAC7B,EAAe,UAAU,EAAK,EAAM,EACpC,CAEJ,EAAO,KAAK,CAAE,KAAM,EAAe,cAAe,UAAW,GAAO,CAAC,EACrE,CAIJ,OAAO,wBACL,EACA,EAC4E,CAC5E,IAAM,EAAkC,EAAE,CACpC,EAAwC,EAAE,CAC1C,EAASA,EAAAA,QAAG,SAAS,QAAQ,EAAS,iBAAiB,CACzD,CAACC,EAAgB,EAAmB,CACpC,CAACC,EAAgB,EAAmB,CAWxC,OAVA,EAAS,WAAW,QAAS,GAAU,CAChC,KAAO,SAAS,EAAM,OAAO,CAClC,GAAI,CACF,EAAO,cAAc,EAAS,iBAAkB,EAAQ,iBAAiB,EAAM,CAAC,CAChF,EAAY,KAAK,EAAM,MAET,CACd,EAAkB,KAAK,EAAM,GAE/B,CACK,CAAE,cAAa,oBAAmB,CAI3C,aAAa,iBACX,EACA,EACA,EACA,EACuB,CACvB,OAAO,IAAI,SAAS,EAAS,IAAY,CACvC,IAAM,EAASH,EAAAA,QAAM,aAAa,CAChC,KAAM,CAAC,OAAgB,EAAmB,CAAC,SAAS,EAAM,OAAO,CAAG,OAAS,OAC7E,UAAW,IAAS,UACrB,CAAC,CACE,EAAQ,GACZ,EACG,GAAG,QAAU,GAAU,CACjB,EAIH,EAAY,EAAM,EAHlB,EAAO,OAAO,CACd,EAAQ,CAAE,QAAS,GAAO,MAAW,MAAM,EAAM,QAAQ,CAAE,CAAC,GAI9D,CACD,GAAG,gBAAmB,CACrB,EAAQ,GACR,EAAQ,CAAE,QAAS,GAAM,QAAO,SAAQ,KAAM,EAAO,KAAK,KAAK,EAAO,CAAE,CAAC,EACzE,CACD,GAAG,WAAY,EAAK,IAA+C,CAElE,EAAM,UAAY,EAAM,KACxB,EAAU,EAAK,EAAM,EACrB,CACD,KAAK,EAAS,SAAW,EAAG,EAAQ,iBAAiB,EAAM,CAAC,EAC/D,CAIJ,OAAO,iBAAiB,EAAiC,CAUvD,MARI,CAAC,OAAgB,EAAmB,CAAC,SAAS,EAAM,OAAO,CACtD,EAAM,QAIX,EAAM,QACD,GAAG,EAAM,QAAQ,GAAG,EAAM,UAE5B,EAAM,UCtJjB,MAAMI,EAAoC,CACxC,UAAW,GACX,QAAS,EACT,WAAY,KACZ,IAAK,IACL,SAAU,GACV,MAAO,GACR,CAED,IAAM,EAAN,cAA0BC,EAAAA,YAAa,CACrC,OACA,MACA,eACA,YACA,WACA,UAEA,YAAY,EAAwB,CAClC,OAAO,CACP,KAAK,OAAS,OAAO,OAAO,EAAE,CAAED,EAAU,EAAO,CACjD,KAAK,MAAQ,GACb,KAAK,eAAiB,EAAE,CACxB,KAAK,YAAc,EAAE,CAIvB,MAAM,MAAyB,CAC7B,GAAI,CACF,KAAK,WAAa,EAAW,cAAc,KAAK,OAAO,YAAc,IAAA,GAAU,OACxE,EAAO,CAEd,MADA,KAAK,UAAU,EAAM,CACf,EAMR,OAJA,KAAK,UAAU,uBAAuBE,EAAAA,QAAK,QAAQ,KAAK,WAAW,GAAG,CACtE,MAAM,KAAK,sBAAsB,CACjC,MAAM,KAAK,mBAAmB,CAC1B,KAAK,eAAe,QAAU,KAAK,YAAY,SAAQ,KAAK,MAAQ,IACjE,KAAK,MAId,MAAM,sBAA0C,CAC9C,GAAI,CAAC,KAAK,WAAY,MAAO,EAAE,CAC/B,IAAM,EAAO,KAAK,WAAW,OAAO,GAClC,CAACC,EAAgB,EAAmB,CAAC,SAAS,EAAE,OAAO,CACxD,CACK,EAAO,KAAK,WAAW,OAAO,GAClC,CAACC,EAAgB,EAAmB,CAAC,SAAS,EAAE,OAAO,CACxD,CAQD,GAPA,KAAK,UACH,6BAA6B,EAAK,OAAS,IAAMD,EAAiB,KAChE,EAAK,QAAU,EAAK,OAChB,OACA,KACH,EAAK,OAAS,IAAMC,EAAiB,KACzC,CACG,EAAK,OAAQ,CACf,IAAM,EAAa,MAAM,EAAQ,sBAAsB,CACrD,iBAAkBC,EAClB,cAAeC,EACf,WAAY,EACZ,UAAW,KAAK,UAAU,KAAK,KAAK,CACpC,YAAa,KAAK,YAAY,KAAK,KAAK,CACzC,CAAC,CACE,EAAW,QAAS,KAAK,eAAe,KAAK,EAAW,CACnD,EAAW,OAAO,KAAK,UAAU,EAAW,MAAM,QAAQ,CAErE,GAAI,EAAK,OAAQ,CACf,IAAM,EAAa,MAAM,EAAQ,sBAAsB,CACrD,iBAAkBC,EAClB,cAAeD,EACf,WAAY,EACZ,UAAW,KAAK,UAAU,KAAK,KAAK,CACpC,YAAa,KAAK,YAAY,KAAK,KAAK,CACzC,CAAC,CACE,EAAW,QAAS,KAAK,eAAe,KAAK,EAAW,CACnD,EAAW,OAAO,KAAK,UAAU,EAAW,MAAM,QAAQ,CAErE,OAAO,KAAK,eAId,MAAM,mBAAmC,CAClC,QAAK,WACV,MAAK,UAAU,0BAA0B,KAAK,WAAW,OAAO,wBAAwB,CACxF,IAAK,IAAI,EAAI,EAAG,EAAI,KAAK,WAAW,OAAQ,IAAK,CAC/C,IAAM,EAAa,MAAM,EAAQ,iBAC/B,KAAK,WAAW,GAChB,KAAK,OACL,KAAK,UAAU,KAAK,KAAK,CACzB,KAAK,YAAY,KAAK,KAAK,CAC5B,CACG,EAAW,QAAS,KAAK,YAAY,KAAK,EAAW,CAChD,EAAW,OAAO,KAAK,UAAU,EAAW,MAAM,QAAQ,GAKvE,UAAU,EAAiB,EAAyB,CAClD,IAAI,EACJ,GAAI,CACF,EAASE,EAAAA,QAAU,OAAO,EAAQ,OAC3B,EAAO,CACd,OAAO,KAAK,SAAS,EAAM,CAE7B,KAAK,KAAK,SAAU,EAAQ,EAAM,CAIpC,YAAY,EAAkB,CACxB,EAAM,OAAS,UAAY,EAAM,OAAS,cAAgB,EAAM,OAAS,gBAC3E,KAAK,UAAU,EAAM,CAErB,KAAK,SAAS,EAAM,CAMxB,MAAM,EAAgC,EAAmC,CACvE,IAAI,EACJ,GAAI,OAAO,GAAc,SACvB,EAAgB,CAAC,CAAE,KAAM,EAAW,KAAO,GAAS,MAAsB,CAAC,SAClE,MAAM,QAAQ,EAAU,CACjC,EAAgB,OAEhB,MAAU,MAAM,4DAA4D,CAE9E,IAAM,EAAQ,CAAE,KAAM,QAAkB,UAAW,EAAe,CAClE,KAAK,UAAU,oBAAoBN,EAAAA,QAAK,QAAQ,EAAM,GAAG,CACzD,KAAK,KAAK,EAAM,CAIlB,KAAK,EAAqB,CACxB,GAAI,KAAK,UAAW,OACpB,IAAM,EAASM,EAAAA,QAAU,OAAO,EAAM,CACtC,IAAK,IAAI,EAAI,EAAG,EAAI,KAAK,YAAY,OAAQ,IAAK,CAChD,IAAM,EAAS,KAAK,YAAY,GAChC,GAAI,EAAO,MAAQ,EAAO,MACxB,GAAI,CACF,EAAO,KACL,EACA,EACA,EAAO,OACPF,EACA,CAAC,OAAgB,EAAmB,CAAC,SAAS,EAAO,MAAM,OAAO,CAC9DD,EACAE,EAAsB,IAAM,EAAO,MAAM,KAC9C,CACD,KAAK,UAAU,kBAAkB,EAAO,MAAM,UAAU,MAClD,IAQd,SAAgB,CACd,KAAK,UAAY,GACjB,KAAK,MAAQ,GACb,KAAK,oBAAoB,CACzB,KAAK,YAAY,QAAQ,GAAK,CAC5B,GAAI,CACF,EAAE,QAAQ,OAAO,MACX,IACR,CACF,KAAK,YAAc,EAAE,CACrB,KAAK,eAAe,QAAQ,GAAK,CAC/B,GAAI,CACF,EAAE,QAAQ,OAAO,MACX,IACR,CACF,KAAK,eAAiB,EAAE,CAO1B,UAAU,EAAkB,CAC1B,KAAK,KAAK,QAAS,EAAM,CAG3B,SAAS,EAAoB,CAC3B,KAAK,KAAK,OAAQ,EAAQ,CAG5B,UAAU,EAAuB,CAC3B,KAAK,OAAO,OAAO,KAAK,KAAK,QAAS,EAAQ,GChMtD,MAAM,EAAqC,CAAE,MAAO,GAAO,CAE3D,IAAM,EAAN,cAA2BE,EAAAA,YAAa,CACtC,OACA,QACA,MACA,cACA,eAEA,YAAY,EAAsB,EAAyB,CACzD,OAAO,CACP,KAAK,eAAiB,KAAK,SAAS,KAAK,KAAK,CAC9C,KAAK,QAAU,EACf,KAAK,OAAS,OAAO,OAAO,EAAE,CAAE,EAAU,EAAO,CACjD,KAAK,MAAQ,EAAE,CACf,KAAK,cAAgB,EAAE,CACvB,KAAK,cAAc,KAAK,QAAQ,CAChC,KAAK,OAAO,CAId,OAAc,CACZ,KAAK,mBAAmB,KAAK,QAAQ,CACrC,KAAK,MAAQ,EAAE,CACf,KAAK,cAAgB,EAAE,CACvB,KAAK,iBAAiB,KAAK,QAAQ,CAIrC,cAAc,EAA4B,CACxC,EACG,GAAG,QAAU,GAAe,CAC3B,KAAK,UAAU,EAAM,EACrB,CACD,GAAG,OAAS,GAAiB,CAC5B,KAAK,SAAS,EAAQ,EACtB,CACD,GAAG,QAAU,GAAoB,CAChC,KAAK,UAAU,EAAQ,EACvB,CAIN,iBAAiB,EAA4B,CAC3C,EAAQ,GAAG,SAAU,KAAK,eAAe,CAI3C,mBAAmB,EAA4B,CAC7C,EAAQ,eAAe,SAAU,KAAK,eAAe,CAIvD,SAAS,EAAgB,EAAyB,CAEhD,OADA,KAAK,UAAU,wBAAwB,EAAO,KAAK,QAAQ,EAAM,QAAQ,GAAG,CACpE,EAAO,KAAf,CACE,IAAK,QACH,KAAK,KAAK,QAAS,EAAQ,EAAM,CACjC,MAEF,IAAK,WACH,KAAK,UACH,iCAAiC,EAAM,QAAQ,QAC7C,EAAO,QACH,EAAO,QAAQ,OACf,EACL,eAAe,EAAO,YAAc,EAAO,YAAY,OAAS,EAAE,eACpE,CACG,EAAO,SAAS,KAAK,eAAe,EAAO,QAAS,EAAM,CAC1D,EAAO,aAAa,KAAK,eAAe,EAAO,YAAa,EAAM,CAEtE,OAKN,eAAe,EAAmB,EAAyB,CACzD,KAAK,UAAU,uCAAuC,CAEtD,IAAM,EAAe,KAAK,kBAAkB,EAAQ,CACpD,KAAK,kBAAkB,EAAQ,CAC/B,KAAK,gBAAgB,EAAQ,CAC7B,KAAK,mBAAmB,EAAQ,CAChC,KAAK,kBAAkB,EAAS,EAAM,CACtC,EAAa,QAAQ,GAAQ,CAC3B,KAAK,KAAK,aAAc,CAAE,KAAM,UAAW,KAAM,KAAK,cAAc,GAAO,CAAC,EAC5E,CAGJ,kBAAkB,EAA6B,CAC7C,IAAM,EAAyB,EAAE,CAWjC,OAVA,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,MAAO,OAC3B,KAAK,UAAU,yBAAyB,CACxC,IAAM,EAAW,EAAO,KAAK,UAAU,CAClC,EAAa,SAAS,EAAS,EAAE,EAAa,KAAK,EAAS,CACjE,KAAK,cAAc,GAAY,KAAK,cAAc,IAAa,EAAE,CACjE,KAAK,cAAc,GAAU,QAAU,EACvC,KAAK,cAAc,GAAU,KAAQ,EAAO,KAAa,OAAO,UAAU,CAC1E,KAAK,cAAc,GAAU,KAAQ,EAAO,KAAa,MACzD,CACK,EAGT,kBAAkB,EAAyB,CACzC,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,MAAO,OAC3B,KAAK,UAAU,yBAAyB,CACxC,IAAM,EAAO,EAAO,KACpB,GAAI,MAAM,QAAQ,EAAK,EAAI,EAAK,OAAS,EAAG,CAC1C,IAAM,EAAW,EAAO,KAAK,UAAU,CACvC,KAAK,cAAc,GAAY,KAAK,cAAc,IAAa,EAAE,CACjE,KAAK,cAAc,GAAU,IAAM,KAAK,sBAAsB,OAAO,OAAO,EAAK,CAAC,SACzE,OAAO,SAAS,EAAK,CAAE,CAChC,IAAM,EAAW,EAAO,KAAK,UAAU,CACvC,KAAK,cAAc,GAAY,KAAK,cAAc,IAAa,EAAE,CACjE,KAAK,cAAc,GAAU,IAAM,KAAK,sBAAsB,EAAK,GAErE,CAGJ,gBAAgB,EAAyB,CACvC,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,IAAK,OACzB,KAAK,UAAU,uBAAuB,CACtC,IAAM,EAAW,EAAO,KAAK,UAAU,CACjC,EAAW,EAAe,KAAK,UAAU,CAC/C,IAAK,IAAM,KAAe,KAAK,cACzB,KAAK,cAAc,GAAa,OAAS,IAC7C,KAAK,cAAc,GAAa,UAAY,KAAK,cAAc,GAAa,WAAa,EAAE,CAC5E,KAAK,cAAc,GAAa,UAAW,QAAQ,EAAG,IAC5D,GAAK,EAAE,UAAY,EACzB,GAAM,EAEP,KAAK,cAAc,GAAa,UAAW,KAAK,CAAE,OAAQC,EAAgB,UAAS,CAAC,GAGxF,CAGJ,mBAAmB,EAAyB,CAC1C,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,OAAQ,OAC5B,KAAK,UAAU,0BAA0B,CACzC,IAAM,EAAW,EAAO,KAAK,UAAU,CACjC,EAAW,EAAe,KAAK,UAAU,CAC/C,IAAK,IAAM,KAAe,KAAK,cACzB,KAAK,cAAc,GAAa,OAAS,IAC7C,KAAK,cAAc,GAAa,UAAY,KAAK,cAAc,GAAa,WAAa,EAAE,CAC5E,KAAK,cAAc,GAAa,UAAW,QAAQ,EAAG,IAC5D,GAAK,EAAE,UAAY,EACzB,GAAM,EAEP,KAAK,cAAc,GAAa,UAAW,KAAK,CAAE,OAAQC,EAAgB,UAAS,CAAC,GAGxF,CAGJ,kBAAkB,EAAmB,EAAyB,CAC5D,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,MAAO,OAC3B,KAAK,UAAU,yBAAyB,CACxC,IAAM,EAAc,KAAK,mBAAmB,EAAO,CAC7C,EAAY,EAAe,KAAK,UAAU,CAE5C,IAAgB,IAClB,KAAK,cAAc,GAAY,KAAK,cAAc,IAAa,EAAE,CACjE,KAAK,cAAc,GAAU,KAAO,EAAS,QAAQ,IAAM,EAAa,GAAG,CAC3E,KAAK,cAAc,GAAU,MAAQ,IAEvC,CAIJ,mBAAmB,EAAwB,CACzC,IAAM,EAAQ,EAAe,KACvB,EAAQ,2BAA2B,KAAK,EAAK,UAAU,CAAC,CACxD,EAAc,EAAQ,EAAM,GAAK,EAAK,UAAU,CAOtD,OANK,KAAK,MAAM,SAAS,EAAY,GACnC,KAAK,MAAM,KAAK,EAAY,CAC5B,KAAK,KAAK,aAAc,CAAE,KAAM,OAAQ,KAAM,EAAa,CAAC,CAC5D,KAAK,UAAU,yBAAyB,EAAY,GAAG,CACvD,KAAK,QAAQ,MAAM,EAAa,MAAM,EAEjC,EAIT,sBACE,EAC8D,CAC9D,IAAM,EAAoB,EAAE,CACtB,EAAkC,EAAE,CACtC,EAAY,EACZ,EAAQ,EAAK,GACjB,KAAO,GAAO,CACZ,IAAM,EAAO,EAAK,MAAM,EAAY,EAAG,EAAY,EAAI,EAAM,CAC7D,EAAQ,KAAK,EAAK,UAAU,CAAC,CAC7B,IAAM,EAAU,oBAAoB,KAAK,EAAK,UAAU,CAAC,CACrD,IACF,EAAQ,EAAQ,IAAM,EAAQ,IAEhC,EAAY,EAAY,EAAI,EAC5B,EAAQ,EAAK,GAEf,MAAO,CAAW,UAAS,cAAe,EAAS,CAOrD,UAAU,EAAkB,CAC1B,KAAK,KAAK,QAAS,EAAM,CAG3B,SAAS,EAAoB,CAC3B,KAAK,KAAK,OAAQ,EAAQ,CAG5B,UAAU,EAAuB,CAC3B,KAAK,OAAO,OAAO,KAAK,KAAK,QAAS,EAAQ,GC9OtD,MAAa,EAAc,MAAO,EAAkB,MAA2B,CACzE,EAAU,KACZ,EAAU,IAGZ,IAAI,EAAU,IAAIC,EAAQ,CAAE,MAAO,GAAM,CAAC,CACtC,EAAW,IAAIC,EAAS,EAAQ,CASpC,GAPA,EAAS,GAAG,QAAU,GAAkB,CACtC,GAAI,CAAC,EAAM,SAAS,cAAc,CAChC,MAAM,MAAM,EAAM,EAEpB,CAGE,CADQ,MAAM,EAAQ,MAAM,CAE9B,MAAU,MAAM,oCAAoC,CAEtD,EAAQ,MAAM,4BAA4B,CAE1C,MAAM,IAAI,QAAS,GAAM,WAAW,EAAG,EAAQ,CAAC,CAGhD,IAAM,EAAY,CAChB,GAAG,IAAI,IACL,OACG,OAAO,EAAS,cAAc,CAC9B,OAAQ,GAAW,IAAM,IAAA,IAAa,EAAE,UAAY,IAAA,GAAU,CAC9D,OAAQ,GAAY,EAAE,QAAQ,KAAgB,SAAS,4BAA4B,CAAC,CACpF,IAAK,GAAW,CACf,IAAM,EAAO,EAAE,WAAW,KAAM,GAAW,EAAE,SAAW,OAAO,CACzD,EAAO,EAAE,WAAW,KAAM,GAAW,EAAE,SAAW,OAAO,CAC/D,OAAQ,GAAQ,IAAO,SACvB,CACD,OAAQ,GAAgC,IAAY,IAAA,GAAU,CAClE,CACF,CAKD,OAHA,EAAQ,SAAS,EAED,MAAM,QAAQ,WAAW,EAAU,IAAK,GAAYC,EAAAA,EAAO,OAAO,EAAQ,CAAC,CAAC,EAC7E,OAAQ,GAA2C,EAAE,SAAW,YAAY,CAAC,IAC1F,GACG,EAAE,MAAM,EC1Cf,IAAa,EAAb,cAA4BC,EAAAA,CAAW,CACrC,OAAgB,WAAaC,EAAAA,EAE7B,OAAO,YAAY,EAAkB,IAAwB,CAC3D,OAAO,EAAY,EAAQ"}
|
package/build/node.d.cts
CHANGED
package/build/node.d.mts
CHANGED
package/build/node.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e,t}from"./at1000-COqCU7HR.mjs";import"./common-DzTRbz1N.mjs";import n from"dns-packet";import{EventEmitter as r}from"node:events";import i from"node:util";import a from"ip-address";import o from"node:os";import s from"node:dgram";const c=`224.0.0.251`,l=`FF02::FB`,u=5353,d=`IPv4`,f=`IPv6`,p=[d,4,f,6];var m=class e{static getInterfaces(t){return t?e.getInterfacesFromStrings(t):e.getAllInterfaces()}static getAllInterfaces(){let e=[],t=[],n=o.networkInterfaces();for(let[r,i]of Object.entries(n))t.includes(r)||(t.push(r),i?.forEach(t=>{t.internal||!p.includes(t.family)||/^(2002|2001):/gi.exec(t.address)||e.push({name:r,address:t.address,family:t.family,scopeid:t.scopeid})}));if(!e.length)throw Error(`No usable network interfaces returned by OS.`);return e}static getInterfacesFromStrings(t){let n=Array.isArray(t)?t:[t],r=this.getAllInterfaces().filter(t=>n.reduce((n,r)=>n||!!(e.stringMatchesAddress(r,t.address)||t.name===r),!1));if(!r||!r.length)throw Error(`No usable network interfaces returned by OS.`);return r}static stringMatchesAddress(e,t){let n,r;try{n=new a.Address4(e),r=new a.Address4(t)}catch{try{n=new a.Address6(e),r=new a.Address6(t)}catch{return!1}}return n.bigInt()===r.bigInt()}};const h={interfaces:[],reuseAddr:!0,ttl:255,loopback:!0,onMessage:(e,t)=>{console.log(`Message `+e.toString())},socketError:e=>{console.log(`Socket error `+e.message)}};var g=class e{static validateSettings(e){if(!e.multicastAddress)throw Error(`Socket settings require multicastAddress`);if(!e.multicastPort)throw Error(`Socket settings require multicastPort`)}static createMulticastSocket(t){return new Promise((n,r)=>{let i=Object.assign({},h,t);e.validateSettings(i);let o=s.createSocket({type:a.Address4.isValid(i.multicastAddress)?`udp4`:`udp6`,reuseAddr:i.reuseAddr}),c=!1;o.on(`error`,e=>{c?i.socketError(e):(o.close(),n({success:!1,error:e}))}).on(`listening`,()=>{c=!0,o.setMulticastTTL(i.ttl??255),o.setMulticastLoopback(i.loopback??!0);let t=e.addMulticastMemberships(o,i);if(!t.memberships.length){c=!1,o.close(),n({success:!1,error:Error(`No interface memberships for multicast address `+i.multicastAddress)});return}n(Object.assign({success:!0},t,{socket:o}))}).on(`message`,(e,t)=>{i.onMessage(e,t)}),o.bind({port:i.multicastPort,exclusive:!1})})}static addMulticastMemberships(t,n){let r=[],i=[],o=a.Address4.isValid(n.multicastAddress)?[d,4]:[f,6];return n.interfaces.forEach(a=>{if(o.includes(a.family))try{t.addMembership(n.multicastAddress,e.interfaceAddress(a)),r.push(a)}catch{i.push(a)}}),{memberships:r,failedMemberships:i}}static async createSendSocket(t,n,r,i){return new Promise((a,o)=>{let c=s.createSocket({type:[`IPv4`,4].includes(t.family)?`udp4`:`udp6`,reuseAddr:!!n.reuseAddr}),l=!1;c.on(`error`,e=>{l?i(e):(c.close(),a({success:!1,error:Error(e.message)}))}).on(`listening`,()=>{l=!0,a({success:!0,iface:t,socket:c,send:c.send.bind(c)})}).on(`message`,(e,n)=>{n.interface=t.name,r(e,n)}).bind(n.srcPort||0,e.interfaceAddress(t))})}static interfaceAddress(e){return[`IPv4`,4].includes(e.family)?e.address:e.scopeid?`${e.address}%${e.scopeid}`:e.address}};const _={reuseAddr:!0,srcPort:0,interfaces:null,ttl:255,loopback:!0,debug:!1};var v=class extends r{Config;ready;receiveSockets;sendSockets;interfaces;destroyed;constructor(e){super(),this.Config=Object.assign({},_,e),this.ready=!1,this.receiveSockets=[],this.sendSockets=[]}async init(){try{this.interfaces=m.getInterfaces(this.Config.interfaces||void 0)}catch(e){throw this.emitError(e),e}return this.emitDebug(`Scanner interfaces: ${i.inspect(this.interfaces)}`),await this.createReceiveSockets(),await this.createSendSockets(),this.receiveSockets.length&&this.sendSockets.length&&(this.ready=!0),this.ready}async createReceiveSockets(){if(!this.interfaces)return[];let e=this.interfaces.filter(e=>[d,4].includes(e.family)),t=this.interfaces.filter(e=>[f,6].includes(e.family));if(this.emitDebug(`Create receive sockets for${e.length?` `+d:``}${e.length&&t.length?` and`:``}${t.length?` `+f:``}`),e.length){let t=await g.createMulticastSocket({multicastAddress:c,multicastPort:u,interfaces:e,onMessage:this.onMessage.bind(this),socketError:this.socketError.bind(this)});t.success?this.receiveSockets.push(t):t.error&&this.emitError(t.error.message)}if(t.length){let e=await g.createMulticastSocket({multicastAddress:l,multicastPort:u,interfaces:t,onMessage:this.onMessage.bind(this),socketError:this.socketError.bind(this)});e.success?this.receiveSockets.push(e):e.error&&this.emitError(e.error.message)}return this.receiveSockets}async createSendSockets(){if(this.interfaces){this.emitDebug(`Create send sockets on ${this.interfaces.length} interfaces/addresses.`);for(let e=0;e<this.interfaces.length;e++){let t=await g.createSendSocket(this.interfaces[e],this.Config,this.onMessage.bind(this),this.socketError.bind(this));t.success?this.sendSockets.push(t):t.error&&this.emitError(t.error.message)}}}onMessage(e,t){let r;try{r=n.decode(e)}catch(e){return this.emitWarn(e)}this.emit(`packet`,r,t)}socketError(e){e.code===`EACCES`||e.code===`EADDRINUSE`||e.code===`EADDRNOTAVAIL`?this.emitError(e):this.emitWarn(e)}query(e,t){let n;if(typeof e==`string`)n=[{name:e,type:t||`ANY`}];else if(Array.isArray(e))n=e;else throw Error(`Query questions must be an array of mDNS query questions.`);let r={type:`query`,questions:n};this.emitDebug(`Send mDNS query: ${i.inspect(r)}`),this.send(r)}send(e){if(this.destroyed)return;let t=n.encode(e);for(let e=0;e<this.sendSockets.length;e++){let n=this.sendSockets[e];if(n.send&&n.iface)try{n.send(t,0,t.length,u,[`IPv4`,4].includes(n.iface.family)?c:l+`%`+n.iface.name),this.emitDebug(`Send packet on ${n.iface.address}`)}catch{}}}destroy(){this.destroyed=!0,this.ready=!1,this.removeAllListeners(),this.sendSockets.forEach(e=>{try{e.socket?.close()}catch{}}),this.sendSockets=[],this.receiveSockets.forEach(e=>{try{e.socket?.close()}catch{}}),this.receiveSockets=[]}emitError(e){this.emit(`error`,e)}emitWarn(e){this.emit(`warn`,e)}emitDebug(e){this.Config.debug&&this.emit(`debug`,e)}};const y={debug:!1};var b=class extends r{Config;scanner;types;namedServices;packetListener;constructor(e,t){super(),this.packetListener=this.onPacket.bind(this),this.scanner=e,this.Config=Object.assign({},y,t),this.types=[],this.namedServices={},this.forwardEvents(this.scanner),this.reset()}reset(){this.removeMDNSListener(this.scanner),this.types=[],this.namedServices={},this.listenMDNSEvents(this.scanner)}forwardEvents(e){e.on(`error`,e=>{this.emitError(e)}).on(`warn`,e=>{this.emitWarn(e)}).on(`debug`,e=>{this.emitDebug(e)})}listenMDNSEvents(e){e.on(`packet`,this.packetListener)}removeMDNSListener(e){e.removeListener(`packet`,this.packetListener)}onPacket(e,t){switch(this.emitDebug(`Received packet type ${e.type} from ${t.address}.`),e.type){case`query`:this.emit(`query`,e,t);break;case`response`:this.emitDebug(`Received response packet from ${t.address} with ${e.answers?e.answers.length:0} answers and ${e.additionals?e.additionals.length:0} additionals.`),e.answers&&this.processAnswers(e.answers,t),e.additionals&&this.processAnswers(e.additionals,t);break}}processAnswers(e,t){this.emitDebug(`Processing answers or additionals...`);let n=this.processSRVAnswers(e);this.processTXTAnswers(e),this.processAAnswers(e),this.processAAAAAnswers(e),this.processPTRAnswers(e,t),n.forEach(e=>{this.emit(`discovered`,{type:`service`,data:this.namedServices[e]})})}processSRVAnswers(e){let t=[];return e.forEach(e=>{if(e.type!==`SRV`)return;this.emitDebug(`Processing SRV answer.`);let n=e.name.toString();t.includes(n)||t.push(n),this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].service=e,this.namedServices[n].host=e.data.target.toString(),this.namedServices[n].port=e.data.port}),t}processTXTAnswers(e){e.forEach(e=>{if(e.type!==`TXT`)return;this.emitDebug(`Processing TXT answer.`);let t=e.data;if(Array.isArray(t)&&t.length>1){let n=e.name.toString();this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].txt=this.answerDataToKeyValues(Buffer.concat(t))}else if(Buffer.isBuffer(t)){let n=e.name.toString();this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].txt=this.answerDataToKeyValues(t)}})}processAAnswers(e){e.forEach(e=>{if(e.type!==`A`)return;this.emitDebug(`Processing A answer.`);let t=e.name.toString(),n=e.data.toString();for(let e in this.namedServices)this.namedServices[e].host===t&&(this.namedServices[e].addresses=this.namedServices[e].addresses||[],this.namedServices[e].addresses.reduce((e,t)=>e||t.address===n,!1)||this.namedServices[e].addresses.push({family:d,address:n}))})}processAAAAAnswers(e){e.forEach(e=>{if(e.type!==`AAAA`)return;this.emitDebug(`Processing AAAA answer.`);let t=e.name.toString(),n=e.data.toString();for(let e in this.namedServices)this.namedServices[e].host===t&&(this.namedServices[e].addresses=this.namedServices[e].addresses||[],this.namedServices[e].addresses.reduce((e,t)=>e||t.address===n,!1)||this.namedServices[e].addresses.push({family:f,address:n}))})}processPTRAnswers(e,t){e.forEach(e=>{if(e.type!==`PTR`)return;this.emitDebug(`Processing PTR answer.`);let n=this.serviceTypeFromPTR(e),r=e.data.toString();n!==r&&(this.namedServices[r]=this.namedServices[r]||{},this.namedServices[r].name=r.replace(`.`+n,``),this.namedServices[r].rinfo=t)})}serviceTypeFromPTR(e){let t=e.data,n=/(?:^|^.+?(?:\.))(_.*)$/gm.exec(t.toString()),r=n?n[1]:t.toString();return this.types.includes(r)||(this.types.push(r),this.emit(`discovered`,{type:`type`,data:r}),this.emitDebug(`Scanning service type ${r}.`),this.scanner.query(r,`ANY`)),r}answerDataToKeyValues(e){let t=[],n={},r=0,i=e[r];for(;i;){let a=e.slice(r+1,r+1+i);t.push(a.toString());let o=/^([^=]+)=([^=]*)$/.exec(a.toString());o&&(n[o[1]]=o[2]),r=r+1+i,i=e[r]}return{strings:t,keyValuePairs:n}}emitError(e){this.emit(`error`,e)}emitWarn(e){this.emit(`warn`,e)}emitDebug(e){this.Config.debug&&this.emit(`debug`,e)}};const x=async(e=500)=>{e<10&&(e=10);let n=new v({debug:!0}),r=new b(n);if(r.on(`error`,e=>{if(!e.includes(`bind ENOENT`))throw Error(e)}),!await n.init())throw Error(`Failed to initialize mDNS scanner`);n.query(`_at1000_server._tcp.local`),await new Promise(t=>setTimeout(t,e));let i=[...new Set(Object.values(r.namedServices).filter(e=>e!==void 0&&e.service!==void 0).filter(e=>e.service.name.endsWith(`_at1000_server._tcp.local`)).map(e=>e.addresses.filter(e=>e.family==`IPv4`).pop()?.address).filter(e=>e!==void 0))];return n.destroy(),(await Promise.allSettled(i.map(e=>t.create(e)))).filter(e=>e.status===`fulfilled`).map(e=>e.value)};var S=class extends t{static apiVersion=e;static findDevices(e=500){return x(e)}};export{S as AT1000};
|
|
1
|
+
import{n as e,t}from"./at1000-D2141F9Y.mjs";import"./common-DzTRbz1N.mjs";import n from"dns-packet";import{EventEmitter as r}from"node:events";import i from"node:util";import a from"ip-address";import o from"node:os";import s from"node:dgram";const c=`224.0.0.251`,l=`FF02::FB`,u=5353,d=`IPv4`,f=`IPv6`,p=[d,4,f,6];var m=class e{static getInterfaces(t){return t?e.getInterfacesFromStrings(t):e.getAllInterfaces()}static getAllInterfaces(){let e=[],t=[],n=o.networkInterfaces();for(let[r,i]of Object.entries(n))t.includes(r)||(t.push(r),i?.forEach(t=>{t.internal||!p.includes(t.family)||/^(2002|2001):/gi.exec(t.address)||e.push({name:r,address:t.address,family:t.family,scopeid:t.scopeid})}));if(!e.length)throw Error(`No usable network interfaces returned by OS.`);return e}static getInterfacesFromStrings(t){let n=Array.isArray(t)?t:[t],r=this.getAllInterfaces().filter(t=>n.reduce((n,r)=>n||!!(e.stringMatchesAddress(r,t.address)||t.name===r),!1));if(!r||!r.length)throw Error(`No usable network interfaces returned by OS.`);return r}static stringMatchesAddress(e,t){let n,r;try{n=new a.Address4(e),r=new a.Address4(t)}catch{try{n=new a.Address6(e),r=new a.Address6(t)}catch{return!1}}return n.bigInt()===r.bigInt()}};const h={interfaces:[],reuseAddr:!0,ttl:255,loopback:!0,onMessage:(e,t)=>{console.log(`Message `+e.toString())},socketError:e=>{console.log(`Socket error `+e.message)}};var g=class e{static validateSettings(e){if(!e.multicastAddress)throw Error(`Socket settings require multicastAddress`);if(!e.multicastPort)throw Error(`Socket settings require multicastPort`)}static createMulticastSocket(t){return new Promise((n,r)=>{let i=Object.assign({},h,t);e.validateSettings(i);let o=s.createSocket({type:a.Address4.isValid(i.multicastAddress)?`udp4`:`udp6`,reuseAddr:i.reuseAddr}),c=!1;o.on(`error`,e=>{c?i.socketError(e):(o.close(),n({success:!1,error:e}))}).on(`listening`,()=>{c=!0,o.setMulticastTTL(i.ttl??255),o.setMulticastLoopback(i.loopback??!0);let t=e.addMulticastMemberships(o,i);if(!t.memberships.length){c=!1,o.close(),n({success:!1,error:Error(`No interface memberships for multicast address `+i.multicastAddress)});return}n(Object.assign({success:!0},t,{socket:o}))}).on(`message`,(e,t)=>{i.onMessage(e,t)}),o.bind({port:i.multicastPort,exclusive:!1})})}static addMulticastMemberships(t,n){let r=[],i=[],o=a.Address4.isValid(n.multicastAddress)?[d,4]:[f,6];return n.interfaces.forEach(a=>{if(o.includes(a.family))try{t.addMembership(n.multicastAddress,e.interfaceAddress(a)),r.push(a)}catch{i.push(a)}}),{memberships:r,failedMemberships:i}}static async createSendSocket(t,n,r,i){return new Promise((a,o)=>{let c=s.createSocket({type:[`IPv4`,4].includes(t.family)?`udp4`:`udp6`,reuseAddr:!!n.reuseAddr}),l=!1;c.on(`error`,e=>{l?i(e):(c.close(),a({success:!1,error:Error(e.message)}))}).on(`listening`,()=>{l=!0,a({success:!0,iface:t,socket:c,send:c.send.bind(c)})}).on(`message`,(e,n)=>{n.interface=t.name,r(e,n)}).bind(n.srcPort||0,e.interfaceAddress(t))})}static interfaceAddress(e){return[`IPv4`,4].includes(e.family)?e.address:e.scopeid?`${e.address}%${e.scopeid}`:e.address}};const _={reuseAddr:!0,srcPort:0,interfaces:null,ttl:255,loopback:!0,debug:!1};var v=class extends r{Config;ready;receiveSockets;sendSockets;interfaces;destroyed;constructor(e){super(),this.Config=Object.assign({},_,e),this.ready=!1,this.receiveSockets=[],this.sendSockets=[]}async init(){try{this.interfaces=m.getInterfaces(this.Config.interfaces||void 0)}catch(e){throw this.emitError(e),e}return this.emitDebug(`Scanner interfaces: ${i.inspect(this.interfaces)}`),await this.createReceiveSockets(),await this.createSendSockets(),this.receiveSockets.length&&this.sendSockets.length&&(this.ready=!0),this.ready}async createReceiveSockets(){if(!this.interfaces)return[];let e=this.interfaces.filter(e=>[d,4].includes(e.family)),t=this.interfaces.filter(e=>[f,6].includes(e.family));if(this.emitDebug(`Create receive sockets for${e.length?` `+d:``}${e.length&&t.length?` and`:``}${t.length?` `+f:``}`),e.length){let t=await g.createMulticastSocket({multicastAddress:c,multicastPort:u,interfaces:e,onMessage:this.onMessage.bind(this),socketError:this.socketError.bind(this)});t.success?this.receiveSockets.push(t):t.error&&this.emitError(t.error.message)}if(t.length){let e=await g.createMulticastSocket({multicastAddress:l,multicastPort:u,interfaces:t,onMessage:this.onMessage.bind(this),socketError:this.socketError.bind(this)});e.success?this.receiveSockets.push(e):e.error&&this.emitError(e.error.message)}return this.receiveSockets}async createSendSockets(){if(this.interfaces){this.emitDebug(`Create send sockets on ${this.interfaces.length} interfaces/addresses.`);for(let e=0;e<this.interfaces.length;e++){let t=await g.createSendSocket(this.interfaces[e],this.Config,this.onMessage.bind(this),this.socketError.bind(this));t.success?this.sendSockets.push(t):t.error&&this.emitError(t.error.message)}}}onMessage(e,t){let r;try{r=n.decode(e)}catch(e){return this.emitWarn(e)}this.emit(`packet`,r,t)}socketError(e){e.code===`EACCES`||e.code===`EADDRINUSE`||e.code===`EADDRNOTAVAIL`?this.emitError(e):this.emitWarn(e)}query(e,t){let n;if(typeof e==`string`)n=[{name:e,type:t||`ANY`}];else if(Array.isArray(e))n=e;else throw Error(`Query questions must be an array of mDNS query questions.`);let r={type:`query`,questions:n};this.emitDebug(`Send mDNS query: ${i.inspect(r)}`),this.send(r)}send(e){if(this.destroyed)return;let t=n.encode(e);for(let e=0;e<this.sendSockets.length;e++){let n=this.sendSockets[e];if(n.send&&n.iface)try{n.send(t,0,t.length,u,[`IPv4`,4].includes(n.iface.family)?c:l+`%`+n.iface.name),this.emitDebug(`Send packet on ${n.iface.address}`)}catch{}}}destroy(){this.destroyed=!0,this.ready=!1,this.removeAllListeners(),this.sendSockets.forEach(e=>{try{e.socket?.close()}catch{}}),this.sendSockets=[],this.receiveSockets.forEach(e=>{try{e.socket?.close()}catch{}}),this.receiveSockets=[]}emitError(e){this.emit(`error`,e)}emitWarn(e){this.emit(`warn`,e)}emitDebug(e){this.Config.debug&&this.emit(`debug`,e)}};const y={debug:!1};var b=class extends r{Config;scanner;types;namedServices;packetListener;constructor(e,t){super(),this.packetListener=this.onPacket.bind(this),this.scanner=e,this.Config=Object.assign({},y,t),this.types=[],this.namedServices={},this.forwardEvents(this.scanner),this.reset()}reset(){this.removeMDNSListener(this.scanner),this.types=[],this.namedServices={},this.listenMDNSEvents(this.scanner)}forwardEvents(e){e.on(`error`,e=>{this.emitError(e)}).on(`warn`,e=>{this.emitWarn(e)}).on(`debug`,e=>{this.emitDebug(e)})}listenMDNSEvents(e){e.on(`packet`,this.packetListener)}removeMDNSListener(e){e.removeListener(`packet`,this.packetListener)}onPacket(e,t){switch(this.emitDebug(`Received packet type ${e.type} from ${t.address}.`),e.type){case`query`:this.emit(`query`,e,t);break;case`response`:this.emitDebug(`Received response packet from ${t.address} with ${e.answers?e.answers.length:0} answers and ${e.additionals?e.additionals.length:0} additionals.`),e.answers&&this.processAnswers(e.answers,t),e.additionals&&this.processAnswers(e.additionals,t);break}}processAnswers(e,t){this.emitDebug(`Processing answers or additionals...`);let n=this.processSRVAnswers(e);this.processTXTAnswers(e),this.processAAnswers(e),this.processAAAAAnswers(e),this.processPTRAnswers(e,t),n.forEach(e=>{this.emit(`discovered`,{type:`service`,data:this.namedServices[e]})})}processSRVAnswers(e){let t=[];return e.forEach(e=>{if(e.type!==`SRV`)return;this.emitDebug(`Processing SRV answer.`);let n=e.name.toString();t.includes(n)||t.push(n),this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].service=e,this.namedServices[n].host=e.data.target.toString(),this.namedServices[n].port=e.data.port}),t}processTXTAnswers(e){e.forEach(e=>{if(e.type!==`TXT`)return;this.emitDebug(`Processing TXT answer.`);let t=e.data;if(Array.isArray(t)&&t.length>1){let n=e.name.toString();this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].txt=this.answerDataToKeyValues(Buffer.concat(t))}else if(Buffer.isBuffer(t)){let n=e.name.toString();this.namedServices[n]=this.namedServices[n]||{},this.namedServices[n].txt=this.answerDataToKeyValues(t)}})}processAAnswers(e){e.forEach(e=>{if(e.type!==`A`)return;this.emitDebug(`Processing A answer.`);let t=e.name.toString(),n=e.data.toString();for(let e in this.namedServices)this.namedServices[e].host===t&&(this.namedServices[e].addresses=this.namedServices[e].addresses||[],this.namedServices[e].addresses.reduce((e,t)=>e||t.address===n,!1)||this.namedServices[e].addresses.push({family:d,address:n}))})}processAAAAAnswers(e){e.forEach(e=>{if(e.type!==`AAAA`)return;this.emitDebug(`Processing AAAA answer.`);let t=e.name.toString(),n=e.data.toString();for(let e in this.namedServices)this.namedServices[e].host===t&&(this.namedServices[e].addresses=this.namedServices[e].addresses||[],this.namedServices[e].addresses.reduce((e,t)=>e||t.address===n,!1)||this.namedServices[e].addresses.push({family:f,address:n}))})}processPTRAnswers(e,t){e.forEach(e=>{if(e.type!==`PTR`)return;this.emitDebug(`Processing PTR answer.`);let n=this.serviceTypeFromPTR(e),r=e.data.toString();n!==r&&(this.namedServices[r]=this.namedServices[r]||{},this.namedServices[r].name=r.replace(`.`+n,``),this.namedServices[r].rinfo=t)})}serviceTypeFromPTR(e){let t=e.data,n=/(?:^|^.+?(?:\.))(_.*)$/gm.exec(t.toString()),r=n?n[1]:t.toString();return this.types.includes(r)||(this.types.push(r),this.emit(`discovered`,{type:`type`,data:r}),this.emitDebug(`Scanning service type ${r}.`),this.scanner.query(r,`ANY`)),r}answerDataToKeyValues(e){let t=[],n={},r=0,i=e[r];for(;i;){let a=e.slice(r+1,r+1+i);t.push(a.toString());let o=/^([^=]+)=([^=]*)$/.exec(a.toString());o&&(n[o[1]]=o[2]),r=r+1+i,i=e[r]}return{strings:t,keyValuePairs:n}}emitError(e){this.emit(`error`,e)}emitWarn(e){this.emit(`warn`,e)}emitDebug(e){this.Config.debug&&this.emit(`debug`,e)}};const x=async(e=500)=>{e<10&&(e=10);let n=new v({debug:!0}),r=new b(n);if(r.on(`error`,e=>{if(!e.includes(`bind ENOENT`))throw Error(e)}),!await n.init())throw Error(`Failed to initialize mDNS scanner`);n.query(`_at1000_server._tcp.local`),await new Promise(t=>setTimeout(t,e));let i=[...new Set(Object.values(r.namedServices).filter(e=>e!==void 0&&e.service!==void 0).filter(e=>e.service.name.endsWith(`_at1000_server._tcp.local`)).map(e=>{let t=e.addresses?.find(e=>e.family===`IPv4`),n=e.addresses?.find(e=>e.family===`IPv6`);return(t??n)?.address}).filter(e=>e!==void 0))];return n.destroy(),(await Promise.allSettled(i.map(e=>t.create(e)))).filter(e=>e.status===`fulfilled`).map(e=>e.value)};var S=class extends t{static apiVersion=e;static findDevices(e=500){return x(e)}};export{S as AT1000};
|
|
2
2
|
//# sourceMappingURL=node.mjs.map
|
package/build/node.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.mjs","names":["Constants.IPv4","Constants.IPv6","Constants.IPv4","Constants.IPv6","Defaults","Constants.IPv4","Constants.IPv6","Constants.MDNS_IPV4","Constants.MDNS_PORT","Constants.MDNS_IPV6","Constants.IPv4","Constants.IPv6","Scanner","Services","AT1000"],"sources":["../src/mdns-scanner/constants.ts","../src/mdns-scanner/interfaces.ts","../src/mdns-scanner/sockets.ts","../src/mdns-scanner/scanner.ts","../src/mdns-scanner/services.ts","../src/discovery.ts","../src/node.ts"],"sourcesContent":["export const MDNS_IPV4 = '224.0.0.251';\nexport const MDNS_IPV6 = 'FF02::FB';\nexport const MDNS_PORT = 5353;\nexport const IPv4 = 'IPv4';\nexport const IPv4_INT = 4; // beginning in node 18 family is integer\nexport const IPv6 = 'IPv6';\nexport const IPv6_INT = 6; // beginning in node 18 family is integer\nexport const ANY_IPV4 = '0.0.0.0';\nexport const ANY_IPV6 = '::';\n\nexport const ErrorMessages = { NO_INTERFACES: 'No available interfaces.' };\n","import IP from 'ip-address';\nimport OS from 'node:os';\nimport * as Constants from './constants.js';\n\nconst SupportedFamilies = [Constants.IPv4, Constants.IPv4_INT, Constants.IPv6, Constants.IPv6_INT];\n\nexport interface NetworkInterface {\n name: string;\n address: string;\n family: string | number;\n scopeid?: number;\n}\n\nclass Interfaces {\n // select appropriate method based on argument\n static getInterfaces(interfaceStrings?: string | string[]): NetworkInterface[] {\n return (!interfaceStrings\n ? Interfaces.getAllInterfaces()\n : Interfaces.getInterfacesFromStrings(interfaceStrings));\n }\n\n // get all usable interfaces from OS\n static getAllInterfaces(): NetworkInterface[] {\n const interfaces: NetworkInterface[] = [];\n const names: string[] = [];\n const osInterfaces = OS.networkInterfaces();\n for (const [name, iface] of Object.entries(osInterfaces)) {\n if (names.includes(name)) {\n continue;\n }\n names.push(name);\n iface?.forEach((assignment) => {\n // check if interface is usable\n if (\n assignment.internal // cannot use internal\n || !SupportedFamilies.includes(assignment.family) // can only use IPv4 and IPv6 family\n || /^(2002|2001):/ig.exec(assignment.address) // cannot use IPv6 special prefix\n ) return;\n interfaces.push({\n name: name,\n address: assignment.address,\n family: assignment.family,\n scopeid: assignment.scopeid,\n });\n });\n }\n if (!interfaces.length) throw new Error('No usable network interfaces returned by OS.');\n return interfaces;\n }\n\n // get interfaces from configuration strings\n static getInterfacesFromStrings(interfaceStrings: string | string[]): NetworkInterface[] {\n const interfaceArray = Array.isArray(interfaceStrings) ? interfaceStrings : [interfaceStrings];\n const interfaces = this.getAllInterfaces().filter((iface) => {\n return interfaceArray.reduce((result, interfaceString) => {\n // return result || (((IP.isV4Format(interfaceString) || IP.isV6Format(interfaceString)) && IP.isEqual(iface.address, interfaceString)) || iface.name === interfaceString ? true : false);\n return result\n || (Interfaces.stringMatchesAddress(interfaceString, iface.address)\n || iface.name === interfaceString\n ? true\n : false);\n }, false);\n });\n if (!interfaces || !interfaces.length) {\n throw new Error('No usable network interfaces returned by OS.');\n }\n return interfaces;\n }\n\n // compare interface settings string to os interface address\n static stringMatchesAddress(ifaceString: string, address: string): boolean {\n // try to create address objects\n let stringAddress: IP.Address4 | IP.Address6;\n let addressAddress: IP.Address4 | IP.Address6;\n try {\n stringAddress = new IP.Address4(ifaceString);\n addressAddress = new IP.Address4(address);\n // oxlint-disable-next-line no-unused-vars\n } catch (e) {\n try {\n stringAddress = new IP.Address6(ifaceString);\n addressAddress = new IP.Address6(address);\n // oxlint-disable-next-line no-unused-vars\n } catch (e) {\n return false;\n }\n }\n // compare addresses\n return stringAddress.bigInt() === addressAddress.bigInt();\n }\n}\n\nexport default Interfaces;\n","import IP from 'ip-address';\nimport type { RemoteInfo, Socket as DgramSocket } from 'node:dgram';\nimport DGram from 'node:dgram';\nimport * as Constants from './constants.js';\nimport type { NetworkInterface } from './interfaces.js';\n\nexport interface MulticastSettings {\n multicastAddress: string;\n multicastPort: number;\n interfaces: NetworkInterface[];\n reuseAddr?: boolean;\n ttl?: number;\n loopback?: boolean;\n onMessage: (message: Buffer, rinfo: RemoteInfo) => void;\n socketError: (error: Error) => void;\n}\n\nexport interface SendSocketSettings {\n reuseAddr?: boolean;\n srcPort?: number;\n}\n\nexport interface SocketResult {\n success: boolean;\n socket?: DgramSocket;\n memberships?: NetworkInterface[];\n failedMemberships?: NetworkInterface[];\n error?: Error;\n iface?: NetworkInterface;\n send?: (...args: any[]) => void;\n}\n\nconst MulticastDefaults = {\n interfaces: [],\n reuseAddr: true,\n ttl: 255,\n loopback: true,\n onMessage: (message: Buffer, _rinfo: RemoteInfo) => {\n console.log('Message ' + message.toString());\n },\n socketError: (error: Error) => {\n console.log('Socket error ' + error.message);\n },\n};\n\nclass Sockets {\n static validateSettings(settings: Partial<MulticastSettings>): void {\n if (!settings.multicastAddress) {\n throw new Error('Socket settings require multicastAddress');\n }\n if (!settings.multicastPort) {\n throw new Error('Socket settings require multicastPort');\n }\n }\n\n // create a multicast socket and add interfaces to group membership\n static createMulticastSocket(settings: Partial<MulticastSettings>): Promise<SocketResult> {\n return new Promise((resolve, _reject) => {\n const mergedSettings = Object.assign({}, MulticastDefaults, settings) as MulticastSettings;\n Sockets.validateSettings(mergedSettings);\n // create multicast socket to listen for packets\n const socket = DGram.createSocket({\n type: IP.Address4.isValid(mergedSettings.multicastAddress) ? 'udp4' : 'udp6',\n reuseAddr: mergedSettings.reuseAddr,\n });\n // track bind status with local variable\n let isListening = false;\n // add event listeners to socket\n socket\n .on('error', (error) => {\n if (isListening) {\n mergedSettings.socketError(error);\n } else {\n socket.close();\n resolve({ success: false, error: error });\n }\n })\n .on('listening', () => {\n isListening = true;\n socket.setMulticastTTL(mergedSettings.ttl ?? 255);\n socket.setMulticastLoopback(mergedSettings.loopback ?? true);\n const result = Sockets.addMulticastMemberships(socket, mergedSettings);\n if (!result.memberships.length) {\n isListening = false;\n socket.close();\n resolve({\n success: false,\n error: new Error(\n 'No interface memberships for multicast address ' + mergedSettings.multicastAddress,\n ),\n });\n return;\n }\n resolve(Object.assign({ success: true }, result, { socket }));\n })\n .on('message', (msg, rinfo) => {\n mergedSettings.onMessage(msg, rinfo);\n });\n // bind socket\n socket.bind({ port: mergedSettings.multicastPort, exclusive: false });\n });\n }\n\n // add interfaces to multicast membership group on socket\n static addMulticastMemberships(\n socket: DgramSocket,\n settings: MulticastSettings,\n ): { memberships: NetworkInterface[]; failedMemberships: NetworkInterface[] } {\n const memberships: NetworkInterface[] = [];\n const failedMemberships: NetworkInterface[] = [];\n const family = IP.Address4.isValid(settings.multicastAddress)\n ? [Constants.IPv4, Constants.IPv4_INT]\n : [Constants.IPv6, Constants.IPv6_INT];\n settings.interfaces.forEach((iface) => {\n if (!family.includes(iface.family)) return; // unsupported family\n try {\n socket.addMembership(settings.multicastAddress, Sockets.interfaceAddress(iface));\n memberships.push(iface);\n // oxlint-disable-next-line no-unused-vars\n } catch (error) {\n failedMemberships.push(iface);\n }\n });\n return { memberships, failedMemberships };\n }\n\n // create a socket to be used when sending mDNS packets\n static async createSendSocket(\n iface: NetworkInterface,\n settings: SendSocketSettings,\n onMessage: (message: Buffer, rinfo: RemoteInfo) => void,\n socketError: (error: Error) => void,\n ): Promise<SocketResult> {\n return new Promise((resolve, _reject) => {\n const socket = DGram.createSocket({\n type: [Constants.IPv4, Constants.IPv4_INT].includes(iface.family) ? 'udp4' : 'udp6',\n reuseAddr: settings.reuseAddr ? true : false,\n });\n let bound = false;\n socket\n .on('error', (error) => {\n if (!bound) {\n socket.close();\n resolve({ success: false, error: new Error(error.message) });\n } else {\n socketError(error);\n }\n })\n .on('listening', () => {\n bound = true;\n resolve({ success: true, iface, socket, send: socket.send.bind(socket) });\n })\n .on('message', (msg, rinfo: RemoteInfo & { interface?: string }) => {\n // include interface name so we know where the message came in\n rinfo.interface = iface.name;\n onMessage(msg, rinfo);\n })\n .bind(settings.srcPort || 0, Sockets.interfaceAddress(iface));\n });\n }\n\n // format an interface address for mDNS socket\n static interfaceAddress(iface: NetworkInterface): string {\n // IPv4 addresses don't need scope\n if ([Constants.IPv4, Constants.IPv4_INT].includes(iface.family)) {\n return iface.address;\n }\n // For IPv6 link-local addresses (scopeid > 0), append the numeric scope ID\n // Global IPv6 addresses (scopeid = 0 or undefined) don't need a scope\n if (iface.scopeid) {\n return `${iface.address}%${iface.scopeid}`;\n }\n return iface.address;\n }\n}\n\nexport default Sockets;\n","import type { Packet, Question, RecordType } from 'dns-packet';\nimport DNSPacket from 'dns-packet';\nimport type { RemoteInfo } from 'node:dgram';\nimport { EventEmitter } from 'node:events';\nimport Util from 'node:util';\nimport * as Constants from './constants.js';\nimport type { NetworkInterface } from './interfaces.js';\nimport Interfaces from './interfaces.js';\nimport type { SocketResult } from './sockets.js';\nimport Sockets from './sockets.js';\n\nexport interface ScannerConfig {\n reuseAddr?: boolean;\n srcPort?: number;\n interfaces?: string | string[] | null;\n ttl?: number;\n loopback?: boolean;\n debug?: boolean;\n}\n\ntype Socket = SocketResult;\n\nconst Defaults: Required<ScannerConfig> = {\n reuseAddr: true,\n srcPort: 0,\n interfaces: null,\n ttl: 255,\n loopback: true,\n debug: false,\n};\n\nclass MDNSScanner extends EventEmitter {\n Config: Required<ScannerConfig>;\n ready: boolean;\n receiveSockets: Socket[];\n sendSockets: Socket[];\n interfaces?: NetworkInterface[];\n destroyed?: boolean;\n\n constructor(config?: ScannerConfig) {\n super();\n this.Config = Object.assign({}, Defaults, config);\n this.ready = false;\n this.receiveSockets = [];\n this.sendSockets = [];\n }\n\n // initialize the scanner\n async init(): Promise<boolean> {\n try {\n this.interfaces = Interfaces.getInterfaces(this.Config.interfaces || undefined);\n } catch (error) {\n this.emitError(error);\n throw error;\n }\n this.emitDebug(`Scanner interfaces: ${Util.inspect(this.interfaces)}`);\n await this.createReceiveSockets();\n await this.createSendSockets();\n if (this.receiveSockets.length && this.sendSockets.length) this.ready = true;\n return this.ready;\n }\n\n // create sockets that will receive mDNS packets\n async createReceiveSockets(): Promise<Socket[]> {\n if (!this.interfaces) return [];\n const ipv4 = this.interfaces.filter(i =>\n [Constants.IPv4, Constants.IPv4_INT].includes(i.family)\n );\n const ipv6 = this.interfaces.filter(i =>\n [Constants.IPv6, Constants.IPv6_INT].includes(i.family)\n );\n this.emitDebug(\n `Create receive sockets for${ipv4.length ? ' ' + Constants.IPv4 : ''}${\n ipv4.length && ipv6.length\n ? ' and'\n : ''\n }${ipv6.length ? ' ' + Constants.IPv6 : ''}`,\n );\n if (ipv4.length) {\n const ipv4Socket = await Sockets.createMulticastSocket({\n multicastAddress: Constants.MDNS_IPV4,\n multicastPort: Constants.MDNS_PORT,\n interfaces: ipv4,\n onMessage: this.onMessage.bind(this),\n socketError: this.socketError.bind(this),\n });\n if (ipv4Socket.success) this.receiveSockets.push(ipv4Socket);\n else if (ipv4Socket.error) this.emitError(ipv4Socket.error.message);\n }\n if (ipv6.length) {\n const ipv6Socket = await Sockets.createMulticastSocket({\n multicastAddress: Constants.MDNS_IPV6,\n multicastPort: Constants.MDNS_PORT,\n interfaces: ipv6,\n onMessage: this.onMessage.bind(this),\n socketError: this.socketError.bind(this),\n });\n if (ipv6Socket.success) this.receiveSockets.push(ipv6Socket);\n else if (ipv6Socket.error) this.emitError(ipv6Socket.error.message);\n }\n return this.receiveSockets;\n }\n\n // create sockets used to send out mDNS packets\n async createSendSockets(): Promise<void> {\n if (!this.interfaces) return;\n this.emitDebug(`Create send sockets on ${this.interfaces.length} interfaces/addresses.`);\n for (let i = 0; i < this.interfaces.length; i++) {\n const sendSocket = await Sockets.createSendSocket(\n this.interfaces[i],\n this.Config,\n this.onMessage.bind(this),\n this.socketError.bind(this),\n );\n if (sendSocket.success) this.sendSockets.push(sendSocket);\n else if (sendSocket.error) this.emitError(sendSocket.error.message);\n }\n }\n\n // handle receive socket message\n onMessage(message: Buffer, rinfo: RemoteInfo): void {\n let packet: Packet;\n try {\n packet = DNSPacket.decode(message);\n } catch (error) {\n return this.emitWarn(error);\n }\n this.emit('packet', packet, rinfo);\n }\n\n // handle socket errors\n socketError(error: any): void {\n if (error.code === 'EACCES' || error.code === 'EADDRINUSE' || error.code === 'EADDRNOTAVAIL') {\n this.emitError(error);\n } else {\n this.emitWarn(error);\n }\n }\n\n // send an mDNS query, questions can be an array of formatted questions or a single question name string, qtype is optionally used with name string\n // oxlint-disable-next-line no-redundant-type-constituents\n query(questions: string | Question[], qtype?: RecordType | string): void {\n let questionArray: Question[];\n if (typeof questions === 'string') {\n questionArray = [{ name: questions, type: (qtype || 'ANY') as RecordType }];\n } else if (Array.isArray(questions)) {\n questionArray = questions;\n } else {\n throw new Error('Query questions must be an array of mDNS query questions.');\n }\n const query = { type: 'query' as const, questions: questionArray };\n this.emitDebug(`Send mDNS query: ${Util.inspect(query)}`);\n this.send(query);\n }\n\n // send mDNS packet\n send(value: Packet): void {\n if (this.destroyed) return;\n const packet = DNSPacket.encode(value);\n for (let i = 0; i < this.sendSockets.length; i++) {\n const socket = this.sendSockets[i];\n if (socket.send && socket.iface) {\n try {\n socket.send(\n packet,\n 0,\n packet.length,\n Constants.MDNS_PORT,\n [Constants.IPv4, Constants.IPv4_INT].includes(socket.iface.family)\n ? Constants.MDNS_IPV4\n : Constants.MDNS_IPV6 + '%' + socket.iface.name,\n );\n this.emitDebug(`Send packet on ${socket.iface.address}`);\n } catch {\n // Socket was closed between check and send — skip silently\n }\n }\n }\n }\n\n // destroy this scanner\n destroy(): void {\n this.destroyed = true;\n this.ready = false;\n this.removeAllListeners();\n this.sendSockets.forEach(s => {\n try {\n s.socket?.close();\n } catch {}\n });\n this.sendSockets = [];\n this.receiveSockets.forEach(s => {\n try {\n s.socket?.close();\n } catch {}\n });\n this.receiveSockets = [];\n }\n\n ////////////////////////\n // emit event methods //\n ////////////////////////\n\n emitError(error: any): void {\n this.emit('error', error);\n }\n\n emitWarn(message: any): void {\n this.emit('warn', message);\n }\n\n emitDebug(message: string): void {\n if (this.Config.debug) this.emit('debug', message);\n }\n}\n\nexport default MDNSScanner;\n","import type { Answer, Packet } from 'dns-packet';\nimport type { RemoteInfo } from 'node:dgram';\nimport { EventEmitter } from 'node:events';\nimport * as Constants from './constants.js';\nimport type MDNSScanner from './scanner.js';\n\nexport interface ServicesConfig {\n debug?: boolean;\n}\n\nexport interface NamedService {\n service?: Answer;\n host?: string;\n port?: number;\n txt?: { strings: string[]; keyValuePairs: Record<string, string> };\n addresses?: Array<{ family: string; address: string }>;\n name?: string;\n rinfo?: RemoteInfo;\n}\n\nconst Defaults: Required<ServicesConfig> = { debug: false };\n\nclass MDNSServices extends EventEmitter {\n Config: Required<ServicesConfig>;\n scanner: MDNSScanner;\n types: string[];\n namedServices: Record<string, NamedService>;\n private packetListener: (packet: Packet, rinfo: RemoteInfo) => void;\n\n constructor(scanner: MDNSScanner, config?: ServicesConfig) {\n super();\n this.packetListener = this.onPacket.bind(this);\n this.scanner = scanner;\n this.Config = Object.assign({}, Defaults, config);\n this.types = [];\n this.namedServices = {};\n this.forwardEvents(this.scanner);\n this.reset();\n }\n\n // reset services\n reset(): void {\n this.removeMDNSListener(this.scanner);\n this.types = [];\n this.namedServices = {};\n this.listenMDNSEvents(this.scanner);\n }\n\n // forward events received from scanner\n forwardEvents(scanner: MDNSScanner): void {\n scanner\n .on('error', (error: any) => {\n this.emitError(error);\n })\n .on('warn', (message: any) => {\n this.emitWarn(message);\n })\n .on('debug', (message: string) => {\n this.emitDebug(message);\n });\n }\n\n // handle packets from scanner\n listenMDNSEvents(scanner: MDNSScanner): void {\n scanner.on('packet', this.packetListener);\n }\n\n // remove packet listener\n removeMDNSListener(scanner: MDNSScanner): void {\n scanner.removeListener('packet', this.packetListener);\n }\n\n // on scanner packet handler\n onPacket(packet: Packet, rinfo: RemoteInfo): void {\n this.emitDebug(`Received packet type ${packet.type} from ${rinfo.address}.`);\n switch (packet.type) {\n case 'query':\n this.emit('query', packet, rinfo);\n break;\n\n case 'response':\n this.emitDebug(\n `Received response packet from ${rinfo.address} with ${\n packet.answers\n ? packet.answers.length\n : 0\n } answers and ${packet.additionals ? packet.additionals.length : 0} additionals.`,\n );\n if (packet.answers) this.processAnswers(packet.answers, rinfo);\n if (packet.additionals) this.processAnswers(packet.additionals, rinfo);\n\n break;\n }\n }\n\n // process answers or additionals in a response type packet\n processAnswers(answers: Answer[], rinfo: RemoteInfo): void {\n this.emitDebug('Processing answers or additionals...');\n // process service answers\n const serviceNames = this.processSRVAnswers(answers);\n this.processTXTAnswers(answers);\n this.processAAnswers(answers);\n this.processAAAAAnswers(answers);\n this.processPTRAnswers(answers, rinfo);\n serviceNames.forEach(name => {\n this.emit('discovered', { type: 'service', data: this.namedServices[name] });\n });\n }\n\n processSRVAnswers(answers: Answer[]): string[] {\n const serviceNames: string[] = [];\n answers.forEach(answer => {\n if (answer.type !== 'SRV') return;\n this.emitDebug(`Processing SRV answer.`);\n const fullName = answer.name.toString();\n if (!serviceNames.includes(fullName)) serviceNames.push(fullName);\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].service = answer;\n this.namedServices[fullName].host = (answer.data as any).target.toString();\n this.namedServices[fullName].port = (answer.data as any).port;\n });\n return serviceNames;\n }\n\n processTXTAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'TXT') return;\n this.emitDebug(`Processing TXT answer.`);\n const data = answer.data as Buffer | Buffer[];\n if (Array.isArray(data) && data.length > 1) {\n const fullName = answer.name.toString();\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].txt = this.answerDataToKeyValues(Buffer.concat(data));\n } else if (Buffer.isBuffer(data)) {\n const fullName = answer.name.toString();\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].txt = this.answerDataToKeyValues(data);\n }\n });\n }\n\n processAAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'A') return;\n this.emitDebug(`Processing A answer.`);\n const hostName = answer.name.toString();\n const address = (answer as any).data.toString();\n for (const serviceName in this.namedServices) {\n if (this.namedServices[serviceName].host !== hostName) continue;\n this.namedServices[serviceName].addresses = this.namedServices[serviceName].addresses || [];\n const exists = this.namedServices[serviceName].addresses!.reduce((e, a) => {\n return e || a.address === address;\n }, false);\n if (!exists) {\n this.namedServices[serviceName].addresses!.push({ family: Constants.IPv4, address });\n }\n }\n });\n }\n\n processAAAAAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'AAAA') return;\n this.emitDebug(`Processing AAAA answer.`);\n const hostName = answer.name.toString();\n const address = (answer as any).data.toString();\n for (const serviceName in this.namedServices) {\n if (this.namedServices[serviceName].host !== hostName) continue;\n this.namedServices[serviceName].addresses = this.namedServices[serviceName].addresses || [];\n const exists = this.namedServices[serviceName].addresses!.reduce((e, a) => {\n return e || a.address === address;\n }, false);\n if (!exists) {\n this.namedServices[serviceName].addresses!.push({ family: Constants.IPv6, address });\n }\n }\n });\n }\n\n processPTRAnswers(answers: Answer[], rinfo: RemoteInfo): void {\n answers.forEach(answer => {\n if (answer.type !== 'PTR') return;\n this.emitDebug(`Processing PTR answer.`);\n const serviceType = this.serviceTypeFromPTR(answer);\n const fullName = (answer as any).data.toString();\n // build host service definition if fullName is a host service\n if (serviceType !== fullName) {\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].name = fullName.replace('.' + serviceType, '');\n this.namedServices[fullName].rinfo = rinfo;\n }\n });\n }\n\n // extract service type from answer data\n serviceTypeFromPTR(answer: Answer): string {\n const data = (answer as any).data;\n const match = /(?:^|^.+?(?:\\.))(_.*)$/mg.exec(data.toString()); // get service type without hostname\n const serviceType = match ? match[1] : data.toString();\n if (!this.types.includes(serviceType)) {\n this.types.push(serviceType);\n this.emit('discovered', { type: 'type', data: serviceType });\n this.emitDebug(`Scanning service type ${serviceType}.`);\n this.scanner.query(serviceType, 'ANY');\n }\n return serviceType;\n }\n\n // extract the key=value pairs from a TXT data buffer\n answerDataToKeyValues(\n data: Buffer,\n ): { strings: string[]; keyValuePairs: Record<string, string> } {\n const strings: string[] = [];\n const kvPairs: Record<string, string> = {};\n let kvPointer = 0;\n let kvLen = data[kvPointer];\n while (kvLen) {\n const pair = data.slice(kvPointer + 1, kvPointer + 1 + kvLen);\n strings.push(pair.toString());\n const kvMatch = /^([^=]+)=([^=]*)$/.exec(pair.toString());\n if (kvMatch) {\n kvPairs[kvMatch[1]] = kvMatch[2];\n }\n kvPointer = kvPointer + 1 + kvLen;\n kvLen = data[kvPointer];\n }\n return { strings: strings, keyValuePairs: kvPairs };\n }\n\n ////////////////////////\n // emit event methods //\n ////////////////////////\n\n emitError(error: any): void {\n this.emit('error', error);\n }\n\n emitWarn(message: any): void {\n this.emit('warn', message);\n }\n\n emitDebug(message: string): void {\n if (this.Config.debug) this.emit('debug', message);\n }\n}\n\nexport default MDNSServices;\n","import { AT1000Base as AT1000 } from './at1000';\n\nimport { Scanner, Services } from './mdns-scanner';\n\nexport const findDevices = async (timeout: number = 500): Promise<AT1000[]> => {\n if (timeout < 10) {\n timeout = 10;\n }\n\n let scanner = new Scanner({ debug: true });\n let services = new Services(scanner);\n\n services.on('error', (error: string) => {\n if (!error.includes('bind ENOENT')) {\n throw Error(error);\n }\n });\n\n let ready = await scanner.init();\n if (!ready) {\n throw new Error('Failed to initialize mDNS scanner');\n }\n scanner.query('_at1000_server._tcp.local');\n\n await new Promise((r) => setTimeout(r, timeout));\n\n // Extract unique IPv4 addresses from discovered services\n const addresses = [\n ...new Set(\n Object\n .values(services.namedServices)\n .filter((s: any) => s !== undefined && s.service !== undefined)\n .filter((s: any) => (s.service.name as string).endsWith('_at1000_server._tcp.local'))\n .map((s: any) => s.addresses.filter((a: any) => a.family == 'IPv4').pop()?.address)\n .filter((ipv4: string | undefined) => ipv4 !== undefined),\n ),\n ];\n\n scanner.destroy();\n\n const results = await Promise.allSettled(addresses.map((ipv4) => AT1000.create(ipv4)));\n return results.filter((r): r is PromiseFulfilledResult<AT1000> => r.status === 'fulfilled').map((\n r,\n ) => r.value);\n};\n","import { version } from '../package.json';\nimport { AT1000Base } from './at1000';\nimport { findDevices } from './discovery';\n\n/** @hideconstructor */\nexport class AT1000 extends AT1000Base {\n static readonly apiVersion = version;\n\n static findDevices(timeout: number = 500): Promise<AT1000[]> {\n return findDevices(timeout);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"node.mjs","names":["Constants.IPv4","Constants.IPv6","Constants.IPv4","Constants.IPv6","Defaults","Constants.IPv4","Constants.IPv6","Constants.MDNS_IPV4","Constants.MDNS_PORT","Constants.MDNS_IPV6","Constants.IPv4","Constants.IPv6","Scanner","Services","AT1000"],"sources":["../src/mdns-scanner/constants.ts","../src/mdns-scanner/interfaces.ts","../src/mdns-scanner/sockets.ts","../src/mdns-scanner/scanner.ts","../src/mdns-scanner/services.ts","../src/discovery.ts","../src/node.ts"],"sourcesContent":["export const MDNS_IPV4 = '224.0.0.251';\nexport const MDNS_IPV6 = 'FF02::FB';\nexport const MDNS_PORT = 5353;\nexport const IPv4 = 'IPv4';\nexport const IPv4_INT = 4; // beginning in node 18 family is integer\nexport const IPv6 = 'IPv6';\nexport const IPv6_INT = 6; // beginning in node 18 family is integer\nexport const ANY_IPV4 = '0.0.0.0';\nexport const ANY_IPV6 = '::';\n\nexport const ErrorMessages = { NO_INTERFACES: 'No available interfaces.' };\n","import IP from 'ip-address';\nimport OS from 'node:os';\nimport * as Constants from './constants.js';\n\nconst SupportedFamilies = [Constants.IPv4, Constants.IPv4_INT, Constants.IPv6, Constants.IPv6_INT];\n\nexport interface NetworkInterface {\n name: string;\n address: string;\n family: string | number;\n scopeid?: number;\n}\n\nclass Interfaces {\n // select appropriate method based on argument\n static getInterfaces(interfaceStrings?: string | string[]): NetworkInterface[] {\n return (!interfaceStrings\n ? Interfaces.getAllInterfaces()\n : Interfaces.getInterfacesFromStrings(interfaceStrings));\n }\n\n // get all usable interfaces from OS\n static getAllInterfaces(): NetworkInterface[] {\n const interfaces: NetworkInterface[] = [];\n const names: string[] = [];\n const osInterfaces = OS.networkInterfaces();\n for (const [name, iface] of Object.entries(osInterfaces)) {\n if (names.includes(name)) {\n continue;\n }\n names.push(name);\n iface?.forEach((assignment) => {\n // check if interface is usable\n if (\n assignment.internal // cannot use internal\n || !SupportedFamilies.includes(assignment.family) // can only use IPv4 and IPv6 family\n || /^(2002|2001):/ig.exec(assignment.address) // cannot use IPv6 special prefix\n ) return;\n interfaces.push({\n name: name,\n address: assignment.address,\n family: assignment.family,\n scopeid: assignment.scopeid,\n });\n });\n }\n if (!interfaces.length) throw new Error('No usable network interfaces returned by OS.');\n return interfaces;\n }\n\n // get interfaces from configuration strings\n static getInterfacesFromStrings(interfaceStrings: string | string[]): NetworkInterface[] {\n const interfaceArray = Array.isArray(interfaceStrings) ? interfaceStrings : [interfaceStrings];\n const interfaces = this.getAllInterfaces().filter((iface) => {\n return interfaceArray.reduce((result, interfaceString) => {\n // return result || (((IP.isV4Format(interfaceString) || IP.isV6Format(interfaceString)) && IP.isEqual(iface.address, interfaceString)) || iface.name === interfaceString ? true : false);\n return result\n || (Interfaces.stringMatchesAddress(interfaceString, iface.address)\n || iface.name === interfaceString\n ? true\n : false);\n }, false);\n });\n if (!interfaces || !interfaces.length) {\n throw new Error('No usable network interfaces returned by OS.');\n }\n return interfaces;\n }\n\n // compare interface settings string to os interface address\n static stringMatchesAddress(ifaceString: string, address: string): boolean {\n // try to create address objects\n let stringAddress: IP.Address4 | IP.Address6;\n let addressAddress: IP.Address4 | IP.Address6;\n try {\n stringAddress = new IP.Address4(ifaceString);\n addressAddress = new IP.Address4(address);\n // oxlint-disable-next-line no-unused-vars\n } catch (e) {\n try {\n stringAddress = new IP.Address6(ifaceString);\n addressAddress = new IP.Address6(address);\n // oxlint-disable-next-line no-unused-vars\n } catch (e) {\n return false;\n }\n }\n // compare addresses\n return stringAddress.bigInt() === addressAddress.bigInt();\n }\n}\n\nexport default Interfaces;\n","import IP from 'ip-address';\nimport type { RemoteInfo, Socket as DgramSocket } from 'node:dgram';\nimport DGram from 'node:dgram';\nimport * as Constants from './constants.js';\nimport type { NetworkInterface } from './interfaces.js';\n\nexport interface MulticastSettings {\n multicastAddress: string;\n multicastPort: number;\n interfaces: NetworkInterface[];\n reuseAddr?: boolean;\n ttl?: number;\n loopback?: boolean;\n onMessage: (message: Buffer, rinfo: RemoteInfo) => void;\n socketError: (error: Error) => void;\n}\n\nexport interface SendSocketSettings {\n reuseAddr?: boolean;\n srcPort?: number;\n}\n\nexport interface SocketResult {\n success: boolean;\n socket?: DgramSocket;\n memberships?: NetworkInterface[];\n failedMemberships?: NetworkInterface[];\n error?: Error;\n iface?: NetworkInterface;\n send?: (...args: any[]) => void;\n}\n\nconst MulticastDefaults = {\n interfaces: [],\n reuseAddr: true,\n ttl: 255,\n loopback: true,\n onMessage: (message: Buffer, _rinfo: RemoteInfo) => {\n console.log('Message ' + message.toString());\n },\n socketError: (error: Error) => {\n console.log('Socket error ' + error.message);\n },\n};\n\nclass Sockets {\n static validateSettings(settings: Partial<MulticastSettings>): void {\n if (!settings.multicastAddress) {\n throw new Error('Socket settings require multicastAddress');\n }\n if (!settings.multicastPort) {\n throw new Error('Socket settings require multicastPort');\n }\n }\n\n // create a multicast socket and add interfaces to group membership\n static createMulticastSocket(settings: Partial<MulticastSettings>): Promise<SocketResult> {\n return new Promise((resolve, _reject) => {\n const mergedSettings = Object.assign({}, MulticastDefaults, settings) as MulticastSettings;\n Sockets.validateSettings(mergedSettings);\n // create multicast socket to listen for packets\n const socket = DGram.createSocket({\n type: IP.Address4.isValid(mergedSettings.multicastAddress) ? 'udp4' : 'udp6',\n reuseAddr: mergedSettings.reuseAddr,\n });\n // track bind status with local variable\n let isListening = false;\n // add event listeners to socket\n socket\n .on('error', (error) => {\n if (isListening) {\n mergedSettings.socketError(error);\n } else {\n socket.close();\n resolve({ success: false, error: error });\n }\n })\n .on('listening', () => {\n isListening = true;\n socket.setMulticastTTL(mergedSettings.ttl ?? 255);\n socket.setMulticastLoopback(mergedSettings.loopback ?? true);\n const result = Sockets.addMulticastMemberships(socket, mergedSettings);\n if (!result.memberships.length) {\n isListening = false;\n socket.close();\n resolve({\n success: false,\n error: new Error(\n 'No interface memberships for multicast address ' + mergedSettings.multicastAddress,\n ),\n });\n return;\n }\n resolve(Object.assign({ success: true }, result, { socket }));\n })\n .on('message', (msg, rinfo) => {\n mergedSettings.onMessage(msg, rinfo);\n });\n // bind socket\n socket.bind({ port: mergedSettings.multicastPort, exclusive: false });\n });\n }\n\n // add interfaces to multicast membership group on socket\n static addMulticastMemberships(\n socket: DgramSocket,\n settings: MulticastSettings,\n ): { memberships: NetworkInterface[]; failedMemberships: NetworkInterface[] } {\n const memberships: NetworkInterface[] = [];\n const failedMemberships: NetworkInterface[] = [];\n const family = IP.Address4.isValid(settings.multicastAddress)\n ? [Constants.IPv4, Constants.IPv4_INT]\n : [Constants.IPv6, Constants.IPv6_INT];\n settings.interfaces.forEach((iface) => {\n if (!family.includes(iface.family)) return; // unsupported family\n try {\n socket.addMembership(settings.multicastAddress, Sockets.interfaceAddress(iface));\n memberships.push(iface);\n // oxlint-disable-next-line no-unused-vars\n } catch (error) {\n failedMemberships.push(iface);\n }\n });\n return { memberships, failedMemberships };\n }\n\n // create a socket to be used when sending mDNS packets\n static async createSendSocket(\n iface: NetworkInterface,\n settings: SendSocketSettings,\n onMessage: (message: Buffer, rinfo: RemoteInfo) => void,\n socketError: (error: Error) => void,\n ): Promise<SocketResult> {\n return new Promise((resolve, _reject) => {\n const socket = DGram.createSocket({\n type: [Constants.IPv4, Constants.IPv4_INT].includes(iface.family) ? 'udp4' : 'udp6',\n reuseAddr: settings.reuseAddr ? true : false,\n });\n let bound = false;\n socket\n .on('error', (error) => {\n if (!bound) {\n socket.close();\n resolve({ success: false, error: new Error(error.message) });\n } else {\n socketError(error);\n }\n })\n .on('listening', () => {\n bound = true;\n resolve({ success: true, iface, socket, send: socket.send.bind(socket) });\n })\n .on('message', (msg, rinfo: RemoteInfo & { interface?: string }) => {\n // include interface name so we know where the message came in\n rinfo.interface = iface.name;\n onMessage(msg, rinfo);\n })\n .bind(settings.srcPort || 0, Sockets.interfaceAddress(iface));\n });\n }\n\n // format an interface address for mDNS socket\n static interfaceAddress(iface: NetworkInterface): string {\n // IPv4 addresses don't need scope\n if ([Constants.IPv4, Constants.IPv4_INT].includes(iface.family)) {\n return iface.address;\n }\n // For IPv6 link-local addresses (scopeid > 0), append the numeric scope ID\n // Global IPv6 addresses (scopeid = 0 or undefined) don't need a scope\n if (iface.scopeid) {\n return `${iface.address}%${iface.scopeid}`;\n }\n return iface.address;\n }\n}\n\nexport default Sockets;\n","import type { Packet, Question, RecordType } from 'dns-packet';\nimport DNSPacket from 'dns-packet';\nimport type { RemoteInfo } from 'node:dgram';\nimport { EventEmitter } from 'node:events';\nimport Util from 'node:util';\nimport * as Constants from './constants.js';\nimport type { NetworkInterface } from './interfaces.js';\nimport Interfaces from './interfaces.js';\nimport type { SocketResult } from './sockets.js';\nimport Sockets from './sockets.js';\n\nexport interface ScannerConfig {\n reuseAddr?: boolean;\n srcPort?: number;\n interfaces?: string | string[] | null;\n ttl?: number;\n loopback?: boolean;\n debug?: boolean;\n}\n\ntype Socket = SocketResult;\n\nconst Defaults: Required<ScannerConfig> = {\n reuseAddr: true,\n srcPort: 0,\n interfaces: null,\n ttl: 255,\n loopback: true,\n debug: false,\n};\n\nclass MDNSScanner extends EventEmitter {\n Config: Required<ScannerConfig>;\n ready: boolean;\n receiveSockets: Socket[];\n sendSockets: Socket[];\n interfaces?: NetworkInterface[];\n destroyed?: boolean;\n\n constructor(config?: ScannerConfig) {\n super();\n this.Config = Object.assign({}, Defaults, config);\n this.ready = false;\n this.receiveSockets = [];\n this.sendSockets = [];\n }\n\n // initialize the scanner\n async init(): Promise<boolean> {\n try {\n this.interfaces = Interfaces.getInterfaces(this.Config.interfaces || undefined);\n } catch (error) {\n this.emitError(error);\n throw error;\n }\n this.emitDebug(`Scanner interfaces: ${Util.inspect(this.interfaces)}`);\n await this.createReceiveSockets();\n await this.createSendSockets();\n if (this.receiveSockets.length && this.sendSockets.length) this.ready = true;\n return this.ready;\n }\n\n // create sockets that will receive mDNS packets\n async createReceiveSockets(): Promise<Socket[]> {\n if (!this.interfaces) return [];\n const ipv4 = this.interfaces.filter(i =>\n [Constants.IPv4, Constants.IPv4_INT].includes(i.family)\n );\n const ipv6 = this.interfaces.filter(i =>\n [Constants.IPv6, Constants.IPv6_INT].includes(i.family)\n );\n this.emitDebug(\n `Create receive sockets for${ipv4.length ? ' ' + Constants.IPv4 : ''}${\n ipv4.length && ipv6.length\n ? ' and'\n : ''\n }${ipv6.length ? ' ' + Constants.IPv6 : ''}`,\n );\n if (ipv4.length) {\n const ipv4Socket = await Sockets.createMulticastSocket({\n multicastAddress: Constants.MDNS_IPV4,\n multicastPort: Constants.MDNS_PORT,\n interfaces: ipv4,\n onMessage: this.onMessage.bind(this),\n socketError: this.socketError.bind(this),\n });\n if (ipv4Socket.success) this.receiveSockets.push(ipv4Socket);\n else if (ipv4Socket.error) this.emitError(ipv4Socket.error.message);\n }\n if (ipv6.length) {\n const ipv6Socket = await Sockets.createMulticastSocket({\n multicastAddress: Constants.MDNS_IPV6,\n multicastPort: Constants.MDNS_PORT,\n interfaces: ipv6,\n onMessage: this.onMessage.bind(this),\n socketError: this.socketError.bind(this),\n });\n if (ipv6Socket.success) this.receiveSockets.push(ipv6Socket);\n else if (ipv6Socket.error) this.emitError(ipv6Socket.error.message);\n }\n return this.receiveSockets;\n }\n\n // create sockets used to send out mDNS packets\n async createSendSockets(): Promise<void> {\n if (!this.interfaces) return;\n this.emitDebug(`Create send sockets on ${this.interfaces.length} interfaces/addresses.`);\n for (let i = 0; i < this.interfaces.length; i++) {\n const sendSocket = await Sockets.createSendSocket(\n this.interfaces[i],\n this.Config,\n this.onMessage.bind(this),\n this.socketError.bind(this),\n );\n if (sendSocket.success) this.sendSockets.push(sendSocket);\n else if (sendSocket.error) this.emitError(sendSocket.error.message);\n }\n }\n\n // handle receive socket message\n onMessage(message: Buffer, rinfo: RemoteInfo): void {\n let packet: Packet;\n try {\n packet = DNSPacket.decode(message);\n } catch (error) {\n return this.emitWarn(error);\n }\n this.emit('packet', packet, rinfo);\n }\n\n // handle socket errors\n socketError(error: any): void {\n if (error.code === 'EACCES' || error.code === 'EADDRINUSE' || error.code === 'EADDRNOTAVAIL') {\n this.emitError(error);\n } else {\n this.emitWarn(error);\n }\n }\n\n // send an mDNS query, questions can be an array of formatted questions or a single question name string, qtype is optionally used with name string\n // oxlint-disable-next-line no-redundant-type-constituents\n query(questions: string | Question[], qtype?: RecordType | string): void {\n let questionArray: Question[];\n if (typeof questions === 'string') {\n questionArray = [{ name: questions, type: (qtype || 'ANY') as RecordType }];\n } else if (Array.isArray(questions)) {\n questionArray = questions;\n } else {\n throw new Error('Query questions must be an array of mDNS query questions.');\n }\n const query = { type: 'query' as const, questions: questionArray };\n this.emitDebug(`Send mDNS query: ${Util.inspect(query)}`);\n this.send(query);\n }\n\n // send mDNS packet\n send(value: Packet): void {\n if (this.destroyed) return;\n const packet = DNSPacket.encode(value);\n for (let i = 0; i < this.sendSockets.length; i++) {\n const socket = this.sendSockets[i];\n if (socket.send && socket.iface) {\n try {\n socket.send(\n packet,\n 0,\n packet.length,\n Constants.MDNS_PORT,\n [Constants.IPv4, Constants.IPv4_INT].includes(socket.iface.family)\n ? Constants.MDNS_IPV4\n : Constants.MDNS_IPV6 + '%' + socket.iface.name,\n );\n this.emitDebug(`Send packet on ${socket.iface.address}`);\n } catch {\n // Socket was closed between check and send — skip silently\n }\n }\n }\n }\n\n // destroy this scanner\n destroy(): void {\n this.destroyed = true;\n this.ready = false;\n this.removeAllListeners();\n this.sendSockets.forEach(s => {\n try {\n s.socket?.close();\n } catch {}\n });\n this.sendSockets = [];\n this.receiveSockets.forEach(s => {\n try {\n s.socket?.close();\n } catch {}\n });\n this.receiveSockets = [];\n }\n\n ////////////////////////\n // emit event methods //\n ////////////////////////\n\n emitError(error: any): void {\n this.emit('error', error);\n }\n\n emitWarn(message: any): void {\n this.emit('warn', message);\n }\n\n emitDebug(message: string): void {\n if (this.Config.debug) this.emit('debug', message);\n }\n}\n\nexport default MDNSScanner;\n","import type { Answer, Packet } from 'dns-packet';\nimport type { RemoteInfo } from 'node:dgram';\nimport { EventEmitter } from 'node:events';\nimport * as Constants from './constants.js';\nimport type MDNSScanner from './scanner.js';\n\nexport interface ServicesConfig {\n debug?: boolean;\n}\n\nexport interface NamedService {\n service?: Answer;\n host?: string;\n port?: number;\n txt?: { strings: string[]; keyValuePairs: Record<string, string> };\n addresses?: Array<{ family: string; address: string }>;\n name?: string;\n rinfo?: RemoteInfo;\n}\n\nconst Defaults: Required<ServicesConfig> = { debug: false };\n\nclass MDNSServices extends EventEmitter {\n Config: Required<ServicesConfig>;\n scanner: MDNSScanner;\n types: string[];\n namedServices: Record<string, NamedService>;\n private packetListener: (packet: Packet, rinfo: RemoteInfo) => void;\n\n constructor(scanner: MDNSScanner, config?: ServicesConfig) {\n super();\n this.packetListener = this.onPacket.bind(this);\n this.scanner = scanner;\n this.Config = Object.assign({}, Defaults, config);\n this.types = [];\n this.namedServices = {};\n this.forwardEvents(this.scanner);\n this.reset();\n }\n\n // reset services\n reset(): void {\n this.removeMDNSListener(this.scanner);\n this.types = [];\n this.namedServices = {};\n this.listenMDNSEvents(this.scanner);\n }\n\n // forward events received from scanner\n forwardEvents(scanner: MDNSScanner): void {\n scanner\n .on('error', (error: any) => {\n this.emitError(error);\n })\n .on('warn', (message: any) => {\n this.emitWarn(message);\n })\n .on('debug', (message: string) => {\n this.emitDebug(message);\n });\n }\n\n // handle packets from scanner\n listenMDNSEvents(scanner: MDNSScanner): void {\n scanner.on('packet', this.packetListener);\n }\n\n // remove packet listener\n removeMDNSListener(scanner: MDNSScanner): void {\n scanner.removeListener('packet', this.packetListener);\n }\n\n // on scanner packet handler\n onPacket(packet: Packet, rinfo: RemoteInfo): void {\n this.emitDebug(`Received packet type ${packet.type} from ${rinfo.address}.`);\n switch (packet.type) {\n case 'query':\n this.emit('query', packet, rinfo);\n break;\n\n case 'response':\n this.emitDebug(\n `Received response packet from ${rinfo.address} with ${\n packet.answers\n ? packet.answers.length\n : 0\n } answers and ${packet.additionals ? packet.additionals.length : 0} additionals.`,\n );\n if (packet.answers) this.processAnswers(packet.answers, rinfo);\n if (packet.additionals) this.processAnswers(packet.additionals, rinfo);\n\n break;\n }\n }\n\n // process answers or additionals in a response type packet\n processAnswers(answers: Answer[], rinfo: RemoteInfo): void {\n this.emitDebug('Processing answers or additionals...');\n // process service answers\n const serviceNames = this.processSRVAnswers(answers);\n this.processTXTAnswers(answers);\n this.processAAnswers(answers);\n this.processAAAAAnswers(answers);\n this.processPTRAnswers(answers, rinfo);\n serviceNames.forEach(name => {\n this.emit('discovered', { type: 'service', data: this.namedServices[name] });\n });\n }\n\n processSRVAnswers(answers: Answer[]): string[] {\n const serviceNames: string[] = [];\n answers.forEach(answer => {\n if (answer.type !== 'SRV') return;\n this.emitDebug(`Processing SRV answer.`);\n const fullName = answer.name.toString();\n if (!serviceNames.includes(fullName)) serviceNames.push(fullName);\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].service = answer;\n this.namedServices[fullName].host = (answer.data as any).target.toString();\n this.namedServices[fullName].port = (answer.data as any).port;\n });\n return serviceNames;\n }\n\n processTXTAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'TXT') return;\n this.emitDebug(`Processing TXT answer.`);\n const data = answer.data as Buffer | Buffer[];\n if (Array.isArray(data) && data.length > 1) {\n const fullName = answer.name.toString();\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].txt = this.answerDataToKeyValues(Buffer.concat(data));\n } else if (Buffer.isBuffer(data)) {\n const fullName = answer.name.toString();\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].txt = this.answerDataToKeyValues(data);\n }\n });\n }\n\n processAAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'A') return;\n this.emitDebug(`Processing A answer.`);\n const hostName = answer.name.toString();\n const address = (answer as any).data.toString();\n for (const serviceName in this.namedServices) {\n if (this.namedServices[serviceName].host !== hostName) continue;\n this.namedServices[serviceName].addresses = this.namedServices[serviceName].addresses || [];\n const exists = this.namedServices[serviceName].addresses!.reduce((e, a) => {\n return e || a.address === address;\n }, false);\n if (!exists) {\n this.namedServices[serviceName].addresses!.push({ family: Constants.IPv4, address });\n }\n }\n });\n }\n\n processAAAAAnswers(answers: Answer[]): void {\n answers.forEach(answer => {\n if (answer.type !== 'AAAA') return;\n this.emitDebug(`Processing AAAA answer.`);\n const hostName = answer.name.toString();\n const address = (answer as any).data.toString();\n for (const serviceName in this.namedServices) {\n if (this.namedServices[serviceName].host !== hostName) continue;\n this.namedServices[serviceName].addresses = this.namedServices[serviceName].addresses || [];\n const exists = this.namedServices[serviceName].addresses!.reduce((e, a) => {\n return e || a.address === address;\n }, false);\n if (!exists) {\n this.namedServices[serviceName].addresses!.push({ family: Constants.IPv6, address });\n }\n }\n });\n }\n\n processPTRAnswers(answers: Answer[], rinfo: RemoteInfo): void {\n answers.forEach(answer => {\n if (answer.type !== 'PTR') return;\n this.emitDebug(`Processing PTR answer.`);\n const serviceType = this.serviceTypeFromPTR(answer);\n const fullName = (answer as any).data.toString();\n // build host service definition if fullName is a host service\n if (serviceType !== fullName) {\n this.namedServices[fullName] = this.namedServices[fullName] || {};\n this.namedServices[fullName].name = fullName.replace('.' + serviceType, '');\n this.namedServices[fullName].rinfo = rinfo;\n }\n });\n }\n\n // extract service type from answer data\n serviceTypeFromPTR(answer: Answer): string {\n const data = (answer as any).data;\n const match = /(?:^|^.+?(?:\\.))(_.*)$/mg.exec(data.toString()); // get service type without hostname\n const serviceType = match ? match[1] : data.toString();\n if (!this.types.includes(serviceType)) {\n this.types.push(serviceType);\n this.emit('discovered', { type: 'type', data: serviceType });\n this.emitDebug(`Scanning service type ${serviceType}.`);\n this.scanner.query(serviceType, 'ANY');\n }\n return serviceType;\n }\n\n // extract the key=value pairs from a TXT data buffer\n answerDataToKeyValues(\n data: Buffer,\n ): { strings: string[]; keyValuePairs: Record<string, string> } {\n const strings: string[] = [];\n const kvPairs: Record<string, string> = {};\n let kvPointer = 0;\n let kvLen = data[kvPointer];\n while (kvLen) {\n const pair = data.slice(kvPointer + 1, kvPointer + 1 + kvLen);\n strings.push(pair.toString());\n const kvMatch = /^([^=]+)=([^=]*)$/.exec(pair.toString());\n if (kvMatch) {\n kvPairs[kvMatch[1]] = kvMatch[2];\n }\n kvPointer = kvPointer + 1 + kvLen;\n kvLen = data[kvPointer];\n }\n return { strings: strings, keyValuePairs: kvPairs };\n }\n\n ////////////////////////\n // emit event methods //\n ////////////////////////\n\n emitError(error: any): void {\n this.emit('error', error);\n }\n\n emitWarn(message: any): void {\n this.emit('warn', message);\n }\n\n emitDebug(message: string): void {\n if (this.Config.debug) this.emit('debug', message);\n }\n}\n\nexport default MDNSServices;\n","import { AT1000Base as AT1000 } from './at1000';\n\nimport { Scanner, Services } from './mdns-scanner';\n\nexport const findDevices = async (timeout: number = 500): Promise<AT1000[]> => {\n if (timeout < 10) {\n timeout = 10;\n }\n\n let scanner = new Scanner({ debug: true });\n let services = new Services(scanner);\n\n services.on('error', (error: string) => {\n if (!error.includes('bind ENOENT')) {\n throw Error(error);\n }\n });\n\n let ready = await scanner.init();\n if (!ready) {\n throw new Error('Failed to initialize mDNS scanner');\n }\n scanner.query('_at1000_server._tcp.local');\n\n await new Promise((r) => setTimeout(r, timeout));\n\n // Extract unique IP addresses from discovered services, preferring IPv4 over IPv6\n const addresses = [\n ...new Set(\n Object\n .values(services.namedServices)\n .filter((s: any) => s !== undefined && s.service !== undefined)\n .filter((s: any) => (s.service.name as string).endsWith('_at1000_server._tcp.local'))\n .map((s: any) => {\n const ipv4 = s.addresses?.find((a: any) => a.family === 'IPv4');\n const ipv6 = s.addresses?.find((a: any) => a.family === 'IPv6');\n return (ipv4 ?? ipv6)?.address;\n })\n .filter((address: string | undefined) => address !== undefined),\n ),\n ];\n\n scanner.destroy();\n\n const results = await Promise.allSettled(addresses.map((address) => AT1000.create(address)));\n return results.filter((r): r is PromiseFulfilledResult<AT1000> => r.status === 'fulfilled').map((\n r,\n ) => r.value);\n};\n","import { version } from '../package.json';\nimport { AT1000Base } from './at1000';\nimport { findDevices } from './discovery';\n\n/** @hideconstructor */\nexport class AT1000 extends AT1000Base {\n static readonly apiVersion = version;\n\n static findDevices(timeout: number = 500): Promise<AT1000[]> {\n return findDevices(timeout);\n }\n}\n"],"mappings":"mPAAA,MAAa,EAAY,cACZ,EAAY,WACZ,EAAY,KACZ,EAAO,OAEP,EAAO,OCDd,EAAoB,CAACA,EAAgB,EAAoBC,EAAgB,EAAmB,CASlG,IAAM,EAAN,MAAM,CAAW,CAEf,OAAO,cAAc,EAA0D,CAC7E,OAAS,EAEL,EAAW,yBAAyB,EAAiB,CADrD,EAAW,kBAAkB,CAKnC,OAAO,kBAAuC,CAC5C,IAAM,EAAiC,EAAE,CACnC,EAAkB,EAAE,CACpB,EAAe,EAAG,mBAAmB,CAC3C,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,EAAa,CAClD,EAAM,SAAS,EAAK,GAGxB,EAAM,KAAK,EAAK,CAChB,GAAO,QAAS,GAAe,CAG3B,EAAW,UACR,CAAC,EAAkB,SAAS,EAAW,OAAO,EAC9C,kBAAkB,KAAK,EAAW,QAAQ,EAE/C,EAAW,KAAK,CACR,OACN,QAAS,EAAW,QACpB,OAAQ,EAAW,OACnB,QAAS,EAAW,QACrB,CAAC,EACF,EAEJ,GAAI,CAAC,EAAW,OAAQ,MAAU,MAAM,+CAA+C,CACvF,OAAO,EAIT,OAAO,yBAAyB,EAAyD,CACvF,IAAM,EAAiB,MAAM,QAAQ,EAAiB,CAAG,EAAmB,CAAC,EAAiB,CACxF,EAAa,KAAK,kBAAkB,CAAC,OAAQ,GAC1C,EAAe,QAAQ,EAAQ,IAE7B,GACD,KAAW,qBAAqB,EAAiB,EAAM,QAAQ,EAC5D,EAAM,OAAS,GAGvB,GAAM,CACT,CACF,GAAI,CAAC,GAAc,CAAC,EAAW,OAC7B,MAAU,MAAM,+CAA+C,CAEjE,OAAO,EAIT,OAAO,qBAAqB,EAAqB,EAA0B,CAEzE,IAAI,EACA,EACJ,GAAI,CACF,EAAgB,IAAI,EAAG,SAAS,EAAY,CAC5C,EAAiB,IAAI,EAAG,SAAS,EAAQ,MAE/B,CACV,GAAI,CACF,EAAgB,IAAI,EAAG,SAAS,EAAY,CAC5C,EAAiB,IAAI,EAAG,SAAS,EAAQ,MAE/B,CACV,MAAO,IAIX,OAAO,EAAc,QAAQ,GAAK,EAAe,QAAQ,GCxD7D,MAAM,EAAoB,CACxB,WAAY,EAAE,CACd,UAAW,GACX,IAAK,IACL,SAAU,GACV,WAAY,EAAiB,IAAuB,CAClD,QAAQ,IAAI,WAAa,EAAQ,UAAU,CAAC,EAE9C,YAAc,GAAiB,CAC7B,QAAQ,IAAI,gBAAkB,EAAM,QAAQ,EAE/C,CAED,IAAM,EAAN,MAAM,CAAQ,CACZ,OAAO,iBAAiB,EAA4C,CAClE,GAAI,CAAC,EAAS,iBACZ,MAAU,MAAM,2CAA2C,CAE7D,GAAI,CAAC,EAAS,cACZ,MAAU,MAAM,wCAAwC,CAK5D,OAAO,sBAAsB,EAA6D,CACxF,OAAO,IAAI,SAAS,EAAS,IAAY,CACvC,IAAM,EAAiB,OAAO,OAAO,EAAE,CAAE,EAAmB,EAAS,CACrE,EAAQ,iBAAiB,EAAe,CAExC,IAAM,EAAS,EAAM,aAAa,CAChC,KAAM,EAAG,SAAS,QAAQ,EAAe,iBAAiB,CAAG,OAAS,OACtE,UAAW,EAAe,UAC3B,CAAC,CAEE,EAAc,GAElB,EACG,GAAG,QAAU,GAAU,CAClB,EACF,EAAe,YAAY,EAAM,EAEjC,EAAO,OAAO,CACd,EAAQ,CAAE,QAAS,GAAc,QAAO,CAAC,GAE3C,CACD,GAAG,gBAAmB,CACrB,EAAc,GACd,EAAO,gBAAgB,EAAe,KAAO,IAAI,CACjD,EAAO,qBAAqB,EAAe,UAAY,GAAK,CAC5D,IAAM,EAAS,EAAQ,wBAAwB,EAAQ,EAAe,CACtE,GAAI,CAAC,EAAO,YAAY,OAAQ,CAC9B,EAAc,GACd,EAAO,OAAO,CACd,EAAQ,CACN,QAAS,GACT,MAAW,MACT,kDAAoD,EAAe,iBACpE,CACF,CAAC,CACF,OAEF,EAAQ,OAAO,OAAO,CAAE,QAAS,GAAM,CAAE,EAAQ,CAAE,SAAQ,CAAC,CAAC,EAC7D,CACD,GAAG,WAAY,EAAK,IAAU,CAC7B,EAAe,UAAU,EAAK,EAAM,EACpC,CAEJ,EAAO,KAAK,CAAE,KAAM,EAAe,cAAe,UAAW,GAAO,CAAC,EACrE,CAIJ,OAAO,wBACL,EACA,EAC4E,CAC5E,IAAM,EAAkC,EAAE,CACpC,EAAwC,EAAE,CAC1C,EAAS,EAAG,SAAS,QAAQ,EAAS,iBAAiB,CACzD,CAACC,EAAgB,EAAmB,CACpC,CAACC,EAAgB,EAAmB,CAWxC,OAVA,EAAS,WAAW,QAAS,GAAU,CAChC,KAAO,SAAS,EAAM,OAAO,CAClC,GAAI,CACF,EAAO,cAAc,EAAS,iBAAkB,EAAQ,iBAAiB,EAAM,CAAC,CAChF,EAAY,KAAK,EAAM,MAET,CACd,EAAkB,KAAK,EAAM,GAE/B,CACK,CAAE,cAAa,oBAAmB,CAI3C,aAAa,iBACX,EACA,EACA,EACA,EACuB,CACvB,OAAO,IAAI,SAAS,EAAS,IAAY,CACvC,IAAM,EAAS,EAAM,aAAa,CAChC,KAAM,CAAC,OAAgB,EAAmB,CAAC,SAAS,EAAM,OAAO,CAAG,OAAS,OAC7E,UAAW,IAAS,UACrB,CAAC,CACE,EAAQ,GACZ,EACG,GAAG,QAAU,GAAU,CACjB,EAIH,EAAY,EAAM,EAHlB,EAAO,OAAO,CACd,EAAQ,CAAE,QAAS,GAAO,MAAW,MAAM,EAAM,QAAQ,CAAE,CAAC,GAI9D,CACD,GAAG,gBAAmB,CACrB,EAAQ,GACR,EAAQ,CAAE,QAAS,GAAM,QAAO,SAAQ,KAAM,EAAO,KAAK,KAAK,EAAO,CAAE,CAAC,EACzE,CACD,GAAG,WAAY,EAAK,IAA+C,CAElE,EAAM,UAAY,EAAM,KACxB,EAAU,EAAK,EAAM,EACrB,CACD,KAAK,EAAS,SAAW,EAAG,EAAQ,iBAAiB,EAAM,CAAC,EAC/D,CAIJ,OAAO,iBAAiB,EAAiC,CAUvD,MARI,CAAC,OAAgB,EAAmB,CAAC,SAAS,EAAM,OAAO,CACtD,EAAM,QAIX,EAAM,QACD,GAAG,EAAM,QAAQ,GAAG,EAAM,UAE5B,EAAM,UCtJjB,MAAMC,EAAoC,CACxC,UAAW,GACX,QAAS,EACT,WAAY,KACZ,IAAK,IACL,SAAU,GACV,MAAO,GACR,CAED,IAAM,EAAN,cAA0B,CAAa,CACrC,OACA,MACA,eACA,YACA,WACA,UAEA,YAAY,EAAwB,CAClC,OAAO,CACP,KAAK,OAAS,OAAO,OAAO,EAAE,CAAEA,EAAU,EAAO,CACjD,KAAK,MAAQ,GACb,KAAK,eAAiB,EAAE,CACxB,KAAK,YAAc,EAAE,CAIvB,MAAM,MAAyB,CAC7B,GAAI,CACF,KAAK,WAAa,EAAW,cAAc,KAAK,OAAO,YAAc,IAAA,GAAU,OACxE,EAAO,CAEd,MADA,KAAK,UAAU,EAAM,CACf,EAMR,OAJA,KAAK,UAAU,uBAAuB,EAAK,QAAQ,KAAK,WAAW,GAAG,CACtE,MAAM,KAAK,sBAAsB,CACjC,MAAM,KAAK,mBAAmB,CAC1B,KAAK,eAAe,QAAU,KAAK,YAAY,SAAQ,KAAK,MAAQ,IACjE,KAAK,MAId,MAAM,sBAA0C,CAC9C,GAAI,CAAC,KAAK,WAAY,MAAO,EAAE,CAC/B,IAAM,EAAO,KAAK,WAAW,OAAO,GAClC,CAACC,EAAgB,EAAmB,CAAC,SAAS,EAAE,OAAO,CACxD,CACK,EAAO,KAAK,WAAW,OAAO,GAClC,CAACC,EAAgB,EAAmB,CAAC,SAAS,EAAE,OAAO,CACxD,CAQD,GAPA,KAAK,UACH,6BAA6B,EAAK,OAAS,IAAMD,EAAiB,KAChE,EAAK,QAAU,EAAK,OAChB,OACA,KACH,EAAK,OAAS,IAAMC,EAAiB,KACzC,CACG,EAAK,OAAQ,CACf,IAAM,EAAa,MAAM,EAAQ,sBAAsB,CACrD,iBAAkBC,EAClB,cAAeC,EACf,WAAY,EACZ,UAAW,KAAK,UAAU,KAAK,KAAK,CACpC,YAAa,KAAK,YAAY,KAAK,KAAK,CACzC,CAAC,CACE,EAAW,QAAS,KAAK,eAAe,KAAK,EAAW,CACnD,EAAW,OAAO,KAAK,UAAU,EAAW,MAAM,QAAQ,CAErE,GAAI,EAAK,OAAQ,CACf,IAAM,EAAa,MAAM,EAAQ,sBAAsB,CACrD,iBAAkBC,EAClB,cAAeD,EACf,WAAY,EACZ,UAAW,KAAK,UAAU,KAAK,KAAK,CACpC,YAAa,KAAK,YAAY,KAAK,KAAK,CACzC,CAAC,CACE,EAAW,QAAS,KAAK,eAAe,KAAK,EAAW,CACnD,EAAW,OAAO,KAAK,UAAU,EAAW,MAAM,QAAQ,CAErE,OAAO,KAAK,eAId,MAAM,mBAAmC,CAClC,QAAK,WACV,MAAK,UAAU,0BAA0B,KAAK,WAAW,OAAO,wBAAwB,CACxF,IAAK,IAAI,EAAI,EAAG,EAAI,KAAK,WAAW,OAAQ,IAAK,CAC/C,IAAM,EAAa,MAAM,EAAQ,iBAC/B,KAAK,WAAW,GAChB,KAAK,OACL,KAAK,UAAU,KAAK,KAAK,CACzB,KAAK,YAAY,KAAK,KAAK,CAC5B,CACG,EAAW,QAAS,KAAK,YAAY,KAAK,EAAW,CAChD,EAAW,OAAO,KAAK,UAAU,EAAW,MAAM,QAAQ,GAKvE,UAAU,EAAiB,EAAyB,CAClD,IAAI,EACJ,GAAI,CACF,EAAS,EAAU,OAAO,EAAQ,OAC3B,EAAO,CACd,OAAO,KAAK,SAAS,EAAM,CAE7B,KAAK,KAAK,SAAU,EAAQ,EAAM,CAIpC,YAAY,EAAkB,CACxB,EAAM,OAAS,UAAY,EAAM,OAAS,cAAgB,EAAM,OAAS,gBAC3E,KAAK,UAAU,EAAM,CAErB,KAAK,SAAS,EAAM,CAMxB,MAAM,EAAgC,EAAmC,CACvE,IAAI,EACJ,GAAI,OAAO,GAAc,SACvB,EAAgB,CAAC,CAAE,KAAM,EAAW,KAAO,GAAS,MAAsB,CAAC,SAClE,MAAM,QAAQ,EAAU,CACjC,EAAgB,OAEhB,MAAU,MAAM,4DAA4D,CAE9E,IAAM,EAAQ,CAAE,KAAM,QAAkB,UAAW,EAAe,CAClE,KAAK,UAAU,oBAAoB,EAAK,QAAQ,EAAM,GAAG,CACzD,KAAK,KAAK,EAAM,CAIlB,KAAK,EAAqB,CACxB,GAAI,KAAK,UAAW,OACpB,IAAM,EAAS,EAAU,OAAO,EAAM,CACtC,IAAK,IAAI,EAAI,EAAG,EAAI,KAAK,YAAY,OAAQ,IAAK,CAChD,IAAM,EAAS,KAAK,YAAY,GAChC,GAAI,EAAO,MAAQ,EAAO,MACxB,GAAI,CACF,EAAO,KACL,EACA,EACA,EAAO,OACPA,EACA,CAAC,OAAgB,EAAmB,CAAC,SAAS,EAAO,MAAM,OAAO,CAC9DD,EACAE,EAAsB,IAAM,EAAO,MAAM,KAC9C,CACD,KAAK,UAAU,kBAAkB,EAAO,MAAM,UAAU,MAClD,IAQd,SAAgB,CACd,KAAK,UAAY,GACjB,KAAK,MAAQ,GACb,KAAK,oBAAoB,CACzB,KAAK,YAAY,QAAQ,GAAK,CAC5B,GAAI,CACF,EAAE,QAAQ,OAAO,MACX,IACR,CACF,KAAK,YAAc,EAAE,CACrB,KAAK,eAAe,QAAQ,GAAK,CAC/B,GAAI,CACF,EAAE,QAAQ,OAAO,MACX,IACR,CACF,KAAK,eAAiB,EAAE,CAO1B,UAAU,EAAkB,CAC1B,KAAK,KAAK,QAAS,EAAM,CAG3B,SAAS,EAAoB,CAC3B,KAAK,KAAK,OAAQ,EAAQ,CAG5B,UAAU,EAAuB,CAC3B,KAAK,OAAO,OAAO,KAAK,KAAK,QAAS,EAAQ,GChMtD,MAAM,EAAqC,CAAE,MAAO,GAAO,CAE3D,IAAM,EAAN,cAA2B,CAAa,CACtC,OACA,QACA,MACA,cACA,eAEA,YAAY,EAAsB,EAAyB,CACzD,OAAO,CACP,KAAK,eAAiB,KAAK,SAAS,KAAK,KAAK,CAC9C,KAAK,QAAU,EACf,KAAK,OAAS,OAAO,OAAO,EAAE,CAAE,EAAU,EAAO,CACjD,KAAK,MAAQ,EAAE,CACf,KAAK,cAAgB,EAAE,CACvB,KAAK,cAAc,KAAK,QAAQ,CAChC,KAAK,OAAO,CAId,OAAc,CACZ,KAAK,mBAAmB,KAAK,QAAQ,CACrC,KAAK,MAAQ,EAAE,CACf,KAAK,cAAgB,EAAE,CACvB,KAAK,iBAAiB,KAAK,QAAQ,CAIrC,cAAc,EAA4B,CACxC,EACG,GAAG,QAAU,GAAe,CAC3B,KAAK,UAAU,EAAM,EACrB,CACD,GAAG,OAAS,GAAiB,CAC5B,KAAK,SAAS,EAAQ,EACtB,CACD,GAAG,QAAU,GAAoB,CAChC,KAAK,UAAU,EAAQ,EACvB,CAIN,iBAAiB,EAA4B,CAC3C,EAAQ,GAAG,SAAU,KAAK,eAAe,CAI3C,mBAAmB,EAA4B,CAC7C,EAAQ,eAAe,SAAU,KAAK,eAAe,CAIvD,SAAS,EAAgB,EAAyB,CAEhD,OADA,KAAK,UAAU,wBAAwB,EAAO,KAAK,QAAQ,EAAM,QAAQ,GAAG,CACpE,EAAO,KAAf,CACE,IAAK,QACH,KAAK,KAAK,QAAS,EAAQ,EAAM,CACjC,MAEF,IAAK,WACH,KAAK,UACH,iCAAiC,EAAM,QAAQ,QAC7C,EAAO,QACH,EAAO,QAAQ,OACf,EACL,eAAe,EAAO,YAAc,EAAO,YAAY,OAAS,EAAE,eACpE,CACG,EAAO,SAAS,KAAK,eAAe,EAAO,QAAS,EAAM,CAC1D,EAAO,aAAa,KAAK,eAAe,EAAO,YAAa,EAAM,CAEtE,OAKN,eAAe,EAAmB,EAAyB,CACzD,KAAK,UAAU,uCAAuC,CAEtD,IAAM,EAAe,KAAK,kBAAkB,EAAQ,CACpD,KAAK,kBAAkB,EAAQ,CAC/B,KAAK,gBAAgB,EAAQ,CAC7B,KAAK,mBAAmB,EAAQ,CAChC,KAAK,kBAAkB,EAAS,EAAM,CACtC,EAAa,QAAQ,GAAQ,CAC3B,KAAK,KAAK,aAAc,CAAE,KAAM,UAAW,KAAM,KAAK,cAAc,GAAO,CAAC,EAC5E,CAGJ,kBAAkB,EAA6B,CAC7C,IAAM,EAAyB,EAAE,CAWjC,OAVA,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,MAAO,OAC3B,KAAK,UAAU,yBAAyB,CACxC,IAAM,EAAW,EAAO,KAAK,UAAU,CAClC,EAAa,SAAS,EAAS,EAAE,EAAa,KAAK,EAAS,CACjE,KAAK,cAAc,GAAY,KAAK,cAAc,IAAa,EAAE,CACjE,KAAK,cAAc,GAAU,QAAU,EACvC,KAAK,cAAc,GAAU,KAAQ,EAAO,KAAa,OAAO,UAAU,CAC1E,KAAK,cAAc,GAAU,KAAQ,EAAO,KAAa,MACzD,CACK,EAGT,kBAAkB,EAAyB,CACzC,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,MAAO,OAC3B,KAAK,UAAU,yBAAyB,CACxC,IAAM,EAAO,EAAO,KACpB,GAAI,MAAM,QAAQ,EAAK,EAAI,EAAK,OAAS,EAAG,CAC1C,IAAM,EAAW,EAAO,KAAK,UAAU,CACvC,KAAK,cAAc,GAAY,KAAK,cAAc,IAAa,EAAE,CACjE,KAAK,cAAc,GAAU,IAAM,KAAK,sBAAsB,OAAO,OAAO,EAAK,CAAC,SACzE,OAAO,SAAS,EAAK,CAAE,CAChC,IAAM,EAAW,EAAO,KAAK,UAAU,CACvC,KAAK,cAAc,GAAY,KAAK,cAAc,IAAa,EAAE,CACjE,KAAK,cAAc,GAAU,IAAM,KAAK,sBAAsB,EAAK,GAErE,CAGJ,gBAAgB,EAAyB,CACvC,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,IAAK,OACzB,KAAK,UAAU,uBAAuB,CACtC,IAAM,EAAW,EAAO,KAAK,UAAU,CACjC,EAAW,EAAe,KAAK,UAAU,CAC/C,IAAK,IAAM,KAAe,KAAK,cACzB,KAAK,cAAc,GAAa,OAAS,IAC7C,KAAK,cAAc,GAAa,UAAY,KAAK,cAAc,GAAa,WAAa,EAAE,CAC5E,KAAK,cAAc,GAAa,UAAW,QAAQ,EAAG,IAC5D,GAAK,EAAE,UAAY,EACzB,GAAM,EAEP,KAAK,cAAc,GAAa,UAAW,KAAK,CAAE,OAAQC,EAAgB,UAAS,CAAC,GAGxF,CAGJ,mBAAmB,EAAyB,CAC1C,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,OAAQ,OAC5B,KAAK,UAAU,0BAA0B,CACzC,IAAM,EAAW,EAAO,KAAK,UAAU,CACjC,EAAW,EAAe,KAAK,UAAU,CAC/C,IAAK,IAAM,KAAe,KAAK,cACzB,KAAK,cAAc,GAAa,OAAS,IAC7C,KAAK,cAAc,GAAa,UAAY,KAAK,cAAc,GAAa,WAAa,EAAE,CAC5E,KAAK,cAAc,GAAa,UAAW,QAAQ,EAAG,IAC5D,GAAK,EAAE,UAAY,EACzB,GAAM,EAEP,KAAK,cAAc,GAAa,UAAW,KAAK,CAAE,OAAQC,EAAgB,UAAS,CAAC,GAGxF,CAGJ,kBAAkB,EAAmB,EAAyB,CAC5D,EAAQ,QAAQ,GAAU,CACxB,GAAI,EAAO,OAAS,MAAO,OAC3B,KAAK,UAAU,yBAAyB,CACxC,IAAM,EAAc,KAAK,mBAAmB,EAAO,CAC7C,EAAY,EAAe,KAAK,UAAU,CAE5C,IAAgB,IAClB,KAAK,cAAc,GAAY,KAAK,cAAc,IAAa,EAAE,CACjE,KAAK,cAAc,GAAU,KAAO,EAAS,QAAQ,IAAM,EAAa,GAAG,CAC3E,KAAK,cAAc,GAAU,MAAQ,IAEvC,CAIJ,mBAAmB,EAAwB,CACzC,IAAM,EAAQ,EAAe,KACvB,EAAQ,2BAA2B,KAAK,EAAK,UAAU,CAAC,CACxD,EAAc,EAAQ,EAAM,GAAK,EAAK,UAAU,CAOtD,OANK,KAAK,MAAM,SAAS,EAAY,GACnC,KAAK,MAAM,KAAK,EAAY,CAC5B,KAAK,KAAK,aAAc,CAAE,KAAM,OAAQ,KAAM,EAAa,CAAC,CAC5D,KAAK,UAAU,yBAAyB,EAAY,GAAG,CACvD,KAAK,QAAQ,MAAM,EAAa,MAAM,EAEjC,EAIT,sBACE,EAC8D,CAC9D,IAAM,EAAoB,EAAE,CACtB,EAAkC,EAAE,CACtC,EAAY,EACZ,EAAQ,EAAK,GACjB,KAAO,GAAO,CACZ,IAAM,EAAO,EAAK,MAAM,EAAY,EAAG,EAAY,EAAI,EAAM,CAC7D,EAAQ,KAAK,EAAK,UAAU,CAAC,CAC7B,IAAM,EAAU,oBAAoB,KAAK,EAAK,UAAU,CAAC,CACrD,IACF,EAAQ,EAAQ,IAAM,EAAQ,IAEhC,EAAY,EAAY,EAAI,EAC5B,EAAQ,EAAK,GAEf,MAAO,CAAW,UAAS,cAAe,EAAS,CAOrD,UAAU,EAAkB,CAC1B,KAAK,KAAK,QAAS,EAAM,CAG3B,SAAS,EAAoB,CAC3B,KAAK,KAAK,OAAQ,EAAQ,CAG5B,UAAU,EAAuB,CAC3B,KAAK,OAAO,OAAO,KAAK,KAAK,QAAS,EAAQ,GC9OtD,MAAa,EAAc,MAAO,EAAkB,MAA2B,CACzE,EAAU,KACZ,EAAU,IAGZ,IAAI,EAAU,IAAIC,EAAQ,CAAE,MAAO,GAAM,CAAC,CACtC,EAAW,IAAIC,EAAS,EAAQ,CASpC,GAPA,EAAS,GAAG,QAAU,GAAkB,CACtC,GAAI,CAAC,EAAM,SAAS,cAAc,CAChC,MAAM,MAAM,EAAM,EAEpB,CAGE,CADQ,MAAM,EAAQ,MAAM,CAE9B,MAAU,MAAM,oCAAoC,CAEtD,EAAQ,MAAM,4BAA4B,CAE1C,MAAM,IAAI,QAAS,GAAM,WAAW,EAAG,EAAQ,CAAC,CAGhD,IAAM,EAAY,CAChB,GAAG,IAAI,IACL,OACG,OAAO,EAAS,cAAc,CAC9B,OAAQ,GAAW,IAAM,IAAA,IAAa,EAAE,UAAY,IAAA,GAAU,CAC9D,OAAQ,GAAY,EAAE,QAAQ,KAAgB,SAAS,4BAA4B,CAAC,CACpF,IAAK,GAAW,CACf,IAAM,EAAO,EAAE,WAAW,KAAM,GAAW,EAAE,SAAW,OAAO,CACzD,EAAO,EAAE,WAAW,KAAM,GAAW,EAAE,SAAW,OAAO,CAC/D,OAAQ,GAAQ,IAAO,SACvB,CACD,OAAQ,GAAgC,IAAY,IAAA,GAAU,CAClE,CACF,CAKD,OAHA,EAAQ,SAAS,EAED,MAAM,QAAQ,WAAW,EAAU,IAAK,GAAYC,EAAO,OAAO,EAAQ,CAAC,CAAC,EAC7E,OAAQ,GAA2C,EAAE,SAAW,YAAY,CAAC,IAC1F,GACG,EAAE,MAAM,EC1Cf,IAAa,EAAb,cAA4B,CAAW,CACrC,OAAgB,WAAa,EAE7B,OAAO,YAAY,EAAkB,IAAwB,CAC3D,OAAO,EAAY,EAAQ"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"at1000-COqCU7HR.mjs","names":[],"sources":["../package.json","../src/at1000.ts"],"sourcesContent":["","import { up, type UpFetch } from 'up-fetch';\n\nimport { ComApi } from './api/com';\nimport { GpioApi } from './api/gpio';\nimport { HmiApi } from './api/hmi';\nimport { type Information, ManagementApi } from './api/management';\nimport { PowerApi } from './api/power';\nimport { RelaysApi } from './api/relays';\n\n/** @hideconstructor */\nexport class AT1000Base {\n /**\n * IP address or hostname of the AT1000 device\n */\n public readonly host: string;\n /**\n * Device information\n */\n public readonly info: Information;\n\n private fetch: UpFetch;\n /**\n * COM API\n */\n public readonly com: ComApi;\n /**\n * HMI API\n */\n public readonly hmi: HmiApi;\n /**\n * GPIO API\n */\n public readonly gpio: GpioApi;\n /**\n * Management API\n */\n public readonly management: ManagementApi;\n /**\n * Power management API\n */\n public readonly power: PowerApi;\n /**\n * Relays API\n */\n public readonly relays: RelaysApi;\n\n constructor(host: string, info: Information) {\n this.host = host;\n this.info = info;\n\n this.fetch = up(\n fetch,\n () => ({\n baseUrl: `http://${this.host}/v0`,\n timeout: 1000,\n parseRejected: async (response, request) => {\n let errorData: any;\n const contentType = response.headers.get('content-type');\n try {\n if (contentType?.includes('application/json')) {\n errorData = await response.json();\n } else {\n errorData = await response.text();\n }\n } catch {\n errorData = 'Failed to parse response body';\n }\n\n if (\n typeof errorData === 'object'\n && ['code', 'message', 'suggestion', 'path'].every((key) => key in errorData)\n ) {\n const formattedSuggestion = errorData.suggestion.replace(/\\n/g, '\\n ');\n throw new Error(\n `${errorData.message} (${errorData.code})\\n Suggestion: ${formattedSuggestion}\\n Path: ${errorData.path}`,\n );\n }\n\n throw new Error(\n `API request to ${request.method} ${response.url} failed with status ${response.status}: ${\n typeof errorData === 'string' ? errorData : JSON.stringify(errorData)\n }`,\n );\n },\n }),\n );\n\n this.com = new ComApi(this.fetch);\n this.hmi = new HmiApi(this.fetch);\n this.gpio = new GpioApi(this.fetch, this.info);\n this.management = new ManagementApi(this.fetch);\n this.power = new PowerApi(this.fetch, this.info);\n this.relays = new RelaysApi(this.fetch);\n }\n\n async reset() {\n await this.com.reset();\n await this.hmi.reset();\n await this.gpio.reset();\n await this.power.reset();\n await this.relays.reset();\n }\n\n public static create = async (host: string): Promise<AT1000Base> => {\n // Create a temporary client to fetch device info\n const management = new ManagementApi(\n up(fetch, () => ({ baseUrl: `http://${host}/v0`, timeout: 1000 })),\n );\n const info = await management.info();\n\n return new AT1000Base(host, info);\n };\n}\n"],"mappings":"yRCUa,EAAb,MAAa,CAAW,CAItB,KAIA,KAEA,MAIA,IAIA,IAIA,KAIA,WAIA,MAIA,OAEA,YAAY,EAAc,EAAmB,CAC3C,KAAK,KAAO,EACZ,KAAK,KAAO,EAEZ,KAAK,MAAQ,EACX,WACO,CACL,QAAS,UAAU,KAAK,KAAK,KAC7B,QAAS,IACT,cAAe,MAAO,EAAU,IAAY,CAC1C,IAAI,EACE,EAAc,EAAS,QAAQ,IAAI,eAAe,CACxD,GAAI,CACF,AAGE,EAHE,GAAa,SAAS,mBAAmB,CAC/B,MAAM,EAAS,MAAM,CAErB,MAAM,EAAS,MAAM,MAE7B,CACN,EAAY,gCAGd,GACE,OAAO,GAAc,UAClB,CAAC,OAAQ,UAAW,aAAc,OAAO,CAAC,MAAO,GAAQ,KAAO,EAAU,CAC7E,CACA,IAAM,EAAsB,EAAU,WAAW,QAAQ,MAAO;kBAAqB,CACrF,MAAU,MACR,GAAG,EAAU,QAAQ,IAAI,EAAU,KAAK,qBAAqB,EAAoB,cAAc,EAAU,OAC1G,CAGH,MAAU,MACR,kBAAkB,EAAQ,OAAO,GAAG,EAAS,IAAI,sBAAsB,EAAS,OAAO,IACrF,OAAO,GAAc,SAAW,EAAY,KAAK,UAAU,EAAU,GAExE,EAEJ,EACF,CAED,KAAK,IAAM,IAAI,EAAO,KAAK,MAAM,CACjC,KAAK,IAAM,IAAI,EAAO,KAAK,MAAM,CACjC,KAAK,KAAO,IAAI,EAAQ,KAAK,MAAO,KAAK,KAAK,CAC9C,KAAK,WAAa,IAAI,EAAc,KAAK,MAAM,CAC/C,KAAK,MAAQ,IAAI,EAAS,KAAK,MAAO,KAAK,KAAK,CAChD,KAAK,OAAS,IAAI,EAAU,KAAK,MAAM,CAGzC,MAAM,OAAQ,CACZ,MAAM,KAAK,IAAI,OAAO,CACtB,MAAM,KAAK,IAAI,OAAO,CACtB,MAAM,KAAK,KAAK,OAAO,CACvB,MAAM,KAAK,MAAM,OAAO,CACxB,MAAM,KAAK,OAAO,OAAO,CAG3B,OAAc,OAAS,KAAO,IAOrB,IAAI,EAAW,EAFT,MAHM,IAAI,EACrB,EAAG,WAAc,CAAE,QAAS,UAAU,EAAK,KAAM,QAAS,IAAM,EAAE,CACnE,CAC6B,MAAM,CAEH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"at1000-CbtCnc9k.d.mts","names":[],"sources":["../src/at1000.ts"],"mappings":";;;;;;;;;cAUa,UAAA;EAAA;;;EAAA,SAIK,IAAA;EAUK;;;EAAA,SANL,IAAA,EAAM,WAAA;EAAA,QAEd,KAAA;EAwBgB;;;EAAA,SApBR,GAAA,EAAK,MAAA;EA+EwB;;;EAAA,SA3E7B,GAAA,EAAK,MAAA;EAVL;;;EAAA,SAcA,IAAA,EAAM,OAAA;EARD;;;EAAA,SAYL,UAAA,EAAY,aAAA;EAJN;;;EAAA,SAQN,KAAA,EAAO,QAAA;EAAA;;;EAAA,SAIP,MAAA,EAAQ,SAAA;cAEZ,IAAA,UAAc,IAAA,EAAM,WAAA;EAiD1B,KAAA,CAAA,GAAK,OAAA;EAAA,OAQG,MAAA,GAAgB,IAAA,aAAe,OAAA,CAAQ,UAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"at1000-Drc2Gwwh.cjs","names":["ComApi","HmiApi","GpioApi","ManagementApi","PowerApi","RelaysApi"],"sources":["../package.json","../src/at1000.ts"],"sourcesContent":["","import { up, type UpFetch } from 'up-fetch';\n\nimport { ComApi } from './api/com';\nimport { GpioApi } from './api/gpio';\nimport { HmiApi } from './api/hmi';\nimport { type Information, ManagementApi } from './api/management';\nimport { PowerApi } from './api/power';\nimport { RelaysApi } from './api/relays';\n\n/** @hideconstructor */\nexport class AT1000Base {\n /**\n * IP address or hostname of the AT1000 device\n */\n public readonly host: string;\n /**\n * Device information\n */\n public readonly info: Information;\n\n private fetch: UpFetch;\n /**\n * COM API\n */\n public readonly com: ComApi;\n /**\n * HMI API\n */\n public readonly hmi: HmiApi;\n /**\n * GPIO API\n */\n public readonly gpio: GpioApi;\n /**\n * Management API\n */\n public readonly management: ManagementApi;\n /**\n * Power management API\n */\n public readonly power: PowerApi;\n /**\n * Relays API\n */\n public readonly relays: RelaysApi;\n\n constructor(host: string, info: Information) {\n this.host = host;\n this.info = info;\n\n this.fetch = up(\n fetch,\n () => ({\n baseUrl: `http://${this.host}/v0`,\n timeout: 1000,\n parseRejected: async (response, request) => {\n let errorData: any;\n const contentType = response.headers.get('content-type');\n try {\n if (contentType?.includes('application/json')) {\n errorData = await response.json();\n } else {\n errorData = await response.text();\n }\n } catch {\n errorData = 'Failed to parse response body';\n }\n\n if (\n typeof errorData === 'object'\n && ['code', 'message', 'suggestion', 'path'].every((key) => key in errorData)\n ) {\n const formattedSuggestion = errorData.suggestion.replace(/\\n/g, '\\n ');\n throw new Error(\n `${errorData.message} (${errorData.code})\\n Suggestion: ${formattedSuggestion}\\n Path: ${errorData.path}`,\n );\n }\n\n throw new Error(\n `API request to ${request.method} ${response.url} failed with status ${response.status}: ${\n typeof errorData === 'string' ? errorData : JSON.stringify(errorData)\n }`,\n );\n },\n }),\n );\n\n this.com = new ComApi(this.fetch);\n this.hmi = new HmiApi(this.fetch);\n this.gpio = new GpioApi(this.fetch, this.info);\n this.management = new ManagementApi(this.fetch);\n this.power = new PowerApi(this.fetch, this.info);\n this.relays = new RelaysApi(this.fetch);\n }\n\n async reset() {\n await this.com.reset();\n await this.hmi.reset();\n await this.gpio.reset();\n await this.power.reset();\n await this.relays.reset();\n }\n\n public static create = async (host: string): Promise<AT1000Base> => {\n // Create a temporary client to fetch device info\n const management = new ManagementApi(\n up(fetch, () => ({ baseUrl: `http://${host}/v0`, timeout: 1000 })),\n );\n const info = await management.info();\n\n return new AT1000Base(host, info);\n };\n}\n"],"mappings":"sOCUa,EAAb,MAAa,CAAW,CAItB,KAIA,KAEA,MAIA,IAIA,IAIA,KAIA,WAIA,MAIA,OAEA,YAAY,EAAc,EAAmB,CAC3C,KAAK,KAAO,EACZ,KAAK,KAAO,EAEZ,KAAK,OAAA,EAAA,EAAA,IACH,WACO,CACL,QAAS,UAAU,KAAK,KAAK,KAC7B,QAAS,IACT,cAAe,MAAO,EAAU,IAAY,CAC1C,IAAI,EACE,EAAc,EAAS,QAAQ,IAAI,eAAe,CACxD,GAAI,CACF,AAGE,EAHE,GAAa,SAAS,mBAAmB,CAC/B,MAAM,EAAS,MAAM,CAErB,MAAM,EAAS,MAAM,MAE7B,CACN,EAAY,gCAGd,GACE,OAAO,GAAc,UAClB,CAAC,OAAQ,UAAW,aAAc,OAAO,CAAC,MAAO,GAAQ,KAAO,EAAU,CAC7E,CACA,IAAM,EAAsB,EAAU,WAAW,QAAQ,MAAO;kBAAqB,CACrF,MAAU,MACR,GAAG,EAAU,QAAQ,IAAI,EAAU,KAAK,qBAAqB,EAAoB,cAAc,EAAU,OAC1G,CAGH,MAAU,MACR,kBAAkB,EAAQ,OAAO,GAAG,EAAS,IAAI,sBAAsB,EAAS,OAAO,IACrF,OAAO,GAAc,SAAW,EAAY,KAAK,UAAU,EAAU,GAExE,EAEJ,EACF,CAED,KAAK,IAAM,IAAIA,EAAAA,OAAO,KAAK,MAAM,CACjC,KAAK,IAAM,IAAIC,EAAAA,OAAO,KAAK,MAAM,CACjC,KAAK,KAAO,IAAIC,EAAAA,QAAQ,KAAK,MAAO,KAAK,KAAK,CAC9C,KAAK,WAAa,IAAIC,EAAAA,cAAc,KAAK,MAAM,CAC/C,KAAK,MAAQ,IAAIC,EAAAA,SAAS,KAAK,MAAO,KAAK,KAAK,CAChD,KAAK,OAAS,IAAIC,EAAAA,UAAU,KAAK,MAAM,CAGzC,MAAM,OAAQ,CACZ,MAAM,KAAK,IAAI,OAAO,CACtB,MAAM,KAAK,IAAI,OAAO,CACtB,MAAM,KAAK,KAAK,OAAO,CACvB,MAAM,KAAK,MAAM,OAAO,CACxB,MAAM,KAAK,OAAO,OAAO,CAG3B,OAAc,OAAS,KAAO,IAOrB,IAAI,EAAW,EAFT,MAHM,IAAIF,EAAAA,eAAAA,EAAAA,EAAAA,IAClB,WAAc,CAAE,QAAS,UAAU,EAAK,KAAM,QAAS,IAAM,EAAE,CACnE,CAC6B,MAAM,CAEH"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"at1000-iknorBtT.d.cts","names":[],"sources":["../src/at1000.ts"],"mappings":";;;;;;;;;cAUa,UAAA;EAAA;;;EAAA,SAIK,IAAA;EAUK;;;EAAA,SANL,IAAA,EAAM,WAAA;EAAA,QAEd,KAAA;EAwBgB;;;EAAA,SApBR,GAAA,EAAK,MAAA;EA+EwB;;;EAAA,SA3E7B,GAAA,EAAK,MAAA;EAVL;;;EAAA,SAcA,IAAA,EAAM,OAAA;EARD;;;EAAA,SAYL,UAAA,EAAY,aAAA;EAJN;;;EAAA,SAQN,KAAA,EAAO,QAAA;EAAA;;;EAAA,SAIP,MAAA,EAAQ,SAAA;cAEZ,IAAA,UAAc,IAAA,EAAM,WAAA;EAiD1B,KAAA,CAAA,GAAK,OAAA;EAAA,OAQG,MAAA,GAAgB,IAAA,aAAe,OAAA,CAAQ,UAAA;AAAA"}
|