@ecobridge.xyz/devicemanager 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.gitea/workflows/default_tags.yaml +0 -21
  2. package/.smartconfig.json +69 -0
  3. package/changelog.md +38 -1
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/device/device.classes.device.d.ts +2 -2
  6. package/dist_ts/device/device.classes.device.js +3 -3
  7. package/dist_ts/devicemanager.classes.devicemanager.d.ts +17 -4
  8. package/dist_ts/devicemanager.classes.devicemanager.js +99 -11
  9. package/dist_ts/discovery/discovery.classes.mdns.js +46 -11
  10. package/dist_ts/discovery/discovery.classes.networkscanner.d.ts +5 -1
  11. package/dist_ts/discovery/discovery.classes.networkscanner.js +44 -3
  12. package/dist_ts/discovery/discovery.classes.ssdp.d.ts +52 -21
  13. package/dist_ts/discovery/discovery.classes.ssdp.js +407 -117
  14. package/dist_ts/events/events.observable.d.ts +15 -0
  15. package/dist_ts/events/events.observable.js +22 -0
  16. package/dist_ts/events/index.d.ts +1 -0
  17. package/dist_ts/events/index.js +2 -0
  18. package/dist_ts/factories/index.js +7 -5
  19. package/dist_ts/features/feature.abstract.d.ts +2 -2
  20. package/dist_ts/features/feature.abstract.js +3 -3
  21. package/dist_ts/features/feature.print.d.ts +3 -0
  22. package/dist_ts/features/feature.print.js +17 -2
  23. package/dist_ts/features/feature.scan.d.ts +5 -2
  24. package/dist_ts/features/feature.scan.js +98 -27
  25. package/dist_ts/index.d.ts +4 -2
  26. package/dist_ts/index.js +4 -2
  27. package/dist_ts/interfaces/feature.interfaces.d.ts +22 -2
  28. package/dist_ts/interfaces/index.d.ts +22 -4
  29. package/dist_ts/interfaces/index.js +1 -1
  30. package/dist_ts/plugins.d.ts +6 -15
  31. package/dist_ts/plugins.js +7 -19
  32. package/dist_ts/protocols/index.d.ts +2 -1
  33. package/dist_ts/protocols/index.js +4 -2
  34. package/dist_ts/protocols/protocol.brother.d.ts +67 -0
  35. package/dist_ts/protocols/protocol.brother.js +560 -0
  36. package/dist_ts/protocols/protocol.escl.d.ts +13 -4
  37. package/dist_ts/protocols/protocol.escl.js +345 -178
  38. package/dist_ts/protocols/protocol.ipp.d.ts +2 -0
  39. package/dist_ts/protocols/protocol.ipp.js +22 -2
  40. package/dist_ts/providers/index.d.ts +1 -0
  41. package/dist_ts/providers/index.js +2 -0
  42. package/dist_ts/providers/provider.smb.d.ts +60 -0
  43. package/dist_ts/providers/provider.smb.js +224 -0
  44. package/license.md +21 -0
  45. package/package.json +15 -20
  46. package/pnpm-workspace.yaml +6 -0
  47. package/readme.md +157 -78
  48. package/test/test.brother.node.ts +306 -0
  49. package/test/test.escl.node.ts +233 -0
  50. package/test/test.ipp.node.ts +75 -0
  51. package/test/{test.ts → test.node.ts} +37 -45
  52. package/test/test.smb.node.ts +123 -0
  53. package/test/test.ssdp.node.ts +978 -0
  54. package/ts/00_commitinfo_data.ts +1 -1
  55. package/ts/device/device.classes.device.ts +2 -2
  56. package/ts/devicemanager.classes.devicemanager.ts +125 -12
  57. package/ts/discovery/discovery.classes.mdns.ts +40 -11
  58. package/ts/discovery/discovery.classes.networkscanner.ts +51 -2
  59. package/ts/discovery/discovery.classes.ssdp.ts +493 -130
  60. package/ts/events/events.observable.ts +31 -0
  61. package/ts/events/index.ts +4 -0
  62. package/ts/factories/index.ts +7 -5
  63. package/ts/features/feature.abstract.ts +2 -2
  64. package/ts/features/feature.print.ts +16 -1
  65. package/ts/features/feature.scan.ts +93 -27
  66. package/ts/index.ts +21 -0
  67. package/ts/interfaces/feature.interfaces.ts +23 -2
  68. package/ts/interfaces/index.ts +23 -4
  69. package/ts/plugins.ts +6 -25
  70. package/ts/protocols/index.ts +11 -1
  71. package/ts/protocols/protocol.brother.ts +648 -0
  72. package/ts/protocols/protocol.escl.ts +348 -191
  73. package/ts/protocols/protocol.ipp.ts +24 -1
  74. package/ts/providers/index.ts +7 -0
  75. package/ts/providers/provider.smb.ts +326 -0
  76. package/dist_ts/protocols/protocol.ipp.old.d.ts +0 -45
  77. package/dist_ts/protocols/protocol.ipp.old.js +0 -284
  78. package/npmextra.json +0 -24
