@delicity/capacitor-thermal-printer 7.0.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 (100) hide show
  1. package/DelicityThermalPrinter.podspec +28 -0
  2. package/LICENSE +21 -0
  3. package/README.md +649 -0
  4. package/android/build.gradle +122 -0
  5. package/android/src/main/AndroidManifest.xml +38 -0
  6. package/android/src/main/java/com/delicity/thermalprinter/Logger.kt +50 -0
  7. package/android/src/main/java/com/delicity/thermalprinter/ThermalPrinterEngine.kt +528 -0
  8. package/android/src/main/java/com/delicity/thermalprinter/ThermalPrinterPlugin.kt +334 -0
  9. package/android/src/main/java/com/delicity/thermalprinter/adapters/BleAdapter.kt +125 -0
  10. package/android/src/main/java/com/delicity/thermalprinter/adapters/BrotherAdapter.kt +206 -0
  11. package/android/src/main/java/com/delicity/thermalprinter/adapters/EpsonAdapter.kt +384 -0
  12. package/android/src/main/java/com/delicity/thermalprinter/adapters/EscPosAdapter.kt +160 -0
  13. package/android/src/main/java/com/delicity/thermalprinter/adapters/EscPosCommands.kt +42 -0
  14. package/android/src/main/java/com/delicity/thermalprinter/adapters/EscPosTextEncoder.kt +138 -0
  15. package/android/src/main/java/com/delicity/thermalprinter/adapters/PrinterAdapter.kt +95 -0
  16. package/android/src/main/java/com/delicity/thermalprinter/adapters/RawTcpAdapter.kt +96 -0
  17. package/android/src/main/java/com/delicity/thermalprinter/adapters/SdkContract.kt +158 -0
  18. package/android/src/main/java/com/delicity/thermalprinter/adapters/SdkReflect.kt +104 -0
  19. package/android/src/main/java/com/delicity/thermalprinter/adapters/StarAdapter.kt +322 -0
  20. package/android/src/main/java/com/delicity/thermalprinter/adapters/UsbAdapter.kt +248 -0
  21. package/android/src/main/java/com/delicity/thermalprinter/adapters/ZebraAdapter.kt +207 -0
  22. package/android/src/main/java/com/delicity/thermalprinter/discovery/AdapterPriority.kt +39 -0
  23. package/android/src/main/java/com/delicity/thermalprinter/discovery/BleScanner.kt +70 -0
  24. package/android/src/main/java/com/delicity/thermalprinter/discovery/BluetoothClassicScanner.kt +112 -0
  25. package/android/src/main/java/com/delicity/thermalprinter/discovery/DiscoveryManager.kt +136 -0
  26. package/android/src/main/java/com/delicity/thermalprinter/discovery/TcpScanner.kt +96 -0
  27. package/android/src/main/java/com/delicity/thermalprinter/image/ImageCache.kt +88 -0
  28. package/android/src/main/java/com/delicity/thermalprinter/image/ImageProcessor.kt +220 -0
  29. package/android/src/main/java/com/delicity/thermalprinter/image/TextRasterizer.kt +99 -0
  30. package/android/src/main/java/com/delicity/thermalprinter/model/Models.kt +206 -0
  31. package/android/src/main/java/com/delicity/thermalprinter/model/PrintItem.kt +100 -0
  32. package/android/src/main/java/com/delicity/thermalprinter/store/PrinterStore.kt +71 -0
  33. package/android/src/main/java/com/delicity/thermalprinter/transport/BleGattClient.kt +201 -0
  34. package/android/src/main/java/com/delicity/thermalprinter/transport/BluetoothSppTransport.kt +110 -0
  35. package/android/src/main/java/com/delicity/thermalprinter/transport/ByteTransport.kt +18 -0
  36. package/android/src/main/java/com/delicity/thermalprinter/transport/TcpTransport.kt +83 -0
  37. package/dist/esm/adapters/dedup.d.ts +26 -0
  38. package/dist/esm/adapters/dedup.js +66 -0
  39. package/dist/esm/adapters/dedup.js.map +1 -0
  40. package/dist/esm/adapters/priority.d.ts +29 -0
  41. package/dist/esm/adapters/priority.js +55 -0
  42. package/dist/esm/adapters/priority.js.map +1 -0
  43. package/dist/esm/core/enums.d.ts +61 -0
  44. package/dist/esm/core/enums.js +25 -0
  45. package/dist/esm/core/enums.js.map +1 -0
  46. package/dist/esm/core/errors.d.ts +16 -0
  47. package/dist/esm/core/errors.js +53 -0
  48. package/dist/esm/core/errors.js.map +1 -0
  49. package/dist/esm/core/escpos-text.d.ts +33 -0
  50. package/dist/esm/core/escpos-text.js +239 -0
  51. package/dist/esm/core/escpos-text.js.map +1 -0
  52. package/dist/esm/core/imaging.d.ts +91 -0
  53. package/dist/esm/core/imaging.js +184 -0
  54. package/dist/esm/core/imaging.js.map +1 -0
  55. package/dist/esm/core/models.d.ts +131 -0
  56. package/dist/esm/core/models.js +2 -0
  57. package/dist/esm/core/models.js.map +1 -0
  58. package/dist/esm/core/options.d.ts +154 -0
  59. package/dist/esm/core/options.js +2 -0
  60. package/dist/esm/core/options.js.map +1 -0
  61. package/dist/esm/core/text.d.ts +138 -0
  62. package/dist/esm/core/text.js +14 -0
  63. package/dist/esm/core/text.js.map +1 -0
  64. package/dist/esm/definitions.d.ts +155 -0
  65. package/dist/esm/definitions.js +2 -0
  66. package/dist/esm/definitions.js.map +1 -0
  67. package/dist/esm/index.d.ts +15 -0
  68. package/dist/esm/index.js +18 -0
  69. package/dist/esm/index.js.map +1 -0
  70. package/dist/esm/web.d.ts +63 -0
  71. package/dist/esm/web.js +112 -0
  72. package/dist/esm/web.js.map +1 -0
  73. package/dist/plugin.cjs.js +224 -0
  74. package/dist/plugin.cjs.js.map +1 -0
  75. package/dist/plugin.js +227 -0
  76. package/dist/plugin.js.map +1 -0
  77. package/ios/Plugin/Adapters/BrotherAdapter.swift +139 -0
  78. package/ios/Plugin/Adapters/EpsonAdapter.swift +131 -0
  79. package/ios/Plugin/Adapters/EscPosAdapter.swift +106 -0
  80. package/ios/Plugin/Adapters/EscPosCommands.swift +32 -0
  81. package/ios/Plugin/Adapters/EscPosTextEncoder.swift +115 -0
  82. package/ios/Plugin/Adapters/PrinterAdapter.swift +44 -0
  83. package/ios/Plugin/Adapters/RawTcpAdapter.swift +70 -0
  84. package/ios/Plugin/Adapters/StarAdapter.swift +305 -0
  85. package/ios/Plugin/Adapters/ZebraAdapter.swift +119 -0
  86. package/ios/Plugin/Discovery/AdapterPriority.swift +21 -0
  87. package/ios/Plugin/Discovery/BonjourScanner.swift +51 -0
  88. package/ios/Plugin/Discovery/DiscoveryManager.swift +86 -0
  89. package/ios/Plugin/Image/ImageCache.swift +73 -0
  90. package/ios/Plugin/Image/ImageProcessor.swift +168 -0
  91. package/ios/Plugin/Image/TextRasterizer.swift +81 -0
  92. package/ios/Plugin/Logger.swift +33 -0
  93. package/ios/Plugin/Model/Models.swift +174 -0
  94. package/ios/Plugin/Model/PrintItem.swift +111 -0
  95. package/ios/Plugin/Store/PrinterStore.swift +51 -0
  96. package/ios/Plugin/ThermalPrinterEngine.swift +395 -0
  97. package/ios/Plugin/ThermalPrinterPlugin.m +22 -0
  98. package/ios/Plugin/ThermalPrinterPlugin.swift +258 -0
  99. package/ios/Plugin/Transport/TcpTransport.swift +89 -0
  100. package/package.json +96 -0
