@delicity/capacitor-thermal-printer 7.0.0 → 7.0.1

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/README.md CHANGED
@@ -6,13 +6,18 @@ For **any Capacitor app that needs to print** — point of sale, receipts, order
6
6
 
7
7
  **Requires Capacitor 7** · Android (`compileSdk 35`, JDK 21) · iOS 14+ / Xcode 16+.
8
8
 
9
+ > 🚧 **Work in progress.** This plugin is under active development and **not yet
10
+ > validated on real hardware** (see [Tested on real hardware](#tested-on-real-hardware)).
11
+ > APIs may still change. **Contributions are very welcome** — bug reports, hardware
12
+ > test feedback, and PRs. See [`CONTRIBUTING.md`](CONTRIBUTING.md).
13
+
9
14
  ---
10
15
 
11
16
  ## Contents
12
17
 
13
18
  1. [Philosophy](#philosophy)
14
- 2. [Architecture](#architecture)
15
- 3. [Installation](#installation)
19
+ 2. [Installation](#installation)
20
+ 3. [Usage patterns](#usage-patterns)
16
21
  4. [Manufacturer SDKs](#manufacturer-sdks)
17
22
  5. [Permissions](#permissions)
18
23
  6. [Public API](#public-api)
@@ -35,45 +40,135 @@ For **any Capacitor app that needs to print** — point of sale, receipts, order
35
40
  - **One JS API.** Internally, an **adapter-based architecture** routes to the right implementation.
36
41
  - **There is no universal protocol**: each family has its adapter. Adapter priority guarantees the best choice.
37
42
 
38
- ## Architecture
39
-
40
- ```
41
- ┌─────────────────────────────────────────────────────────────┐
42
- │ App (Ionic/JS/TS) │
43
- │ discoverPrinters / connect / setDefault / printImage ... │
44
- └───────────────────────────────┬───────────────────────────────┘
45
- │ Single API (definitions.ts)
46
- ┌───────────────┴───────────────┐
47
- │ Capacitor Bridge │
48
- ┌────────┴─────────┐ ┌──────────┴─────────┐
49
- │ Android (Kotlin) │ │ iOS (Swift) │
50
- │ ThermalPrinter… │ │ ThermalPrinter… │
51
- └────────┬─────────┘ └──────────┬─────────┘
52
- │ ThermalPrinterEngine │ ThermalPrinterEngine
53
- ┌─────────────┼──────────────┐ ┌───────────┼──────────────┐
54
- │ Discovery │ Adapters │ │ Discovery │ Adapters │
55
- │ Manager │ (registry) │ │ Manager │ (registry) │
56
- └─────────────┴──────────────┘ └───────────┴──────────────┘
57
- │ │
58
- ┌───────┴────────────────────────────────────┴─────────┐
59
- │ EscPos · Epson · Star · Brother · Zebra · RawTcp · BLE │
60
- │ Transport: TCP9100 / SPP(Android) / NWConnection(iOS) │
61
- │ Image: decode → resize → grayscale → dither → raster │
62
- │ Store: profiles + default printer (persisted) │
63
- └────────────────────────────────────────────────────────┘
64
- ```
65
-
66
- > 📁 Repo layout, internal architecture, tests and the contribution guide live in
43
+ > 📁 Internal architecture, repo layout, tests and the contribution guide live in
67
44
  > [`CONTRIBUTING.md`](CONTRIBUTING.md).
68
45
 
69
46
  ## Installation
70
47
 
48
+ > Package: **`@delicity/capacitor-thermal-printer`** · Capacitor 7 · Android (`compileSdk 35`, JDK 21) · iOS 14+ / Xcode 16+.
49
+
50
+ ### Step by step
51
+
52
+ **1. Install the package**
53
+
71
54
  ```bash
72
55
  npm install @delicity/capacitor-thermal-printer
56
+ ```
57
+
58
+ **2. Sync the native projects**
59
+
60
+ ```bash
73
61
  npx cap sync
74
62
  ```
75
63
 
76
- **Capacitor 7 requirements**: Android `compileSdk 35` / JDK 21 ; iOS 14+ / Xcode 16+.
64
+ This adds the Android library to your Gradle project and runs `pod install` for iOS.
65
+
66
+ **3. iOS — add the required keys to your app's `Info.plist`**
67
+
68
+ At minimum, for Wi-Fi/network printers (see [Permissions](#permissions) for the full list):
69
+
70
+ ```xml
71
+ <key>NSLocalNetworkUsageDescription</key>
72
+ <string>Discover and print to printers on the local network.</string>
73
+ <key>NSBonjourServices</key>
74
+ <array>
75
+ <string>_pdl-datastream._tcp</string>
76
+ <string>_printer._tcp</string>
77
+ </array>
78
+ ```
79
+
80
+ Then re-sync: `npx cap sync ios`.
81
+
82
+ **4. Android — nothing to configure** for the default path. The plugin ships its own
83
+ manifest permissions (Bluetooth, network, USB feature). Just call
84
+ `requestPermissions()` before scanning (needed for Bluetooth on Android 12+).
85
+
86
+ **5. (Optional) Add a manufacturer SDK** — only if you use **Epson / Star / Brother /
87
+ Zebra** via their native SDK. Generic ESC/POS (Wi-Fi/Bluetooth/USB) and Star work
88
+ without extra setup; the others need a one-time binary drop. See
89
+ [Manufacturer SDKs](#manufacturer-sdks) and [`docs/SDK_INTEGRATION.md`](docs/SDK_INTEGRATION.md).
90
+
91
+ **6. Use it**
92
+
93
+ ```ts
94
+ import { ThermalPrinter } from '@delicity/capacitor-thermal-printer';
95
+
96
+ await ThermalPrinter.requestPermissions();
97
+ const { printers } = await ThermalPrinter.discoverPrinters({ timeoutMs: 8000 });
98
+ // printImage auto-connects on demand (autoReconnect defaults to true) — no connectPrinter needed.
99
+ await ThermalPrinter.printImage({
100
+ printerId: printers[0].id,
101
+ image: { filePath: '/data/.../receipt.png' },
102
+ });
103
+ ```
104
+
105
+ ✅ **Works out of the box** for **Wi-Fi/Ethernet ESC/POS** printers — no SDK required.
106
+ For Bluetooth/USB/BLE and brand SDKs, see the sections below.
107
+
108
+ ## Usage patterns
109
+
110
+ Pick the pattern that fits your UX. **You don't have to call `connectPrinter` to print** —
111
+ `printImage` / `printText` connect on demand (`autoReconnect: true` by default).
112
+
113
+ ### A. One-shot — simplest
114
+
115
+ Discover, then print by `printerId`. The print call connects automatically.
116
+
117
+ ```ts
118
+ const { printers } = await ThermalPrinter.discoverPrinters({ timeoutMs: 8000 });
119
+ await ThermalPrinter.printImage({ printerId: printers[0].id, image: { filePath } });
120
+ // → resolves the printer (from the latest discovery) + connects + prints
121
+ ```
122
+
123
+ ### B. Default printer — recommended for repeated use
124
+
125
+ **Once** (setup): let the user pick a printer, then connect & persist it as default
126
+ **only if the connection succeeds**. **Afterwards** (even after an app restart): print
127
+ without a `printerId` — the default profile is used and reconnected automatically.
128
+
129
+ ```ts
130
+ // Setup (once), e.g. after a successful test print:
131
+ const { connected } = await ThermalPrinter.connectPrinter({ printerId, setAsDefault: true });
132
+
133
+ // Daily use — no printerId, no connect:
134
+ await ThermalPrinter.printImage({ image: { filePath } }); // uses default + auto-reconnect
135
+ await ThermalPrinter.printText({ items }); // same
136
+ ```
137
+
138
+ ### C. Explicit connect — to test, read paper size, or show status
139
+
140
+ Use `connectPrinter` when you need a result **before** printing: a connection test,
141
+ the **paper size**, or a status badge.
142
+
143
+ ```ts
144
+ const { connected, paper } = await ThermalPrinter.connectPrinter({ printerId });
145
+ if (!connected) return showError('Unreachable');
146
+ showLabel(paper?.widthMm ? `${paper.widthMm} mm` : 'Unknown width');
147
+ const status = await ThermalPrinter.getPrinterStatus({ printerId }); // paper/cover/online
148
+ await ThermalPrinter.printImage({ printerId, image: { filePath } });
149
+ ```
150
+
151
+ ### D. Manual connection management — `autoReconnect: false`
152
+
153
+ Opt out of on-demand connection (you manage `connectPrinter` / `disconnectPrinter`
154
+ yourself). Printing while disconnected then rejects with `CONNECTION_FAILED`.
155
+
156
+ ```ts
157
+ await ThermalPrinter.connectPrinter({ printerId });
158
+ await ThermalPrinter.printImage({ printerId, image: { filePath }, autoReconnect: false });
159
+ await ThermalPrinter.disconnectPrinter({ printerId });
160
+ ```
161
+
162
+ ### Good to know
163
+
164
+ - **Resolution**: a `printerId` must be resolvable — either freshly discovered (this
165
+ session) or a saved profile. Without `printerId`, the **default printer** is used.
166
+ - **Connection lifecycle**: connections are opened **just-in-time** before printing,
167
+ not held open permanently. Reconnection uses exponential backoff (3 attempts).
168
+ - **`connectPrinter` is optional** — needed only to test, set the default, or read the
169
+ paper size. See [Default printer & reconnection](#default-printer--reconnection).
170
+ - **Profiles**: `getSavedPrinters` / `getDefaultPrinter` / `setDefaultPrinter` /
171
+ `removePrinter` manage persisted printers.
77
172
 
78
173
  ## Manufacturer SDKs
79
174
 
@@ -106,6 +201,20 @@ and each brand **activates automatically** as soon as its binary is present.
106
201
  Step-by-step setup (where to drop each binary, Zebra private Maven repo, iOS module
107
202
  names, git-ignored test folder): **[`docs/SDK_INTEGRATION.md`](docs/SDK_INTEGRATION.md)**.
108
203
 
204
+ ### Tested on real hardware
205
+
206
+ > ⚠️ **No brand has been validated on physical hardware yet.** The native SDK code is
207
+ > implemented but **not yet verified on-device** (see [`CONTRIBUTING.md`](CONTRIBUTING.md)).
208
+ > **Epson** and **Star** are the first brands planned for on-device testing.
209
+
210
+ | Brand | On-device tested |
211
+ |---|---|
212
+ | **Star** | ⏳ planned |
213
+ | **Epson** | ⏳ planned |
214
+ | **Brother** | ❌ not yet |
215
+ | **Zebra** | ❌ not yet |
216
+ | Generic ESC/POS (Wi-Fi / Bluetooth / USB) | ❌ not yet |
217
+
109
218
  ### Know which SDKs are active (runtime)
110
219
 
111
220
  `getActiveSdks()` reports, at the current moment, which adapters/SDKs are available:
@@ -170,7 +279,7 @@ Call `requestPermissions()` before the first scan.
170
279
  import { ThermalPrinter } from '@delicity/capacitor-thermal-printer';
171
280
 
172
281
  ThermalPrinter.discoverPrinters(options?) // → { printers: DiscoveredPrinter[] }
173
- ThermalPrinter.connectPrinter({ printerId, timeoutMs?, forceAdapter?, setAsDefault? }) // → { connected }
282
+ ThermalPrinter.connectPrinter({ printerId, timeoutMs?, forceAdapter?, setAsDefault? }) // → { connected, paper: PaperInfo | null }
174
283
  ThermalPrinter.disconnectPrinter({ printerId }) // → void
175
284
  ThermalPrinter.setDefaultPrinter({ printerId }) // → { profile }
176
285
  ThermalPrinter.getDefaultPrinter() // → { profile | null }
@@ -196,6 +305,16 @@ ThermalPrinter.addListener('printJobStatus', e => ...) // JobState: pending
196
305
  > the connection succeeds** (`connect` + `setDefaultPrinter` in one step, without
197
306
  > persisting an unreachable printer).
198
307
 
308
+ > **Paper size on connect.** `connectPrinter` also returns `paper` — the paper size
309
+ > deduced from the printer's model (**best-effort**), or **`null`** when it can't be
310
+ > determined (typical for generic ESC/POS). The printer hardware does not report
311
+ > remaining/printed length; only the width is derivable. Example:
312
+ > ```ts
313
+ > const { connected, paper } = await ThermalPrinter.connectPrinter({ printerId });
314
+ > // paper?.widthMm → 80 | 58 | … | null
315
+ > if (paper?.widthMm) showLabel(`${paper.widthMm} mm`); else showLabel('Unknown width');
316
+ > ```
317
+
199
318
  ### Print completion / `await`
200
319
 
201
320
  `printImage` and `printText` are **async and resolve when physical printing is done**
@@ -329,6 +448,14 @@ interface SdkStatus {
329
448
  transports: PrinterTransport[];
330
449
  }
331
450
 
451
+ // ---- Paper size (returned by connectPrinter, best-effort) ----
452
+ interface PaperInfo {
453
+ widthMm: number | null; // 58 | 80 | 112 … (null if unknown)
454
+ printableDots: number | null; // 384 | 576 | 832 … @203 dpi (null if unknown)
455
+ dpi: number | null; // 203 when width is known
456
+ source: 'model' | 'sdk' | 'profile';
457
+ }
458
+
332
459
  // ---- Events ----
333
460
  interface PrinterFoundEvent { printer: DiscoveredPrinter; }
334
461
  interface DiscoveryCompleteEvent { printers: DiscoveredPrinter[]; failedSources?: string[]; }
@@ -137,7 +137,10 @@ class ThermalPrinterEngine(private val context: Context) {
137
137
  // Connexion / reconnexion
138
138
  // -------------------------------------------------------------------------
139
139
 
140
- suspend fun connect(printerId: String, timeoutMs: Long, forceAdapter: AdapterId?, setAsDefault: Boolean = false): Boolean {
140
+ /** Résultat de connexion : état + taille papier déduite (best-effort, null si inconnue). */
141
+ data class ConnectResult(val connected: Boolean, val paper: com.delicity.thermalprinter.model.PaperInfo?)
142
+
143
+ suspend fun connect(printerId: String, timeoutMs: Long, forceAdapter: AdapterId?, setAsDefault: Boolean = false): ConnectResult {
141
144
  val profile = resolveProfile(printerId, forceAdapter)
142
145
  val adapter = adapterFor(profile)
143
146
  ?: throw PrinterException(ErrorCode.UNSUPPORTED_PRINTER, "Aucun adapter pour ${profile.adapter.value}")
@@ -154,7 +157,13 @@ class ThermalPrinterEngine(private val context: Context) {
154
157
  store.setDefault(printerId)
155
158
  Logger.log("connect", "set-default-after-connect", mapOf("id" to printerId))
156
159
  }
157
- return connected
160
+ // Taille papier best-effort (déduite du modèle remonté), null si inconnue.
161
+ val paper = if (connected) {
162
+ com.delicity.thermalprinter.model.PaperSizeGuess.fromBrandModel(profile.brand, profile.model)
163
+ } else {
164
+ null
165
+ }
166
+ return ConnectResult(connected, paper)
158
167
  }
159
168
 
160
169
  suspend fun disconnect(printerId: String) {
@@ -147,8 +147,10 @@ class ThermalPrinterPlugin : Plugin() {
147
147
  val timeout = (call.getInt("timeoutMs")?.toLong()) ?: 10000L
148
148
  val force = call.getString("forceAdapter")?.let { com.delicity.thermalprinter.model.AdapterId.from(it) }
149
149
  val setAsDefault = call.getBoolean("setAsDefault", false) ?: false
150
- val connected = engine.connect(printerId, timeout, force, setAsDefault)
151
- JSObject().put("connected", connected)
150
+ val result = engine.connect(printerId, timeout, force, setAsDefault)
151
+ JSObject()
152
+ .put("connected", result.connected)
153
+ .put("paper", result.paper?.toJson() ?: JSObject.NULL)
152
154
  }
153
155
 
154
156
  @PluginMethod
@@ -0,0 +1,46 @@
1
+ package com.delicity.thermalprinter.model
2
+
3
+ import org.json.JSONObject
4
+
5
+ /**
6
+ * Taille de papier déduite à la connexion (best-effort). Miroir Kotlin de
7
+ * `src/core/paper.ts`. Tous les champs sont nullables : `null` = inconnu.
8
+ */
9
+ data class PaperInfo(
10
+ val widthMm: Int?,
11
+ val printableDots: Int?,
12
+ val dpi: Int?,
13
+ val source: String, // 'model' | 'sdk' | 'profile'
14
+ ) {
15
+ fun toJson(): JSONObject = JSONObject().apply {
16
+ put("widthMm", widthMm ?: JSONObject.NULL)
17
+ put("printableDots", printableDots ?: JSONObject.NULL)
18
+ put("dpi", dpi ?: JSONObject.NULL)
19
+ put("source", source)
20
+ }
21
+ }
22
+
23
+ /** Déduction de la taille papier depuis la marque/modèle (best-effort). */
24
+ object PaperSizeGuess {
25
+
26
+ fun dotsForWidth(widthMm: Int): Int? = when (widthMm) {
27
+ 58 -> 384
28
+ 80 -> 576
29
+ 112 -> 832
30
+ else -> null
31
+ }
32
+
33
+ /** Renvoie la taille papier déduite, ou null si le modèle est inconnu. */
34
+ fun fromBrandModel(brand: String?, model: String?): PaperInfo? {
35
+ if (model.isNullOrBlank()) return null
36
+ val m = "${brand ?: ""}$model".uppercase().replace(Regex("[^A-Z0-9]"), "")
37
+ if (m.isEmpty()) return null
38
+ val widthMm = when {
39
+ Regex("TMM10|TMP20|TMP60|MCPRINT2|MCP2|SML200|SMS2").containsMatchIn(m) -> 58
40
+ Regex("SMT400|TUP5").containsMatchIn(m) -> 112
41
+ Regex("TMM30|TMM50|TMT20|TMT70|TMT8|TMT100|TMP80|TML90|MCPRINT3|MCP3|TSP1|TSP6|TSP7|TSP8|SMT300").containsMatchIn(m) -> 80
42
+ else -> return null
43
+ }
44
+ return PaperInfo(widthMm, dotsForWidth(widthMm), 203, "model")
45
+ }
46
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Déduction best-effort de la taille de papier d'une imprimante à partir de sa
3
+ * marque/modèle (remontés par l'imprimante ou son SDK à la connexion).
4
+ *
5
+ * L'imprimante NE renvoie PAS sa largeur de papier de façon standard : on la déduit
6
+ * du modèle via une table de correspondance (extensible). Renvoie `null` si le modèle
7
+ * est inconnu (cas fréquent des ESC/POS génériques) — à afficher tel quel à l'utilisateur.
8
+ *
9
+ * Implémentation de référence (testée), mirrorée en Kotlin (`PaperSize.kt`) et
10
+ * Swift (`PaperSize.swift`) pour le calcul natif au moment du `connectPrinter`.
11
+ */
12
+ export interface PaperInfo {
13
+ /** Largeur papier en mm (58 / 80 / 112…), ou null si inconnue. */
14
+ widthMm: number | null;
15
+ /** Largeur imprimable en points @203 dpi (384 / 576 / 832…), ou null. */
16
+ printableDots: number | null;
17
+ /** Résolution en dpi (203 par défaut quand la largeur est connue), ou null. */
18
+ dpi: number | null;
19
+ /** Origine de l'info : 'model' (déduit du modèle), 'sdk', 'profile'. */
20
+ source: 'model' | 'sdk' | 'profile';
21
+ }
22
+ /** Largeur imprimable standard @203 dpi pour une largeur papier donnée. */
23
+ export declare function paperDotsForWidth(widthMm: number): number | null;
24
+ /**
25
+ * Devine la taille de papier depuis la marque/modèle. Best-effort, `null` si inconnu.
26
+ * La table couvre les modèles courants Epson/Star ; à enrichir au besoin.
27
+ */
28
+ export declare function guessPaperInfo(brand?: string | null, model?: string | null): PaperInfo | null;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Déduction best-effort de la taille de papier d'une imprimante à partir de sa
3
+ * marque/modèle (remontés par l'imprimante ou son SDK à la connexion).
4
+ *
5
+ * L'imprimante NE renvoie PAS sa largeur de papier de façon standard : on la déduit
6
+ * du modèle via une table de correspondance (extensible). Renvoie `null` si le modèle
7
+ * est inconnu (cas fréquent des ESC/POS génériques) — à afficher tel quel à l'utilisateur.
8
+ *
9
+ * Implémentation de référence (testée), mirrorée en Kotlin (`PaperSize.kt`) et
10
+ * Swift (`PaperSize.swift`) pour le calcul natif au moment du `connectPrinter`.
11
+ */
12
+ /** Largeur imprimable standard @203 dpi pour une largeur papier donnée. */
13
+ export function paperDotsForWidth(widthMm) {
14
+ switch (widthMm) {
15
+ case 58:
16
+ return 384;
17
+ case 80:
18
+ return 576;
19
+ case 112:
20
+ return 832;
21
+ default:
22
+ return null;
23
+ }
24
+ }
25
+ /**
26
+ * Devine la taille de papier depuis la marque/modèle. Best-effort, `null` si inconnu.
27
+ * La table couvre les modèles courants Epson/Star ; à enrichir au besoin.
28
+ */
29
+ export function guessPaperInfo(brand, model) {
30
+ if (!model)
31
+ return null;
32
+ // On combine marque + modèle : selon la source, le nom du modèle se retrouve
33
+ // parfois dans l'un ou l'autre champ.
34
+ const m = `${brand !== null && brand !== void 0 ? brand : ''}${model}`.toUpperCase().replace(/[^A-Z0-9]/g, '');
35
+ if (!m)
36
+ return null;
37
+ let widthMm = null;
38
+ if (/TMM10|TMP20|TMP60|MCPRINT2|MCP2|SML200|SMS2/.test(m)) {
39
+ widthMm = 58; // Epson TM-m10/P20/P60, Star mC-Print2/SM-L200/SM-S2x
40
+ }
41
+ else if (/SMT400|TUP5/.test(m)) {
42
+ widthMm = 112; // Star SM-T400 / TUP500
43
+ }
44
+ else if (/TMM30|TMM50|TMT20|TMT70|TMT8|TMT100|TMP80|TML90|MCPRINT3|MCP3|TSP1|TSP6|TSP7|TSP8|SMT300/.test(m)) {
45
+ widthMm = 80; // Epson TM-m30/T20/T88/…, Star mC-Print3/TSP1xx-8xx/SM-T300
46
+ }
47
+ if (widthMm == null)
48
+ return null;
49
+ return { widthMm, printableDots: paperDotsForWidth(widthMm), dpi: 203, source: 'model' };
50
+ }
51
+ //# sourceMappingURL=paper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paper.js","sourceRoot":"","sources":["../../../src/core/paper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,2EAA2E;AAC3E,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,EAAE;YACL,OAAO,GAAG,CAAC;QACb,KAAK,EAAE;YACL,OAAO,GAAG,CAAC;QACb,KAAK,GAAG;YACN,OAAO,GAAG,CAAC;QACb;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAqB,EAAE,KAAqB;IACzE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,6EAA6E;IAC7E,sCAAsC;IACtC,MAAM,CAAC,GAAG,GAAG,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,GAAG,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpB,IAAI,OAAO,GAAkB,IAAI,CAAC;IAClC,IAAI,6CAA6C,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,OAAO,GAAG,EAAE,CAAC,CAAC,sDAAsD;IACtE,CAAC;SAAM,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACjC,OAAO,GAAG,GAAG,CAAC,CAAC,wBAAwB;IACzC,CAAC;SAAM,IAAI,0FAA0F,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9G,OAAO,GAAG,EAAE,CAAC,CAAC,4DAA4D;IAC5E,CAAC;IAED,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC3F,CAAC","sourcesContent":["/**\n * Déduction best-effort de la taille de papier d'une imprimante à partir de sa\n * marque/modèle (remontés par l'imprimante ou son SDK à la connexion).\n *\n * L'imprimante NE renvoie PAS sa largeur de papier de façon standard : on la déduit\n * du modèle via une table de correspondance (extensible). Renvoie `null` si le modèle\n * est inconnu (cas fréquent des ESC/POS génériques) — à afficher tel quel à l'utilisateur.\n *\n * Implémentation de référence (testée), mirrorée en Kotlin (`PaperSize.kt`) et\n * Swift (`PaperSize.swift`) pour le calcul natif au moment du `connectPrinter`.\n */\n\nexport interface PaperInfo {\n /** Largeur papier en mm (58 / 80 / 112…), ou null si inconnue. */\n widthMm: number | null;\n /** Largeur imprimable en points @203 dpi (384 / 576 / 832…), ou null. */\n printableDots: number | null;\n /** Résolution en dpi (203 par défaut quand la largeur est connue), ou null. */\n dpi: number | null;\n /** Origine de l'info : 'model' (déduit du modèle), 'sdk', 'profile'. */\n source: 'model' | 'sdk' | 'profile';\n}\n\n/** Largeur imprimable standard @203 dpi pour une largeur papier donnée. */\nexport function paperDotsForWidth(widthMm: number): number | null {\n switch (widthMm) {\n case 58:\n return 384;\n case 80:\n return 576;\n case 112:\n return 832;\n default:\n return null;\n }\n}\n\n/**\n * Devine la taille de papier depuis la marque/modèle. Best-effort, `null` si inconnu.\n * La table couvre les modèles courants Epson/Star ; à enrichir au besoin.\n */\nexport function guessPaperInfo(brand?: string | null, model?: string | null): PaperInfo | null {\n if (!model) return null;\n // On combine marque + modèle : selon la source, le nom du modèle se retrouve\n // parfois dans l'un ou l'autre champ.\n const m = `${brand ?? ''}${model}`.toUpperCase().replace(/[^A-Z0-9]/g, '');\n if (!m) return null;\n\n let widthMm: number | null = null;\n if (/TMM10|TMP20|TMP60|MCPRINT2|MCP2|SML200|SMS2/.test(m)) {\n widthMm = 58; // Epson TM-m10/P20/P60, Star mC-Print2/SM-L200/SM-S2x\n } else if (/SMT400|TUP5/.test(m)) {\n widthMm = 112; // Star SM-T400 / TUP500\n } else if (/TMM30|TMM50|TMT20|TMT70|TMT8|TMT100|TMP80|TML90|MCPRINT3|MCP3|TSP1|TSP6|TSP7|TSP8|SMT300/.test(m)) {\n widthMm = 80; // Epson TM-m30/T20/T88/…, Star mC-Print3/TSP1xx-8xx/SM-T300\n }\n\n if (widthMm == null) return null;\n return { widthMm, printableDots: paperDotsForWidth(widthMm), dpi: 203, source: 'model' };\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import type { PluginListenerHandle } from '@capacitor/core';
2
2
  import type { ConnectOptions, DiscoverOptions, PrintImageOptions, PrintTextOptions } from './core/options';
3
3
  import type { PrinterAdapterId, PrinterTransport } from './core/enums';
4
+ import type { PaperInfo } from './core/paper';
4
5
  import type { DiscoveredPrinter, PrinterProfile, PrinterStatus, PrintJobStatus, PrintResult } from './core/models';
5
6
  /**
6
7
  * État d'un adapter/SDK à l'instant présent (résultat de `getActiveSdks`).
@@ -67,9 +68,14 @@ export interface ThermalPrinterPlugin {
67
68
  discoverPrinters(options?: DiscoverOptions): Promise<{
68
69
  printers: DiscoveredPrinter[];
69
70
  }>;
70
- /** Ouvre explicitement une connexion vers une imprimante connue/découverte. */
71
+ /**
72
+ * Ouvre explicitement une connexion vers une imprimante connue/découverte.
73
+ * Renvoie aussi la **taille de papier** déduite du modèle (best-effort), ou
74
+ * `paper: null` si elle n'a pas pu être déterminée (à afficher à l'utilisateur).
75
+ */
71
76
  connectPrinter(options: ConnectOptions): Promise<{
72
77
  connected: boolean;
78
+ paper: PaperInfo | null;
73
79
  }>;
74
80
  /** Ferme la connexion active (sans supprimer le profil). */
75
81
  disconnectPrinter(options: {
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\nimport type {\n ConnectOptions,\n DiscoverOptions,\n PrintImageOptions,\n PrintTextOptions,\n} from './core/options';\nimport type { PrinterAdapterId, PrinterTransport } from './core/enums';\nimport type {\n DiscoveredPrinter,\n PrinterProfile,\n PrinterStatus,\n PrintJobStatus,\n PrintResult,\n} from './core/models';\n\n/**\n * État d'un adapter/SDK à l'instant présent (résultat de `getActiveSdks`).\n */\nexport interface SdkStatus {\n /** Identifiant d'adapter (marque ou intégré). */\n adapter: PrinterAdapterId;\n /** Libellé lisible (ex. \"Star StarXpand\"). */\n label: string;\n /**\n * `true` si le SDK/binaire est détecté et utilisable MAINTENANT.\n * Pour les adapters intégrés (escpos, rawTcp) : toujours `true`.\n * Pour les marques (star, epson, brother, zebra) : `true` si le SDK est lié.\n */\n available: boolean;\n /**\n * `true` si l'adapter dépend d'un SDK fabricant (à fournir), `false` s'il est\n * intégré au plugin (ESC/POS générique, TCP brut, BLE, USB).\n */\n requiresSdk: boolean;\n /** Transports gérés par cet adapter quand il est disponible. */\n transports: PrinterTransport[];\n}\n\n/** Payload de l'event émis pendant un scan quand une imprimante est trouvée. */\nexport interface PrinterFoundEvent {\n printer: DiscoveredPrinter;\n}\n\n/** Payload de l'event de fin de découverte. */\nexport interface DiscoveryCompleteEvent {\n printers: DiscoveredPrinter[];\n /** Sources ayant échoué (ex: SDK manquant), pour diagnostic non bloquant. */\n failedSources?: string[];\n}\n\n/** Payload de changement de statut imprimante (connexion, papier, capot). */\nexport interface StatusChangeEvent {\n status: PrinterStatus;\n}\n\n/** Payload de changement d'état d'un job d'impression. */\nexport interface PrintJobStatusEvent {\n job: PrintJobStatus;\n}\n\nexport type ThermalPrinterEvent =\n | 'printerFound'\n | 'discoveryComplete'\n | 'statusChange'\n | 'printJobStatus';\n\n/** Entrée du journal de diagnostic (ring-buffer natif). */\nexport interface DebugLogEntry {\n ts: number;\n category: string;\n message: string;\n [key: string]: unknown;\n}\n\n/**\n * API native exposée par le plugin. C'est le contrat strict implémenté\n * par Android (Kotlin), iOS (Swift) et le fallback Web.\n *\n * NB: l'objet exporté par `index.ts` enrichit ce contrat avec des helpers\n * ergonomiques (overloads, conversions d'erreur), mais la surface native\n * reste celle-ci.\n */\nexport interface ThermalPrinterPlugin {\n /**\n * Lance une découverte agrégée multi-sources et renvoie la liste\n * dédoublonnée et normalisée à la fin du scan.\n * Émet aussi `printerFound` au fil de l'eau si `emitPartialResults`.\n */\n discoverPrinters(options?: DiscoverOptions): Promise<{ printers: DiscoveredPrinter[] }>;\n\n /** Ouvre explicitement une connexion vers une imprimante connue/découverte. */\n connectPrinter(options: ConnectOptions): Promise<{ connected: boolean }>;\n\n /** Ferme la connexion active (sans supprimer le profil). */\n disconnectPrinter(options: { printerId: string }): Promise<void>;\n\n /**\n * Enregistre une imprimante comme imprimante par défaut et persiste son profil.\n * À appeler après un test d'impression réussi.\n */\n setDefaultPrinter(options: { printerId: string }): Promise<{ profile: PrinterProfile }>;\n\n /** Retourne le profil par défaut, ou null si aucun. */\n getDefaultPrinter(): Promise<{ profile: PrinterProfile | null }>;\n\n /** Liste tous les profils enregistrés (persistés). */\n getSavedPrinters(): Promise<{ profiles: PrinterProfile[] }>;\n\n /** Supprime un profil enregistré (oubli total). */\n removePrinter(options: { printerId: string }): Promise<void>;\n\n /**\n * Imprime une image. Gère reconnexion auto, redimensionnement, binarisation,\n * dithering, conversion adapter et envoi. Voir flux détaillé dans le README.\n *\n * La promesse se résout quand l'impression physique est terminée (best-effort\n * selon transport/SDK — voir README \"Fin d'impression / await\").\n */\n printImage(options: PrintImageOptions): Promise<PrintResult>;\n\n /**\n * Imprime un tableau d'items texte stylés (+ QR/code-barres/feed/cut/image).\n * Voir les types `PrintItem` / `TextStyle` et le tableau de styles dans le README.\n *\n * La promesse se résout quand l'impression physique est terminée (best-effort).\n */\n printText(options: PrintTextOptions): Promise<PrintResult>;\n\n /** Lit le statut temps réel (si supporté par l'adapter/transport). */\n getPrinterStatus(options: { printerId?: string }): Promise<PrinterStatus>;\n\n /** Demande/vérifie les permissions natives nécessaires (Bluetooth, etc.). */\n requestPermissions(): Promise<PermissionStatus>;\n checkPermissions(): Promise<PermissionStatus>;\n\n /** Active/désactive le monitoring de statut en arrière-plan pour une imprimante. */\n startStatusMonitor(options: { printerId: string; intervalMs?: number }): Promise<void>;\n stopStatusMonitor(options: { printerId: string }): Promise<void>;\n\n /**\n * Retourne l'état, à l'instant présent, de chaque adapter/SDK : quels SDK\n * fabricants sont actifs (binaire détecté) et quels adapters intégrés sont\n * disponibles. Utile pour un écran de diagnostic ou pour adapter l'UI.\n */\n getActiveSdks(): Promise<{ sdks: SdkStatus[] }>;\n\n /** Récupère le journal de diagnostic en mémoire (support client). */\n getDebugLog(): Promise<{ log: DebugLogEntry[] }>;\n\n addListener(\n eventName: 'printerFound',\n listener: (event: PrinterFoundEvent) => void,\n ): Promise<PluginListenerHandle>;\n addListener(\n eventName: 'discoveryComplete',\n listener: (event: DiscoveryCompleteEvent) => void,\n ): Promise<PluginListenerHandle>;\n addListener(\n eventName: 'statusChange',\n listener: (event: StatusChangeEvent) => void,\n ): Promise<PluginListenerHandle>;\n addListener(\n eventName: 'printJobStatus',\n listener: (event: PrintJobStatusEvent) => void,\n ): Promise<PluginListenerHandle>;\n\n removeAllListeners(): Promise<void>;\n}\n\n/** État des permissions natives liées au transport. */\nexport interface PermissionStatus {\n bluetooth: PermissionState;\n bluetoothScan: PermissionState;\n bluetoothConnect: PermissionState;\n location: PermissionState; // requis pour le scan BLE sur anciens Android\n localNetwork: PermissionState; // iOS Local Network usage\n}\n\nexport type PermissionState = 'granted' | 'denied' | 'prompt' | 'prompt-with-rationale' | 'unavailable';\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\nimport type {\n ConnectOptions,\n DiscoverOptions,\n PrintImageOptions,\n PrintTextOptions,\n} from './core/options';\nimport type { PrinterAdapterId, PrinterTransport } from './core/enums';\nimport type { PaperInfo } from './core/paper';\nimport type {\n DiscoveredPrinter,\n PrinterProfile,\n PrinterStatus,\n PrintJobStatus,\n PrintResult,\n} from './core/models';\n\n/**\n * État d'un adapter/SDK à l'instant présent (résultat de `getActiveSdks`).\n */\nexport interface SdkStatus {\n /** Identifiant d'adapter (marque ou intégré). */\n adapter: PrinterAdapterId;\n /** Libellé lisible (ex. \"Star StarXpand\"). */\n label: string;\n /**\n * `true` si le SDK/binaire est détecté et utilisable MAINTENANT.\n * Pour les adapters intégrés (escpos, rawTcp) : toujours `true`.\n * Pour les marques (star, epson, brother, zebra) : `true` si le SDK est lié.\n */\n available: boolean;\n /**\n * `true` si l'adapter dépend d'un SDK fabricant (à fournir), `false` s'il est\n * intégré au plugin (ESC/POS générique, TCP brut, BLE, USB).\n */\n requiresSdk: boolean;\n /** Transports gérés par cet adapter quand il est disponible. */\n transports: PrinterTransport[];\n}\n\n/** Payload de l'event émis pendant un scan quand une imprimante est trouvée. */\nexport interface PrinterFoundEvent {\n printer: DiscoveredPrinter;\n}\n\n/** Payload de l'event de fin de découverte. */\nexport interface DiscoveryCompleteEvent {\n printers: DiscoveredPrinter[];\n /** Sources ayant échoué (ex: SDK manquant), pour diagnostic non bloquant. */\n failedSources?: string[];\n}\n\n/** Payload de changement de statut imprimante (connexion, papier, capot). */\nexport interface StatusChangeEvent {\n status: PrinterStatus;\n}\n\n/** Payload de changement d'état d'un job d'impression. */\nexport interface PrintJobStatusEvent {\n job: PrintJobStatus;\n}\n\nexport type ThermalPrinterEvent =\n | 'printerFound'\n | 'discoveryComplete'\n | 'statusChange'\n | 'printJobStatus';\n\n/** Entrée du journal de diagnostic (ring-buffer natif). */\nexport interface DebugLogEntry {\n ts: number;\n category: string;\n message: string;\n [key: string]: unknown;\n}\n\n/**\n * API native exposée par le plugin. C'est le contrat strict implémenté\n * par Android (Kotlin), iOS (Swift) et le fallback Web.\n *\n * NB: l'objet exporté par `index.ts` enrichit ce contrat avec des helpers\n * ergonomiques (overloads, conversions d'erreur), mais la surface native\n * reste celle-ci.\n */\nexport interface ThermalPrinterPlugin {\n /**\n * Lance une découverte agrégée multi-sources et renvoie la liste\n * dédoublonnée et normalisée à la fin du scan.\n * Émet aussi `printerFound` au fil de l'eau si `emitPartialResults`.\n */\n discoverPrinters(options?: DiscoverOptions): Promise<{ printers: DiscoveredPrinter[] }>;\n\n /**\n * Ouvre explicitement une connexion vers une imprimante connue/découverte.\n * Renvoie aussi la **taille de papier** déduite du modèle (best-effort), ou\n * `paper: null` si elle n'a pas pu être déterminée (à afficher à l'utilisateur).\n */\n connectPrinter(options: ConnectOptions): Promise<{ connected: boolean; paper: PaperInfo | null }>;\n\n /** Ferme la connexion active (sans supprimer le profil). */\n disconnectPrinter(options: { printerId: string }): Promise<void>;\n\n /**\n * Enregistre une imprimante comme imprimante par défaut et persiste son profil.\n * À appeler après un test d'impression réussi.\n */\n setDefaultPrinter(options: { printerId: string }): Promise<{ profile: PrinterProfile }>;\n\n /** Retourne le profil par défaut, ou null si aucun. */\n getDefaultPrinter(): Promise<{ profile: PrinterProfile | null }>;\n\n /** Liste tous les profils enregistrés (persistés). */\n getSavedPrinters(): Promise<{ profiles: PrinterProfile[] }>;\n\n /** Supprime un profil enregistré (oubli total). */\n removePrinter(options: { printerId: string }): Promise<void>;\n\n /**\n * Imprime une image. Gère reconnexion auto, redimensionnement, binarisation,\n * dithering, conversion adapter et envoi. Voir flux détaillé dans le README.\n *\n * La promesse se résout quand l'impression physique est terminée (best-effort\n * selon transport/SDK — voir README \"Fin d'impression / await\").\n */\n printImage(options: PrintImageOptions): Promise<PrintResult>;\n\n /**\n * Imprime un tableau d'items texte stylés (+ QR/code-barres/feed/cut/image).\n * Voir les types `PrintItem` / `TextStyle` et le tableau de styles dans le README.\n *\n * La promesse se résout quand l'impression physique est terminée (best-effort).\n */\n printText(options: PrintTextOptions): Promise<PrintResult>;\n\n /** Lit le statut temps réel (si supporté par l'adapter/transport). */\n getPrinterStatus(options: { printerId?: string }): Promise<PrinterStatus>;\n\n /** Demande/vérifie les permissions natives nécessaires (Bluetooth, etc.). */\n requestPermissions(): Promise<PermissionStatus>;\n checkPermissions(): Promise<PermissionStatus>;\n\n /** Active/désactive le monitoring de statut en arrière-plan pour une imprimante. */\n startStatusMonitor(options: { printerId: string; intervalMs?: number }): Promise<void>;\n stopStatusMonitor(options: { printerId: string }): Promise<void>;\n\n /**\n * Retourne l'état, à l'instant présent, de chaque adapter/SDK : quels SDK\n * fabricants sont actifs (binaire détecté) et quels adapters intégrés sont\n * disponibles. Utile pour un écran de diagnostic ou pour adapter l'UI.\n */\n getActiveSdks(): Promise<{ sdks: SdkStatus[] }>;\n\n /** Récupère le journal de diagnostic en mémoire (support client). */\n getDebugLog(): Promise<{ log: DebugLogEntry[] }>;\n\n addListener(\n eventName: 'printerFound',\n listener: (event: PrinterFoundEvent) => void,\n ): Promise<PluginListenerHandle>;\n addListener(\n eventName: 'discoveryComplete',\n listener: (event: DiscoveryCompleteEvent) => void,\n ): Promise<PluginListenerHandle>;\n addListener(\n eventName: 'statusChange',\n listener: (event: StatusChangeEvent) => void,\n ): Promise<PluginListenerHandle>;\n addListener(\n eventName: 'printJobStatus',\n listener: (event: PrintJobStatusEvent) => void,\n ): Promise<PluginListenerHandle>;\n\n removeAllListeners(): Promise<void>;\n}\n\n/** État des permissions natives liées au transport. */\nexport interface PermissionStatus {\n bluetooth: PermissionState;\n bluetoothScan: PermissionState;\n bluetoothConnect: PermissionState;\n location: PermissionState; // requis pour le scan BLE sur anciens Android\n localNetwork: PermissionState; // iOS Local Network usage\n}\n\nexport type PermissionState = 'granted' | 'denied' | 'prompt' | 'prompt-with-rationale' | 'unavailable';\n"]}
@@ -10,6 +10,7 @@ export * from './definitions';
10
10
  export * from './core/enums';
11
11
  export * from './core/models';
12
12
  export * from './core/options';
13
+ export * from './core/paper';
13
14
  export * from './core/text';
14
15
  export * from './core/errors';
15
16
  export { ThermalPrinter };
package/dist/esm/index.js CHANGED
@@ -12,6 +12,7 @@ export * from './definitions';
12
12
  export * from './core/enums';
13
13
  export * from './core/models';
14
14
  export * from './core/options';
15
+ export * from './core/paper';
15
16
  export * from './core/text';
16
17
  export * from './core/errors';
17
18
  export { ThermalPrinter };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD;;;;;GAKG;AACH,MAAM,cAAc,GAAG,cAAc,CAAuB,gBAAgB,EAAE;IAC5E,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,iBAAiB,EAAE,CAAC;CAChE,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { ThermalPrinterPlugin } from './definitions';\n\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<ThermalPrinterPlugin>('ThermalPrinter', {\n web: () => import('./web').then(m => new m.ThermalPrinterWeb()),\n});\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"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD;;;;;GAKG;AACH,MAAM,cAAc,GAAG,cAAc,CAAuB,gBAAgB,EAAE;IAC5E,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,iBAAiB,EAAE,CAAC;CAChE,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { ThermalPrinterPlugin } from './definitions';\n\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<ThermalPrinterPlugin>('ThermalPrinter', {\n web: () => import('./web').then(m => new m.ThermalPrinterWeb()),\n});\n\nexport * from './definitions';\nexport * from './core/enums';\nexport * from './core/models';\nexport * from './core/options';\nexport * from './core/paper';\nexport * from './core/text';\nexport * from './core/errors';\nexport { ThermalPrinter };\n"]}
package/dist/esm/web.d.ts CHANGED
@@ -19,6 +19,7 @@ export declare class ThermalPrinterWeb extends WebPlugin implements ThermalPrint
19
19
  }>;
20
20
  connectPrinter(_options: ConnectOptions): Promise<{
21
21
  connected: boolean;
22
+ paper: import('./core/paper').PaperInfo | null;
22
23
  }>;
23
24
  disconnectPrinter(_options: {
24
25
  printerId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAM5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAc7C;;;;;;;;;GASG;AACH,MAAM,OAAO,iBAAkB,SAAQ,SAAS;IAAhD;;QACmB,eAAU,GAAG,kCAAkC,CAAC;IA4GnE,CAAC;IA1GC,KAAK,CAAC,gBAAgB,CAAC,QAA0B;QAC/C,oDAAoD;QACpD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,QAAwB;QAC3C,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAA+B;QACrD,OAAO;IACT,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,OAA8B;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,YAAY,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,iBAAiB,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC;QAC/G,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QAClE,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,iBAAiB;;QACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACrC,OAAO,EAAE,OAAO,EAAE,MAAA,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,mCAAI,IAAI,EAAE,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAA8B;QAChD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAA2B;QAC1C,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,QAA0B;QACxC,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAgC;QACrD,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,OAAO;YACL,SAAS,EAAE,aAAa;YACxB,aAAa,EAAE,aAAa;YAC5B,gBAAgB,EAAE,aAAa;YAC/B,QAAQ,EAAE,aAAa;YACvB,YAAY,EAAE,aAAa;SAC5B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,QAAoD;QAC3E,OAAO;IACT,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAA+B;QACrD,OAAO;IACT,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,8CAA8C;QAC9C,OAAO;YACL,IAAI,EAAE;gBACJ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE;gBACpJ,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE;gBAClI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE;gBACzH,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE;gBACvH,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE;gBACpH,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE;aACjH;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;IACrB,CAAC;IAEO,WAAW,CAAC,MAAc;QAChC,OAAO,IAAI,YAAY,CAAC;YACtB,IAAI,EAAE,cAAc,CAAC,iBAAiB;YACtC,OAAO,EAAE,GAAG,MAAM,mEAAmE;SACtF,CAAC,CAAC;IACL,CAAC;IAEO,YAAY;;QAClB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAA,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,mCAAI,IAAI,CAAC,CAAC;QACnE,CAAC;QAAC,WAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,QAA0B;QAC9C,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClE,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n PermissionStatus,\n ThermalPrinterPlugin,\n} from './definitions';\nimport { PrintErrorCode } from './core/enums';\nimport { PrinterError } from './core/errors';\nimport type {\n ConnectOptions,\n DiscoverOptions,\n PrintImageOptions,\n PrintTextOptions,\n} from './core/options';\nimport type {\n DiscoveredPrinter,\n PrinterProfile,\n PrinterStatus,\n PrintResult,\n} from './core/models';\n\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 implements ThermalPrinterPlugin {\n private readonly storageKey = 'delicity.thermalprinter.profiles';\n\n async discoverPrinters(_options?: DiscoverOptions): Promise<{ printers: DiscoveredPrinter[] }> {\n // Aucune découverte matérielle possible sur le web.\n return { printers: [] };\n }\n\n async connectPrinter(_options: ConnectOptions): Promise<{ connected: boolean }> {\n throw this.unsupported('connectPrinter');\n }\n\n async disconnectPrinter(_options: { printerId: string }): Promise<void> {\n return;\n }\n\n async setDefaultPrinter(options: { printerId: string }): Promise<{ profile: PrinterProfile }> {\n const profiles = this.readProfiles();\n const target = profiles.find(p => p.id === options.printerId);\n if (!target) 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\n async getDefaultPrinter(): Promise<{ profile: PrinterProfile | null }> {\n const profiles = this.readProfiles();\n return { profile: profiles.find(p => p.isDefault) ?? null };\n }\n\n async getSavedPrinters(): Promise<{ profiles: PrinterProfile[] }> {\n return { profiles: this.readProfiles() };\n }\n\n async removePrinter(options: { printerId: string }): Promise<void> {\n this.writeProfiles(this.readProfiles().filter(p => p.id !== options.printerId));\n }\n\n async printImage(_options: PrintImageOptions): Promise<PrintResult> {\n throw this.unsupported('printImage');\n }\n\n async printText(_options: PrintTextOptions): Promise<PrintResult> {\n throw this.unsupported('printText');\n }\n\n async getPrinterStatus(_options: { printerId?: string }): Promise<PrinterStatus> {\n throw this.unsupported('getPrinterStatus');\n }\n\n async requestPermissions(): Promise<PermissionStatus> {\n return this.checkPermissions();\n }\n\n async checkPermissions(): Promise<PermissionStatus> {\n return {\n bluetooth: 'unavailable',\n bluetoothScan: 'unavailable',\n bluetoothConnect: 'unavailable',\n location: 'unavailable',\n localNetwork: 'unavailable',\n };\n }\n\n async startStatusMonitor(_options: { printerId: string; intervalMs?: number }): Promise<void> {\n return;\n }\n\n async stopStatusMonitor(_options: { printerId: string }): Promise<void> {\n return;\n }\n\n async getActiveSdks(): Promise<{ sdks: import('./definitions').SdkStatus[] }> {\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\n async getDebugLog(): Promise<{ log: import('./definitions').DebugLogEntry[] }> {\n return { log: [] };\n }\n\n private unsupported(method: string): PrinterError {\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\n private readProfiles(): PrinterProfile[] {\n try {\n return JSON.parse(localStorage.getItem(this.storageKey) ?? '[]');\n } catch {\n return [];\n }\n }\n\n private writeProfiles(profiles: PrinterProfile[]): void {\n localStorage.setItem(this.storageKey, JSON.stringify(profiles));\n }\n}\n"]}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n PermissionStatus,\n ThermalPrinterPlugin,\n} from './definitions';\nimport { PrintErrorCode } from './core/enums';\nimport { PrinterError } from './core/errors';\nimport type {\n ConnectOptions,\n DiscoverOptions,\n PrintImageOptions,\n PrintTextOptions,\n} from './core/options';\nimport type {\n DiscoveredPrinter,\n PrinterProfile,\n PrinterStatus,\n PrintResult,\n} from './core/models';\n\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 implements ThermalPrinterPlugin {\n private readonly storageKey = 'delicity.thermalprinter.profiles';\n\n async discoverPrinters(_options?: DiscoverOptions): Promise<{ printers: DiscoveredPrinter[] }> {\n // Aucune découverte matérielle possible sur le web.\n return { printers: [] };\n }\n\n async connectPrinter(_options: ConnectOptions): Promise<{ connected: boolean; paper: import('./core/paper').PaperInfo | null }> {\n throw this.unsupported('connectPrinter');\n }\n\n async disconnectPrinter(_options: { printerId: string }): Promise<void> {\n return;\n }\n\n async setDefaultPrinter(options: { printerId: string }): Promise<{ profile: PrinterProfile }> {\n const profiles = this.readProfiles();\n const target = profiles.find(p => p.id === options.printerId);\n if (!target) 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\n async getDefaultPrinter(): Promise<{ profile: PrinterProfile | null }> {\n const profiles = this.readProfiles();\n return { profile: profiles.find(p => p.isDefault) ?? null };\n }\n\n async getSavedPrinters(): Promise<{ profiles: PrinterProfile[] }> {\n return { profiles: this.readProfiles() };\n }\n\n async removePrinter(options: { printerId: string }): Promise<void> {\n this.writeProfiles(this.readProfiles().filter(p => p.id !== options.printerId));\n }\n\n async printImage(_options: PrintImageOptions): Promise<PrintResult> {\n throw this.unsupported('printImage');\n }\n\n async printText(_options: PrintTextOptions): Promise<PrintResult> {\n throw this.unsupported('printText');\n }\n\n async getPrinterStatus(_options: { printerId?: string }): Promise<PrinterStatus> {\n throw this.unsupported('getPrinterStatus');\n }\n\n async requestPermissions(): Promise<PermissionStatus> {\n return this.checkPermissions();\n }\n\n async checkPermissions(): Promise<PermissionStatus> {\n return {\n bluetooth: 'unavailable',\n bluetoothScan: 'unavailable',\n bluetoothConnect: 'unavailable',\n location: 'unavailable',\n localNetwork: 'unavailable',\n };\n }\n\n async startStatusMonitor(_options: { printerId: string; intervalMs?: number }): Promise<void> {\n return;\n }\n\n async stopStatusMonitor(_options: { printerId: string }): Promise<void> {\n return;\n }\n\n async getActiveSdks(): Promise<{ sdks: import('./definitions').SdkStatus[] }> {\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\n async getDebugLog(): Promise<{ log: import('./definitions').DebugLogEntry[] }> {\n return { log: [] };\n }\n\n private unsupported(method: string): PrinterError {\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\n private readProfiles(): PrinterProfile[] {\n try {\n return JSON.parse(localStorage.getItem(this.storageKey) ?? '[]');\n } catch {\n return [];\n }\n }\n\n private writeProfiles(profiles: PrinterProfile[]): void {\n localStorage.setItem(this.storageKey, JSON.stringify(profiles));\n }\n}\n"]}
@@ -27,6 +27,57 @@ exports.PrintErrorCode = void 0;
27
27
  PrintErrorCode["UNKNOWN"] = "UNKNOWN";
28
28
  })(exports.PrintErrorCode || (exports.PrintErrorCode = {}));
29
29
 
30
+ /**
31
+ * Déduction best-effort de la taille de papier d'une imprimante à partir de sa
32
+ * marque/modèle (remontés par l'imprimante ou son SDK à la connexion).
33
+ *
34
+ * L'imprimante NE renvoie PAS sa largeur de papier de façon standard : on la déduit
35
+ * du modèle via une table de correspondance (extensible). Renvoie `null` si le modèle
36
+ * est inconnu (cas fréquent des ESC/POS génériques) — à afficher tel quel à l'utilisateur.
37
+ *
38
+ * Implémentation de référence (testée), mirrorée en Kotlin (`PaperSize.kt`) et
39
+ * Swift (`PaperSize.swift`) pour le calcul natif au moment du `connectPrinter`.
40
+ */
41
+ /** Largeur imprimable standard @203 dpi pour une largeur papier donnée. */
42
+ function paperDotsForWidth(widthMm) {
43
+ switch (widthMm) {
44
+ case 58:
45
+ return 384;
46
+ case 80:
47
+ return 576;
48
+ case 112:
49
+ return 832;
50
+ default:
51
+ return null;
52
+ }
53
+ }
54
+ /**
55
+ * Devine la taille de papier depuis la marque/modèle. Best-effort, `null` si inconnu.
56
+ * La table couvre les modèles courants Epson/Star ; à enrichir au besoin.
57
+ */
58
+ function guessPaperInfo(brand, model) {
59
+ if (!model)
60
+ return null;
61
+ // On combine marque + modèle : selon la source, le nom du modèle se retrouve
62
+ // parfois dans l'un ou l'autre champ.
63
+ const m = `${brand !== null && brand !== void 0 ? brand : ''}${model}`.toUpperCase().replace(/[^A-Z0-9]/g, '');
64
+ if (!m)
65
+ return null;
66
+ let widthMm = null;
67
+ if (/TMM10|TMP20|TMP60|MCPRINT2|MCP2|SML200|SMS2/.test(m)) {
68
+ widthMm = 58; // Epson TM-m10/P20/P60, Star mC-Print2/SM-L200/SM-S2x
69
+ }
70
+ else if (/SMT400|TUP5/.test(m)) {
71
+ widthMm = 112; // Star SM-T400 / TUP500
72
+ }
73
+ else if (/TMM30|TMM50|TMT20|TMT70|TMT8|TMT100|TMP80|TML90|MCPRINT3|MCP3|TSP1|TSP6|TSP7|TSP8|SMT300/.test(m)) {
74
+ widthMm = 80; // Epson TM-m30/T20/T88/…, Star mC-Print3/TSP1xx-8xx/SM-T300
75
+ }
76
+ if (widthMm == null)
77
+ return null;
78
+ return { widthMm, printableDots: paperDotsForWidth(widthMm), dpi: 203, source: 'model' };
79
+ }
80
+
30
81
  /**
31
82
  * Correspondance page de code -> argument de la commande ESC t (n).
32
83
  * Ces valeurs sont les plus répandues ; certaines imprimantes diffèrent
@@ -220,5 +271,7 @@ var web = /*#__PURE__*/Object.freeze({
220
271
  exports.CODE_PAGE_TO_ESC_T = CODE_PAGE_TO_ESC_T;
221
272
  exports.PrinterError = PrinterError;
222
273
  exports.ThermalPrinter = ThermalPrinter;
274
+ exports.guessPaperInfo = guessPaperInfo;
275
+ exports.paperDotsForWidth = paperDotsForWidth;
223
276
  exports.toPrinterError = toPrinterError;
224
277
  //# sourceMappingURL=plugin.cjs.js.map
@@ -1 +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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"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/core/enums.js","esm/core/paper.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 * Déduction best-effort de la taille de papier d'une imprimante à partir de sa\n * marque/modèle (remontés par l'imprimante ou son SDK à la connexion).\n *\n * L'imprimante NE renvoie PAS sa largeur de papier de façon standard : on la déduit\n * du modèle via une table de correspondance (extensible). Renvoie `null` si le modèle\n * est inconnu (cas fréquent des ESC/POS génériques) — à afficher tel quel à l'utilisateur.\n *\n * Implémentation de référence (testée), mirrorée en Kotlin (`PaperSize.kt`) et\n * Swift (`PaperSize.swift`) pour le calcul natif au moment du `connectPrinter`.\n */\n/** Largeur imprimable standard @203 dpi pour une largeur papier donnée. */\nexport function paperDotsForWidth(widthMm) {\n switch (widthMm) {\n case 58:\n return 384;\n case 80:\n return 576;\n case 112:\n return 832;\n default:\n return null;\n }\n}\n/**\n * Devine la taille de papier depuis la marque/modèle. Best-effort, `null` si inconnu.\n * La table couvre les modèles courants Epson/Star ; à enrichir au besoin.\n */\nexport function guessPaperInfo(brand, model) {\n if (!model)\n return null;\n // On combine marque + modèle : selon la source, le nom du modèle se retrouve\n // parfois dans l'un ou l'autre champ.\n const m = `${brand !== null && brand !== void 0 ? brand : ''}${model}`.toUpperCase().replace(/[^A-Z0-9]/g, '');\n if (!m)\n return null;\n let widthMm = null;\n if (/TMM10|TMP20|TMP60|MCPRINT2|MCP2|SML200|SMS2/.test(m)) {\n widthMm = 58; // Epson TM-m10/P20/P60, Star mC-Print2/SM-L200/SM-S2x\n }\n else if (/SMT400|TUP5/.test(m)) {\n widthMm = 112; // Star SM-T400 / TUP500\n }\n else if (/TMM30|TMM50|TMT20|TMT70|TMT8|TMT100|TMP80|TML90|MCPRINT3|MCP3|TSP1|TSP6|TSP7|TSP8|SMT300/.test(m)) {\n widthMm = 80; // Epson TM-m30/T20/T88/…, Star mC-Print3/TSP1xx-8xx/SM-T300\n }\n if (widthMm == null)\n return null;\n return { widthMm, printableDots: paperDotsForWidth(widthMm), dpi: 203, source: 'model' };\n}\n//# sourceMappingURL=paper.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/paper';\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 CHANGED
@@ -26,6 +26,57 @@ var capacitorThermalPrinter = (function (exports, core) {
26
26
  PrintErrorCode["UNKNOWN"] = "UNKNOWN";
27
27
  })(exports.PrintErrorCode || (exports.PrintErrorCode = {}));
28
28
 
29
+ /**
30
+ * Déduction best-effort de la taille de papier d'une imprimante à partir de sa
31
+ * marque/modèle (remontés par l'imprimante ou son SDK à la connexion).
32
+ *
33
+ * L'imprimante NE renvoie PAS sa largeur de papier de façon standard : on la déduit
34
+ * du modèle via une table de correspondance (extensible). Renvoie `null` si le modèle
35
+ * est inconnu (cas fréquent des ESC/POS génériques) — à afficher tel quel à l'utilisateur.
36
+ *
37
+ * Implémentation de référence (testée), mirrorée en Kotlin (`PaperSize.kt`) et
38
+ * Swift (`PaperSize.swift`) pour le calcul natif au moment du `connectPrinter`.
39
+ */
40
+ /** Largeur imprimable standard @203 dpi pour une largeur papier donnée. */
41
+ function paperDotsForWidth(widthMm) {
42
+ switch (widthMm) {
43
+ case 58:
44
+ return 384;
45
+ case 80:
46
+ return 576;
47
+ case 112:
48
+ return 832;
49
+ default:
50
+ return null;
51
+ }
52
+ }
53
+ /**
54
+ * Devine la taille de papier depuis la marque/modèle. Best-effort, `null` si inconnu.
55
+ * La table couvre les modèles courants Epson/Star ; à enrichir au besoin.
56
+ */
57
+ function guessPaperInfo(brand, model) {
58
+ if (!model)
59
+ return null;
60
+ // On combine marque + modèle : selon la source, le nom du modèle se retrouve
61
+ // parfois dans l'un ou l'autre champ.
62
+ const m = `${brand !== null && brand !== void 0 ? brand : ''}${model}`.toUpperCase().replace(/[^A-Z0-9]/g, '');
63
+ if (!m)
64
+ return null;
65
+ let widthMm = null;
66
+ if (/TMM10|TMP20|TMP60|MCPRINT2|MCP2|SML200|SMS2/.test(m)) {
67
+ widthMm = 58; // Epson TM-m10/P20/P60, Star mC-Print2/SM-L200/SM-S2x
68
+ }
69
+ else if (/SMT400|TUP5/.test(m)) {
70
+ widthMm = 112; // Star SM-T400 / TUP500
71
+ }
72
+ else if (/TMM30|TMM50|TMT20|TMT70|TMT8|TMT100|TMP80|TML90|MCPRINT3|MCP3|TSP1|TSP6|TSP7|TSP8|SMT300/.test(m)) {
73
+ widthMm = 80; // Epson TM-m30/T20/T88/…, Star mC-Print3/TSP1xx-8xx/SM-T300
74
+ }
75
+ if (widthMm == null)
76
+ return null;
77
+ return { widthMm, printableDots: paperDotsForWidth(widthMm), dpi: 203, source: 'model' };
78
+ }
79
+
29
80
  /**
30
81
  * Correspondance page de code -> argument de la commande ESC t (n).
31
82
  * Ces valeurs sont les plus répandues ; certaines imprimantes diffèrent
@@ -219,6 +270,8 @@ var capacitorThermalPrinter = (function (exports, core) {
219
270
  exports.CODE_PAGE_TO_ESC_T = CODE_PAGE_TO_ESC_T;
220
271
  exports.PrinterError = PrinterError;
221
272
  exports.ThermalPrinter = ThermalPrinter;
273
+ exports.guessPaperInfo = guessPaperInfo;
274
+ exports.paperDotsForWidth = paperDotsForWidth;
222
275
  exports.toPrinterError = toPrinterError;
223
276
 
224
277
  return exports;
@@ -1 +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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"}
1
+ {"version":3,"file":"plugin.js","sources":["esm/core/enums.js","esm/core/paper.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 * Déduction best-effort de la taille de papier d'une imprimante à partir de sa\n * marque/modèle (remontés par l'imprimante ou son SDK à la connexion).\n *\n * L'imprimante NE renvoie PAS sa largeur de papier de façon standard : on la déduit\n * du modèle via une table de correspondance (extensible). Renvoie `null` si le modèle\n * est inconnu (cas fréquent des ESC/POS génériques) — à afficher tel quel à l'utilisateur.\n *\n * Implémentation de référence (testée), mirrorée en Kotlin (`PaperSize.kt`) et\n * Swift (`PaperSize.swift`) pour le calcul natif au moment du `connectPrinter`.\n */\n/** Largeur imprimable standard @203 dpi pour une largeur papier donnée. */\nexport function paperDotsForWidth(widthMm) {\n switch (widthMm) {\n case 58:\n return 384;\n case 80:\n return 576;\n case 112:\n return 832;\n default:\n return null;\n }\n}\n/**\n * Devine la taille de papier depuis la marque/modèle. Best-effort, `null` si inconnu.\n * La table couvre les modèles courants Epson/Star ; à enrichir au besoin.\n */\nexport function guessPaperInfo(brand, model) {\n if (!model)\n return null;\n // On combine marque + modèle : selon la source, le nom du modèle se retrouve\n // parfois dans l'un ou l'autre champ.\n const m = `${brand !== null && brand !== void 0 ? brand : ''}${model}`.toUpperCase().replace(/[^A-Z0-9]/g, '');\n if (!m)\n return null;\n let widthMm = null;\n if (/TMM10|TMP20|TMP60|MCPRINT2|MCP2|SML200|SMS2/.test(m)) {\n widthMm = 58; // Epson TM-m10/P20/P60, Star mC-Print2/SM-L200/SM-S2x\n }\n else if (/SMT400|TUP5/.test(m)) {\n widthMm = 112; // Star SM-T400 / TUP500\n }\n else if (/TMM30|TMM50|TMT20|TMT70|TMT8|TMT100|TMP80|TML90|MCPRINT3|MCP3|TSP1|TSP6|TSP7|TSP8|SMT300/.test(m)) {\n widthMm = 80; // Epson TM-m30/T20/T88/…, Star mC-Print3/TSP1xx-8xx/SM-T300\n }\n if (widthMm == null)\n return null;\n return { widthMm, printableDots: paperDotsForWidth(widthMm), dpi: 203, source: 'model' };\n}\n//# sourceMappingURL=paper.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/paper';\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,53 @@
1
+ import Foundation
2
+
3
+ /// Taille de papier déduite à la connexion (best-effort). Miroir Swift de
4
+ /// `src/core/paper.ts`. Champs nullables : `nil` = inconnu.
5
+ struct PaperInfo {
6
+ let widthMm: Int?
7
+ let printableDots: Int?
8
+ let dpi: Int?
9
+ let source: String // 'model' | 'sdk' | 'profile'
10
+
11
+ func toDict() -> [String: Any] {
12
+ [
13
+ "widthMm": widthMm as Any? ?? NSNull(),
14
+ "printableDots": printableDots as Any? ?? NSNull(),
15
+ "dpi": dpi as Any? ?? NSNull(),
16
+ "source": source,
17
+ ]
18
+ }
19
+ }
20
+
21
+ /// Déduction de la taille papier depuis la marque/modèle (best-effort).
22
+ enum PaperSizeGuess {
23
+
24
+ static func dotsForWidth(_ widthMm: Int) -> Int? {
25
+ switch widthMm {
26
+ case 58: return 384
27
+ case 80: return 576
28
+ case 112: return 832
29
+ default: return nil
30
+ }
31
+ }
32
+
33
+ /// Renvoie la taille papier déduite, ou nil si le modèle est inconnu.
34
+ static func fromBrandModel(_ brand: String?, _ model: String?) -> PaperInfo? {
35
+ guard let model = model, !model.isEmpty else { return nil }
36
+ let m = ((brand ?? "") + model).uppercased().replacingOccurrences(of: "[^A-Z0-9]", with: "", options: .regularExpression)
37
+ if m.isEmpty { return nil }
38
+
39
+ func has(_ pattern: String) -> Bool { m.range(of: pattern, options: .regularExpression) != nil }
40
+
41
+ let widthMm: Int
42
+ if has("TMM10|TMP20|TMP60|MCPRINT2|MCP2|SML200|SMS2") {
43
+ widthMm = 58
44
+ } else if has("SMT400|TUP5") {
45
+ widthMm = 112
46
+ } else if has("TMM30|TMM50|TMT20|TMT70|TMT8|TMT100|TMP80|TML90|MCPRINT3|MCP3|TSP1|TSP6|TSP7|TSP8|SMT300") {
47
+ widthMm = 80
48
+ } else {
49
+ return nil
50
+ }
51
+ return PaperInfo(widthMm: widthMm, printableDots: dotsForWidth(widthMm), dpi: 203, source: "model")
52
+ }
53
+ }
@@ -51,7 +51,10 @@ final class ThermalPrinterEngine {
51
51
 
52
52
  // MARK: Connexion
53
53
 
54
- func connect(_ printerId: String, timeoutMs: Int, forceAdapter: AdapterId?, setAsDefault: Bool = false) async throws -> Bool {
54
+ /// Résultat de connexion : état + taille papier déduite (best-effort, nil si inconnue).
55
+ struct ConnectResult { let connected: Bool; let paper: PaperInfo? }
56
+
57
+ func connect(_ printerId: String, timeoutMs: Int, forceAdapter: AdapterId?, setAsDefault: Bool = false) async throws -> ConnectResult {
55
58
  let profile = try resolveProfile(printerId, forceAdapter: forceAdapter)
56
59
  guard let adapter = adapterFor(profile.adapter) else {
57
60
  throw PrinterError(.UNSUPPORTED_PRINTER, "Aucun adapter pour \(profile.adapter.rawValue)")
@@ -67,7 +70,9 @@ final class ThermalPrinterEngine {
67
70
  store.setDefault(printerId)
68
71
  Logger.shared.log("connect", "set-default-after-connect", ["id": printerId])
69
72
  }
70
- return connected
73
+ // Taille papier best-effort (déduite du modèle remonté), nil si inconnue.
74
+ let paper = connected ? PaperSizeGuess.fromBrandModel(profile.brand, profile.model) : nil
75
+ return ConnectResult(connected: connected, paper: paper)
71
76
  }
72
77
 
73
78
  func disconnect(_ printerId: String) async {
@@ -101,8 +101,8 @@ public class ThermalPrinterPlugin: CAPPlugin, CAPBridgedPlugin {
101
101
  let force = call.getString("forceAdapter").map { AdapterId.from($0) }
102
102
  let setAsDefault = call.getBool("setAsDefault") ?? false
103
103
  Task { await self.guarded(call) {
104
- let connected = try await self.engine.connect(printerId, timeoutMs: timeout, forceAdapter: force, setAsDefault: setAsDefault)
105
- call.resolve(["connected": connected])
104
+ let result = try await self.engine.connect(printerId, timeoutMs: timeout, forceAdapter: force, setAsDefault: setAsDefault)
105
+ call.resolve(["connected": result.connected, "paper": result.paper?.toDict() ?? NSNull()])
106
106
  } }
107
107
  }
108
108
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@delicity/capacitor-thermal-printer",
3
- "version": "7.0.0",
4
- "description": "Plugin Capacitor d'impression thermique multi-marques (ESC/POS, Epson, Star, Brother, Zebra) par image, avec découverte agrégée et reconnexion automatique.",
3
+ "version": "7.0.1",
4
+ "description": "@delicity/capacitor-thermal-printer multi-brand thermal/receipt/label printing for Capacitor 7 (ESC/POS, Epson, Star, Brother, Zebra), image-based, with aggregated discovery and automatic reconnection.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "types": "dist/esm/index.d.ts",
@@ -17,11 +17,12 @@
17
17
  "license": "MIT",
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "https://github.com/your-org/capacitor-thermal-printer.git"
20
+ "url": "https://github.com/kevinfavv/CapacitorThermalPrinter.git"
21
21
  },
22
22
  "bugs": {
23
- "url": "https://github.com/your-org/capacitor-thermal-printer/issues"
23
+ "url": "https://github.com/kevinfavv/CapacitorThermalPrinter/issues"
24
24
  },
25
+ "homepage": "https://github.com/kevinfavv/CapacitorThermalPrinter#readme",
25
26
  "keywords": [
26
27
  "capacitor",
27
28
  "plugin",