@@ -4,12 +4,14 @@
4
4
  * Supports: Scanners, Printers, SNMP devices, UPS, DLNA, Sonos, AirPlay, Chromecast
5
5
  */
6
6
  export { DeviceManager, MdnsDiscovery, NetworkScanner, SsdpDiscovery, SERVICE_TYPES, SSDP_SERVICE_TYPES, } from './devicemanager.classes.devicemanager.js';
7
+ export { ObservableEventEmitter, type IObservableEvent, } from './events/index.js';
8
+ export { SmbShareProvider, type ISmbDocumentEvent, type ISmbServerAdapter, type ISmbShareProviderDependencies, type ISmbShareProviderOptions, } from './providers/index.js';
7
9
  export { UniversalDevice, type IUniversalDeviceInfo, type IDeviceCreateOptions } from './device/device.classes.device.js';
8
10
  export { Feature, ScanFeature, PrintFeature, PlaybackFeature, VolumeFeature, PowerFeature, SnmpFeature, SwitchFeature, SensorFeature, LightFeature, CoverFeature, LockFeature, FanFeature, ClimateFeature, CameraFeature, type TDeviceReference, type IScanFeatureOptions, type IPrintFeatureOptions, type IPlaybackFeatureOptions, type IVolumeFeatureOptions, type IVolumeController, type IPowerFeatureOptions, type ISnmpFeatureOptions, type ISwitchFeatureOptions, type ISensorFeatureOptions, type ILightFeatureOptions, type ICoverFeatureOptions, type ILockFeatureOptions, type IFanFeatureOptions, type IClimateFeatureOptions, type ICameraFeatureOptions, } from './features/index.js';
9
11
  export { createScanner, createPrinter, createSnmpDevice, createUpsDevice, createSpeaker, createDlnaRenderer, createSmartSwitch, createSmartSensor, createSmartLight, createSmartCover, createSmartLock, createSmartFan, createSmartClimate, createSmartCamera, type IScannerDiscoveryInfo, type IPrinterDiscoveryInfo, type ISnmpDiscoveryInfo, type IUpsDiscoveryInfo, type ISpeakerDiscoveryInfo, type IDlnaRendererDiscoveryInfo, type ISmartSwitchDiscoveryInfo, type ISmartSensorDiscoveryInfo, type ISmartLightDiscoveryInfo, type ISmartCoverDiscoveryInfo, type ISmartLockDiscoveryInfo, type ISmartFanDiscoveryInfo, type ISmartClimateDiscoveryInfo, type ISmartCameraDiscoveryInfo, } from './factories/index.js';
10
- export { EsclProtocol, SaneProtocol, IppProtocol, SnmpProtocol, SNMP_OIDS, NutProtocol, NUT_COMMANDS, NUT_VARIABLES, UpnpSoapClient, UPNP_SERVICE_TYPES, UPNP_DEVICE_TYPES, UpsSnmpHandler, UPS_SNMP_OIDS, HomeAssistantProtocol, type ISnmpOptions, type ISnmpVarbind, type TSnmpValueType, type TNutStatusFlag, type INutUpsInfo, type INutVariable, type TDlnaTransportState, type TDlnaTransportStatus, type IDlnaPositionInfo, type IDlnaTransportInfo, type IDlnaMediaInfo, type IDlnaContentItem, type IDlnaBrowseResult, type TUpsBatteryStatus, type TUpsOutputSource, type TUpsTestResult, type IUpsSnmpStatus, } from './protocols/index.js';
12
+ export { EsclProtocol, EsclScanError, BrotherScanProtocol, BrotherScanError, SaneProtocol, IppProtocol, SnmpProtocol, SNMP_OIDS, NutProtocol, NUT_COMMANDS, NUT_VARIABLES, UpnpSoapClient, UPNP_SERVICE_TYPES, UPNP_DEVICE_TYPES, UpsSnmpHandler, UPS_SNMP_OIDS, HomeAssistantProtocol, type ISnmpOptions, type IBrotherScanLease, type IBrotherScanOptions, type IBrotherScanProtocolOptions, type TBrotherScanErrorCode, type ISnmpVarbind, type TSnmpValueType, type TNutStatusFlag, type INutUpsInfo, type INutVariable, type TDlnaTransportState, type TDlnaTransportStatus, type IDlnaPositionInfo, type IDlnaTransportInfo, type IDlnaMediaInfo, type IDlnaContentItem, type IDlnaBrowseResult, type TUpsBatteryStatus, type TUpsOutputSource, type TUpsTestResult, type IUpsSnmpStatus, } from './protocols/index.js';
11
13
  export { HomeAssistantDiscovery, HA_SERVICE_TYPE } from './discovery/discovery.classes.homeassistant.js';
12
14
  export { withRetry, createRetryable, defaultRetryOptions } from './helpers/helpers.retry.js';
13
15
  export { isValidIp, ipToNumber, numberToIp, ipRangeToIps, cidrToIps, getLocalSubnet, countIpsInCidr, } from './helpers/helpers.iprange.js';
14
16
  export * from './interfaces/index.js';
