{"version":3,"sources":["../src/index.ts","../src/Core.ts","../src/types.ts"],"sourcesContent":["/**\n * mdns-listener-advanced\n * Main entry point – re-exports the Core class and related types.\n */\n\nimport { Core } from \"./Core.js\";\n\n// Default export for CommonJS interop\nexport default Core;\n\n// Re-export shared types\nexport * from \"./types.js\";\n","// src/Core.ts\nimport { Bonjour, ServiceConfig } from \"bonjour-service\";\nimport multicastDns, { ResponsePacket } from \"multicast-dns\";\nimport { EventEmitter } from \"node:events\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { networkInterfaces, platform } from \"node:os\";\nimport { Logger } from \"tslog\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { Device, DeviceBuffer, EmittedEvent, NPM_URL, Options } from \"./types.js\";\n\nexport class Core {\n  private hostnames: string[];\n  private mdnsHostsFile?: string;\n  private readonly debugEnabled: boolean;\n  private disableListener: boolean;\n  private disablePublisher: boolean;\n  private error = false;\n\n  private readonly mdnsInstance: ReturnType<typeof multicastDns>;\n  private readonly publisher: Bonjour;\n  private readonly myEvent: EventEmitter;\n  private readonly logger: Logger<any>;\n\n  constructor(\n    hostsList?: string[] | null,\n    mdnsHostsPath?: string | null,\n    options?: Options,\n    logger?: Logger<any>,\n    mdnsInstance?: ReturnType<typeof multicastDns>,\n    myEvent?: EventEmitter,\n    publisher?: Bonjour,\n  ) {\n    this.hostnames = hostsList ?? [];\n    this.mdnsHostsFile = mdnsHostsPath ?? undefined;\n    this.debugEnabled = !!options?.debug;\n    this.disableListener = !!options?.disableListener;\n    this.disablePublisher = !!options?.disablePublisher;\n\n    this.logger = logger ?? new Logger({ name: \"MDNS ADVANCED\" });\n    this.mdnsInstance = mdnsInstance ?? multicastDns();\n    this.myEvent = myEvent ?? new EventEmitter();\n    this.publisher = publisher ?? new Bonjour();\n  }\n\n  private debug(...args: unknown[]) {\n    if (this.debugEnabled) {\n      this.logger.debug(...(args as [unknown, ...unknown[]]));\n    }\n  }\n  public setDisableListener(value: boolean): void {\n    this.disableListener = value;\n  }\n  public setDisablePublisher(value: boolean): void {\n    this.disablePublisher = value;\n  }\n  private __initListener(): void {\n    try {\n      const hostsRaw = this.__getHosts();\n      this.hostnames = hostsRaw\n        .split(/\\r?\\n/)\n        .map((line) => line.replace(/#.*/, \"\").trim())\n        .filter(Boolean);\n      if (!this.hostnames.length) {\n        this.logger.warn(\"Hosts are empty\");\n      }\n    } catch (err) {\n      this.debug(err as Error);\n      this.error = true;\n    }\n  }\n\n  private __getHosts(): string {\n    if (this.mdnsHostsFile && existsSync(this.mdnsHostsFile)) {\n      return readFileSync(this.mdnsHostsFile, { encoding: \"utf-8\" });\n    } else if (this.hostnames.length) {\n      // join with \\n for cross-platform\n      return this.hostnames.join(\"\\n\");\n    } else {\n      // fallback default\n      this.mdnsHostsFile = platform().startsWith(\"win\")\n        ? `${process.env.HOMEPATH}\\\\.mdns-hosts`\n        : `${process.env.HOME}/.mdns-hosts`;\n      if (this.mdnsHostsFile && existsSync(this.mdnsHostsFile)) {\n        return this.__getHosts();\n      }\n      this.logger.warn(\"Hostnames or path to hostnames is not provided, listening to a host is compromised!\");\n      throw new Error(`Provide hostnames or path to hostnames! Report this error ${NPM_URL}`);\n    }\n  }\n\n  private getLocalIpAddress(): string | undefined {\n    const ifaces = networkInterfaces();\n    for (const name of Object.keys(ifaces)) {\n      const net = ifaces[name];\n      if (!net) continue;\n      for (const addr of net) {\n        if (!addr.internal && addr.family === \"IPv4\" && !addr.address.startsWith(\"169.\")) {\n          return addr.address;\n        }\n      }\n    }\n    return undefined;\n  }\n\n  public publish(name: string) {\n    if (this.disablePublisher) {\n      this.logger.info(\n        \"Publisher is disabled unset 'Options.disablePublisher' or set it to 'false' to enable hosts publication !\",\n      );\n      return;\n    }\n    const options: ServiceConfig = {\n      port: 3000,\n      name,\n      type: \"TXT\",\n      txt: {\n        uuid: `\"${uuidv4()}\"`,\n        ipv4: JSON.stringify(this.getLocalIpAddress() ?? \"\"),\n      },\n    };\n    const bonjourService = this.publisher.publish(options);\n    this.logger.info(\"A hostname has been published with options\", options);\n    this.debug(bonjourService);\n    return bonjourService;\n  }\n\n  public unpublishAll(): void {\n    try {\n      this.publisher.unpublishAll();\n      this.logger.info(\"All hostnames have been unpublished\");\n    } catch (err) {\n      this.debug(\"unpublishAll error\", err);\n    }\n  }\n\n  public listen(): EventEmitter {\n    if (this.disableListener) {\n      this.logger.info(\"Listener is disabled\");\n      return this.myEvent;\n    }\n\n    this.__initListener();\n    if (this.error) {\n      const errorMessage = `An error occurred while trying to listen to mdns! Report this error ${NPM_URL}`;\n      process.nextTick(() => this.myEvent.emit(EmittedEvent.ERROR, new Error(errorMessage)));\n      return this.myEvent;\n    }\n    this.logger.info(\"Looking for hostnames...\", this.hostnames);\n\n    this.mdnsInstance.on(EmittedEvent.RESPONSE, this.handleResponse.bind(this));\n    return this.myEvent;\n  }\n\n  private handleBufferData(dataBuffer: Buffer): { [key: string]: string } {\n    const str = dataBuffer.toString(\"utf8\");\n    const props: { [key: string]: string } = {};\n    const regex = /([^=\\s]+)=(\"((?:\\\\.|[^\"\\\\])*)\"|[^\\s\"]+)/g;\n    let match: RegExpExecArray | null;\n\n    while ((match = regex.exec(str)) !== null) {\n      const key = match[1];\n      // if group 3 exists it's the inner quoted capture\n      let value = match[3] ?? match[2];\n      value = value.replace(/\\\\\"/g, '\"');\n      // strip surrounding quotes if still present\n      if (value.startsWith('\"') && value.endsWith('\"')) {\n        value = value.slice(1, -1);\n      }\n      props[key] = value;\n    }\n    return props;\n  }\n\n  private handleResponse(response: { answers: Array<DeviceBuffer> } | ResponsePacket): void {\n    const findHosts: Array<Device> = [];\n    this.debug(\"RESPONSE:\", response);\n    this.myEvent.emit(EmittedEvent.RAW_RESPONSE, response);\n\n    const answers = Array.isArray((response as any).answers) ? (response as any).answers : [];\n\n    for (const hostname of this.hostnames) {\n      for (const a of answers) {\n        if (a.data && Array.isArray(a.data) && a?.name?.includes(hostname)) {\n          findHosts.push({\n            name: a.name,\n            type: a.type,\n            data: this.handleBufferData(Buffer.concat((a.data as Buffer[]).map((d: any) => Buffer.from(d)))),\n          });\n        }\n      }\n\n      if (findHosts.length) {\n        this.myEvent.emit(EmittedEvent.RESPONSE, findHosts);\n      }\n    }\n  }\n  public info(...args: any[]): void {\n    this.logger.info(...args);\n  }\n  public stop(): void {\n    this.logger.info(\"Stopping mdns listener...\");\n    try {\n      if (this.mdnsInstance?.removeAllListeners) this.mdnsInstance.removeAllListeners();\n      if (this.myEvent?.removeAllListeners) this.myEvent.removeAllListeners();\n    } catch (err) {\n      this.debug(\"stop error\", err);\n    }\n  }\n}\n","export interface Options {\n  debug?: boolean | null;\n  disableListener?: boolean;\n  disablePublisher?: boolean;\n}\nexport const NPM_URL = \"https://www.npmjs.com/package/mdns-listener-advanced\";\n\nexport type Device = {\n  name: string;\n  type: string;\n  data: DeviceData | { [key: string]: string };\n};\nexport type DeviceBuffer = {\n  name: string;\n  type: string;\n  data: Buffer;\n};\nexport type DeviceData = {\n  uuid: string;\n  ipv4: string;\n};\n\n/**\n * Emitted event const\n */\nexport enum EmittedEvent {\n  RESPONSE = \"response\",\n  RAW_RESPONSE = \"rawResponse\",\n  ERROR = \"error\",\n}\n"],"mappings":"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","names":["EmittedEvent","multicastDns","uuidv4"]}