@thermal-label/brother-ql-core 0.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/LICENSE +21 -0
- package/README.md +23 -0
- package/dist/__tests__/devices.test.d.ts +2 -0
- package/dist/__tests__/devices.test.d.ts.map +1 -0
- package/dist/__tests__/devices.test.js +63 -0
- package/dist/__tests__/devices.test.js.map +1 -0
- package/dist/__tests__/media.test.d.ts +2 -0
- package/dist/__tests__/media.test.d.ts.map +1 -0
- package/dist/__tests__/media.test.js +62 -0
- package/dist/__tests__/media.test.js.map +1 -0
- package/dist/__tests__/protocol.test.d.ts +2 -0
- package/dist/__tests__/protocol.test.d.ts.map +1 -0
- package/dist/__tests__/protocol.test.js +202 -0
- package/dist/__tests__/protocol.test.js.map +1 -0
- package/dist/__tests__/status.test.d.ts +2 -0
- package/dist/__tests__/status.test.d.ts.map +1 -0
- package/dist/__tests__/status.test.js +74 -0
- package/dist/__tests__/status.test.js.map +1 -0
- package/dist/devices.d.ts +255 -0
- package/dist/devices.d.ts.map +1 -0
- package/dist/devices.js +260 -0
- package/dist/devices.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/media.d.ts +5 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +247 -0
- package/dist/media.js.map +1 -0
- package/dist/protocol.d.ts +17 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +173 -0
- package/dist/protocol.js.map +1 -0
- package/dist/status.d.ts +4 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +61 -0
- package/dist/status.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +71 -0
- package/src/__tests__/devices.test.ts +73 -0
- package/src/__tests__/media.test.ts +70 -0
- package/src/__tests__/protocol.test.ts +241 -0
- package/src/__tests__/status.test.ts +95 -0
- package/src/devices.ts +263 -0
- package/src/index.ts +22 -0
- package/src/media.ts +250 -0
- package/src/protocol.ts +213 -0
- package/src/status.ts +67 -0
- package/src/types.ts +77 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mannes Brak
|
|
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,23 @@
|
|
|
1
|
+
# @thermal-label/brother-ql-core
|
|
2
|
+
|
|
3
|
+
Protocol encoding, device registry, and media registry for Brother QL label printers.
|
|
4
|
+
|
|
5
|
+
> Consumers rarely import this package directly — use `@thermal-label/brother-ql-node` (Node.js) or `@thermal-label/brother-ql-web` (browser) instead. This package is for porting or advanced use cases.
|
|
6
|
+
|
|
7
|
+
## Key Exports
|
|
8
|
+
|
|
9
|
+
- `encodeJob(pages, options?)` — encode a complete print job to a `Uint8Array` byte stream
|
|
10
|
+
- `DEVICES` — registry of all supported Brother QL devices
|
|
11
|
+
- `MEDIA` — registry of all supported label media
|
|
12
|
+
- `findDevice(vid, pid)` — look up a device descriptor by USB VID+PID
|
|
13
|
+
- `findMedia(id)` — look up a media descriptor by ID
|
|
14
|
+
- `renderText`, `renderImage` — re-exported from `@mbtech-nl/bitmap`
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
- Node.js `>=24.0.0`
|
|
19
|
+
- Runs in browser and Node.js — no Node.js built-ins used
|
|
20
|
+
|
|
21
|
+
## License
|
|
22
|
+
|
|
23
|
+
MIT © Mannes Brak
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devices.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/devices.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { DEVICES, findDevice, isMassStorageMode } from '../devices.js';
|
|
3
|
+
describe('findDevice', () => {
|
|
4
|
+
it('returns correct descriptor for QL-820NWB', () => {
|
|
5
|
+
const dev = findDevice(0x04f9, 0x20a7);
|
|
6
|
+
expect(dev).toBeDefined();
|
|
7
|
+
expect(dev.name).toBe('QL-820NWB');
|
|
8
|
+
expect(dev.twoColor).toBe(true);
|
|
9
|
+
});
|
|
10
|
+
it('returns correct descriptor for QL-820NWBc', () => {
|
|
11
|
+
const dev = findDevice(0x04f9, 0x209d);
|
|
12
|
+
expect(dev).toBeDefined();
|
|
13
|
+
expect(dev.name).toBe('QL-820NWBc');
|
|
14
|
+
expect(dev.twoColor).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
it('returns correct descriptor for QL-500', () => {
|
|
17
|
+
const dev = findDevice(0x04f9, 0x2013);
|
|
18
|
+
expect(dev).toBeDefined();
|
|
19
|
+
expect(dev.name).toBe('QL-500');
|
|
20
|
+
expect(dev.autocut).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
it('returns undefined for unknown PID', () => {
|
|
23
|
+
expect(findDevice(0x04f9, 0x9999)).toBeUndefined();
|
|
24
|
+
});
|
|
25
|
+
it('returns undefined for unknown VID', () => {
|
|
26
|
+
expect(findDevice(0x1234, 0x20a7)).toBeUndefined();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe('isMassStorageMode', () => {
|
|
30
|
+
it('returns true for 0x20AA (QL-1100 mass storage)', () => {
|
|
31
|
+
expect(isMassStorageMode(0x20aa)).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
it('returns true for 0x20AB (QL-1110NWB mass storage)', () => {
|
|
34
|
+
expect(isMassStorageMode(0x20ab)).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
it('returns false for all printer-class PIDs', () => {
|
|
37
|
+
for (const dev of Object.values(DEVICES)) {
|
|
38
|
+
expect(isMassStorageMode(dev.pid)).toBe(false);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe('Device registry invariants', () => {
|
|
43
|
+
it('every two-color device has bytesPerRow 90', () => {
|
|
44
|
+
for (const dev of Object.values(DEVICES)) {
|
|
45
|
+
if (dev.twoColor) {
|
|
46
|
+
expect(dev.bytesPerRow).toBe(90);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
it('every device with headPins 1296 has bytesPerRow 162', () => {
|
|
51
|
+
for (const dev of Object.values(DEVICES)) {
|
|
52
|
+
if (dev.headPins === 1296) {
|
|
53
|
+
expect(dev.bytesPerRow).toBe(162);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
it('every device has bluetooth: false (BT out of scope)', () => {
|
|
58
|
+
for (const dev of Object.values(DEVICES)) {
|
|
59
|
+
expect(dev.bluetooth).toBe(false);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
//# sourceMappingURL=devices.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devices.test.js","sourceRoot":"","sources":["../../src/__tests__/devices.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/media.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { MEDIA, findMedia, findMediaByWidth } from '../media.js';
|
|
3
|
+
describe('findMedia', () => {
|
|
4
|
+
it('returns correct descriptor for 62mm continuous (ID 259)', () => {
|
|
5
|
+
const m = findMedia(259);
|
|
6
|
+
expect(m).toBeDefined();
|
|
7
|
+
expect(m.widthMm).toBe(62);
|
|
8
|
+
expect(m.type).toBe('continuous');
|
|
9
|
+
expect(m.lengthMm).toBe(0);
|
|
10
|
+
});
|
|
11
|
+
it('returns correct descriptor for 62x29mm die-cut (ID 274)', () => {
|
|
12
|
+
const m = findMedia(274);
|
|
13
|
+
expect(m).toBeDefined();
|
|
14
|
+
expect(m.type).toBe('die-cut');
|
|
15
|
+
expect(m.lengthMm).toBeGreaterThan(0);
|
|
16
|
+
});
|
|
17
|
+
it('returns undefined for unknown ID', () => {
|
|
18
|
+
expect(findMedia(9999)).toBeUndefined();
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('findMediaByWidth', () => {
|
|
22
|
+
it('returns all 62mm continuous options', () => {
|
|
23
|
+
const results = findMediaByWidth(62, 'continuous');
|
|
24
|
+
expect(results.length).toBeGreaterThan(0);
|
|
25
|
+
for (const m of results) {
|
|
26
|
+
expect(m.widthMm).toBe(62);
|
|
27
|
+
expect(m.type).toBe('continuous');
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
it('returns die-cut for 62mm die-cut', () => {
|
|
31
|
+
const results = findMediaByWidth(62, 'die-cut');
|
|
32
|
+
expect(results.length).toBeGreaterThan(0);
|
|
33
|
+
for (const m of results) {
|
|
34
|
+
expect(m.type).toBe('die-cut');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
it('returns empty array for unknown width', () => {
|
|
38
|
+
expect(findMediaByWidth(999, 'continuous')).toHaveLength(0);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe('Media registry invariants', () => {
|
|
42
|
+
it('die-cut media has non-zero lengthMm', () => {
|
|
43
|
+
for (const m of Object.values(MEDIA)) {
|
|
44
|
+
if (m.type === 'die-cut') {
|
|
45
|
+
expect(m.lengthMm).toBeGreaterThan(0);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
it('continuous media has lengthMm === 0', () => {
|
|
50
|
+
for (const m of Object.values(MEDIA)) {
|
|
51
|
+
if (m.type === 'continuous') {
|
|
52
|
+
expect(m.lengthMm).toBe(0);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
it('all IDs are unique', () => {
|
|
57
|
+
const ids = Object.values(MEDIA).map(m => m.id);
|
|
58
|
+
const unique = new Set(ids);
|
|
59
|
+
expect(unique.size).toBe(ids.length);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=media.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.test.js","sourceRoot":"","sources":["../../src/__tests__/media.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/protocol.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { createBitmap } from '@mbtech-nl/bitmap';
|
|
3
|
+
import { buildInvalidate, buildInitialize, buildRasterMode, buildRasterRow, buildPrintCommand, buildPrintInfo, buildZeroRow, buildCompression, buildStatusNotification, buildVariousMode, buildExpandedMode, encodeJob, } from '../protocol.js';
|
|
4
|
+
import {} from '../types.js';
|
|
5
|
+
import { MEDIA } from '../media.js';
|
|
6
|
+
describe('buildInvalidate', () => {
|
|
7
|
+
it('returns exactly 200 zero bytes', () => {
|
|
8
|
+
const buf = buildInvalidate();
|
|
9
|
+
expect(buf.length).toBe(200);
|
|
10
|
+
expect(buf.every(b => b === 0)).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
describe('buildInitialize', () => {
|
|
14
|
+
it('returns [0x1B, 0x40]', () => {
|
|
15
|
+
expect(Array.from(buildInitialize())).toEqual([0x1b, 0x40]);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe('buildRasterRow', () => {
|
|
19
|
+
it('single-color black: [0x67][0x00][len][data]', () => {
|
|
20
|
+
const payload = new Uint8Array(90).fill(0xaa);
|
|
21
|
+
const row = buildRasterRow(payload, 'black');
|
|
22
|
+
expect(row[0]).toBe(0x67);
|
|
23
|
+
expect(row[1]).toBe(0x00);
|
|
24
|
+
expect(row[2]).toBe(90);
|
|
25
|
+
expect(row.length).toBe(93);
|
|
26
|
+
});
|
|
27
|
+
it('two-color black: [0x77][0x01][len][data]', () => {
|
|
28
|
+
const payload = new Uint8Array(90);
|
|
29
|
+
const row = buildRasterRow(payload, 'black', true);
|
|
30
|
+
expect(row[0]).toBe(0x77);
|
|
31
|
+
expect(row[1]).toBe(0x01);
|
|
32
|
+
expect(row[2]).toBe(90);
|
|
33
|
+
});
|
|
34
|
+
it('two-color red: [0x77][0x02][len][data]', () => {
|
|
35
|
+
const payload = new Uint8Array(90);
|
|
36
|
+
const row = buildRasterRow(payload, 'red', true);
|
|
37
|
+
expect(row[0]).toBe(0x77);
|
|
38
|
+
expect(row[1]).toBe(0x02);
|
|
39
|
+
expect(row[2]).toBe(90);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe('buildPrintCommand', () => {
|
|
43
|
+
it('last page returns [0x1A]', () => {
|
|
44
|
+
expect(Array.from(buildPrintCommand(true))).toEqual([0x1a]);
|
|
45
|
+
});
|
|
46
|
+
it('non-last page returns [0x0C]', () => {
|
|
47
|
+
expect(Array.from(buildPrintCommand(false))).toEqual([0x0c]);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe('buildPrintInfo', () => {
|
|
51
|
+
it('byte 5 contains correct media width, bytes 7-8 correct row count LE', () => {
|
|
52
|
+
const media = MEDIA[259]; // 62mm continuous
|
|
53
|
+
const buf = buildPrintInfo(media, 200, 0);
|
|
54
|
+
expect(buf[5]).toBe(62); // widthMm
|
|
55
|
+
// rowCount 200 = 0xC8 at bytes 7-8
|
|
56
|
+
expect(buf[7]).toBe(0xc8);
|
|
57
|
+
expect(buf[8]).toBe(0x00);
|
|
58
|
+
});
|
|
59
|
+
it('page index is at byte 9', () => {
|
|
60
|
+
const media = MEDIA[259];
|
|
61
|
+
const buf = buildPrintInfo(media, 100, 3);
|
|
62
|
+
expect(buf[9]).toBe(3);
|
|
63
|
+
});
|
|
64
|
+
it('die-cut media sets mediaType byte to 0x0b', () => {
|
|
65
|
+
const media = MEDIA[271]; // 29x90mm die-cut
|
|
66
|
+
const buf = buildPrintInfo(media, 100, 0);
|
|
67
|
+
expect(buf[4]).toBe(0x0b);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe('encodeJob', () => {
|
|
71
|
+
const media62 = MEDIA[259]; // 62mm, 696 printAreaDots
|
|
72
|
+
function makePage(widthPx, heightPx) {
|
|
73
|
+
const bitmap = createBitmap(widthPx, heightPx);
|
|
74
|
+
return { bitmap, media: media62 };
|
|
75
|
+
}
|
|
76
|
+
it('single page: contains ESC i a + 200 zero invalidate, ends with 0x1A', () => {
|
|
77
|
+
const page = makePage(696, 50);
|
|
78
|
+
const buf = encodeJob([page]);
|
|
79
|
+
// Starts with ESC i a 01 (raster mode, 4 bytes) then 200 zero invalidate bytes
|
|
80
|
+
expect(buf[0]).toBe(0x1b);
|
|
81
|
+
expect(buf[1]).toBe(0x69);
|
|
82
|
+
expect(buf[2]).toBe(0x61);
|
|
83
|
+
expect(buf[3]).toBe(0x01);
|
|
84
|
+
for (let i = 4; i < 204; i++)
|
|
85
|
+
expect(buf[i]).toBe(0);
|
|
86
|
+
expect(buf.at(-1)).toBe(0x1a);
|
|
87
|
+
});
|
|
88
|
+
it('two-page job: second page has control codes, ends with 0x1A', () => {
|
|
89
|
+
const page1 = makePage(696, 10);
|
|
90
|
+
const page2 = makePage(696, 10);
|
|
91
|
+
const buf = encodeJob([page1, page2]);
|
|
92
|
+
expect(buf.at(-1)).toBe(0x1a);
|
|
93
|
+
// 0x0C should appear as the inter-page print command somewhere before the last byte
|
|
94
|
+
const printCmds = [];
|
|
95
|
+
for (let i = 0; i < buf.length; i++) {
|
|
96
|
+
if (buf[i] === 0x0c)
|
|
97
|
+
printCmds.push(i);
|
|
98
|
+
}
|
|
99
|
+
expect(printCmds.length).toBeGreaterThan(0);
|
|
100
|
+
});
|
|
101
|
+
it('two-color job: black rows [0x77,0x01,len], red rows [0x77,0x02,len], interleaved', () => {
|
|
102
|
+
const bitmap = createBitmap(696, 5);
|
|
103
|
+
const redBitmap = createBitmap(696, 5);
|
|
104
|
+
const page = { bitmap, redBitmap, media: media62 };
|
|
105
|
+
const buf = encodeJob([page]);
|
|
106
|
+
const rowLen = 90;
|
|
107
|
+
const blackRows = [];
|
|
108
|
+
const redRows = [];
|
|
109
|
+
for (let i = 0; i < buf.length - 2; i++) {
|
|
110
|
+
if (buf[i] === 0x77 && buf[i + 1] === 0x01 && buf[i + 2] === rowLen)
|
|
111
|
+
blackRows.push(i);
|
|
112
|
+
if (buf[i] === 0x77 && buf[i + 1] === 0x02 && buf[i + 2] === rowLen)
|
|
113
|
+
redRows.push(i);
|
|
114
|
+
}
|
|
115
|
+
expect(blackRows.length).toBe(5);
|
|
116
|
+
expect(redRows.length).toBe(5);
|
|
117
|
+
// Verify interleaving: each black row is immediately followed by a red row (93 bytes apart)
|
|
118
|
+
for (let r = 0; r < 5; r++) {
|
|
119
|
+
expect(redRows[r] - blackRows[r]).toBe(93); // 3 header + 90 data
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
it('two-color job: throws if red bitmap dimensions mismatch', () => {
|
|
123
|
+
const bitmap = createBitmap(720, 5);
|
|
124
|
+
const redBitmap = createBitmap(720, 10); // different height
|
|
125
|
+
const page = { bitmap, redBitmap, media: media62 };
|
|
126
|
+
expect(() => encodeJob([page])).toThrow('identical dimensions');
|
|
127
|
+
});
|
|
128
|
+
it('copies option repeats the job', () => {
|
|
129
|
+
const page = makePage(720, 2);
|
|
130
|
+
const buf1 = encodeJob([page]);
|
|
131
|
+
const buf2 = encodeJob([page], { copies: 2 });
|
|
132
|
+
expect(buf2.length).toBeGreaterThan(buf1.length);
|
|
133
|
+
});
|
|
134
|
+
it('compress option includes compression command [0x4D, 0x02]', () => {
|
|
135
|
+
const page = { ...makePage(696, 5), options: { compress: true } };
|
|
136
|
+
const buf = encodeJob([page]);
|
|
137
|
+
let found = false;
|
|
138
|
+
for (let i = 0; i < buf.length - 1; i++) {
|
|
139
|
+
if (buf[i] === 0x4d && buf[i + 1] === 0x02) {
|
|
140
|
+
found = true;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
expect(found).toBe(true);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
describe('buildRasterMode', () => {
|
|
148
|
+
it('returns correct bytes', () => {
|
|
149
|
+
expect(Array.from(buildRasterMode())).toEqual([0x1b, 0x69, 0x61, 0x01]);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
describe('buildStatusNotification', () => {
|
|
153
|
+
it('disabled returns [0x1B, 0x69, 0x21, 0x00]', () => {
|
|
154
|
+
expect(Array.from(buildStatusNotification(false))).toEqual([0x1b, 0x69, 0x21, 0x00]);
|
|
155
|
+
});
|
|
156
|
+
it('enabled returns [0x1B, 0x69, 0x21, 0x01]', () => {
|
|
157
|
+
expect(Array.from(buildStatusNotification(true))).toEqual([0x1b, 0x69, 0x21, 0x01]);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
describe('buildVariousMode', () => {
|
|
161
|
+
it('autoCut=true returns 0x40 flag', () => {
|
|
162
|
+
expect(buildVariousMode(true)[3]).toBe(0x40);
|
|
163
|
+
});
|
|
164
|
+
it('autoCut=false returns 0x00 flag', () => {
|
|
165
|
+
expect(buildVariousMode(false)[3]).toBe(0x00);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
describe('buildExpandedMode', () => {
|
|
169
|
+
it('cutAtEnd=true sets bit 3', () => {
|
|
170
|
+
expect((buildExpandedMode(true, false)[3] ?? 0) & 0x08).toBe(0x08);
|
|
171
|
+
});
|
|
172
|
+
it('highRes=true sets bit 4', () => {
|
|
173
|
+
expect((buildExpandedMode(false, true)[3] ?? 0) & 0x10).toBe(0x10);
|
|
174
|
+
});
|
|
175
|
+
it('twoColor=true sets bit 0', () => {
|
|
176
|
+
expect((buildExpandedMode(false, false, true)[3] ?? 0) & 0x01).toBe(0x01);
|
|
177
|
+
});
|
|
178
|
+
it('both false returns 0x00 flags', () => {
|
|
179
|
+
expect(buildExpandedMode(false, false)[3]).toBe(0x00);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
describe('buildPrintInfo twoColor flag', () => {
|
|
183
|
+
it('always uses 0xCE valid flags (Python brother_ql behaviour for two-color capable models)', () => {
|
|
184
|
+
const media = MEDIA[259];
|
|
185
|
+
const buf = buildPrintInfo(media, 100, 0);
|
|
186
|
+
expect(buf[3]).toBe(0xce);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
describe('buildZeroRow', () => {
|
|
190
|
+
it('returns [0x5A]', () => {
|
|
191
|
+
expect(Array.from(buildZeroRow())).toEqual([0x5a]);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
describe('buildCompression', () => {
|
|
195
|
+
it('enabled returns [0x4D, 0x02]', () => {
|
|
196
|
+
expect(Array.from(buildCompression(true))).toEqual([0x4d, 0x02]);
|
|
197
|
+
});
|
|
198
|
+
it('disabled returns [0x4D, 0x00]', () => {
|
|
199
|
+
expect(Array.from(buildCompression(false))).toEqual([0x4d, 0x00]);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
//# sourceMappingURL=protocol.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.test.js","sourceRoot":"","sources":["../../src/__tests__/protocol.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/status.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { parseStatus, STATUS_REQUEST } from '../status.js';
|
|
3
|
+
function makeStatusBytes(overrides) {
|
|
4
|
+
const bytes = new Uint8Array(32);
|
|
5
|
+
bytes[0] = 0x80;
|
|
6
|
+
bytes[1] = 0x20;
|
|
7
|
+
bytes[2] = 0x42;
|
|
8
|
+
bytes[3] = 0x30;
|
|
9
|
+
bytes[8] = overrides?.errInfo1 ?? 0;
|
|
10
|
+
bytes[9] = overrides?.errInfo2 ?? 0;
|
|
11
|
+
bytes[10] = overrides?.mediaWidthMm ?? 62;
|
|
12
|
+
bytes[11] = overrides?.mediaTypeByte ?? 0x0a;
|
|
13
|
+
bytes[17] = overrides?.mediaLengthMm ?? 0;
|
|
14
|
+
bytes[18] = overrides?.statusType ?? 0x00;
|
|
15
|
+
return bytes;
|
|
16
|
+
}
|
|
17
|
+
describe('parseStatus', () => {
|
|
18
|
+
it('throws on short input', () => {
|
|
19
|
+
expect(() => parseStatus(new Uint8Array(10))).toThrow('too short');
|
|
20
|
+
});
|
|
21
|
+
it('returns ready=true with no errors', () => {
|
|
22
|
+
const status = parseStatus(makeStatusBytes());
|
|
23
|
+
expect(status.ready).toBe(true);
|
|
24
|
+
expect(status.errors).toHaveLength(0);
|
|
25
|
+
});
|
|
26
|
+
it('parses media width and type', () => {
|
|
27
|
+
const status = parseStatus(makeStatusBytes({ mediaWidthMm: 62, mediaTypeByte: 0x0a }));
|
|
28
|
+
expect(status.mediaWidthMm).toBe(62);
|
|
29
|
+
expect(status.mediaType).toBe('continuous');
|
|
30
|
+
});
|
|
31
|
+
it('parses media length from byte 17 (0 for continuous, mm for die-cut)', () => {
|
|
32
|
+
const cont = parseStatus(makeStatusBytes({ mediaLengthMm: 0 }));
|
|
33
|
+
expect(cont.mediaLengthMm).toBe(0);
|
|
34
|
+
const diecut = parseStatus(makeStatusBytes({ mediaTypeByte: 0x0b, mediaLengthMm: 90 }));
|
|
35
|
+
expect(diecut.mediaLengthMm).toBe(90);
|
|
36
|
+
});
|
|
37
|
+
it('parses die-cut media type', () => {
|
|
38
|
+
const status = parseStatus(makeStatusBytes({ mediaTypeByte: 0x0b }));
|
|
39
|
+
expect(status.mediaType).toBe('die-cut');
|
|
40
|
+
});
|
|
41
|
+
it('returns null mediaType for unknown byte', () => {
|
|
42
|
+
const status = parseStatus(makeStatusBytes({ mediaTypeByte: 0xff }));
|
|
43
|
+
expect(status.mediaType).toBeNull();
|
|
44
|
+
});
|
|
45
|
+
it('parses error info 1 bits', () => {
|
|
46
|
+
const status = parseStatus(makeStatusBytes({ errInfo1: 0b00000001 })); // No media
|
|
47
|
+
expect(status.errors).toContain('No media');
|
|
48
|
+
expect(status.ready).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
it('parses error info 2 bits', () => {
|
|
51
|
+
const status = parseStatus(makeStatusBytes({ errInfo2: 0b00010000 })); // Cover open
|
|
52
|
+
expect(status.errors).toContain('Cover open');
|
|
53
|
+
expect(status.ready).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
it('ready=false when statusType is error (0x02)', () => {
|
|
56
|
+
const status = parseStatus(makeStatusBytes({ statusType: 0x02 }));
|
|
57
|
+
expect(status.ready).toBe(false);
|
|
58
|
+
});
|
|
59
|
+
it('rawBytes contains the full 32-byte input', () => {
|
|
60
|
+
const bytes = makeStatusBytes();
|
|
61
|
+
const status = parseStatus(bytes);
|
|
62
|
+
expect(status.rawBytes).toEqual(bytes);
|
|
63
|
+
});
|
|
64
|
+
it('editorLiteMode is false (detected at discovery time, not from status bytes)', () => {
|
|
65
|
+
const status = parseStatus(makeStatusBytes());
|
|
66
|
+
expect(status.editorLiteMode).toBe(false);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe('STATUS_REQUEST', () => {
|
|
70
|
+
it('is the correct byte sequence', () => {
|
|
71
|
+
expect(Array.from(STATUS_REQUEST)).toEqual([0x1b, 0x69, 0x53]);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=status.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.test.js","sourceRoot":"","sources":["../../src/__tests__/status.test.ts"],"names":[],"mappings":"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"}
|