15
- export type { ISsdpDevice, ISsdpDeviceDescription, ISsdpService, ISsdpIcon, } from './discovery/discovery.classes.ssdp.js';
17
+ export type { ISsdpDevice, ISsdpDeviceDescription, ISsdpDiscoveryDependencies, ISsdpService, ISsdpIcon, } from './discovery/discovery.classes.ssdp.js';
package/dist_ts/index.js CHANGED
@@ -7,6 +7,8 @@
7
7
  // Core Device Manager
8
8
  // ============================================================================
9
9
  export { DeviceManager, MdnsDiscovery, NetworkScanner, SsdpDiscovery, SERVICE_TYPES, SSDP_SERVICE_TYPES, } from './devicemanager.classes.devicemanager.js';
10
+ export { ObservableEventEmitter, } from './events/index.js';
11
+ export { SmbShareProvider, } from './providers/index.js';
10
12
  // ============================================================================
11
13
  // Universal Device & Features
12
14
  // ============================================================================
@@ -23,7 +25,7 @@ createSmartSwitch, createSmartSensor, createSmartLight, createSmartCover, create
23
25
  // ============================================================================
24
26
  // Protocol Implementations
25
27
  // ============================================================================
26
- export { EsclProtocol, SaneProtocol, IppProtocol, SnmpProtocol, SNMP_OIDS, NutProtocol, NUT_COMMANDS, NUT_VARIABLES, UpnpSoapClient, UPNP_SERVICE_TYPES, UPNP_DEVICE_TYPES, UpsSnmpHandler, UPS_SNMP_OIDS,
28
+ export { EsclProtocol, EsclScanError, BrotherScanProtocol, BrotherScanError, SaneProtocol, IppProtocol, SnmpProtocol, SNMP_OIDS, NutProtocol, NUT_COMMANDS, NUT_VARIABLES, UpnpSoapClient, UPNP_SERVICE_TYPES, UPNP_DEVICE_TYPES, UpsSnmpHandler, UPS_SNMP_OIDS,
27
29
  // Home Assistant protocol
28
30
  HomeAssistantProtocol, } from './protocols/index.js';
29
31
  // Home Assistant Discovery
@@ -37,4 +39,4 @@ export { isValidIp, ipToNumber, numberToIp, ipRangeToIps, cidrToIps, getLocalSub
37
39
  // All Interfaces and Types
38
40
  // ============================================================================
39
41
  export * from './interfaces/index.js';
40
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsK0VBQStFO0FBQy9FLHNCQUFzQjtBQUN0QiwrRUFBK0U7QUFFL0UsT0FBTyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2IsY0FBYyxFQUNkLGFBQWEsRUFDYixhQUFhLEVBQ2Isa0JBQWtCLEdBQ25CLE1BQU0sMENBQTBDLENBQUM7QUFFbEQsK0VBQStFO0FBQy9FLDhCQUE4QjtBQUM5QiwrRUFBK0U7QUFFL0UsT0FBTyxFQUFFLGVBQWUsRUFBd0QsTUFBTSxtQ0FBbUMsQ0FBQztBQUMxSCxPQUFPLEVBQ0wsT0FBTyxFQUNQLFdBQVcsRUFDWCxZQUFZLEVBQ1osZUFBZSxFQUNmLGFBQWEsRUFDYixZQUFZLEVBQ1osV0FBVztBQUNYLHNCQUFzQjtBQUN0QixhQUFhLEVBQ2IsYUFBYSxFQUNiLFlBQVksRUFDWixZQUFZLEVBQ1osV0FBVyxFQUNYLFVBQVUsRUFDVixjQUFjLEVBQ2QsYUFBYSxHQWlCZCxNQUFNLHFCQUFxQixDQUFDO0FBRTdCLCtFQUErRTtBQUMvRSxtQkFBbUI7QUFDbkIsK0VBQStFO0FBRS9FLE9BQU8sRUFDTCxhQUFhLEVBQ2IsYUFBYSxFQUNiLGdCQUFnQixFQUNoQixlQUFlLEVBQ2YsYUFBYSxFQUNiLGtCQUFrQjtBQUNsQix1QkFBdUI7QUFDdkIsaUJBQWlCLEVBQ2pCLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZixjQUFjLEVBQ2Qsa0JBQWtCLEVBQ2xCLGlCQUFpQixHQWVsQixNQUFNLHNCQUFzQixDQUFDO0FBRTlCLCtFQUErRTtBQUMvRSwyQkFBMkI7QUFDM0IsK0VBQStFO0FBRS9FLE9BQU8sRUFDTCxZQUFZLEVBQ1osWUFBWSxFQUNaLFdBQVcsRUFDWCxZQUFZLEVBQ1osU0FBUyxFQUNULFdBQVcsRUFDWCxZQUFZLEVBQ1osYUFBYSxFQUNiLGNBQWMsRUFDZCxrQkFBa0IsRUFDbEIsaUJBQWlCLEVBQ2pCLGNBQWMsRUFDZCxhQUFhO0FBQ2IsMEJBQTBCO0FBQzFCLHFCQUFxQixHQWtCdEIsTUFBTSxzQkFBc0IsQ0FBQztBQUU5QiwyQkFBMkI7QUFDM0IsT0FBTyxFQUFFLHNCQUFzQixFQUFFLGVBQWUsRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBRXpHLCtFQUErRTtBQUMvRSxVQUFVO0FBQ1YsK0VBQStFO0FBRS9FLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0YsT0FBTyxFQUNMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsVUFBVSxFQUNWLFlBQVksRUFDWixTQUFTLEVBQ1QsY0FBYyxFQUNkLGNBQWMsR0FDZixNQUFNLDhCQUE4QixDQUFDO0FBRXRDLCtFQUErRTtBQUMvRSwyQkFBMkI7QUFDM0IsK0VBQStFO0FBRS9FLGNBQWMsdUJBQXVCLENBQUMifQ==
42
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsK0VBQStFO0FBQy9FLHNCQUFzQjtBQUN0QiwrRUFBK0U7QUFFL0UsT0FBTyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2IsY0FBYyxFQUNkLGFBQWEsRUFDYixhQUFhLEVBQ2Isa0JBQWtCLEdBQ25CLE1BQU0sMENBQTBDLENBQUM7QUFFbEQsT0FBTyxFQUNMLHNCQUFzQixHQUV2QixNQUFNLG1CQUFtQixDQUFDO0FBRTNCLE9BQU8sRUFDTCxnQkFBZ0IsR0FLakIsTUFBTSxzQkFBc0IsQ0FBQztBQUU5QiwrRUFBK0U7QUFDL0UsOEJBQThCO0FBQzlCLCtFQUErRTtBQUUvRSxPQUFPLEVBQUUsZUFBZSxFQUF3RCxNQUFNLG1DQUFtQyxDQUFDO0FBQzFILE9BQU8sRUFDTCxPQUFPLEVBQ1AsV0FBVyxFQUNYLFlBQVksRUFDWixlQUFlLEVBQ2YsYUFBYSxFQUNiLFlBQVksRUFDWixXQUFXO0FBQ1gsc0JBQXNCO0FBQ3RCLGFBQWEsRUFDYixhQUFhLEVBQ2IsWUFBWSxFQUNaLFlBQVksRUFDWixXQUFXLEVBQ1gsVUFBVSxFQUNWLGNBQWMsRUFDZCxhQUFhLEdBaUJkLE1BQU0scUJBQXFCLENBQUM7QUFFN0IsK0VBQStFO0FBQy9FLG1CQUFtQjtBQUNuQiwrRUFBK0U7QUFFL0UsT0FBTyxFQUNMLGFBQWEsRUFDYixhQUFhLEVBQ2IsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDZixhQUFhLEVBQ2Isa0JBQWtCO0FBQ2xCLHVCQUF1QjtBQUN2QixpQkFBaUIsRUFDakIsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsZUFBZSxFQUNmLGNBQWMsRUFDZCxrQkFBa0IsRUFDbEIsaUJBQWlCLEdBZWxCLE1BQU0sc0JBQXNCLENBQUM7QUFFOUIsK0VBQStFO0FBQy9FLDJCQUEyQjtBQUMzQiwrRUFBK0U7QUFFL0UsT0FBTyxFQUNMLFlBQVksRUFDWixhQUFhLEVBQ2IsbUJBQW1CLEVBQ25CLGdCQUFnQixFQUNoQixZQUFZLEVBQ1osV0FBVyxFQUNYLFlBQVksRUFDWixTQUFTLEVBQ1QsV0FBVyxFQUNYLFlBQVksRUFDWixhQUFhLEVBQ2IsY0FBYyxFQUNkLGtCQUFrQixFQUNsQixpQkFBaUIsRUFDakIsY0FBYyxFQUNkLGFBQWE7QUFDYiwwQkFBMEI7QUFDMUIscUJBQXFCLEdBc0J0QixNQUFNLHNCQUFzQixDQUFDO0FBRTlCLDJCQUEyQjtBQUMzQixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFFekcsK0VBQStFO0FBQy9FLFVBQVU7QUFDViwrRUFBK0U7QUFFL0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RixPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFDVixVQUFVLEVBQ1YsWUFBWSxFQUNaLFNBQVMsRUFDVCxjQUFjLEVBQ2QsY0FBYyxHQUNmLE1BQU0sOEJBQThCLENBQUM7QUFFdEMsK0VBQStFO0FBQy9FLDJCQUEyQjtBQUMzQiwrRUFBK0U7QUFFL0UsY0FBYyx1QkFBdUIsQ0FBQyJ9
@@ -37,7 +37,7 @@ export interface IFeatureInfo {
37
37
  port: number;
38
38
  state: TFeatureState;
39
39
  }
40
- export type TScanProtocol = 'escl' | 'sane' | 'wia';
40
+ export type TScanProtocol = 'brother' | 'escl' | 'sane' | 'wia';
41
41
  export type TScanFormat = 'png' | 'jpeg' | 'pdf' | 'tiff';
42
42
  export type TColorMode = 'color' | 'grayscale' | 'blackwhite';
43
43
  export type TScanSource = 'flatbed' | 'adf' | 'adf-duplex';
@@ -74,6 +74,22 @@ export interface IScanResult {
74
74
  resolution: number;
75
75
  colorMode: TColorMode;
76
76
  mimeType: string;
77
+ /** Number of documents returned by a multipage-capable scanner transport */
78
+ pageCount?: number;
79
+ /** All returned documents, including the first document exposed as data */
80
+ pages?: IScanPage[];
81
+ /** Whether the scanner reported a cleanly completed job */
82
+ isComplete?: boolean;
83
+ /** Scanner reason when a partial result is returned with an error */
84
+ jobStateReason?: string;
85
+ /** Differences detected between requested and returned scan settings */
86
+ settingsWarnings?: string[];
87
+ }
88
+ export interface IScanPage {
89
+ data: Buffer;
90
+ width: number;
91
+ height: number;
92
+ mimeType: string;
77
93
  }
78
94
  export interface IScanFeatureInfo extends IFeatureInfo {
79
95
  type: 'scan';
@@ -90,8 +106,10 @@ export type TPrintSides = 'one-sided' | 'two-sided-long-edge' | 'two-sided-short
90
106
  export type TPrintQuality = 'draft' | 'normal' | 'high';
91
107
  export type TPrintColorMode = 'color' | 'monochrome';
92
108
  export interface IPrintCapabilities {
109
+ airPrintSupported: boolean;
93
110
  colorSupported: boolean;
94
111
  duplexSupported: boolean;
112
+ documentFormats: string[];
95
113
  mediaSizes: string[];
96
114
  mediaTypes: string[];
97
115
  resolutions: number[];
@@ -113,7 +131,7 @@ export interface IPrintJob {
113
131
  name: string;
114
132
  state: 'pending' | 'processing' | 'completed' | 'canceled' | 'aborted';
115
133
  stateReason?: string;
116
- createdAt: Date;
134
+ createdAt?: Date;
117
135
  completedAt?: Date;
118
136
  pagesPrinted?: number;
119
137
  pagesTotal?: number;
@@ -121,8 +139,10 @@ export interface IPrintJob {
121
139
  export interface IPrintFeatureInfo extends IFeatureInfo {
122
140
  type: 'print';
123
141
  protocol: TPrintProtocol;
142
+ airPrintSupported: boolean;
124
143
  supportsColor: boolean;
125
144
  supportsDuplex: boolean;
145
+ supportedDocumentFormats: string[];
126
146
  supportedMediaSizes: string[];
127
147
  }
128
148
  export type TPlaybackProtocol = 'sonos' | 'airplay' | 'chromecast' | 'dlna';
@@ -4,7 +4,7 @@
4
4
  export type TDeviceType = 'scanner' | 'printer' | 'snmp' | 'ups' | 'speaker' | 'dlna-renderer' | 'dlna-server';
5
5
  export type TDeviceStatus = 'online' | 'offline' | 'busy' | 'error' | 'unknown';
6
6
  export type TConnectionState = 'disconnected' | 'connecting' | 'connected' | 'error';
7
- export type TScannerProtocol = 'sane' | 'escl';
7
+ export type TScannerProtocol = 'brother' | 'sane' | 'escl';
8
8
  export type TScanFormat = 'png' | 'jpeg' | 'pdf' | 'tiff';
9
9
  export type TColorMode = 'color' | 'grayscale' | 'blackwhite';
10
10
  export type TScanSource = 'flatbed' | 'adf' | 'adf-duplex';
@@ -81,6 +81,22 @@ export interface IScanResult {
81
81
  colorMode: TColorMode;
82
82
  /** MIME type */
83
83
  mimeType: string;
84
+ /** Number of documents returned by a multipage-capable scanner transport */
85
+ pageCount?: number;
86
+ /** All returned documents, including the first document exposed as data */
87
+ pages?: IScanPage[];
88
+ /** Whether the scanner reported a cleanly completed job */
89
+ isComplete?: boolean;
90
+ /** Scanner reason when a partial result is returned with an error */
91
+ jobStateReason?: string;
92
+ /** Differences detected between requested and returned scan settings */
93
+ settingsWarnings?: string[];
94
+ }
95
+ export interface IScanPage {
96
+ data: Buffer;
97
+ width: number;
98
+ height: number;
99
+ mimeType: string;
84
100
  }
85
101
  export interface IScannerCapabilities {
86
102
  resolutions: number[];
@@ -122,7 +138,7 @@ export interface IPrintJob {
122
138
  name: string;
123
139
  state: 'pending' | 'processing' | 'completed' | 'canceled' | 'aborted';
124
140
  stateReason?: string;
125
- createdAt: Date;
141
+ createdAt?: Date;
126
142
  completedAt?: Date;
127
143
  pagesPrinted?: number;
128
144
  pagesTotal?: number;
@@ -255,8 +271,10 @@ export interface INetworkScanOptions {
255
271
  concurrency?: number;
256
272
  /** Timeout per probe in milliseconds (default: 2000) */
257
273
  timeout?: number;
258
- /** Ports to probe (default: [80, 443, 631, 6566, 9100, 7000, 1400, 8009]) */
274
+ /** Ports to probe (includes Brother native scan on 54921 by default) */
259
275
  ports?: number[];
276
+ /** Check for Brother native network scanners (default: true) */
277
+ probeBrother?: boolean;
260
278
  /** Check for eSCL scanners (default: true) */
261
279
  probeEscl?: boolean;
262
280
  /** Check for IPP printers (default: true) */
@@ -272,7 +290,7 @@ export interface INetworkScanOptions {
272
290
  }
273
291
  export interface INetworkScanDevice {
274
292
  type: 'scanner' | 'printer' | 'speaker';
275
- protocol: 'escl' | 'sane' | 'ipp' | 'jetdirect' | 'airplay' | 'sonos' | 'chromecast';
293
+ protocol: 'brother' | 'escl' | 'sane' | 'ipp' | 'jetdirect' | 'airplay' | 'sonos' | 'chromecast';
276
294
  port: number;
277
295
  name?: string;
278
296
  model?: string;
@@ -13,4 +13,4 @@ export * from './smarthome.interfaces.js';
13
13
  // Home Assistant Specific Types
14
14
  // ============================================================================
15
15
  export * from './homeassistant.interfaces.js';
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9pbnRlcmZhY2VzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBa1pILCtFQUErRTtBQUMvRSxnREFBZ0Q7QUFDaEQsK0VBQStFO0FBRS9FLGNBQWMseUJBQXlCLENBQUM7QUFFeEMsK0VBQStFO0FBQy9FLGdEQUFnRDtBQUNoRCwrRUFBK0U7QUFFL0UsY0FBYywyQkFBMkIsQ0FBQztBQUUxQywrRUFBK0U7QUFDL0UsZ0NBQWdDO0FBQ2hDLCtFQUErRTtBQUUvRSxjQUFjLCtCQUErQixDQUFDIn0=
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9pbnRlcmZhY2VzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBcWFILCtFQUErRTtBQUMvRSxnREFBZ0Q7QUFDaEQsK0VBQStFO0FBRS9FLGNBQWMseUJBQXlCLENBQUM7QUFFeEMsK0VBQStFO0FBQy9FLGdEQUFnRDtBQUNoRCwrRUFBK0U7QUFFL0UsY0FBYywyQkFBMkIsQ0FBQztBQUUxQywrRUFBK0U7QUFDL0UsZ0NBQWdDO0FBQ2hDLCtFQUErRTtBQUUvRSxjQUFjLCtCQUErQixDQUFDIn0=
@@ -1,23 +1,14 @@
1
1
  import * as path from 'path';
2
2
  import * as net from 'net';
3
- import * as dgram from 'dgram';
3
+ import * as dgram from 'node:dgram';
4
+ import * as os from 'node:os';
4
5
  import * as events from 'events';
5
- export { path, net, dgram, events };
6
+ export { path, net, dgram, os, events };
6
7
  import * as smartpath from '@push.rocks/smartpath';
7
- import * as smartpromise from '@push.rocks/smartpromise';
8
8
  import * as smartdelay from '@push.rocks/smartdelay';
9
- import * as smartnetwork from '@push.rocks/smartnetwork';
10
- import { SmartRequest } from '@push.rocks/smartrequest';
11
- export { SmartRequest };
12
- export { smartpath, smartpromise, smartdelay, smartnetwork, };
9
+ export { smartpath, smartdelay };
13
10
  import * as bonjourService from 'bonjour-service';
14
- import ipp from 'ipp';
15
11
  import * as netSnmp from 'net-snmp';
16
- import * as sonos from 'sonos';
17
- import * as castv2Client from 'castv2-client';
18
12
  import WebSocket from 'ws';
19
- declare const nodeSsdp: {
20
- Client: any;
21
- Server: any;
22
- };
23
- export { bonjourService, ipp, nodeSsdp, netSnmp, sonos, castv2Client, WebSocket };
13
+ import * as rxjs from 'rxjs';
14
+ export { bonjourService, netSnmp, WebSocket, rxjs };
@@ -1,30 +1,18 @@
1
1
  // native scope
2
2
  import * as path from 'path';
3
3
  import * as net from 'net';
4
- import * as dgram from 'dgram';
4
+ import * as dgram from 'node:dgram';
5
+ import * as os from 'node:os';
5
6
  import * as events from 'events';
6
- export { path, net, dgram, events };
7
+ export { path, net, dgram, os, events };
7
8
  // @push.rocks scope
8
9
  import * as smartpath from '@push.rocks/smartpath';
9
- import * as smartpromise from '@push.rocks/smartpromise';
10
10
  import * as smartdelay from '@push.rocks/smartdelay';
11
- import * as smartnetwork from '@push.rocks/smartnetwork';
12
- // Re-export SmartRequest for HTTP
13
- import { SmartRequest } from '@push.rocks/smartrequest';
14
- export { SmartRequest };
15
- export { smartpath, smartpromise, smartdelay, smartnetwork, };
11
+ export { smartpath, smartdelay };
16
12
  // third party
17
13
  import * as bonjourService from 'bonjour-service';
18
- import ipp from 'ipp';
19
- import nodeSsdpModule from 'node-ssdp';
20
14
  import * as netSnmp from 'net-snmp';
21
- import * as sonos from 'sonos';
22
- import * as castv2Client from 'castv2-client';
23
15
  import WebSocket from 'ws';
24
- // node-ssdp exports Client/Server under default in ESM
25
- const nodeSsdp = {
26
- Client: nodeSsdpModule.Client,
27
- Server: nodeSsdpModule.Server,
28
- };
29
- export { bonjourService, ipp, nodeSsdp, netSnmp, sonos, castv2Client, WebSocket };
30
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZUFBZTtBQUNmLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBQzNCLE9BQU8sS0FBSyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQy9CLE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBRWpDLE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQztBQUVwQyxvQkFBb0I7QUFDcEIsT0FBTyxLQUFLLFNBQVMsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRCxPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxVQUFVLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUV6RCxrQ0FBa0M7QUFDbEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUV4QixPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxHQUNiLENBQUM7QUFFRixjQUFjO0FBQ2QsT0FBTyxLQUFLLGNBQWMsTUFBTSxpQkFBaUIsQ0FBQztBQUNsRCxPQUFPLEdBQUcsTUFBTSxLQUFLLENBQUM7QUFDdEIsT0FBTyxjQUFjLE1BQU0sV0FBVyxDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxPQUFPLE1BQU0sVUFBVSxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQy9CLE9BQU8sS0FBSyxZQUFZLE1BQU0sZUFBZSxDQUFDO0FBQzlDLE9BQU8sU0FBUyxNQUFNLElBQUksQ0FBQztBQUUzQix1REFBdUQ7QUFDdkQsTUFBTSxRQUFRLEdBQUc7SUFDZixNQUFNLEVBQUUsY0FBYyxDQUFDLE1BQU07SUFDN0IsTUFBTSxFQUFFLGNBQWMsQ0FBQyxNQUFNO0NBQzlCLENBQUM7QUFFRixPQUFPLEVBQUUsY0FBYyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLENBQUMifQ==
16
+ import * as rxjs from 'rxjs';
17
+ export { bonjourService, netSnmp, WebSocket, rxjs };
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZUFBZTtBQUNmLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBQzNCLE9BQU8sS0FBSyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBRWpDLE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFFeEMsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQztBQUVyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxDQUFDO0FBRWpDLGNBQWM7QUFDZCxPQUFPLEtBQUssY0FBYyxNQUFNLGlCQUFpQixDQUFDO0FBQ2xELE9BQU8sS0FBSyxPQUFPLE1BQU0sVUFBVSxDQUFDO0FBQ3BDLE9BQU8sU0FBUyxNQUFNLElBQUksQ0FBQztBQUMzQixPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUU3QixPQUFPLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMifQ==
@@ -2,7 +2,8 @@
2
2
  * Protocol implementations
3
3
  * All network communication protocols for device interaction
4
4
  */
5
- export { EsclProtocol } from './protocol.escl.js';
5
+ export { EsclProtocol, EsclScanError } from './protocol.escl.js';
6
+ export { BrotherScanProtocol, BrotherScanError, type IBrotherScanLease, type IBrotherScanOptions, type IBrotherScanProtocolOptions, type TBrotherScanErrorCode, } from './protocol.brother.js';
6
7
  export { SaneProtocol } from './protocol.sane.js';
7
8
  export { IppProtocol, type IIppPrinterCapabilities, type IIppJob, type IIppPrintOptions, } from './protocol.ipp.js';
8
9
  export { SnmpProtocol, SNMP_OIDS, type TSnmpValueType, type ISnmpVarbind, type ISnmpOptions, } from './protocol.snmp.js';
@@ -3,7 +3,9 @@
3
3
  * All network communication protocols for device interaction
4
4
  */
5
5
  // eSCL/AirScan scanner protocol
6
- export { EsclProtocol } from './protocol.escl.js';
6
+ export { EsclProtocol, EsclScanError } from './protocol.escl.js';
7
+ // Brother native network scanner protocol
8
+ export { BrotherScanProtocol, BrotherScanError, } from './protocol.brother.js';
7
9
  // SANE network scanner protocol
8
10
  export { SaneProtocol } from './protocol.sane.js';
9
11
  // IPP printer protocol
@@ -18,4 +20,4 @@ export { UpnpSoapClient, UPNP_SERVICE_TYPES, UPNP_DEVICE_TYPES, } from './protoc
18
20
  export { UpsSnmpHandler, UPS_SNMP_OIDS, } from './protocol.upssnmp.js';
19
21
  // Home Assistant WebSocket protocol
20
22
  export { HomeAssistantProtocol } from './protocol.homeassistant.js';
21
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9wcm90b2NvbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsZ0NBQWdDO0FBQ2hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxnQ0FBZ0M7QUFDaEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRWxELHVCQUF1QjtBQUN2QixPQUFPLEVBQ0wsV0FBVyxHQUlaLE1BQU0sbUJBQW1CLENBQUM7QUFFM0Isc0JBQXNCO0FBQ3RCLE9BQU8sRUFDTCxZQUFZLEVBQ1osU0FBUyxHQUlWLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsNkJBQTZCO0FBQzdCLE9BQU8sRUFDTCxXQUFXLEVBQ1gsYUFBYSxFQUNiLFlBQVksR0FJYixNQUFNLG1CQUFtQixDQUFDO0FBRTNCLDBCQUEwQjtBQUMxQixPQUFPLEVBQ0wsY0FBYyxFQUNkLGtCQUFrQixFQUNsQixpQkFBaUIsR0FRbEIsTUFBTSxvQkFBb0IsQ0FBQztBQUU1Qiw4QkFBOEI7QUFDOUIsT0FBTyxFQUNMLGNBQWMsRUFDZCxhQUFhLEdBS2QsTUFBTSx1QkFBdUIsQ0FBQztBQUUvQixvQ0FBb0M7QUFDcEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNkJBQTZCLENBQUMifQ==
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9wcm90b2NvbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsZ0NBQWdDO0FBQ2hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFakUsMENBQTBDO0FBQzFDLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsZ0JBQWdCLEdBS2pCLE1BQU0sdUJBQXVCLENBQUM7QUFFL0IsZ0NBQWdDO0FBQ2hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCx1QkFBdUI7QUFDdkIsT0FBTyxFQUNMLFdBQVcsR0FJWixNQUFNLG1CQUFtQixDQUFDO0FBRTNCLHNCQUFzQjtBQUN0QixPQUFPLEVBQ0wsWUFBWSxFQUNaLFNBQVMsR0FJVixNQUFNLG9CQUFvQixDQUFDO0FBRTVCLDZCQUE2QjtBQUM3QixPQUFPLEVBQ0wsV0FBVyxFQUNYLGFBQWEsRUFDYixZQUFZLEdBSWIsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQiwwQkFBMEI7QUFDMUIsT0FBTyxFQUNMLGNBQWMsRUFDZCxrQkFBa0IsRUFDbEIsaUJBQWlCLEdBUWxCLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsOEJBQThCO0FBQzlCLE9BQU8sRUFDTCxjQUFjLEVBQ2QsYUFBYSxHQUtkLE1BQU0sdUJBQXVCLENBQUM7QUFFL0Isb0NBQW9DO0FBQ3BDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDIn0=
@@ -0,0 +1,67 @@
1
+ import type { IScanArea, IScanCapabilities, IScanResult, TColorMode, TScanFormat, TScanSource } from '../interfaces/index.js';
2
+ export type TBrotherScanErrorCode = 'busy' | 'cancelled' | 'cover-open' | 'device-stuck' | 'document-jam' | 'invalid-response' | 'no-document' | 'service-error' | 'settings-rejected' | 'timeout' | 'unsupported';
3
+ export declare class BrotherScanError extends Error {
4
+ readonly code: TBrotherScanErrorCode;
5
+ readonly statusCode?: number | undefined;
6
+ constructor(message: string, code: TBrotherScanErrorCode, statusCode?: number | undefined);
7
+ }
8
+ export interface IBrotherScanProtocolOptions {
9
+ timeout?: number;
10
+ scanTimeout?: number;
11
+ busyRetryInterval?: number;
12
+ busyTimeout?: number;
13
+ }
14
+ export interface IBrotherScanLease {
15
+ resolutionX: number;
16
+ resolutionY: number;
17
+ adfStatus: number;
18
+ planeWidth: number;
19
+ width: number;
20
+ planeHeight: number;
21
+ height: number;
22
+ }
23
+ export interface IBrotherScanOptions {
24
+ resolution: number;
25
+ format: TScanFormat;
26
+ colorMode: TColorMode;
27
+ source: TScanSource;
28
+ area: IScanArea;
29
+ quality?: number;
30
+ }
31
+ /**
32
+ * Brother's native network scan protocol on TCP 54921.
33
+ *
34
+ * Brother devices expose richer scan control here than they do through some
35
+ * eSCL implementations. The protocol returns one JPEG stream per sheet/side.
36
+ */
37
+ export declare class BrotherScanProtocol {
38
+ private readonly address;
39
+ private readonly port;
40
+ private socket;
41
+ private reader;
42
+ private scanning;
43
+ private cancelled;
44
+ private readonly timeout;
45
+ private readonly scanTimeout;
46
+ private readonly busyRetryInterval;
47
+ private readonly busyTimeout;
48
+ constructor(address: string, port?: number, options?: IBrotherScanProtocolOptions);
49
+ connect(): Promise<void>;
50
+ private connectOnce;
51
+ disconnect(): Promise<void>;
52
+ getCapabilities(): IScanCapabilities;
53
+ scan(options: IBrotherScanOptions): Promise<IScanResult>;
54
+ cancel(): Promise<void>;
55
+ private validateOptions;
56
+ private selectSource;
57
+ private requestLease;
58
+ private assertLease;
59
+ private resolveScanArea;
60
+ private readPages;
61
+ private finishPage;
62
+ private makePage;
63
+ private statusError;
64
+ private writeCommand;
65
+ private write;
66
+ private requireReader;
67
+ }