@@ -0,0 +1,224 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ /**
6
+ * Codes d'erreur normalisés renvoyés par le plugin sur toutes les plateformes.
7
+ * Ils sont stables et destinés à être mappés dans l'UI / le support.
8
+ */
9
+ exports.PrintErrorCode = void 0;
10
+ (function (PrintErrorCode) {
11
+ PrintErrorCode["PRINTER_NOT_FOUND"] = "PRINTER_NOT_FOUND";
12
+ PrintErrorCode["PRINTER_OFFLINE"] = "PRINTER_OFFLINE";
13
+ PrintErrorCode["CONNECTION_FAILED"] = "CONNECTION_FAILED";
14
+ PrintErrorCode["PERMISSION_DENIED"] = "PERMISSION_DENIED";
15
+ PrintErrorCode["BLUETOOTH_DISABLED"] = "BLUETOOTH_DISABLED";
16
+ PrintErrorCode["WIFI_NOT_CONNECTED"] = "WIFI_NOT_CONNECTED";
17
+ PrintErrorCode["PAIRING_REQUIRED"] = "PAIRING_REQUIRED";
18
+ PrintErrorCode["UNSUPPORTED_TRANSPORT"] = "UNSUPPORTED_TRANSPORT";
19
+ PrintErrorCode["UNSUPPORTED_PRINTER"] = "UNSUPPORTED_PRINTER";
20
+ PrintErrorCode["IMAGE_INVALID"] = "IMAGE_INVALID";
21
+ PrintErrorCode["IMAGE_TOO_LARGE"] = "IMAGE_TOO_LARGE";
22
+ PrintErrorCode["PRINT_FAILED"] = "PRINT_FAILED";
23
+ PrintErrorCode["PAPER_EMPTY"] = "PAPER_EMPTY";
24
+ PrintErrorCode["COVER_OPEN"] = "COVER_OPEN";
25
+ PrintErrorCode["SDK_NOT_AVAILABLE"] = "SDK_NOT_AVAILABLE";
26
+ PrintErrorCode["TIMEOUT"] = "TIMEOUT";
27
+ PrintErrorCode["UNKNOWN"] = "UNKNOWN";
28
+ })(exports.PrintErrorCode || (exports.PrintErrorCode = {}));
29
+
30
+ /**
31
+ * Correspondance page de code -> argument de la commande ESC t (n).
32
+ * Ces valeurs sont les plus répandues ; certaines imprimantes diffèrent
33
+ * (override possible via `TextStyle.codePageId`).
34
+ */
35
+ const CODE_PAGE_TO_ESC_T = {
36
+ CP437: 0,
37
+ CP850: 2,
38
+ CP858: 19,
39
+ WPC1252: 16,
40
+ CP852: 18,
41
+ CP866: 17,
42
+ };
43
+
44
+ /**
45
+ * Erreur typée exposée côté JS. Les rejets de promesse du plugin sont
46
+ * normalisés vers cette classe via `toPrinterError`.
47
+ */
48
+ class PrinterError extends Error {
49
+ constructor(shape) {
50
+ var _a;
51
+ super(shape.message);
52
+ this.name = 'PrinterError';
53
+ this.code = shape.code;
54
+ this.detail = shape.detail;
55
+ this.retryable = (_a = shape.retryable) !== null && _a !== void 0 ? _a : defaultRetryable(shape.code);
56
+ Object.setPrototypeOf(this, PrinterError.prototype);
57
+ }
58
+ }
59
+ /**
60
+ * Convertit une erreur Capacitor (qui porte souvent `code` et `message`) en PrinterError.
61
+ */
62
+ function toPrinterError(err) {
63
+ var _a;
64
+ if (err instanceof PrinterError)
65
+ return err;
66
+ const anyErr = err;
67
+ const code = mapToErrorCode(anyErr === null || anyErr === void 0 ? void 0 : anyErr.code);
68
+ return new PrinterError({
69
+ code,
70
+ message: (_a = anyErr === null || anyErr === void 0 ? void 0 : anyErr.message) !== null && _a !== void 0 ? _a : 'Erreur imprimante inconnue',
71
+ detail: anyErr === null || anyErr === void 0 ? void 0 : anyErr.detail,
72
+ });
73
+ }
74
+ function mapToErrorCode(raw) {
75
+ if (!raw)
76
+ return exports.PrintErrorCode.UNKNOWN;
77
+ const upper = raw.toUpperCase();
78
+ if (upper in exports.PrintErrorCode) {
79
+ return exports.PrintErrorCode[upper];
80
+ }
81
+ return exports.PrintErrorCode.UNKNOWN;
82
+ }
83
+ /** Les erreurs réseau/connexion/timeout justifient un retry automatique. */
84
+ function defaultRetryable(code) {
85
+ switch (code) {
86
+ case exports.PrintErrorCode.CONNECTION_FAILED:
87
+ case exports.PrintErrorCode.PRINTER_OFFLINE:
88
+ case exports.PrintErrorCode.TIMEOUT:
89
+ case exports.PrintErrorCode.WIFI_NOT_CONNECTED:
90
+ return true;
91
+ default:
92
+ return false;
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Point d'entrée du plugin.
98
+ *
99
+ * `registerPlugin` renvoie un proxy : sur natif il route vers Kotlin/Swift,
100
+ * sur web il charge dynamiquement l'implémentation `ThermalPrinterWeb`.
101
+ */
102
+ const ThermalPrinter = core.registerPlugin('ThermalPrinter', {
103
+ web: () => Promise.resolve().then(function () { return web; }).then(m => new m.ThermalPrinterWeb()),
104
+ });
105
+
106
+ /**
107
+ * Implémentation Web (fallback navigateur / SSR).
108
+ *
109
+ * Le matériel d'impression thermique n'est pas adressable de façon fiable
110
+ * depuis un navigateur standard. On expose donc une implémentation qui :
111
+ * - persiste les profils dans localStorage (utile pour le dev UI),
112
+ * - rejette explicitement les opérations matérielles avec SDK_NOT_AVAILABLE.
113
+ *
114
+ * Cela permet de développer toute l'UI Capacitor sans device.
115
+ */
116
+ class ThermalPrinterWeb extends core.WebPlugin {
117
+ constructor() {
118
+ super(...arguments);
119
+ this.storageKey = 'delicity.thermalprinter.profiles';
120
+ }
121
+ async discoverPrinters(_options) {
122
+ // Aucune découverte matérielle possible sur le web.
123
+ return { printers: [] };
124
+ }
125
+ async connectPrinter(_options) {
126
+ throw this.unsupported('connectPrinter');
127
+ }
128
+ async disconnectPrinter(_options) {
129
+ return;
130
+ }
131
+ async setDefaultPrinter(options) {
132
+ const profiles = this.readProfiles();
133
+ const target = profiles.find(p => p.id === options.printerId);
134
+ if (!target)
135
+ throw new PrinterError({ code: exports.PrintErrorCode.PRINTER_NOT_FOUND, message: 'Profil introuvable' });
136
+ profiles.forEach(p => (p.isDefault = p.id === options.printerId));
137
+ target.updatedAt = Date.now();
138
+ this.writeProfiles(profiles);
139
+ return { profile: target };
140
+ }
141
+ async getDefaultPrinter() {
142
+ var _a;
143
+ const profiles = this.readProfiles();
144
+ return { profile: (_a = profiles.find(p => p.isDefault)) !== null && _a !== void 0 ? _a : null };
145
+ }
146
+ async getSavedPrinters() {
147
+ return { profiles: this.readProfiles() };
148
+ }
149
+ async removePrinter(options) {
150
+ this.writeProfiles(this.readProfiles().filter(p => p.id !== options.printerId));
151
+ }
152
+ async printImage(_options) {
153
+ throw this.unsupported('printImage');
154
+ }
155
+ async printText(_options) {
156
+ throw this.unsupported('printText');
157
+ }
158
+ async getPrinterStatus(_options) {
159
+ throw this.unsupported('getPrinterStatus');
160
+ }
161
+ async requestPermissions() {
162
+ return this.checkPermissions();
163
+ }
164
+ async checkPermissions() {
165
+ return {
166
+ bluetooth: 'unavailable',
167
+ bluetoothScan: 'unavailable',
168
+ bluetoothConnect: 'unavailable',
169
+ location: 'unavailable',
170
+ localNetwork: 'unavailable',
171
+ };
172
+ }
173
+ async startStatusMonitor(_options) {
174
+ return;
175
+ }
176
+ async stopStatusMonitor(_options) {
177
+ return;
178
+ }
179
+ async getActiveSdks() {
180
+ // Aucun adapter natif n'est actif sur le web.
181
+ return {
182
+ sdks: [
183
+ { adapter: 'escpos', label: 'ESC/POS générique', available: false, requiresSdk: false, transports: ['wifi', 'ethernet', 'bluetooth', 'ble', 'usb'] },
184
+ { adapter: 'star', label: 'Star StarXpand', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'ble', 'usb'] },
185
+ { adapter: 'epson', label: 'Epson ePOS2', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'usb'] },
186
+ { adapter: 'brother', label: 'Brother', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'ble'] },
187
+ { adapter: 'zebra', label: 'Zebra Link-OS', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth'] },
188
+ { adapter: 'rawTcp', label: 'TCP brut', available: false, requiresSdk: false, transports: ['wifi', 'ethernet'] },
189
+ ],
190
+ };
191
+ }
192
+ async getDebugLog() {
193
+ return { log: [] };
194
+ }
195
+ unsupported(method) {
196
+ return new PrinterError({
197
+ code: exports.PrintErrorCode.SDK_NOT_AVAILABLE,
198
+ message: `${method} n'est pas disponible sur le web. Utilisez un device Android/iOS.`,
199
+ });
200
+ }
201
+ readProfiles() {
202
+ var _a;
203
+ try {
204
+ return JSON.parse((_a = localStorage.getItem(this.storageKey)) !== null && _a !== void 0 ? _a : '[]');
205
+ }
206
+ catch (_b) {
207
+ return [];
208
+ }
209
+ }
210
+ writeProfiles(profiles) {
211
+ localStorage.setItem(this.storageKey, JSON.stringify(profiles));
212
+ }
213
+ }
214
+
215
+ var web = /*#__PURE__*/Object.freeze({
216
+ __proto__: null,
217
+ ThermalPrinterWeb: ThermalPrinterWeb
218
+ });
219
+
220
+ exports.CODE_PAGE_TO_ESC_T = CODE_PAGE_TO_ESC_T;
221
+ exports.PrinterError = PrinterError;
222
+ exports.ThermalPrinter = ThermalPrinter;
223
+ exports.toPrinterError = toPrinterError;
224
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/core/enums.js","esm/core/text.js","esm/core/errors.js","esm/index.js","esm/web.js"],"sourcesContent":["/**\n * Codes d'erreur normalisés renvoyés par le plugin sur toutes les plateformes.\n * Ils sont stables et destinés à être mappés dans l'UI / le support.\n */\nexport var PrintErrorCode;\n(function (PrintErrorCode) {\n PrintErrorCode[\"PRINTER_NOT_FOUND\"] = \"PRINTER_NOT_FOUND\";\n PrintErrorCode[\"PRINTER_OFFLINE\"] = \"PRINTER_OFFLINE\";\n PrintErrorCode[\"CONNECTION_FAILED\"] = \"CONNECTION_FAILED\";\n PrintErrorCode[\"PERMISSION_DENIED\"] = \"PERMISSION_DENIED\";\n PrintErrorCode[\"BLUETOOTH_DISABLED\"] = \"BLUETOOTH_DISABLED\";\n PrintErrorCode[\"WIFI_NOT_CONNECTED\"] = \"WIFI_NOT_CONNECTED\";\n PrintErrorCode[\"PAIRING_REQUIRED\"] = \"PAIRING_REQUIRED\";\n PrintErrorCode[\"UNSUPPORTED_TRANSPORT\"] = \"UNSUPPORTED_TRANSPORT\";\n PrintErrorCode[\"UNSUPPORTED_PRINTER\"] = \"UNSUPPORTED_PRINTER\";\n PrintErrorCode[\"IMAGE_INVALID\"] = \"IMAGE_INVALID\";\n PrintErrorCode[\"IMAGE_TOO_LARGE\"] = \"IMAGE_TOO_LARGE\";\n PrintErrorCode[\"PRINT_FAILED\"] = \"PRINT_FAILED\";\n PrintErrorCode[\"PAPER_EMPTY\"] = \"PAPER_EMPTY\";\n PrintErrorCode[\"COVER_OPEN\"] = \"COVER_OPEN\";\n PrintErrorCode[\"SDK_NOT_AVAILABLE\"] = \"SDK_NOT_AVAILABLE\";\n PrintErrorCode[\"TIMEOUT\"] = \"TIMEOUT\";\n PrintErrorCode[\"UNKNOWN\"] = \"UNKNOWN\";\n})(PrintErrorCode || (PrintErrorCode = {}));\n//# sourceMappingURL=enums.js.map","/**\n * Correspondance page de code -> argument de la commande ESC t (n).\n * Ces valeurs sont les plus répandues ; certaines imprimantes diffèrent\n * (override possible via `TextStyle.codePageId`).\n */\nexport const CODE_PAGE_TO_ESC_T = {\n CP437: 0,\n CP850: 2,\n CP858: 19,\n WPC1252: 16,\n CP852: 18,\n CP866: 17,\n};\n//# sourceMappingURL=text.js.map","import { PrintErrorCode } from './enums';\n/**\n * Erreur typée exposée côté JS. Les rejets de promesse du plugin sont\n * normalisés vers cette classe via `toPrinterError`.\n */\nexport class PrinterError extends Error {\n constructor(shape) {\n var _a;\n super(shape.message);\n this.name = 'PrinterError';\n this.code = shape.code;\n this.detail = shape.detail;\n this.retryable = (_a = shape.retryable) !== null && _a !== void 0 ? _a : defaultRetryable(shape.code);\n Object.setPrototypeOf(this, PrinterError.prototype);\n }\n}\n/**\n * Convertit une erreur Capacitor (qui porte souvent `code` et `message`) en PrinterError.\n */\nexport function toPrinterError(err) {\n var _a;\n if (err instanceof PrinterError)\n return err;\n const anyErr = err;\n const code = mapToErrorCode(anyErr === null || anyErr === void 0 ? void 0 : anyErr.code);\n return new PrinterError({\n code,\n message: (_a = anyErr === null || anyErr === void 0 ? void 0 : anyErr.message) !== null && _a !== void 0 ? _a : 'Erreur imprimante inconnue',\n detail: anyErr === null || anyErr === void 0 ? void 0 : anyErr.detail,\n });\n}\nfunction mapToErrorCode(raw) {\n if (!raw)\n return PrintErrorCode.UNKNOWN;\n const upper = raw.toUpperCase();\n if (upper in PrintErrorCode) {\n return PrintErrorCode[upper];\n }\n return PrintErrorCode.UNKNOWN;\n}\n/** Les erreurs réseau/connexion/timeout justifient un retry automatique. */\nfunction defaultRetryable(code) {\n switch (code) {\n case PrintErrorCode.CONNECTION_FAILED:\n case PrintErrorCode.PRINTER_OFFLINE:\n case PrintErrorCode.TIMEOUT:\n case PrintErrorCode.WIFI_NOT_CONNECTED:\n return true;\n default:\n return false;\n }\n}\n//# sourceMappingURL=errors.js.map","import { registerPlugin } from '@capacitor/core';\n/**\n * Point d'entrée du plugin.\n *\n * `registerPlugin` renvoie un proxy : sur natif il route vers Kotlin/Swift,\n * sur web il charge dynamiquement l'implémentation `ThermalPrinterWeb`.\n */\nconst ThermalPrinter = registerPlugin('ThermalPrinter', {\n web: () => import('./web').then(m => new m.ThermalPrinterWeb()),\n});\nexport * from './definitions';\nexport * from './core/enums';\nexport * from './core/models';\nexport * from './core/options';\nexport * from './core/text';\nexport * from './core/errors';\nexport { ThermalPrinter };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nimport { PrintErrorCode } from './core/enums';\nimport { PrinterError } from './core/errors';\n/**\n * Implémentation Web (fallback navigateur / SSR).\n *\n * Le matériel d'impression thermique n'est pas adressable de façon fiable\n * depuis un navigateur standard. On expose donc une implémentation qui :\n * - persiste les profils dans localStorage (utile pour le dev UI),\n * - rejette explicitement les opérations matérielles avec SDK_NOT_AVAILABLE.\n *\n * Cela permet de développer toute l'UI Capacitor sans device.\n */\nexport class ThermalPrinterWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.storageKey = 'delicity.thermalprinter.profiles';\n }\n async discoverPrinters(_options) {\n // Aucune découverte matérielle possible sur le web.\n return { printers: [] };\n }\n async connectPrinter(_options) {\n throw this.unsupported('connectPrinter');\n }\n async disconnectPrinter(_options) {\n return;\n }\n async setDefaultPrinter(options) {\n const profiles = this.readProfiles();\n const target = profiles.find(p => p.id === options.printerId);\n if (!target)\n throw new PrinterError({ code: PrintErrorCode.PRINTER_NOT_FOUND, message: 'Profil introuvable' });\n profiles.forEach(p => (p.isDefault = p.id === options.printerId));\n target.updatedAt = Date.now();\n this.writeProfiles(profiles);\n return { profile: target };\n }\n async getDefaultPrinter() {\n var _a;\n const profiles = this.readProfiles();\n return { profile: (_a = profiles.find(p => p.isDefault)) !== null && _a !== void 0 ? _a : null };\n }\n async getSavedPrinters() {\n return { profiles: this.readProfiles() };\n }\n async removePrinter(options) {\n this.writeProfiles(this.readProfiles().filter(p => p.id !== options.printerId));\n }\n async printImage(_options) {\n throw this.unsupported('printImage');\n }\n async printText(_options) {\n throw this.unsupported('printText');\n }\n async getPrinterStatus(_options) {\n throw this.unsupported('getPrinterStatus');\n }\n async requestPermissions() {\n return this.checkPermissions();\n }\n async checkPermissions() {\n return {\n bluetooth: 'unavailable',\n bluetoothScan: 'unavailable',\n bluetoothConnect: 'unavailable',\n location: 'unavailable',\n localNetwork: 'unavailable',\n };\n }\n async startStatusMonitor(_options) {\n return;\n }\n async stopStatusMonitor(_options) {\n return;\n }\n async getActiveSdks() {\n // Aucun adapter natif n'est actif sur le web.\n return {\n sdks: [\n { adapter: 'escpos', label: 'ESC/POS générique', available: false, requiresSdk: false, transports: ['wifi', 'ethernet', 'bluetooth', 'ble', 'usb'] },\n { adapter: 'star', label: 'Star StarXpand', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'ble', 'usb'] },\n { adapter: 'epson', label: 'Epson ePOS2', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'usb'] },\n { adapter: 'brother', label: 'Brother', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'ble'] },\n { adapter: 'zebra', label: 'Zebra Link-OS', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth'] },\n { adapter: 'rawTcp', label: 'TCP brut', available: false, requiresSdk: false, transports: ['wifi', 'ethernet'] },\n ],\n };\n }\n async getDebugLog() {\n return { log: [] };\n }\n unsupported(method) {\n return new PrinterError({\n code: PrintErrorCode.SDK_NOT_AVAILABLE,\n message: `${method} n'est pas disponible sur le web. Utilisez un device Android/iOS.`,\n });\n }\n readProfiles() {\n var _a;\n try {\n return JSON.parse((_a = localStorage.getItem(this.storageKey)) !== null && _a !== void 0 ? _a : '[]');\n }\n catch (_b) {\n return [];\n }\n }\n writeProfiles(profiles) {\n localStorage.setItem(this.storageKey, JSON.stringify(profiles));\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["PrintErrorCode","registerPlugin","WebPlugin"],"mappings":"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"}
package/dist/plugin.js ADDED
@@ -0,0 +1,227 @@
1
+ var capacitorThermalPrinter = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ /**
5
+ * Codes d'erreur normalisés renvoyés par le plugin sur toutes les plateformes.
6
+ * Ils sont stables et destinés à être mappés dans l'UI / le support.
7
+ */
8
+ exports.PrintErrorCode = void 0;
9
+ (function (PrintErrorCode) {
10
+ PrintErrorCode["PRINTER_NOT_FOUND"] = "PRINTER_NOT_FOUND";
11
+ PrintErrorCode["PRINTER_OFFLINE"] = "PRINTER_OFFLINE";
12
+ PrintErrorCode["CONNECTION_FAILED"] = "CONNECTION_FAILED";
13
+ PrintErrorCode["PERMISSION_DENIED"] = "PERMISSION_DENIED";
14
+ PrintErrorCode["BLUETOOTH_DISABLED"] = "BLUETOOTH_DISABLED";
15
+ PrintErrorCode["WIFI_NOT_CONNECTED"] = "WIFI_NOT_CONNECTED";
16
+ PrintErrorCode["PAIRING_REQUIRED"] = "PAIRING_REQUIRED";
17
+ PrintErrorCode["UNSUPPORTED_TRANSPORT"] = "UNSUPPORTED_TRANSPORT";
18
+ PrintErrorCode["UNSUPPORTED_PRINTER"] = "UNSUPPORTED_PRINTER";
19
+ PrintErrorCode["IMAGE_INVALID"] = "IMAGE_INVALID";
20
+ PrintErrorCode["IMAGE_TOO_LARGE"] = "IMAGE_TOO_LARGE";
21
+ PrintErrorCode["PRINT_FAILED"] = "PRINT_FAILED";
22
+ PrintErrorCode["PAPER_EMPTY"] = "PAPER_EMPTY";
23
+ PrintErrorCode["COVER_OPEN"] = "COVER_OPEN";
24
+ PrintErrorCode["SDK_NOT_AVAILABLE"] = "SDK_NOT_AVAILABLE";
25
+ PrintErrorCode["TIMEOUT"] = "TIMEOUT";
26
+ PrintErrorCode["UNKNOWN"] = "UNKNOWN";
27
+ })(exports.PrintErrorCode || (exports.PrintErrorCode = {}));
28
+
29
+ /**
30
+ * Correspondance page de code -> argument de la commande ESC t (n).
31
+ * Ces valeurs sont les plus répandues ; certaines imprimantes diffèrent
32
+ * (override possible via `TextStyle.codePageId`).
33
+ */
34
+ const CODE_PAGE_TO_ESC_T = {
35
+ CP437: 0,
36
+ CP850: 2,
37
+ CP858: 19,
38
+ WPC1252: 16,
39
+ CP852: 18,
40
+ CP866: 17,
41
+ };
42
+
43
+ /**
44
+ * Erreur typée exposée côté JS. Les rejets de promesse du plugin sont
45
+ * normalisés vers cette classe via `toPrinterError`.
46
+ */
47
+ class PrinterError extends Error {
48
+ constructor(shape) {
49
+ var _a;
50
+ super(shape.message);
51
+ this.name = 'PrinterError';
52
+ this.code = shape.code;
53
+ this.detail = shape.detail;
54
+ this.retryable = (_a = shape.retryable) !== null && _a !== void 0 ? _a : defaultRetryable(shape.code);
55
+ Object.setPrototypeOf(this, PrinterError.prototype);
56
+ }
57
+ }
58
+ /**
59
+ * Convertit une erreur Capacitor (qui porte souvent `code` et `message`) en PrinterError.
60
+ */
61
+ function toPrinterError(err) {
62
+ var _a;
63
+ if (err instanceof PrinterError)
64
+ return err;
65
+ const anyErr = err;
66
+ const code = mapToErrorCode(anyErr === null || anyErr === void 0 ? void 0 : anyErr.code);
67
+ return new PrinterError({
68
+ code,
69
+ message: (_a = anyErr === null || anyErr === void 0 ? void 0 : anyErr.message) !== null && _a !== void 0 ? _a : 'Erreur imprimante inconnue',
70
+ detail: anyErr === null || anyErr === void 0 ? void 0 : anyErr.detail,
71
+ });
72
+ }
73
+ function mapToErrorCode(raw) {
74
+ if (!raw)
75
+ return exports.PrintErrorCode.UNKNOWN;
76
+ const upper = raw.toUpperCase();
77
+ if (upper in exports.PrintErrorCode) {
78
+ return exports.PrintErrorCode[upper];
79
+ }
80
+ return exports.PrintErrorCode.UNKNOWN;
81
+ }
82
+ /** Les erreurs réseau/connexion/timeout justifient un retry automatique. */
83
+ function defaultRetryable(code) {
84
+ switch (code) {
85
+ case exports.PrintErrorCode.CONNECTION_FAILED:
86
+ case exports.PrintErrorCode.PRINTER_OFFLINE:
87
+ case exports.PrintErrorCode.TIMEOUT:
88
+ case exports.PrintErrorCode.WIFI_NOT_CONNECTED:
89
+ return true;
90
+ default:
91
+ return false;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Point d'entrée du plugin.
97
+ *
98
+ * `registerPlugin` renvoie un proxy : sur natif il route vers Kotlin/Swift,
99
+ * sur web il charge dynamiquement l'implémentation `ThermalPrinterWeb`.
100
+ */
101
+ const ThermalPrinter = core.registerPlugin('ThermalPrinter', {
102
+ web: () => Promise.resolve().then(function () { return web; }).then(m => new m.ThermalPrinterWeb()),
103
+ });
104
+
105
+ /**
106
+ * Implémentation Web (fallback navigateur / SSR).
107
+ *
108
+ * Le matériel d'impression thermique n'est pas adressable de façon fiable
109
+ * depuis un navigateur standard. On expose donc une implémentation qui :
110
+ * - persiste les profils dans localStorage (utile pour le dev UI),
111
+ * - rejette explicitement les opérations matérielles avec SDK_NOT_AVAILABLE.
112
+ *
113
+ * Cela permet de développer toute l'UI Capacitor sans device.
114
+ */
115
+ class ThermalPrinterWeb extends core.WebPlugin {
116
+ constructor() {
117
+ super(...arguments);
118
+ this.storageKey = 'delicity.thermalprinter.profiles';
119
+ }
120
+ async discoverPrinters(_options) {
121
+ // Aucune découverte matérielle possible sur le web.
122
+ return { printers: [] };
123
+ }
124
+ async connectPrinter(_options) {
125
+ throw this.unsupported('connectPrinter');
126
+ }
127
+ async disconnectPrinter(_options) {
128
+ return;
129
+ }
130
+ async setDefaultPrinter(options) {
131
+ const profiles = this.readProfiles();
132
+ const target = profiles.find(p => p.id === options.printerId);
133
+ if (!target)
134
+ throw new PrinterError({ code: exports.PrintErrorCode.PRINTER_NOT_FOUND, message: 'Profil introuvable' });
135
+ profiles.forEach(p => (p.isDefault = p.id === options.printerId));
136
+ target.updatedAt = Date.now();
137
+ this.writeProfiles(profiles);
138
+ return { profile: target };
139
+ }
140
+ async getDefaultPrinter() {
141
+ var _a;
142
+ const profiles = this.readProfiles();
143
+ return { profile: (_a = profiles.find(p => p.isDefault)) !== null && _a !== void 0 ? _a : null };
144
+ }
145
+ async getSavedPrinters() {
146
+ return { profiles: this.readProfiles() };
147
+ }
148
+ async removePrinter(options) {
149
+ this.writeProfiles(this.readProfiles().filter(p => p.id !== options.printerId));
150
+ }
151
+ async printImage(_options) {
152
+ throw this.unsupported('printImage');
153
+ }
154
+ async printText(_options) {
155
+ throw this.unsupported('printText');
156
+ }
157
+ async getPrinterStatus(_options) {
158
+ throw this.unsupported('getPrinterStatus');
159
+ }
160
+ async requestPermissions() {
161
+ return this.checkPermissions();
162
+ }
163
+ async checkPermissions() {
164
+ return {
165
+ bluetooth: 'unavailable',
166
+ bluetoothScan: 'unavailable',
167
+ bluetoothConnect: 'unavailable',
168
+ location: 'unavailable',
169
+ localNetwork: 'unavailable',
170
+ };
171
+ }
172
+ async startStatusMonitor(_options) {
173
+ return;
174
+ }
175
+ async stopStatusMonitor(_options) {
176
+ return;
177
+ }
178
+ async getActiveSdks() {
179
+ // Aucun adapter natif n'est actif sur le web.
180
+ return {
181
+ sdks: [
182
+ { adapter: 'escpos', label: 'ESC/POS générique', available: false, requiresSdk: false, transports: ['wifi', 'ethernet', 'bluetooth', 'ble', 'usb'] },
183
+ { adapter: 'star', label: 'Star StarXpand', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'ble', 'usb'] },
184
+ { adapter: 'epson', label: 'Epson ePOS2', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'usb'] },
185
+ { adapter: 'brother', label: 'Brother', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'ble'] },
186
+ { adapter: 'zebra', label: 'Zebra Link-OS', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth'] },
187
+ { adapter: 'rawTcp', label: 'TCP brut', available: false, requiresSdk: false, transports: ['wifi', 'ethernet'] },
188
+ ],
189
+ };
190
+ }
191
+ async getDebugLog() {
192
+ return { log: [] };
193
+ }
194
+ unsupported(method) {
195
+ return new PrinterError({
196
+ code: exports.PrintErrorCode.SDK_NOT_AVAILABLE,
197
+ message: `${method} n'est pas disponible sur le web. Utilisez un device Android/iOS.`,
198
+ });
199
+ }
200
+ readProfiles() {
201
+ var _a;
202
+ try {
203
+ return JSON.parse((_a = localStorage.getItem(this.storageKey)) !== null && _a !== void 0 ? _a : '[]');
204
+ }
205
+ catch (_b) {
206
+ return [];
207
+ }
208
+ }
209
+ writeProfiles(profiles) {
210
+ localStorage.setItem(this.storageKey, JSON.stringify(profiles));
211
+ }
212
+ }
213
+
214
+ var web = /*#__PURE__*/Object.freeze({
215
+ __proto__: null,
216
+ ThermalPrinterWeb: ThermalPrinterWeb
217
+ });
218
+
219
+ exports.CODE_PAGE_TO_ESC_T = CODE_PAGE_TO_ESC_T;
220
+ exports.PrinterError = PrinterError;
221
+ exports.ThermalPrinter = ThermalPrinter;
222
+ exports.toPrinterError = toPrinterError;
223
+
224
+ return exports;
225
+
226
+ })({}, capacitorExports);
227
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/core/enums.js","esm/core/text.js","esm/core/errors.js","esm/index.js","esm/web.js"],"sourcesContent":["/**\n * Codes d'erreur normalisés renvoyés par le plugin sur toutes les plateformes.\n * Ils sont stables et destinés à être mappés dans l'UI / le support.\n */\nexport var PrintErrorCode;\n(function (PrintErrorCode) {\n PrintErrorCode[\"PRINTER_NOT_FOUND\"] = \"PRINTER_NOT_FOUND\";\n PrintErrorCode[\"PRINTER_OFFLINE\"] = \"PRINTER_OFFLINE\";\n PrintErrorCode[\"CONNECTION_FAILED\"] = \"CONNECTION_FAILED\";\n PrintErrorCode[\"PERMISSION_DENIED\"] = \"PERMISSION_DENIED\";\n PrintErrorCode[\"BLUETOOTH_DISABLED\"] = \"BLUETOOTH_DISABLED\";\n PrintErrorCode[\"WIFI_NOT_CONNECTED\"] = \"WIFI_NOT_CONNECTED\";\n PrintErrorCode[\"PAIRING_REQUIRED\"] = \"PAIRING_REQUIRED\";\n PrintErrorCode[\"UNSUPPORTED_TRANSPORT\"] = \"UNSUPPORTED_TRANSPORT\";\n PrintErrorCode[\"UNSUPPORTED_PRINTER\"] = \"UNSUPPORTED_PRINTER\";\n PrintErrorCode[\"IMAGE_INVALID\"] = \"IMAGE_INVALID\";\n PrintErrorCode[\"IMAGE_TOO_LARGE\"] = \"IMAGE_TOO_LARGE\";\n PrintErrorCode[\"PRINT_FAILED\"] = \"PRINT_FAILED\";\n PrintErrorCode[\"PAPER_EMPTY\"] = \"PAPER_EMPTY\";\n PrintErrorCode[\"COVER_OPEN\"] = \"COVER_OPEN\";\n PrintErrorCode[\"SDK_NOT_AVAILABLE\"] = \"SDK_NOT_AVAILABLE\";\n PrintErrorCode[\"TIMEOUT\"] = \"TIMEOUT\";\n PrintErrorCode[\"UNKNOWN\"] = \"UNKNOWN\";\n})(PrintErrorCode || (PrintErrorCode = {}));\n//# sourceMappingURL=enums.js.map","/**\n * Correspondance page de code -> argument de la commande ESC t (n).\n * Ces valeurs sont les plus répandues ; certaines imprimantes diffèrent\n * (override possible via `TextStyle.codePageId`).\n */\nexport const CODE_PAGE_TO_ESC_T = {\n CP437: 0,\n CP850: 2,\n CP858: 19,\n WPC1252: 16,\n CP852: 18,\n CP866: 17,\n};\n//# sourceMappingURL=text.js.map","import { PrintErrorCode } from './enums';\n/**\n * Erreur typée exposée côté JS. Les rejets de promesse du plugin sont\n * normalisés vers cette classe via `toPrinterError`.\n */\nexport class PrinterError extends Error {\n constructor(shape) {\n var _a;\n super(shape.message);\n this.name = 'PrinterError';\n this.code = shape.code;\n this.detail = shape.detail;\n this.retryable = (_a = shape.retryable) !== null && _a !== void 0 ? _a : defaultRetryable(shape.code);\n Object.setPrototypeOf(this, PrinterError.prototype);\n }\n}\n/**\n * Convertit une erreur Capacitor (qui porte souvent `code` et `message`) en PrinterError.\n */\nexport function toPrinterError(err) {\n var _a;\n if (err instanceof PrinterError)\n return err;\n const anyErr = err;\n const code = mapToErrorCode(anyErr === null || anyErr === void 0 ? void 0 : anyErr.code);\n return new PrinterError({\n code,\n message: (_a = anyErr === null || anyErr === void 0 ? void 0 : anyErr.message) !== null && _a !== void 0 ? _a : 'Erreur imprimante inconnue',\n detail: anyErr === null || anyErr === void 0 ? void 0 : anyErr.detail,\n });\n}\nfunction mapToErrorCode(raw) {\n if (!raw)\n return PrintErrorCode.UNKNOWN;\n const upper = raw.toUpperCase();\n if (upper in PrintErrorCode) {\n return PrintErrorCode[upper];\n }\n return PrintErrorCode.UNKNOWN;\n}\n/** Les erreurs réseau/connexion/timeout justifient un retry automatique. */\nfunction defaultRetryable(code) {\n switch (code) {\n case PrintErrorCode.CONNECTION_FAILED:\n case PrintErrorCode.PRINTER_OFFLINE:\n case PrintErrorCode.TIMEOUT:\n case PrintErrorCode.WIFI_NOT_CONNECTED:\n return true;\n default:\n return false;\n }\n}\n//# sourceMappingURL=errors.js.map","import { registerPlugin } from '@capacitor/core';\n/**\n * Point d'entrée du plugin.\n *\n * `registerPlugin` renvoie un proxy : sur natif il route vers Kotlin/Swift,\n * sur web il charge dynamiquement l'implémentation `ThermalPrinterWeb`.\n */\nconst ThermalPrinter = registerPlugin('ThermalPrinter', {\n web: () => import('./web').then(m => new m.ThermalPrinterWeb()),\n});\nexport * from './definitions';\nexport * from './core/enums';\nexport * from './core/models';\nexport * from './core/options';\nexport * from './core/text';\nexport * from './core/errors';\nexport { ThermalPrinter };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nimport { PrintErrorCode } from './core/enums';\nimport { PrinterError } from './core/errors';\n/**\n * Implémentation Web (fallback navigateur / SSR).\n *\n * Le matériel d'impression thermique n'est pas adressable de façon fiable\n * depuis un navigateur standard. On expose donc une implémentation qui :\n * - persiste les profils dans localStorage (utile pour le dev UI),\n * - rejette explicitement les opérations matérielles avec SDK_NOT_AVAILABLE.\n *\n * Cela permet de développer toute l'UI Capacitor sans device.\n */\nexport class ThermalPrinterWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.storageKey = 'delicity.thermalprinter.profiles';\n }\n async discoverPrinters(_options) {\n // Aucune découverte matérielle possible sur le web.\n return { printers: [] };\n }\n async connectPrinter(_options) {\n throw this.unsupported('connectPrinter');\n }\n async disconnectPrinter(_options) {\n return;\n }\n async setDefaultPrinter(options) {\n const profiles = this.readProfiles();\n const target = profiles.find(p => p.id === options.printerId);\n if (!target)\n throw new PrinterError({ code: PrintErrorCode.PRINTER_NOT_FOUND, message: 'Profil introuvable' });\n profiles.forEach(p => (p.isDefault = p.id === options.printerId));\n target.updatedAt = Date.now();\n this.writeProfiles(profiles);\n return { profile: target };\n }\n async getDefaultPrinter() {\n var _a;\n const profiles = this.readProfiles();\n return { profile: (_a = profiles.find(p => p.isDefault)) !== null && _a !== void 0 ? _a : null };\n }\n async getSavedPrinters() {\n return { profiles: this.readProfiles() };\n }\n async removePrinter(options) {\n this.writeProfiles(this.readProfiles().filter(p => p.id !== options.printerId));\n }\n async printImage(_options) {\n throw this.unsupported('printImage');\n }\n async printText(_options) {\n throw this.unsupported('printText');\n }\n async getPrinterStatus(_options) {\n throw this.unsupported('getPrinterStatus');\n }\n async requestPermissions() {\n return this.checkPermissions();\n }\n async checkPermissions() {\n return {\n bluetooth: 'unavailable',\n bluetoothScan: 'unavailable',\n bluetoothConnect: 'unavailable',\n location: 'unavailable',\n localNetwork: 'unavailable',\n };\n }\n async startStatusMonitor(_options) {\n return;\n }\n async stopStatusMonitor(_options) {\n return;\n }\n async getActiveSdks() {\n // Aucun adapter natif n'est actif sur le web.\n return {\n sdks: [\n { adapter: 'escpos', label: 'ESC/POS générique', available: false, requiresSdk: false, transports: ['wifi', 'ethernet', 'bluetooth', 'ble', 'usb'] },\n { adapter: 'star', label: 'Star StarXpand', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'ble', 'usb'] },\n { adapter: 'epson', label: 'Epson ePOS2', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'usb'] },\n { adapter: 'brother', label: 'Brother', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth', 'ble'] },\n { adapter: 'zebra', label: 'Zebra Link-OS', available: false, requiresSdk: true, transports: ['wifi', 'bluetooth'] },\n { adapter: 'rawTcp', label: 'TCP brut', available: false, requiresSdk: false, transports: ['wifi', 'ethernet'] },\n ],\n };\n }\n async getDebugLog() {\n return { log: [] };\n }\n unsupported(method) {\n return new PrinterError({\n code: PrintErrorCode.SDK_NOT_AVAILABLE,\n message: `${method} n'est pas disponible sur le web. Utilisez un device Android/iOS.`,\n });\n }\n readProfiles() {\n var _a;\n try {\n return JSON.parse((_a = localStorage.getItem(this.storageKey)) !== null && _a !== void 0 ? _a : '[]');\n }\n catch (_b) {\n return [];\n }\n }\n writeProfiles(profiles) {\n localStorage.setItem(this.storageKey, JSON.stringify(profiles));\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["PrintErrorCode","registerPlugin","WebPlugin"],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ import Foundation
2
+ import UIKit
3
+
4
+ #if canImport(BRLMPrinterKit)
5
+ import BRLMPrinterKit
6
+ #endif
7
+
8
+ /// Adapter Brother iOS (Brother Print SDK v4 / BRLMPrinterKit).
9
+ ///
10
+ /// Brother iOS est le SEUL des SDK "gated" auto-installable sur iOS : pod officiel
11
+ /// `BRLMPrinterKit` (CocoaPods trunk). On l'ajoute en dépendance OPTIONNELLE via le
12
+ /// Podfile de l'app puis on l'utilise sous `#if canImport(BRLMPrinterKit)`.
13
+ /// Si le pod n'est pas ajouté -> stub inerte, adapter ignoré.
14
+ ///
15
+ /// Gère réseau + Bluetooth MFi + BLE selon modèles (QL/TD/RJ/PJ). Impression image
16
+ /// native via BRLMPrinterDriver.printImage(_:settings:).
17
+ final class BrotherAdapter: PrinterAdapter {
18
+
19
+ let id: AdapterId = .brother
20
+
21
+ private var drivers: [String: AnyObject] = [:]
22
+ private let lock = NSLock()
23
+
24
+ func isAvailable() -> Bool {
25
+ #if canImport(BRLMPrinterKit)
26
+ return true
27
+ #else
28
+ return false
29
+ #endif
30
+ }
31
+
32
+ func canHandle(_ profile: PrinterProfile) -> Bool { isAvailable() && profile.adapter == .brother }
33
+
34
+ func discover(timeoutMs: Int, onFound: @escaping (DiscoveredPrinter) -> Void) async {
35
+ #if canImport(BRLMPrinterKit)
36
+ let option = BRLMNetworkSearchOption()
37
+ option.searchDuration = TimeInterval(max(1, timeoutMs / 1000))
38
+ _ = BRLMPrinterSearcher.startNetworkSearch(option) { channel in
39
+ let info = channel.channelInfo
40
+ onFound(DiscoveredPrinter(
41
+ id: "brother:\(info)",
42
+ name: channel.extraInfo?[BRLMChannelExtraInfoKey.modelName] as? String ?? "Brother",
43
+ brand: "Brother",
44
+ transport: .wifi,
45
+ adapter: .brother,
46
+ address: info,
47
+ discoveredBy: ["brother"]
48
+ ))
49
+ }
50
+ #endif
51
+ }
52
+
53
+ func connect(_ profile: PrinterProfile, timeoutMs: Int) async throws {
54
+ #if canImport(BRLMPrinterKit)
55
+ if isConnected(profile.id) { return }
56
+ let channel = try Self.channel(for: profile)
57
+ let result = BRLMPrinterDriverGenerator.open(channel)
58
+ guard result.error.code == .noError, let driver = result.driver else {
59
+ throw PrinterError(.CONNECTION_FAILED, "Connexion Brother échouée: \(profile.address)", detail: "\(result.error.code.rawValue)", retryable: true)
60
+ }
61
+ lock.lock(); drivers[profile.id] = driver; lock.unlock()
62
+ #else
63
+ throw PrinterError(.SDK_NOT_AVAILABLE, "SDK Brother (BRLMPrinterKit) absent")
64
+ #endif
65
+ }
66
+
67
+ func isConnected(_ printerId: String) -> Bool {
68
+ lock.lock(); defer { lock.unlock() }
69
+ return drivers[printerId] != nil
70
+ }
71
+
72
+ func disconnect(_ printerId: String) async {
73
+ #if canImport(BRLMPrinterKit)
74
+ lock.lock(); let d = drivers.removeValue(forKey: printerId) as? BRLMPrinterDriver; lock.unlock()
75
+ d?.closeChannel()
76
+ #endif
77
+ }
78
+
79
+ func printImage(_ profile: PrinterProfile, image: UIImage, options: RenderOptions) async throws -> Int {
80
+ #if canImport(BRLMPrinterKit)
81
+ lock.lock(); let d = drivers[profile.id] as? BRLMPrinterDriver; lock.unlock()
82
+ guard let driver = d else { throw PrinterError(.CONNECTION_FAILED, "Brother non connecté: \(profile.id)") }
83
+ guard let cg = image.cgImage else { throw PrinterError(.IMAGE_INVALID, "CGImage indisponible") }
84
+ let settings = try Self.printSettings(for: profile)
85
+ for _ in 0..<max(1, options.copies) {
86
+ let err = driver.printImage(with: cg, settings: settings)
87
+ if err.code != .noError {
88
+ throw PrinterError(.PRINT_FAILED, "Impression Brother échouée", detail: "\(err.code.rawValue)", retryable: true)
89
+ }
90
+ }
91
+ return Int(image.size.width * image.size.height) / 8
92
+ #else
93
+ throw PrinterError(.SDK_NOT_AVAILABLE, "SDK Brother (BRLMPrinterKit) absent")
94
+ #endif
95
+ }
96
+
97
+ func getStatus(_ profile: PrinterProfile) async throws -> PrinterStatus {
98
+ let connected = isConnected(profile.id)
99
+ return PrinterStatus(id: profile.id, connection: connected ? "connected" : "disconnected",
100
+ online: connected, paper: "unknown",
101
+ rawStatus: "Brother: statut détaillé non lu (best effort)")
102
+ }
103
+
104
+ // MARK: Helpers typés
105
+
106
+ #if canImport(BRLMPrinterKit)
107
+ private static func channel(for profile: PrinterProfile) throws -> BRLMChannel {
108
+ switch profile.transport {
109
+ case .wifi, .ethernet:
110
+ return BRLMChannel(wifiIPAddress: profile.address.split(separator: ":").first.map(String.init) ?? profile.address)
111
+ case .bluetooth:
112
+ return BRLMChannel(bluetoothSerialNumber: profile.address)
113
+ case .ble:
114
+ return BRLMChannel(bleLocalName: profile.address)
115
+ case .usb:
116
+ throw PrinterError(.UNSUPPORTED_TRANSPORT, "USB non supporté pour Brother iOS")
117
+ }
118
+ }
119
+
120
+ /// Réglages d'impression selon la famille du modèle (QL/PJ/RJ/TD/PT).
121
+ private static func printSettings(for profile: PrinterProfile) throws -> BRLMPrintSettingsProtocol {
122
+ guard let model = profile.model else {
123
+ throw PrinterError(.UNSUPPORTED_PRINTER, "Modèle Brother requis (ex 'RJ-3150')")
124
+ }
125
+ let m = model.uppercased()
126
+ // Roll/receipt: RJ / TD ; labels: QL ; mobiles: PJ
127
+ if m.hasPrefix("RJ") || m.hasPrefix("TD") || m.hasPrefix("PJ") || m.hasPrefix("QL") || m.hasPrefix("PT") {
128
+ // BRLMPrintSettings générique convient pour l'impression image roll.
129
+ if let s = BRLMPrintSettings(printerModel: brlmModel(from: m)) { return s }
130
+ }
131
+ throw PrinterError(.UNSUPPORTED_PRINTER, "Famille Brother inconnue pour '\(model)'")
132
+ }
133
+
134
+ private static func brlmModel(from m: String) -> BRLMPrinterModel {
135
+ // Best effort : laisser .other si le mapping précis n'est pas connu.
136
+ return .other
137
+ }
138
+ #endif
139
+ }