@thermal-print/escpos 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +193 -0
- package/dist/command-adapters/escbematech-adapter.d.ts +30 -0
- package/dist/command-adapters/escbematech-adapter.d.ts.map +1 -0
- package/dist/command-adapters/escbematech-adapter.js +175 -0
- package/dist/command-adapters/escpos-adapter.d.ts +25 -0
- package/dist/command-adapters/escpos-adapter.d.ts.map +1 -0
- package/dist/command-adapters/escpos-adapter.js +144 -0
- package/dist/command-adapters/index.d.ts +11 -0
- package/dist/command-adapters/index.d.ts.map +1 -0
- package/dist/command-adapters/index.js +14 -0
- package/dist/command-adapters/types.d.ts +78 -0
- package/dist/command-adapters/types.d.ts.map +1 -0
- package/dist/command-adapters/types.js +8 -0
- package/dist/commands/escbematech.d.ts +867 -0
- package/dist/commands/escbematech.d.ts.map +1 -0
- package/dist/commands/escbematech.js +1387 -0
- package/dist/commands/escpos.d.ts +582 -0
- package/dist/commands/escpos.d.ts.map +1 -0
- package/dist/commands/escpos.js +1048 -0
- package/dist/converter.d.ts +47 -0
- package/dist/converter.d.ts.map +1 -0
- package/dist/converter.js +92 -0
- package/dist/encodings/cp860.d.ts +25 -0
- package/dist/encodings/cp860.d.ts.map +1 -0
- package/dist/encodings/cp860.js +187 -0
- package/dist/generator.d.ts +118 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +383 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/styles.d.ts +72 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +210 -0
- package/dist/traverser.d.ts +60 -0
- package/dist/traverser.d.ts.map +1 -0
- package/dist/traverser.js +285 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/package.json +31 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 NUVEL
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# @thermal-print/escpos
|
|
2
|
+
|
|
3
|
+
ESC/POS command generation and thermal printer control.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @thermal-print/escpos
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 🎯 Purpose
|
|
12
|
+
|
|
13
|
+
Converts `PrintNode` trees (universal IR) to ESC/POS command buffers for thermal printers.
|
|
14
|
+
|
|
15
|
+
**Architecture:**
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
PrintNode → ESCPOSGenerator → Buffer (ESC/POS commands)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 🚀 Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { printNodesToESCPOS } from "@thermal-print/escpos";
|
|
25
|
+
import { PrintNode } from "@thermal-print/core";
|
|
26
|
+
|
|
27
|
+
const printNode: PrintNode = {
|
|
28
|
+
type: "document",
|
|
29
|
+
props: {},
|
|
30
|
+
children: [
|
|
31
|
+
{
|
|
32
|
+
type: "text",
|
|
33
|
+
props: { children: "Hello World" },
|
|
34
|
+
children: [],
|
|
35
|
+
style: { textAlign: "center", fontSize: 20 },
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
style: {},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Convert to ESC/POS buffer
|
|
42
|
+
const buffer = await printNodesToESCPOS(printNode, {
|
|
43
|
+
paperWidth: 48,
|
|
44
|
+
cut: "full",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Send to printer
|
|
48
|
+
await printer.write(buffer);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 📖 API
|
|
52
|
+
|
|
53
|
+
### printNodesToESCPOS(printNode, options)
|
|
54
|
+
|
|
55
|
+
Main conversion function.
|
|
56
|
+
|
|
57
|
+
**Parameters:**
|
|
58
|
+
|
|
59
|
+
- `printNode: PrintNode` - Root node of the tree to convert
|
|
60
|
+
- `options?: PrintNodeToESCPOSOptions` - Conversion options
|
|
61
|
+
|
|
62
|
+
**Options:**
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
interface PrintNodeToESCPOSOptions {
|
|
66
|
+
paperWidth?: number; // Characters per line (default: 48)
|
|
67
|
+
encoding?: string; // Character encoding (default: 'utf-8')
|
|
68
|
+
debug?: boolean; // Enable debug output
|
|
69
|
+
cut?: boolean | "full" | "partial"; // Paper cut (default: 'full')
|
|
70
|
+
feedBeforeCut?: number; // Lines to feed before cut (default: 3)
|
|
71
|
+
commandAdapter?: "escpos" | "escbematech"; // Protocol (default: 'escpos')
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Returns:** `Promise<Buffer>` - ESC/POS command buffer
|
|
76
|
+
|
|
77
|
+
## 🎛 Command Adapters
|
|
78
|
+
|
|
79
|
+
### ESC/POS (Default)
|
|
80
|
+
|
|
81
|
+
Standard ESC/POS protocol compatible with most thermal printers.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
const buffer = await printNodesToESCPOS(printNode, {
|
|
85
|
+
commandAdapter: "escpos",
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### ESC/Bematech
|
|
90
|
+
|
|
91
|
+
Bematech MP-4200 TH specific protocol.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const buffer = await printNodesToESCPOS(printNode, {
|
|
95
|
+
commandAdapter: "escbematech",
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## 🔧 Advanced Usage
|
|
100
|
+
|
|
101
|
+
### Custom Command Adapter
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { CommandAdapter, ESCPOSGenerator } from "@thermal-print/escpos";
|
|
105
|
+
|
|
106
|
+
class CustomAdapter implements CommandAdapter {
|
|
107
|
+
getName(): string {
|
|
108
|
+
return "custom";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
getInitCommand(): number[] {
|
|
112
|
+
return [0x1b, 0x40]; // ESC @
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ... implement other methods
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const buffer = await printNodesToESCPOS(printNode, {
|
|
119
|
+
commandAdapter: new CustomAdapter(),
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Direct Generator Usage
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { ESCPOSGenerator, TreeTraverser } from "@thermal-print/escpos";
|
|
127
|
+
|
|
128
|
+
const generator = new ESCPOSGenerator(48, "utf-8");
|
|
129
|
+
generator.initialize();
|
|
130
|
+
|
|
131
|
+
const traverser = new TreeTraverser(generator);
|
|
132
|
+
await traverser.traverse(printNode);
|
|
133
|
+
|
|
134
|
+
generator.cutFullWithFeed(3);
|
|
135
|
+
const buffer = generator.getBuffer();
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## 🎨 Styling Support
|
|
139
|
+
|
|
140
|
+
### Text Styles
|
|
141
|
+
|
|
142
|
+
- **fontSize**: Maps to character sizes (1x1, 1x2, 2x1, 2x2)
|
|
143
|
+
- **fontWeight**: 'bold' or numeric ≥700
|
|
144
|
+
- **textAlign**: 'left', 'center', 'right'
|
|
145
|
+
|
|
146
|
+
### Layout Styles
|
|
147
|
+
|
|
148
|
+
- **flexDirection**: 'row' (side-by-side), 'column' (stacked)
|
|
149
|
+
- **justifyContent**: 'space-between', 'center', etc.
|
|
150
|
+
- **padding/margin**: Top and bottom spacing (converted to line feeds)
|
|
151
|
+
- **borderTop/borderBottom**: Divider lines (solid or dashed)
|
|
152
|
+
- **width**: Column width (percentage or fixed characters)
|
|
153
|
+
|
|
154
|
+
## 🌍 Character Encoding
|
|
155
|
+
|
|
156
|
+
### CP860 (Default)
|
|
157
|
+
|
|
158
|
+
Brazilian Portuguese support with special characters: ç, á, é, í, ó, ú, ã, õ
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const buffer = await printNodesToESCPOS(printNode, {
|
|
162
|
+
encoding: "cp860",
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## 📏 Paper Widths
|
|
167
|
+
|
|
168
|
+
Common thermal printer paper widths:
|
|
169
|
+
|
|
170
|
+
- **58mm** = 32 characters
|
|
171
|
+
- **80mm** = 48 characters (default)
|
|
172
|
+
- **112mm** = 64 characters
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const buffer = await printNodesToESCPOS(printNode, {
|
|
176
|
+
paperWidth: 48, // 80mm paper
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## 🖼 Image Support
|
|
181
|
+
|
|
182
|
+
Images are automatically:
|
|
183
|
+
|
|
184
|
+
- Resized to fit paper width
|
|
185
|
+
- Converted to grayscale
|
|
186
|
+
- Converted to monochrome (1-bit)
|
|
187
|
+
- Printed using ESC/POS raster graphics
|
|
188
|
+
|
|
189
|
+
Requires `jimp` for image processing (optional dependency).
|
|
190
|
+
|
|
191
|
+
## 📄 License
|
|
192
|
+
|
|
193
|
+
MIT © Gabriel Martinusso
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESC/Bematech Command Adapter
|
|
3
|
+
*
|
|
4
|
+
* ESC/Bematech (ESC/Bema) command implementation for Bematech thermal printers.
|
|
5
|
+
* The MP-4200 TH supports both ESC/Bema and ESC/POS modes - only one active at a time.
|
|
6
|
+
*
|
|
7
|
+
* Note: ESC/Bema has limited command support compared to ESC/POS.
|
|
8
|
+
* Some advanced features (like QR codes) may not be available.
|
|
9
|
+
*
|
|
10
|
+
* Reference: Bematech MP-4200 TH Programming Manual
|
|
11
|
+
*/
|
|
12
|
+
import { CommandAdapter, CharacterSize } from './types';
|
|
13
|
+
/**
|
|
14
|
+
* ESC/Bematech Command Adapter
|
|
15
|
+
* For Bematech printers in ESC/Bema mode
|
|
16
|
+
*/
|
|
17
|
+
export declare class ESCBematechCommandAdapter implements CommandAdapter {
|
|
18
|
+
getName(): string;
|
|
19
|
+
getMaxCharacterSize(): CharacterSize;
|
|
20
|
+
getInitCommand(): number[];
|
|
21
|
+
getAlignCommand(align: 'left' | 'center' | 'right'): number[];
|
|
22
|
+
getCharacterSizeCommand(width: number, height: number, bold: boolean): number[];
|
|
23
|
+
getLineSpacingCommand(dots?: number): number[];
|
|
24
|
+
getCutCommand(type: 'full' | 'partial', feedLines?: number): number[];
|
|
25
|
+
getQRCodeCommand(data: string, size: number): number[];
|
|
26
|
+
getRasterImageCommand(imageData: number[], width: number, height: number): number[];
|
|
27
|
+
getLineFeedCommand(lines?: number): number[];
|
|
28
|
+
getFeedLinesCommand(lines: number): number[];
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=escbematech-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escbematech-adapter.d.ts","sourceRoot":"","sources":["../../src/command-adapters/escbematech-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxD;;;GAGG;AACH,qBAAa,yBAA0B,YAAW,cAAc;IAC9D,OAAO,IAAI,MAAM;IAIjB,mBAAmB,IAAI,aAAa;IAMpC,cAAc,IAAI,MAAM,EAAE;IAK1B,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,EAAE;IAY7D,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE;IAiB/E,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAW9C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAqBrE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAgBtD,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAuBnF,kBAAkB,CAAC,KAAK,GAAE,MAAU,GAAG,MAAM,EAAE;IAU/C,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAa7C"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ESC/Bematech Command Adapter
|
|
4
|
+
*
|
|
5
|
+
* ESC/Bematech (ESC/Bema) command implementation for Bematech thermal printers.
|
|
6
|
+
* The MP-4200 TH supports both ESC/Bema and ESC/POS modes - only one active at a time.
|
|
7
|
+
*
|
|
8
|
+
* Note: ESC/Bema has limited command support compared to ESC/POS.
|
|
9
|
+
* Some advanced features (like QR codes) may not be available.
|
|
10
|
+
*
|
|
11
|
+
* Reference: Bematech MP-4200 TH Programming Manual
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.ESCBematechCommandAdapter = void 0;
|
|
48
|
+
const ESCBema = __importStar(require("../commands/escbematech"));
|
|
49
|
+
/**
|
|
50
|
+
* ESC/Bematech Command Adapter
|
|
51
|
+
* For Bematech printers in ESC/Bema mode
|
|
52
|
+
*/
|
|
53
|
+
class ESCBematechCommandAdapter {
|
|
54
|
+
getName() {
|
|
55
|
+
return 'ESC/Bematech';
|
|
56
|
+
}
|
|
57
|
+
getMaxCharacterSize() {
|
|
58
|
+
// ESC/Bema supports double width and double height
|
|
59
|
+
// but typically not independent control like ESC/POS
|
|
60
|
+
return { width: 2, height: 2 };
|
|
61
|
+
}
|
|
62
|
+
getInitCommand() {
|
|
63
|
+
// ESC @ - Reset printer
|
|
64
|
+
return ESCBema.INIT;
|
|
65
|
+
}
|
|
66
|
+
getAlignCommand(align) {
|
|
67
|
+
// ESC a n - Set text alignment (ESC/Bema uses same command as ESC/POS)
|
|
68
|
+
switch (align) {
|
|
69
|
+
case 'left':
|
|
70
|
+
return ESCBema.ALIGN_LEFT;
|
|
71
|
+
case 'center':
|
|
72
|
+
return ESCBema.ALIGN_CENTER;
|
|
73
|
+
case 'right':
|
|
74
|
+
return ESCBema.ALIGN_RIGHT;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
getCharacterSizeCommand(width, height, bold) {
|
|
78
|
+
/**
|
|
79
|
+
* ESC/Bema character sizing:
|
|
80
|
+
* - Uses ESC ! n for combined mode (emphasis, double-height, double-width)
|
|
81
|
+
* - Also supports separate commands: ESC E/F (bold), ESC W (width), ESC d (height)
|
|
82
|
+
*
|
|
83
|
+
* We'll use the combined ESC ! command for better efficiency
|
|
84
|
+
* Max size: 2x2 (same as ESC/POS compatibility mode)
|
|
85
|
+
*/
|
|
86
|
+
return ESCBema.calculatePrintMode({
|
|
87
|
+
emphasized: bold,
|
|
88
|
+
doubleHeight: height >= 2,
|
|
89
|
+
doubleWidth: width >= 2,
|
|
90
|
+
underline: false
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
getLineSpacingCommand(dots) {
|
|
94
|
+
if (dots === undefined) {
|
|
95
|
+
// ESC 2 - Reset to default spacing (1/6 inches)
|
|
96
|
+
return ESCBema.SET_LINE_HEIGHT_DEFAULT;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// ESC 3 n - Set line spacing to n/144 inches
|
|
100
|
+
// Range: 18 ≤ n ≤ 255
|
|
101
|
+
return ESCBema.setLineSpacing(dots);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
getCutCommand(type, feedLines) {
|
|
105
|
+
const commands = [];
|
|
106
|
+
// Feed paper if requested
|
|
107
|
+
if (feedLines && feedLines > 0) {
|
|
108
|
+
commands.push(...this.getLineFeedCommand(feedLines));
|
|
109
|
+
}
|
|
110
|
+
// ESC/Bema cut commands
|
|
111
|
+
// ESC i or ESC w: Full cut (both work, ESC i is primary)
|
|
112
|
+
// Note: Partial cut (ESC m) is ESC/POS command, not documented in ESC/Bema manual
|
|
113
|
+
if (type === 'full') {
|
|
114
|
+
commands.push(...ESCBema.CUT_FULL);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// Partial cut not available in ESC/Bema, use full cut instead
|
|
118
|
+
commands.push(...ESCBema.CUT_FULL);
|
|
119
|
+
}
|
|
120
|
+
return commands;
|
|
121
|
+
}
|
|
122
|
+
getQRCodeCommand(data, size) {
|
|
123
|
+
/**
|
|
124
|
+
* QR Code support is NOT documented in ESC/Bematech manual Chapter 3.
|
|
125
|
+
* QR codes require ESC/POS mode with GS ( k commands.
|
|
126
|
+
*
|
|
127
|
+
* Recommendation: Switch printer to ESC/POS mode temporarily:
|
|
128
|
+
* 1. Send GS F9h SP 1 (temp switch to ESC/POS)
|
|
129
|
+
* 2. Print QR code using ESC/POS commands
|
|
130
|
+
* 3. Send GS F9h 1Fh 1 (return to previous mode)
|
|
131
|
+
*
|
|
132
|
+
* For now, we return empty array and log a warning.
|
|
133
|
+
*/
|
|
134
|
+
console.warn('QR Code generation is not supported in ESC/Bematech mode. Switch to ESC/POS mode using GS F9h SP 1.');
|
|
135
|
+
return [];
|
|
136
|
+
}
|
|
137
|
+
getRasterImageCommand(imageData, width, height) {
|
|
138
|
+
/**
|
|
139
|
+
* ESC/Bematech supports multiple graphics formats:
|
|
140
|
+
* - GS v 0 m: Raster bitmap (documented, preferred)
|
|
141
|
+
* - ESC * !: 24-bit graphics (documented)
|
|
142
|
+
* - ESC K: 8-bit graphics (documented, lower quality)
|
|
143
|
+
*
|
|
144
|
+
* We'll use GS v 0 format (raster bitmap) which is explicitly documented
|
|
145
|
+
* in the Bematech manual and provides best compatibility.
|
|
146
|
+
*/
|
|
147
|
+
const bytesPerLine = Math.ceil(width / 8);
|
|
148
|
+
// Use raster bitmap format with normal mode (203 dpi × 203 dpi)
|
|
149
|
+
const commands = ESCBema.printRasterBitmap(ESCBema.RasterMode.NORMAL, bytesPerLine, height, imageData);
|
|
150
|
+
return commands;
|
|
151
|
+
}
|
|
152
|
+
getLineFeedCommand(lines = 1) {
|
|
153
|
+
// LF (0x0A) - Feed one line
|
|
154
|
+
// Repeat for multiple lines
|
|
155
|
+
const commands = [];
|
|
156
|
+
for (let i = 0; i < lines; i++) {
|
|
157
|
+
commands.push(...ESCBema.FEED_LINE);
|
|
158
|
+
}
|
|
159
|
+
return commands;
|
|
160
|
+
}
|
|
161
|
+
getFeedLinesCommand(lines) {
|
|
162
|
+
/**
|
|
163
|
+
* IMPORTANT FIX: ESC d in ESC/Bema is for DOUBLE-HEIGHT, not line feed!
|
|
164
|
+
*
|
|
165
|
+
* For paper feeding in ESC/Bema, use:
|
|
166
|
+
* - LF (0x0A): Feed one line (preferred for multiple lines)
|
|
167
|
+
* - ESC A n: Feed paper by [n × 0.375mm]
|
|
168
|
+
* - ESC J n: Fine line feed [(n-48) × 0.125mm]
|
|
169
|
+
*
|
|
170
|
+
* We'll use LF for simplicity
|
|
171
|
+
*/
|
|
172
|
+
return this.getLineFeedCommand(lines);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.ESCBematechCommandAdapter = ESCBematechCommandAdapter;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESC/POS Command Adapter
|
|
3
|
+
*
|
|
4
|
+
* Standard ESC/POS command implementation using ESC ! for character sizing.
|
|
5
|
+
* Compatible with most thermal printers that support ESC/POS protocol.
|
|
6
|
+
*/
|
|
7
|
+
import { CommandAdapter, CharacterSize } from "./types";
|
|
8
|
+
/**
|
|
9
|
+
* ESC/POS Command Adapter
|
|
10
|
+
* Uses ESC ! for character sizing (max 2x2) for better compatibility
|
|
11
|
+
*/
|
|
12
|
+
export declare class ESCPOSCommandAdapter implements CommandAdapter {
|
|
13
|
+
getName(): string;
|
|
14
|
+
getMaxCharacterSize(): CharacterSize;
|
|
15
|
+
getInitCommand(): number[];
|
|
16
|
+
getAlignCommand(align: "left" | "center" | "right"): number[];
|
|
17
|
+
getCharacterSizeCommand(width: number, height: number, bold: boolean): number[];
|
|
18
|
+
getLineSpacingCommand(dots?: number): number[];
|
|
19
|
+
getCutCommand(type: "full" | "partial", feedLines?: number): number[];
|
|
20
|
+
getQRCodeCommand(data: string, size: number): number[];
|
|
21
|
+
getRasterImageCommand(imageData: number[], width: number, height: number): number[];
|
|
22
|
+
getLineFeedCommand(lines?: number): number[];
|
|
23
|
+
getFeedLinesCommand(lines: number): number[];
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=escpos-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escpos-adapter.d.ts","sourceRoot":"","sources":["../../src/command-adapters/escpos-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAQxD;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,IAAI,MAAM;IAIjB,mBAAmB,IAAI,aAAa;IAMpC,cAAc,IAAI,MAAM,EAAE;IAoB1B,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,EAAE;IAY7D,uBAAuB,CACrB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GACZ,MAAM,EAAE;IASX,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAU9C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAoBrE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAKtD,qBAAqB,CACnB,SAAS,EAAE,MAAM,EAAE,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,MAAM,EAAE;IAKX,kBAAkB,CAAC,KAAK,GAAE,MAAU,GAAG,MAAM,EAAE;IAU/C,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAI7C"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ESC/POS Command Adapter
|
|
4
|
+
*
|
|
5
|
+
* Standard ESC/POS command implementation using ESC ! for character sizing.
|
|
6
|
+
* Compatible with most thermal printers that support ESC/POS protocol.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.ESCPOSCommandAdapter = void 0;
|
|
43
|
+
const ESCPOS = __importStar(require("../commands/escpos"));
|
|
44
|
+
// Control characters (for backward compatibility)
|
|
45
|
+
const ESC = ESCPOS.ESC;
|
|
46
|
+
const GS = ESCPOS.GS;
|
|
47
|
+
const LF = ESCPOS.LF;
|
|
48
|
+
/**
|
|
49
|
+
* ESC/POS Command Adapter
|
|
50
|
+
* Uses ESC ! for character sizing (max 2x2) for better compatibility
|
|
51
|
+
*/
|
|
52
|
+
class ESCPOSCommandAdapter {
|
|
53
|
+
getName() {
|
|
54
|
+
return "ESC/POS";
|
|
55
|
+
}
|
|
56
|
+
getMaxCharacterSize() {
|
|
57
|
+
// ESC ! command supports up to 2x2 for compatibility
|
|
58
|
+
// Note: GS ! supports up to 8x8, but ESC ! is more widely supported
|
|
59
|
+
return { width: 2, height: 2 };
|
|
60
|
+
}
|
|
61
|
+
getInitCommand() {
|
|
62
|
+
const commands = [];
|
|
63
|
+
// ESC @ - Reset printer to default state
|
|
64
|
+
commands.push(...ESCPOS.INIT);
|
|
65
|
+
// GS P x y - Set horizontal and vertical motion units
|
|
66
|
+
// Set both to 203 DPI (standard thermal printer resolution)
|
|
67
|
+
// This ensures GS W and other commands use 1/203 inch per unit
|
|
68
|
+
commands.push(0x1D, 0x50, 203, 203);
|
|
69
|
+
// GS W nL nH - Set printing area width
|
|
70
|
+
// For 80mm paper at 203 DPI: 80mm ≈ 3.15" × 203 = 640 dots
|
|
71
|
+
// Using 640 dots to match physical paper width
|
|
72
|
+
const width = 640;
|
|
73
|
+
commands.push(0x1D, 0x57, width & 0xFF, (width >> 8) & 0xFF);
|
|
74
|
+
return commands;
|
|
75
|
+
}
|
|
76
|
+
getAlignCommand(align) {
|
|
77
|
+
// ESC a n - Set text alignment (n: 0=left, 1=center, 2=right)
|
|
78
|
+
switch (align) {
|
|
79
|
+
case "left":
|
|
80
|
+
return ESCPOS.ALIGN_LEFT;
|
|
81
|
+
case "center":
|
|
82
|
+
return ESCPOS.ALIGN_CENTER;
|
|
83
|
+
case "right":
|
|
84
|
+
return ESCPOS.ALIGN_RIGHT;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
getCharacterSizeCommand(width, height, bold) {
|
|
88
|
+
/**
|
|
89
|
+
* ESC ! n - Select print mode
|
|
90
|
+
* Uses the calculateCharacterSize function from escpos.ts
|
|
91
|
+
* This provides character sizing up to 2x2 with optional bold
|
|
92
|
+
*/
|
|
93
|
+
return ESCPOS.calculateCharacterSize(width, height, bold);
|
|
94
|
+
}
|
|
95
|
+
getLineSpacingCommand(dots) {
|
|
96
|
+
if (dots === undefined) {
|
|
97
|
+
// ESC 2 - Reset to default spacing (1/6 inch)
|
|
98
|
+
return ESCPOS.LINE_SPACING_DEFAULT_ALT;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// ESC 3 n - Set line spacing to n dots
|
|
102
|
+
return ESCPOS.setLineSpacing(dots);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
getCutCommand(type, feedLines) {
|
|
106
|
+
const commands = [];
|
|
107
|
+
// Feed paper if requested
|
|
108
|
+
if (feedLines && feedLines > 0) {
|
|
109
|
+
commands.push(...this.getFeedLinesCommand(feedLines));
|
|
110
|
+
}
|
|
111
|
+
// Cut command - using commands from escpos.ts
|
|
112
|
+
if (type === "full") {
|
|
113
|
+
// ESC i - Full cut
|
|
114
|
+
commands.push(...ESCPOS.CUT_FULL_ESC);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// ESC m - Partial cut
|
|
118
|
+
commands.push(...ESCPOS.CUT_PARTIAL_ESC);
|
|
119
|
+
}
|
|
120
|
+
return commands;
|
|
121
|
+
}
|
|
122
|
+
getQRCodeCommand(data, size) {
|
|
123
|
+
// Use the generateQRCode function from escpos.ts
|
|
124
|
+
return ESCPOS.generateQRCode(data, size);
|
|
125
|
+
}
|
|
126
|
+
getRasterImageCommand(imageData, width, height) {
|
|
127
|
+
// Use the generateRasterImage function from escpos.ts
|
|
128
|
+
return ESCPOS.generateRasterImage(imageData, width, height);
|
|
129
|
+
}
|
|
130
|
+
getLineFeedCommand(lines = 1) {
|
|
131
|
+
// LF - Line feed (0x0A)
|
|
132
|
+
// Repeat LF command for multiple lines
|
|
133
|
+
const commands = [];
|
|
134
|
+
for (let i = 0; i < lines; i++) {
|
|
135
|
+
commands.push(...ESCPOS.LINE_FEED);
|
|
136
|
+
}
|
|
137
|
+
return commands;
|
|
138
|
+
}
|
|
139
|
+
getFeedLinesCommand(lines) {
|
|
140
|
+
// ESC d n - Print and feed n lines
|
|
141
|
+
return ESCPOS.feedLines(lines);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.ESCPOSCommandAdapter = ESCPOSCommandAdapter;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Adapters
|
|
3
|
+
*
|
|
4
|
+
* Provides printer protocol abstraction for different command sets:
|
|
5
|
+
* - ESC/POS: Standard thermal printer protocol
|
|
6
|
+
* - ESC/Bematech: Bematech-specific protocol
|
|
7
|
+
*/
|
|
8
|
+
export { CommandAdapter, CharacterSize } from './types';
|
|
9
|
+
export { ESCPOSCommandAdapter } from './escpos-adapter';
|
|
10
|
+
export { ESCBematechCommandAdapter } from './escbematech-adapter';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/command-adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Command Adapters
|
|
4
|
+
*
|
|
5
|
+
* Provides printer protocol abstraction for different command sets:
|
|
6
|
+
* - ESC/POS: Standard thermal printer protocol
|
|
7
|
+
* - ESC/Bematech: Bematech-specific protocol
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ESCBematechCommandAdapter = exports.ESCPOSCommandAdapter = void 0;
|
|
11
|
+
var escpos_adapter_1 = require("./escpos-adapter");
|
|
12
|
+
Object.defineProperty(exports, "ESCPOSCommandAdapter", { enumerable: true, get: function () { return escpos_adapter_1.ESCPOSCommandAdapter; } });
|
|
13
|
+
var escbematech_adapter_1 = require("./escbematech-adapter");
|
|
14
|
+
Object.defineProperty(exports, "ESCBematechCommandAdapter", { enumerable: true, get: function () { return escbematech_adapter_1.ESCBematechCommandAdapter; } });
|