@bobfrankston/brother-label 1.0.13 → 1.0.14
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 +20 -3
- package/api.d.ts +11 -0
- package/api.d.ts.map +1 -1
- package/api.js +105 -0
- package/api.js.map +1 -1
- package/api.ts +110 -0
- package/cli.js +219 -79
- package/cli.js.map +1 -1
- package/cli.ts +221 -61
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/index.ts +3 -0
- package/package.json +3 -3
- package/brother-print.d.ts +0 -3
- package/brother-print.d.ts.map +0 -1
- package/brother-print.js +0 -629
- package/brother-print.js.map +0 -1
- package/brother-print.ts +0 -697
package/cli.ts
CHANGED
|
@@ -6,18 +6,21 @@
|
|
|
6
6
|
|
|
7
7
|
import * as fs from "fs";
|
|
8
8
|
import * as path from "path";
|
|
9
|
-
import { program } from "commander";
|
|
10
9
|
import {
|
|
11
10
|
print,
|
|
12
11
|
render,
|
|
12
|
+
renderSegments,
|
|
13
|
+
printSegments,
|
|
13
14
|
getConfig,
|
|
14
15
|
setConfig,
|
|
15
16
|
getConfigPath,
|
|
16
17
|
listPrinters,
|
|
17
18
|
TapeSize,
|
|
18
19
|
PrintOptions,
|
|
20
|
+
Segment,
|
|
19
21
|
} from "./api.js";
|
|
20
22
|
|
|
23
|
+
const VERSION = "1.0.13";
|
|
21
24
|
const VALID_TAPES: TapeSize[] = [6, 9, 12, 18, 24];
|
|
22
25
|
|
|
23
26
|
function parseTape(value: string): TapeSize {
|
|
@@ -85,53 +88,165 @@ function buildPrintOptions(input: string, opts: { tape?: string; printer?: strin
|
|
|
85
88
|
return options;
|
|
86
89
|
}
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
91
|
+
interface ParsedArgs {
|
|
92
|
+
command: string | null;
|
|
93
|
+
opts: Record<string, string | boolean>;
|
|
94
|
+
segments: Segment[];
|
|
95
|
+
input: string | null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Valued options: flag name(s) → canonical key
|
|
99
|
+
const VALUED_OPTIONS: [string[], string][] = [
|
|
100
|
+
[["-tape"], "tape"],
|
|
101
|
+
[["-p", "-printer"], "printer"],
|
|
102
|
+
[["-o", "-output"], "output"],
|
|
103
|
+
[["-a", "-aspect"], "aspect"],
|
|
104
|
+
[["-H", "-height"], "height"],
|
|
105
|
+
[["-s", "-sp", "-space"], "space"],
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
// Boolean flags: flag name(s) → canonical key
|
|
109
|
+
const BOOLEAN_FLAGS: [string[], string][] = [
|
|
110
|
+
[["-w", "-html"], "html"],
|
|
111
|
+
[["-i", "-image"], "image"],
|
|
112
|
+
[["-t"], "text"],
|
|
113
|
+
[["-help", "-h"], "help"],
|
|
114
|
+
[["-version", "-v"], "version"],
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
function parseArgs(argv: string[]): ParsedArgs {
|
|
118
|
+
const args = argv.slice(2).map(a => a.startsWith("--") ? a.slice(1) : a);
|
|
119
|
+
const command: string | null = null;
|
|
120
|
+
const opts: Record<string, string | boolean> = {};
|
|
121
|
+
const segments: Segment[] = [];
|
|
122
|
+
let input: string | null = null;
|
|
123
|
+
let i = 0;
|
|
124
|
+
|
|
125
|
+
while (i < args.length) {
|
|
126
|
+
const arg = args[i];
|
|
127
|
+
|
|
128
|
+
// Segment flags: -text <value>, -qr <value>
|
|
129
|
+
if ((arg === "-text" || arg === "-qr") && i + 1 < args.length) {
|
|
130
|
+
segments.push({ type: arg === "-text" ? "text" : "qr", value: args[i + 1] });
|
|
131
|
+
i += 2;
|
|
132
|
+
continue;
|
|
108
133
|
}
|
|
109
134
|
|
|
110
|
-
|
|
111
|
-
|
|
135
|
+
// Valued options
|
|
136
|
+
let matched = false;
|
|
137
|
+
for (const [names, key] of VALUED_OPTIONS) {
|
|
138
|
+
if (names.includes(arg) && i + 1 < args.length) {
|
|
139
|
+
opts[key] = args[i + 1];
|
|
140
|
+
i += 2;
|
|
141
|
+
matched = true;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (matched) continue;
|
|
112
146
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const result = await print(options);
|
|
121
|
-
const tape = options.tape ?? getConfig().defaultTape ?? 24;
|
|
122
|
-
console.log(`Printed on ${tape}mm tape`);
|
|
147
|
+
// Boolean flags
|
|
148
|
+
for (const [names, key] of BOOLEAN_FLAGS) {
|
|
149
|
+
if (names.includes(arg)) {
|
|
150
|
+
opts[key] = true;
|
|
151
|
+
i++;
|
|
152
|
+
matched = true;
|
|
153
|
+
break;
|
|
123
154
|
}
|
|
124
|
-
} catch (err) {
|
|
125
|
-
console.error(`Error: ${(err as Error).message}`);
|
|
126
|
-
process.exit(1);
|
|
127
155
|
}
|
|
128
|
-
|
|
156
|
+
if (matched) continue;
|
|
157
|
+
|
|
158
|
+
// Subcommands
|
|
159
|
+
if ((arg === "list" || arg === "config") && command === null && input === null) {
|
|
160
|
+
return { ...parseRest(args, i), command: arg };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Bare string → positional input (first one wins)
|
|
164
|
+
if (input === null) {
|
|
165
|
+
input = arg;
|
|
166
|
+
}
|
|
167
|
+
i++;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return { command, opts, segments, input };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// After recognizing a subcommand, parse the rest for that subcommand's options
|
|
174
|
+
function parseRest(args: string[], startIndex: number): ParsedArgs {
|
|
175
|
+
const opts: Record<string, string | boolean> = {};
|
|
176
|
+
const segments: Segment[] = [];
|
|
177
|
+
let input: string | null = null;
|
|
178
|
+
let i = startIndex + 1;
|
|
179
|
+
|
|
180
|
+
while (i < args.length) {
|
|
181
|
+
const arg = args[i];
|
|
182
|
+
let matched = false;
|
|
183
|
+
for (const [names, key] of VALUED_OPTIONS) {
|
|
184
|
+
if (names.includes(arg) && i + 1 < args.length) {
|
|
185
|
+
opts[key] = args[i + 1];
|
|
186
|
+
i += 2;
|
|
187
|
+
matched = true;
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (matched) continue;
|
|
192
|
+
|
|
193
|
+
for (const [names, key] of BOOLEAN_FLAGS) {
|
|
194
|
+
if (names.includes(arg)) {
|
|
195
|
+
opts[key] = true;
|
|
196
|
+
i++;
|
|
197
|
+
matched = true;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (matched) continue;
|
|
202
|
+
|
|
203
|
+
if (input === null) input = arg;
|
|
204
|
+
i++;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return { command: null, opts, segments, input };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function showHelp(): void {
|
|
211
|
+
console.log(`Brother Label Printer CLI v${VERSION}
|
|
212
|
+
|
|
213
|
+
Usage:
|
|
214
|
+
brother-print [options] <input> Print text, file, or image
|
|
215
|
+
brother-print -text <v> -qr <v> ... Print ordered segments
|
|
216
|
+
brother-print list List available printers
|
|
217
|
+
brother-print config Show/set configuration
|
|
218
|
+
|
|
219
|
+
Options:
|
|
220
|
+
-tape <size> Tape size: 6, 9, 12, 18, 24 (mm)
|
|
221
|
+
-p, -printer <n> Printer name
|
|
222
|
+
-o, -output <file> Save to file instead of printing (png, jpg, bmp)
|
|
223
|
+
-a, -aspect <r> Aspect ratio width:height for HTML (e.g., 3.5:2)
|
|
224
|
+
-H, -height <size> Text height: 12mm, .5in, or 50% (of tape height)
|
|
225
|
+
-s, -space <size> Space between segments: 12px, 1mm, .2in
|
|
226
|
+
-t, -text Force input as literal text (or -text <v> for segments)
|
|
227
|
+
-qr <data> QR code segment
|
|
228
|
+
-w, -html Force input as HTML file path
|
|
229
|
+
-i, -image Force input as image file path
|
|
230
|
+
-help Show this help
|
|
231
|
+
-version Show version`);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// --- Main ---
|
|
129
235
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
.
|
|
134
|
-
|
|
236
|
+
async function main(): Promise<void> {
|
|
237
|
+
const parsed = parseArgs(process.argv);
|
|
238
|
+
|
|
239
|
+
if (parsed.opts.help) {
|
|
240
|
+
showHelp();
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (parsed.opts.version) {
|
|
244
|
+
console.log(VERSION);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Subcommands
|
|
249
|
+
if (parsed.command === "list") {
|
|
135
250
|
try {
|
|
136
251
|
const printers = await listPrinters();
|
|
137
252
|
if (printers.length === 0) {
|
|
@@ -144,18 +259,12 @@ program
|
|
|
144
259
|
console.error(`Error: ${(err as Error).message}`);
|
|
145
260
|
process.exit(1);
|
|
146
261
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
.command("config")
|
|
152
|
-
.description("Show or set configuration")
|
|
153
|
-
.option("-t, --tape <size>", "Set default tape size: 6, 9, 12, 18, 24 (mm)")
|
|
154
|
-
.option("-p, --printer <name>", "Set default printer name")
|
|
155
|
-
.action((opts) => {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (parsed.command === "config") {
|
|
156
266
|
try {
|
|
157
|
-
if (!opts.tape && !opts.printer) {
|
|
158
|
-
// Show config
|
|
267
|
+
if (!parsed.opts.tape && !parsed.opts.printer) {
|
|
159
268
|
const config = getConfig();
|
|
160
269
|
console.log("Configuration:");
|
|
161
270
|
console.log(` File: ${getConfigPath()}`);
|
|
@@ -164,21 +273,72 @@ program
|
|
|
164
273
|
console.log("\nValid tape sizes: 6, 9, 12, 18, 24");
|
|
165
274
|
return;
|
|
166
275
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const tape = parseTape(opts.tape);
|
|
276
|
+
if (parsed.opts.tape) {
|
|
277
|
+
const tape = parseTape(parsed.opts.tape as string);
|
|
170
278
|
setConfig({ defaultTape: tape });
|
|
171
279
|
console.log(`Default tape set to: ${tape}mm`);
|
|
172
280
|
}
|
|
281
|
+
if (parsed.opts.printer) {
|
|
282
|
+
setConfig({ defaultPrinter: parsed.opts.printer as string });
|
|
283
|
+
console.log(`Default printer set to: ${parsed.opts.printer}`);
|
|
284
|
+
}
|
|
285
|
+
} catch (err) {
|
|
286
|
+
console.error(`Error: ${(err as Error).message}`);
|
|
287
|
+
process.exit(1);
|
|
288
|
+
}
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
173
291
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
292
|
+
// Multi-segment mode
|
|
293
|
+
if (parsed.segments.length > 0) {
|
|
294
|
+
try {
|
|
295
|
+
const tape = parsed.opts.tape ? parseTape(parsed.opts.tape as string) : undefined;
|
|
296
|
+
if (parsed.opts.output) {
|
|
297
|
+
const buffer = await renderSegments(parsed.segments, tape, parsed.opts.height as string | undefined, parsed.opts.space as string | undefined);
|
|
298
|
+
fs.writeFileSync(parsed.opts.output as string, buffer);
|
|
299
|
+
console.log(`Saved to ${parsed.opts.output}`);
|
|
300
|
+
} else {
|
|
301
|
+
await printSegments(parsed.segments, { tape, printer: parsed.opts.printer as string | undefined, textHeight: parsed.opts.height as string | undefined, space: parsed.opts.space as string | undefined });
|
|
302
|
+
const effectiveTape = tape ?? getConfig().defaultTape ?? 24;
|
|
303
|
+
console.log(`Printed ${parsed.segments.length} segments on ${effectiveTape}mm tape`);
|
|
177
304
|
}
|
|
178
305
|
} catch (err) {
|
|
179
306
|
console.error(`Error: ${(err as Error).message}`);
|
|
180
307
|
process.exit(1);
|
|
181
308
|
}
|
|
182
|
-
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Single input mode
|
|
313
|
+
if (!parsed.input) {
|
|
314
|
+
showHelp();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
try {
|
|
319
|
+
const options = buildPrintOptions(parsed.input, {
|
|
320
|
+
tape: parsed.opts.tape as string | undefined,
|
|
321
|
+
printer: parsed.opts.printer as string | undefined,
|
|
322
|
+
text: parsed.opts.text as boolean | undefined,
|
|
323
|
+
html: parsed.opts.html as boolean | undefined,
|
|
324
|
+
image: parsed.opts.image as boolean | undefined,
|
|
325
|
+
aspect: parsed.opts.aspect as string | undefined,
|
|
326
|
+
height: parsed.opts.height as string | undefined,
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
if (parsed.opts.output) {
|
|
330
|
+
const buffer = await render(options);
|
|
331
|
+
fs.writeFileSync(parsed.opts.output as string, buffer);
|
|
332
|
+
console.log(`Saved to ${parsed.opts.output}`);
|
|
333
|
+
} else {
|
|
334
|
+
await print(options);
|
|
335
|
+
const tape = options.tape ?? getConfig().defaultTape ?? 24;
|
|
336
|
+
console.log(`Printed on ${tape}mm tape`);
|
|
337
|
+
}
|
|
338
|
+
} catch (err) {
|
|
339
|
+
console.error(`Error: ${(err as Error).message}`);
|
|
340
|
+
process.exit(1);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
183
343
|
|
|
184
|
-
|
|
344
|
+
main();
|
package/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Brother Label Printer API
|
|
3
3
|
* @module @bobfrankston/brother-label
|
|
4
4
|
*/
|
|
5
|
-
export { TapeSize, Orientation, PrinterConfig, PrinterInfo, PrintOptions, PrintResult, print, render, getConfig, setConfig, getConfigPath, listPrinters, } from "./api.js";
|
|
5
|
+
export { TapeSize, Orientation, PrinterConfig, PrinterInfo, PrintOptions, PrintResult, Segment, print, render, renderSegments, printSegments, getConfig, setConfig, getConfigPath, listPrinters, } from "./api.js";
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEH,QAAQ,EACR,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEH,QAAQ,EACR,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,WAAW,EACX,OAAO,EAEP,KAAK,EACL,MAAM,EACN,cAAc,EACd,aAAa,EACb,SAAS,EACT,SAAS,EACT,aAAa,EACb,YAAY,GACf,MAAM,UAAU,CAAC"}
|
package/index.js
CHANGED
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO;AASH,YAAY;AACZ,KAAK,EACL,MAAM,EACN,cAAc,EACd,aAAa,EACb,SAAS,EACT,SAAS,EACT,aAAa,EACb,YAAY,GACf,MAAM,UAAU,CAAC","sourcesContent":["/**\r\n * Brother Label Printer API\r\n * @module @bobfrankston/brother-label\r\n */\r\n\r\nexport {\r\n // Types\r\n TapeSize,\r\n Orientation,\r\n PrinterConfig,\r\n PrinterInfo,\r\n PrintOptions,\r\n PrintResult,\r\n Segment,\r\n // Functions\r\n print,\r\n render,\r\n renderSegments,\r\n printSegments,\r\n getConfig,\r\n setConfig,\r\n getConfigPath,\r\n listPrinters,\r\n} from \"./api.js\";\r\n"]}
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/brother-label",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "API and CLI for printing labels on Brother P-touch printers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsc",
|
|
29
29
|
"prepublishOnly": "npm run build",
|
|
30
|
-
"start": "node cli.js"
|
|
30
|
+
"start": "node cli.js",
|
|
31
|
+
"release": "npmglobalize"
|
|
31
32
|
},
|
|
32
33
|
"keywords": [
|
|
33
34
|
"brother",
|
|
@@ -44,7 +45,6 @@
|
|
|
44
45
|
"url": "https://github.com/BobFrankston/brother-label.git"
|
|
45
46
|
},
|
|
46
47
|
"dependencies": {
|
|
47
|
-
"commander": "^12.0.0",
|
|
48
48
|
"jimp": "^1.6.0",
|
|
49
49
|
"puppeteer": "^23.11.1",
|
|
50
50
|
"qrcode": "^1.5.4"
|
package/brother-print.d.ts
DELETED
package/brother-print.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"brother-print.d.ts","sourceRoot":"","sources":["brother-print.ts"],"names":[],"mappings":""}
|