@m-scan/device-kit
v0.0.1
Published
Unified device SDK for web applications: network, Bluetooth, USB and ESC/POS printers behind one API
Downloads
0
Readme
@m-scan/device-kit
SDK unifié pour parler aux périphériques d'un poste de caisse (imprimantes ESC/POS réseau, USB et Bluetooth, tiroir-caisse) depuis une application web — Vue, React, ou n'importe quel front JS/TS.
Pourquoi un agent local ?
Un navigateur ne peut pas ouvrir de socket TCP brut, accéder aux queues
d'impression du système, ni lire un port série — les restrictions de
sécurité du navigateur l'en empêchent. @m-scan/device-kit s'appuie donc
sur un petit programme qui tourne en local sur le poste de caisse,
@m-scan/device-kit-agent,
et qui expose ces accès via une API HTTP sur localhost.
Application web (Vue/React)
│ fetch('http://localhost:4310/api/...')
▼
@m-scan/device-kit-agent (tourne sur le poste de caisse)
│
┌────────┼─────────┐
▼ ▼ ▼
Réseau USB Bluetooth
(TCP) (queue (port COM)
Windows)Installation
npm install @m-scan/device-kitSur le poste de caisse, lancer l'agent (voir @m-scan/device-kit-agent pour les détails) :
npx m-scan-device-agentUsage
import { DeviceKit } from '@m-scan/device-kit'
const deviceKit = new DeviceKit()
// Découvre les imprimantes disponibles (réseau + USB + Bluetooth)
const printers = await deviceKit.printers.discover()Pour se connecter et imprimer un ticket, on parle directement à l'agent en HTTP — voir la section suivante pour construire le contenu du ticket.
Construire un ticket avec buildReceipt
import { buildReceipt, type Receipt } from '@m-scan/device-kit'
const receipt: Receipt = {
id: 'TKT-20260902-0001',
logo: './logo.png', // optionnel
store: { name: 'M-Cash Store', address: 'Goma, RDC', phone: '+243 900 000 000' },
transaction: { date: '2026-09-02', time: '14:25:32', cashier: 'Caisse 01' },
items: [
{ name: 'Eau La Vie', quantity: 2, unitPrice: 2500, total: 5000, currency: 'CDF' },
],
summary: { subtotal: 5000, total: 5000, currency: 'CDF' },
payment: { method: 'CASH', amountReceived: 5000, change: 0, currency: 'CDF' },
footer: { message: 'Merci pour votre achat !', qrCode: 'https://m-cash.com/ticket/TKT-20260902-0001' }, // qrCode optionnel
}
const doc = await buildReceipt(receipt, { paperWidth: '80mm' }) // async (charge le logo si présent)
const bytes = doc.build() // Uint8Array de commandes ESC/POS prêtes à envoyerbuildReceipt aligne automatiquement les colonnes (nom du produit à gauche,
prix à droite) selon la largeur de papier choisie ('58mm' ou '80mm', 48
colonnes par défaut), et imprime le logo/QR code s'ils sont fournis. Voir
@m-scan/device-kit-escpos pour construire un ticket
"à la main" avec l'API bas niveau (align, bold, row, separator,
feed, cut, openCashDrawer, image, qrCode...).
Imprimer via l'agent
L'agent expose une API HTTP par transport. Exemple réseau :
// 1. Se connecter (garde la connexion ouverte pour les prochains print)
await fetch('http://localhost:4310/api/connect', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ host: '192.168.1.50', port: 9100 }),
})
// 2. Imprimer un ticket structuré
await fetch('http://localhost:4310/api/print', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ receipt }),
})
// 3. Ouvrir le tiroir-caisse (câblé sur l'imprimante)
await fetch('http://localhost:4310/api/cash-drawer', { method: 'POST' })Mêmes routes préfixées /api/usb/... et /api/bluetooth/... pour les
autres transports — voir
@m-scan/device-kit-agent
pour la liste complète.
Packages du SDK
| Package | Rôle |
|---|---|
| @m-scan/device-kit | Façade — ce package, à installer dans l'app web |
| @m-scan/device-kit-agent | Agent local à lancer sur le poste de caisse |
| @m-scan/device-kit-escpos | Générateur de commandes ESC/POS (EscPos, buildReceipt) |
| @m-scan/device-kit-network | Scan réseau + impression TCP |
| @m-scan/device-kit-usb | Scan + impression USB (Windows) |
| @m-scan/device-kit-bluetooth | Scan + impression Bluetooth (port COM) |
| @m-scan/device-kit-core | Types partagés (Device, Printer, DeviceScanner) |
Limitations connues
- Réseau, USB et Bluetooth : Windows, Linux, macOS. L'USB passe par la
queue d'impression système (
winspool.drvsur Windows, CUPS sur Linux/macOS), le Bluetooth par un port série (l'imprimante doit être appairée au préalable dans l'OS). - Pas de support Android/iOS via l'agent — pas d'environnement Node.js persistant sur mobile. Sur tablette/téléphone, prévu comme une PWA parlant directement à l'imprimante via Web Bluetooth/WebUSB (Chrome sur Android ; iOS Safari ne supporte ni l'un ni l'autre) — pas encore implémenté.
- Réseau et agent doivent être sur le même réseau local que l'imprimante. Un agent hébergé sur un cloud externe ne peut pas atteindre une imprimante sur le réseau privé d'un magasin.
- Le tiroir-caisse n'a pas de retour d'état (pas de capteur physique) — la commande d'ouverture est "envoyée et espérée", sans confirmation matérielle.
Licence
MIT
