@ecobridge.xyz/devicemanager 3.0.2 → 3.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/changelog.md +10 -0
- package/dist_ts/features/feature.print.d.ts +4 -2
- package/dist_ts/features/feature.print.js +48 -38
- package/dist_ts/protocols/index.d.ts +1 -1
- package/dist_ts/protocols/index.js +2 -2
- package/dist_ts/protocols/protocol.ipp.d.ts +144 -33
- package/dist_ts/protocols/protocol.ipp.js +942 -239
- package/dist_ts/protocols/protocol.ipp.old.d.ts +45 -0
- package/dist_ts/protocols/protocol.ipp.old.js +284 -0
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/features/feature.print.ts +53 -45
- package/ts/protocols/index.ts +6 -1
- package/ts/protocols/protocol.ipp.ts +1183 -260
|
@@ -1,284 +1,987 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
1
|
/**
|
|
3
|
-
* IPP
|
|
2
|
+
* Clean IPP Protocol Implementation
|
|
3
|
+
* RFC 8010 (Encoding) and RFC 8011 (Model)
|
|
4
|
+
*
|
|
5
|
+
* This is a from-scratch implementation with proper capability detection,
|
|
6
|
+
* document format negotiation, and clean attribute parsing.
|
|
4
7
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Constants
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/** IPP Version */
|
|
12
|
+
const IPP_VERSION = {
|
|
13
|
+
V1_1: 0x0101,
|
|
14
|
+
V2_0: 0x0200,
|
|
15
|
+
};
|
|
16
|
+
/** IPP Operations */
|
|
17
|
+
const IPP_OPERATION = {
|
|
18
|
+
PRINT_JOB: 0x0002,
|
|
19
|
+
VALIDATE_JOB: 0x0004,
|
|
20
|
+
CANCEL_JOB: 0x0008,
|
|
21
|
+
GET_JOB_ATTRIBUTES: 0x0009,
|
|
22
|
+
GET_JOBS: 0x000a,
|
|
23
|
+
GET_PRINTER_ATTRIBUTES: 0x000b,
|
|
24
|
+
};
|
|
25
|
+
/** IPP Status Codes */
|
|
26
|
+
const IPP_STATUS = {
|
|
27
|
+
// Successful
|
|
28
|
+
SUCCESSFUL_OK: 0x0000,
|
|
29
|
+
SUCCESSFUL_OK_IGNORED_ATTRIBUTES: 0x0001,
|
|
30
|
+
SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES: 0x0002,
|
|
31
|
+
// Client errors
|
|
32
|
+
CLIENT_ERROR_BAD_REQUEST: 0x0400,
|
|
33
|
+
CLIENT_ERROR_FORBIDDEN: 0x0401,
|
|
34
|
+
CLIENT_ERROR_NOT_AUTHENTICATED: 0x0402,
|
|
35
|
+
CLIENT_ERROR_NOT_AUTHORIZED: 0x0403,
|
|
36
|
+
CLIENT_ERROR_NOT_POSSIBLE: 0x0404,
|
|
37
|
+
CLIENT_ERROR_TIMEOUT: 0x0405,
|
|
38
|
+
CLIENT_ERROR_NOT_FOUND: 0x0406,
|
|
39
|
+
CLIENT_ERROR_DOCUMENT_FORMAT_NOT_SUPPORTED: 0x040a,
|
|
40
|
+
// Server errors
|
|
41
|
+
SERVER_ERROR_INTERNAL: 0x0500,
|
|
42
|
+
SERVER_ERROR_OPERATION_NOT_SUPPORTED: 0x0501,
|
|
43
|
+
SERVER_ERROR_SERVICE_UNAVAILABLE: 0x0502,
|
|
44
|
+
SERVER_ERROR_DEVICE_ERROR: 0x0504,
|
|
45
|
+
SERVER_ERROR_NOT_ACCEPTING_JOBS: 0x0506,
|
|
46
|
+
SERVER_ERROR_BUSY: 0x0507,
|
|
47
|
+
};
|
|
48
|
+
/** Delimiter Tags */
|
|
49
|
+
const TAG_DELIMITER = {
|
|
50
|
+
OPERATION_ATTRIBUTES: 0x01,
|
|
51
|
+
JOB_ATTRIBUTES: 0x02,
|
|
52
|
+
END_OF_ATTRIBUTES: 0x03,
|
|
53
|
+
PRINTER_ATTRIBUTES: 0x04,
|
|
54
|
+
UNSUPPORTED_ATTRIBUTES: 0x05,
|
|
55
|
+
};
|
|
56
|
+
/** Value Tags */
|
|
57
|
+
const TAG_VALUE = {
|
|
58
|
+
// Out-of-band
|
|
59
|
+
UNSUPPORTED: 0x10,
|
|
60
|
+
UNKNOWN: 0x12,
|
|
61
|
+
NO_VALUE: 0x13,
|
|
62
|
+
// Integer
|
|
63
|
+
INTEGER: 0x21,
|
|
64
|
+
BOOLEAN: 0x22,
|
|
65
|
+
ENUM: 0x23,
|
|
66
|
+
// Octet string
|
|
67
|
+
OCTET_STRING: 0x30,
|
|
68
|
+
DATE_TIME: 0x31,
|
|
69
|
+
RESOLUTION: 0x32,
|
|
70
|
+
RANGE_OF_INTEGER: 0x33,
|
|
71
|
+
BEG_COLLECTION: 0x34,
|
|
72
|
+
TEXT_WITH_LANGUAGE: 0x35,
|
|
73
|
+
NAME_WITH_LANGUAGE: 0x36,
|
|
74
|
+
END_COLLECTION: 0x37,
|
|
75
|
+
// Character string
|
|
76
|
+
TEXT_WITHOUT_LANGUAGE: 0x41,
|
|
77
|
+
NAME_WITHOUT_LANGUAGE: 0x42,
|
|
78
|
+
KEYWORD: 0x44,
|
|
79
|
+
URI: 0x45,
|
|
80
|
+
URI_SCHEME: 0x46,
|
|
81
|
+
CHARSET: 0x47,
|
|
82
|
+
NATURAL_LANGUAGE: 0x48,
|
|
83
|
+
MIME_MEDIA_TYPE: 0x49,
|
|
84
|
+
MEMBER_ATTR_NAME: 0x4a,
|
|
85
|
+
};
|
|
86
|
+
/** Job States */
|
|
87
|
+
const JOB_STATE = {
|
|
88
|
+
PENDING: 3,
|
|
89
|
+
PENDING_HELD: 4,
|
|
90
|
+
PROCESSING: 5,
|
|
91
|
+
PROCESSING_STOPPED: 6,
|
|
92
|
+
CANCELED: 7,
|
|
93
|
+
ABORTED: 8,
|
|
94
|
+
COMPLETED: 9,
|
|
95
|
+
};
|
|
96
|
+
/** Printer States */
|
|
97
|
+
const PRINTER_STATE = {
|
|
98
|
+
IDLE: 3,
|
|
99
|
+
PROCESSING: 4,
|
|
100
|
+
STOPPED: 5,
|
|
101
|
+
};
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// IPP Message Encoder
|
|
104
|
+
// ============================================================================
|
|
105
|
+
class IppEncoder {
|
|
106
|
+
buffer = [];
|
|
107
|
+
encode(message) {
|
|
108
|
+
this.buffer = [];
|
|
109
|
+
// Version
|
|
110
|
+
this.writeInt16(message.version);
|
|
111
|
+
// Operation ID or Status Code
|
|
112
|
+
this.writeInt16(message.operationIdOrStatusCode);
|
|
113
|
+
// Request ID
|
|
114
|
+
this.writeInt32(message.requestId);
|
|
115
|
+
// Operation attributes (always required)
|
|
116
|
+
this.writeDelimiter(TAG_DELIMITER.OPERATION_ATTRIBUTES);
|
|
117
|
+
this.writeAttributes(message.operationAttributes);
|
|
118
|
+
// Job attributes (optional)
|
|
119
|
+
if (message.jobAttributes && Object.keys(message.jobAttributes).length > 0) {
|
|
120
|
+
this.writeDelimiter(TAG_DELIMITER.JOB_ATTRIBUTES);
|
|
121
|
+
this.writeAttributes(message.jobAttributes);
|
|
122
|
+
}
|
|
123
|
+
// End of attributes
|
|
124
|
+
this.writeDelimiter(TAG_DELIMITER.END_OF_ATTRIBUTES);
|
|
125
|
+
// Data (for Print-Job)
|
|
126
|
+
const headerBuffer = Buffer.from(this.buffer);
|
|
127
|
+
if (message.data) {
|
|
128
|
+
return Buffer.concat([headerBuffer, message.data]);
|
|
129
|
+
}
|
|
130
|
+
return headerBuffer;
|
|
11
131
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*/
|
|
15
|
-
async getAttributes() {
|
|
16
|
-
return new Promise((resolve, reject) => {
|
|
17
|
-
this.printer.execute('Get-Printer-Attributes', null, (err, res) => {
|
|
18
|
-
if (err) {
|
|
19
|
-
reject(err);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
const attrs = res['printer-attributes-tag'] || {};
|
|
24
|
-
resolve(this.parseCapabilities(attrs));
|
|
25
|
-
}
|
|
26
|
-
catch (parseErr) {
|
|
27
|
-
reject(parseErr);
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
});
|
|
132
|
+
writeInt8(value) {
|
|
133
|
+
this.buffer.push(value & 0xff);
|
|
31
134
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
async print(data, options) {
|
|
36
|
-
const msg = this.buildPrintMessage(options);
|
|
37
|
-
return new Promise((resolve, reject) => {
|
|
38
|
-
this.printer.execute('Print-Job', { ...msg, data }, (err, res) => {
|
|
39
|
-
if (err) {
|
|
40
|
-
reject(err);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
try {
|
|
44
|
-
const jobAttrs = res['job-attributes-tag'] || {};
|
|
45
|
-
resolve(this.parseJobInfo(jobAttrs));
|
|
46
|
-
}
|
|
47
|
-
catch (parseErr) {
|
|
48
|
-
reject(parseErr);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
});
|
|
135
|
+
writeInt16(value) {
|
|
136
|
+
this.buffer.push((value >> 8) & 0xff);
|
|
137
|
+
this.buffer.push(value & 0xff);
|
|
52
138
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
139
|
+
writeInt32(value) {
|
|
140
|
+
this.buffer.push((value >> 24) & 0xff);
|
|
141
|
+
this.buffer.push((value >> 16) & 0xff);
|
|
142
|
+
this.buffer.push((value >> 8) & 0xff);
|
|
143
|
+
this.buffer.push(value & 0xff);
|
|
144
|
+
}
|
|
145
|
+
writeString(value) {
|
|
146
|
+
const bytes = Buffer.from(value, 'utf-8');
|
|
147
|
+
this.writeInt16(bytes.length);
|
|
148
|
+
for (const byte of bytes) {
|
|
149
|
+
this.buffer.push(byte);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
writeDelimiter(tag) {
|
|
153
|
+
this.writeInt8(tag);
|
|
154
|
+
}
|
|
155
|
+
writeAttributes(attrs) {
|
|
156
|
+
for (const [name, value] of Object.entries(attrs)) {
|
|
157
|
+
this.writeAttribute(name, value);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
writeAttribute(name, value) {
|
|
161
|
+
if (Array.isArray(value)) {
|
|
162
|
+
// Multi-value attribute
|
|
163
|
+
for (let i = 0; i < value.length; i++) {
|
|
164
|
+
this.writeSingleAttribute(i === 0 ? name : '', value[i], name);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
this.writeSingleAttribute(name, value, name);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
writeSingleAttribute(name, value, originalName) {
|
|
172
|
+
const tag = this.inferTag(originalName || name, value);
|
|
173
|
+
this.writeInt8(tag);
|
|
174
|
+
// Name
|
|
175
|
+
const nameBytes = Buffer.from(name, 'utf-8');
|
|
176
|
+
this.writeInt16(nameBytes.length);
|
|
177
|
+
for (const byte of nameBytes) {
|
|
178
|
+
this.buffer.push(byte);
|
|
179
|
+
}
|
|
180
|
+
// Value
|
|
181
|
+
this.writeValue(tag, value);
|
|
182
|
+
}
|
|
183
|
+
inferTag(name, value) {
|
|
184
|
+
// IPP requires specific tags for certain attributes
|
|
185
|
+
const knownTags = {
|
|
186
|
+
// Operation attributes
|
|
187
|
+
'attributes-charset': TAG_VALUE.CHARSET,
|
|
188
|
+
'attributes-natural-language': TAG_VALUE.NATURAL_LANGUAGE,
|
|
189
|
+
'printer-uri': TAG_VALUE.URI,
|
|
190
|
+
'job-uri': TAG_VALUE.URI,
|
|
191
|
+
'job-name': TAG_VALUE.NAME_WITHOUT_LANGUAGE,
|
|
192
|
+
'requesting-user-name': TAG_VALUE.NAME_WITHOUT_LANGUAGE,
|
|
193
|
+
'document-name': TAG_VALUE.NAME_WITHOUT_LANGUAGE,
|
|
194
|
+
'document-format': TAG_VALUE.MIME_MEDIA_TYPE,
|
|
195
|
+
// Job attributes - keywords
|
|
196
|
+
'media': TAG_VALUE.KEYWORD,
|
|
197
|
+
'media-type': TAG_VALUE.KEYWORD,
|
|
198
|
+
'sides': TAG_VALUE.KEYWORD,
|
|
199
|
+
'print-color-mode': TAG_VALUE.KEYWORD,
|
|
200
|
+
'output-bin': TAG_VALUE.KEYWORD,
|
|
201
|
+
'which-jobs': TAG_VALUE.KEYWORD,
|
|
202
|
+
// Job attributes - enums (not integers!)
|
|
203
|
+
'print-quality': TAG_VALUE.ENUM,
|
|
204
|
+
'orientation-requested': TAG_VALUE.ENUM,
|
|
205
|
+
'finishings': TAG_VALUE.ENUM,
|
|
206
|
+
// Job attributes - integers
|
|
207
|
+
'copies': TAG_VALUE.INTEGER,
|
|
208
|
+
'job-id': TAG_VALUE.INTEGER,
|
|
209
|
+
'job-priority': TAG_VALUE.INTEGER,
|
|
210
|
+
};
|
|
211
|
+
if (knownTags[name]) {
|
|
212
|
+
return knownTags[name];
|
|
213
|
+
}
|
|
214
|
+
// Infer from value type
|
|
215
|
+
if (typeof value === 'boolean')
|
|
216
|
+
return TAG_VALUE.BOOLEAN;
|
|
217
|
+
if (typeof value === 'number')
|
|
218
|
+
return TAG_VALUE.INTEGER;
|
|
219
|
+
if (value instanceof Date)
|
|
220
|
+
return TAG_VALUE.DATE_TIME;
|
|
221
|
+
if (typeof value === 'object' && 'crossFeed' in value)
|
|
222
|
+
return TAG_VALUE.RESOLUTION;
|
|
223
|
+
if (typeof value === 'object' && 'lower' in value)
|
|
224
|
+
return TAG_VALUE.RANGE_OF_INTEGER;
|
|
225
|
+
// String - try to infer type
|
|
226
|
+
const str = String(value);
|
|
227
|
+
if (str.startsWith('ipp://') || str.startsWith('ipps://') || str.startsWith('http://')) {
|
|
228
|
+
return TAG_VALUE.URI;
|
|
229
|
+
}
|
|
230
|
+
if (str.includes('/'))
|
|
231
|
+
return TAG_VALUE.MIME_MEDIA_TYPE; // e.g., application/pdf
|
|
232
|
+
if (str.match(/^[a-z][a-z0-9-]*$/))
|
|
233
|
+
return TAG_VALUE.KEYWORD;
|
|
234
|
+
return TAG_VALUE.NAME_WITHOUT_LANGUAGE;
|
|
235
|
+
}
|
|
236
|
+
writeValue(tag, value) {
|
|
237
|
+
switch (tag) {
|
|
238
|
+
case TAG_VALUE.INTEGER:
|
|
239
|
+
case TAG_VALUE.ENUM:
|
|
240
|
+
this.writeInt16(4);
|
|
241
|
+
this.writeInt32(value);
|
|
242
|
+
break;
|
|
243
|
+
case TAG_VALUE.BOOLEAN:
|
|
244
|
+
this.writeInt16(1);
|
|
245
|
+
this.writeInt8(value ? 1 : 0);
|
|
246
|
+
break;
|
|
247
|
+
case TAG_VALUE.RESOLUTION: {
|
|
248
|
+
const res = value;
|
|
249
|
+
this.writeInt16(9);
|
|
250
|
+
this.writeInt32(res.crossFeed);
|
|
251
|
+
this.writeInt32(res.feed);
|
|
252
|
+
this.writeInt8(res.units === 'dpi' ? 3 : 4);
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
case TAG_VALUE.RANGE_OF_INTEGER: {
|
|
256
|
+
const range = value;
|
|
257
|
+
this.writeInt16(8);
|
|
258
|
+
this.writeInt32(range.lower);
|
|
259
|
+
this.writeInt32(range.upper);
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
case TAG_VALUE.DATE_TIME: {
|
|
263
|
+
const date = value;
|
|
264
|
+
this.writeInt16(11);
|
|
265
|
+
this.writeInt16(date.getUTCFullYear());
|
|
266
|
+
this.writeInt8(date.getUTCMonth() + 1);
|
|
267
|
+
this.writeInt8(date.getUTCDate());
|
|
268
|
+
this.writeInt8(date.getUTCHours());
|
|
269
|
+
this.writeInt8(date.getUTCMinutes());
|
|
270
|
+
this.writeInt8(date.getUTCSeconds());
|
|
271
|
+
this.writeInt8(0); // deciseconds
|
|
272
|
+
this.writeInt8('+'.charCodeAt(0));
|
|
273
|
+
this.writeInt8(0); // UTC offset hours
|
|
274
|
+
this.writeInt8(0); // UTC offset minutes
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
default:
|
|
278
|
+
// String types
|
|
279
|
+
this.writeString(String(value));
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// ============================================================================
|
|
285
|
+
// IPP Message Decoder
|
|
286
|
+
// ============================================================================
|
|
287
|
+
class IppDecoder {
|
|
288
|
+
buffer = Buffer.alloc(0);
|
|
289
|
+
offset = 0;
|
|
290
|
+
decode(data) {
|
|
291
|
+
this.buffer = data;
|
|
292
|
+
this.offset = 0;
|
|
293
|
+
const version = this.readInt16();
|
|
294
|
+
const operationIdOrStatusCode = this.readInt16();
|
|
295
|
+
const requestId = this.readInt32();
|
|
296
|
+
const message = {
|
|
297
|
+
version,
|
|
298
|
+
operationIdOrStatusCode,
|
|
299
|
+
requestId,
|
|
300
|
+
operationAttributes: {},
|
|
301
|
+
};
|
|
302
|
+
// Read attribute groups
|
|
303
|
+
while (this.offset < this.buffer.length) {
|
|
304
|
+
const tag = this.readInt8();
|
|
305
|
+
if (tag === TAG_DELIMITER.END_OF_ATTRIBUTES) {
|
|
306
|
+
// Remaining data is document data
|
|
307
|
+
if (this.offset < this.buffer.length) {
|
|
308
|
+
message.data = this.buffer.subarray(this.offset);
|
|
67
309
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
if (tag === TAG_DELIMITER.OPERATION_ATTRIBUTES) {
|
|
313
|
+
message.operationAttributes = this.readAttributes();
|
|
314
|
+
}
|
|
315
|
+
else if (tag === TAG_DELIMITER.JOB_ATTRIBUTES) {
|
|
316
|
+
message.jobAttributes = this.readAttributes();
|
|
317
|
+
}
|
|
318
|
+
else if (tag === TAG_DELIMITER.PRINTER_ATTRIBUTES) {
|
|
319
|
+
message.printerAttributes = this.readAttributes();
|
|
320
|
+
}
|
|
321
|
+
else if (tag === TAG_DELIMITER.UNSUPPORTED_ATTRIBUTES) {
|
|
322
|
+
message.unsupportedAttributes = this.readAttributes();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return message;
|
|
326
|
+
}
|
|
327
|
+
readInt8() {
|
|
328
|
+
return this.buffer[this.offset++];
|
|
329
|
+
}
|
|
330
|
+
readInt16() {
|
|
331
|
+
const value = this.buffer.readUInt16BE(this.offset);
|
|
332
|
+
this.offset += 2;
|
|
333
|
+
return value;
|
|
334
|
+
}
|
|
335
|
+
readInt32() {
|
|
336
|
+
const value = this.buffer.readInt32BE(this.offset);
|
|
337
|
+
this.offset += 4;
|
|
338
|
+
return value;
|
|
339
|
+
}
|
|
340
|
+
readUInt32() {
|
|
341
|
+
const value = this.buffer.readUInt32BE(this.offset);
|
|
342
|
+
this.offset += 4;
|
|
343
|
+
return value;
|
|
344
|
+
}
|
|
345
|
+
readString(length) {
|
|
346
|
+
const str = this.buffer.toString('utf-8', this.offset, this.offset + length);
|
|
347
|
+
this.offset += length;
|
|
348
|
+
return str;
|
|
349
|
+
}
|
|
350
|
+
readAttributes() {
|
|
351
|
+
const attrs = {};
|
|
352
|
+
let currentName = '';
|
|
353
|
+
while (this.offset < this.buffer.length) {
|
|
354
|
+
const tag = this.buffer[this.offset];
|
|
355
|
+
// Check for delimiter tag (start of new group or end)
|
|
356
|
+
if (tag <= 0x0f) {
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
this.offset++; // Consume the tag
|
|
360
|
+
const nameLength = this.readInt16();
|
|
361
|
+
const name = nameLength > 0 ? this.readString(nameLength) : currentName;
|
|
362
|
+
const valueLength = this.readInt16();
|
|
363
|
+
const value = this.readValue(tag, valueLength);
|
|
364
|
+
if (nameLength > 0) {
|
|
365
|
+
currentName = name;
|
|
366
|
+
attrs[name] = value;
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
// Additional value for same attribute - make it an array
|
|
370
|
+
const existing = attrs[currentName];
|
|
371
|
+
if (Array.isArray(existing)) {
|
|
372
|
+
existing.push(value);
|
|
80
373
|
}
|
|
81
|
-
|
|
82
|
-
|
|
374
|
+
else {
|
|
375
|
+
attrs[currentName] = [existing, value];
|
|
83
376
|
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return attrs;
|
|
86
380
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
381
|
+
readValue(tag, length) {
|
|
382
|
+
switch (tag) {
|
|
383
|
+
case TAG_VALUE.INTEGER:
|
|
384
|
+
case TAG_VALUE.ENUM:
|
|
385
|
+
return this.readInt32();
|
|
386
|
+
case TAG_VALUE.BOOLEAN:
|
|
387
|
+
return this.readInt8() !== 0;
|
|
388
|
+
case TAG_VALUE.RESOLUTION: {
|
|
389
|
+
const crossFeed = this.readInt32();
|
|
390
|
+
const feed = this.readInt32();
|
|
391
|
+
const units = this.readInt8() === 3 ? 'dpi' : 'dpcm';
|
|
392
|
+
return { crossFeed, feed, units };
|
|
393
|
+
}
|
|
394
|
+
case TAG_VALUE.RANGE_OF_INTEGER: {
|
|
395
|
+
const lower = this.readInt32();
|
|
396
|
+
const upper = this.readInt32();
|
|
397
|
+
return { lower, upper };
|
|
398
|
+
}
|
|
399
|
+
case TAG_VALUE.DATE_TIME: {
|
|
400
|
+
const year = this.readInt16();
|
|
401
|
+
const month = this.readInt8();
|
|
402
|
+
const day = this.readInt8();
|
|
403
|
+
const hour = this.readInt8();
|
|
404
|
+
const minute = this.readInt8();
|
|
405
|
+
const second = this.readInt8();
|
|
406
|
+
this.readInt8(); // deciseconds
|
|
407
|
+
const direction = String.fromCharCode(this.readInt8());
|
|
408
|
+
const offsetHours = this.readInt8();
|
|
409
|
+
const offsetMinutes = this.readInt8();
|
|
410
|
+
const date = new Date(Date.UTC(year, month - 1, day, hour, minute, second));
|
|
411
|
+
const offsetMs = (offsetHours * 60 + offsetMinutes) * 60 * 1000;
|
|
412
|
+
if (direction === '-') {
|
|
413
|
+
date.setTime(date.getTime() + offsetMs);
|
|
104
414
|
}
|
|
105
|
-
|
|
106
|
-
|
|
415
|
+
else {
|
|
416
|
+
date.setTime(date.getTime() - offsetMs);
|
|
107
417
|
}
|
|
108
|
-
|
|
109
|
-
|
|
418
|
+
return date;
|
|
419
|
+
}
|
|
420
|
+
case TAG_VALUE.NO_VALUE:
|
|
421
|
+
case TAG_VALUE.UNKNOWN:
|
|
422
|
+
case TAG_VALUE.UNSUPPORTED:
|
|
423
|
+
this.offset += length;
|
|
424
|
+
return '';
|
|
425
|
+
default:
|
|
426
|
+
// String types
|
|
427
|
+
return this.readString(length);
|
|
428
|
+
}
|
|
110
429
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
430
|
+
}
|
|
431
|
+
// ============================================================================
|
|
432
|
+
// Status Code Helpers
|
|
433
|
+
// ============================================================================
|
|
434
|
+
function isSuccessful(statusCode) {
|
|
435
|
+
return statusCode >= 0x0000 && statusCode <= 0x00ff;
|
|
436
|
+
}
|
|
437
|
+
function statusCodeToString(code) {
|
|
438
|
+
const statusMap = {
|
|
439
|
+
0x0000: 'successful-ok',
|
|
440
|
+
0x0001: 'successful-ok-ignored-or-substituted-attributes',
|
|
441
|
+
0x0002: 'successful-ok-conflicting-attributes',
|
|
442
|
+
0x0400: 'client-error-bad-request',
|
|
443
|
+
0x0401: 'client-error-forbidden',
|
|
444
|
+
0x0402: 'client-error-not-authenticated',
|
|
445
|
+
0x0403: 'client-error-not-authorized',
|
|
446
|
+
0x0404: 'client-error-not-possible',
|
|
447
|
+
0x0405: 'client-error-timeout',
|
|
448
|
+
0x0406: 'client-error-not-found',
|
|
449
|
+
0x040a: 'client-error-document-format-not-supported',
|
|
450
|
+
0x040b: 'client-error-attributes-or-values-not-supported',
|
|
451
|
+
0x0500: 'server-error-internal-error',
|
|
452
|
+
0x0501: 'server-error-operation-not-supported',
|
|
453
|
+
0x0502: 'server-error-service-unavailable',
|
|
454
|
+
0x0504: 'server-error-device-error',
|
|
455
|
+
0x0506: 'server-error-not-accepting-jobs',
|
|
456
|
+
0x0507: 'server-error-busy',
|
|
457
|
+
};
|
|
458
|
+
return statusMap[code] || `unknown-status-${code.toString(16)}`;
|
|
459
|
+
}
|
|
460
|
+
// ============================================================================
|
|
461
|
+
// IPP Client
|
|
462
|
+
// ============================================================================
|
|
463
|
+
export class IppClient {
|
|
464
|
+
printerUri;
|
|
465
|
+
httpUri;
|
|
466
|
+
requestId = 1;
|
|
467
|
+
encoder = new IppEncoder();
|
|
468
|
+
decoder = new IppDecoder();
|
|
469
|
+
constructor(address, port = 631, path = '/ipp/print') {
|
|
470
|
+
this.printerUri = `ipp://${address}:${port}${path}`;
|
|
471
|
+
this.httpUri = `http://${address}:${port}${path}`;
|
|
128
472
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
async
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
473
|
+
// ==========================================================================
|
|
474
|
+
// Core Request Method
|
|
475
|
+
// ==========================================================================
|
|
476
|
+
async request(message) {
|
|
477
|
+
const requestData = this.encoder.encode(message);
|
|
478
|
+
const response = await fetch(this.httpUri, {
|
|
479
|
+
method: 'POST',
|
|
480
|
+
headers: {
|
|
481
|
+
'Content-Type': 'application/ipp',
|
|
482
|
+
'Accept': 'application/ipp',
|
|
483
|
+
},
|
|
484
|
+
body: new Uint8Array(requestData),
|
|
485
|
+
});
|
|
486
|
+
if (!response.ok) {
|
|
487
|
+
throw new Error(`HTTP error: ${response.status} ${response.statusText}`);
|
|
136
488
|
}
|
|
137
|
-
|
|
138
|
-
|
|
489
|
+
const responseData = Buffer.from(await response.arrayBuffer());
|
|
490
|
+
return this.decoder.decode(responseData);
|
|
491
|
+
}
|
|
492
|
+
// ==========================================================================
|
|
493
|
+
// Get Printer Attributes
|
|
494
|
+
// ==========================================================================
|
|
495
|
+
async getPrinterAttributes() {
|
|
496
|
+
const message = {
|
|
497
|
+
version: IPP_VERSION.V2_0,
|
|
498
|
+
operationIdOrStatusCode: IPP_OPERATION.GET_PRINTER_ATTRIBUTES,
|
|
499
|
+
requestId: this.requestId++,
|
|
500
|
+
operationAttributes: {
|
|
501
|
+
'attributes-charset': 'utf-8',
|
|
502
|
+
'attributes-natural-language': 'en-us',
|
|
503
|
+
'printer-uri': this.printerUri,
|
|
504
|
+
},
|
|
505
|
+
};
|
|
506
|
+
const response = await this.request(message);
|
|
507
|
+
if (!isSuccessful(response.operationIdOrStatusCode)) {
|
|
508
|
+
throw new Error(`IPP error: ${statusCodeToString(response.operationIdOrStatusCode)}`);
|
|
139
509
|
}
|
|
510
|
+
return this.parseCapabilities(response.printerAttributes || {});
|
|
140
511
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
512
|
+
parseCapabilities(attrs) {
|
|
513
|
+
const getString = (key, defaultVal = '') => {
|
|
514
|
+
const val = attrs[key];
|
|
515
|
+
if (typeof val === 'string')
|
|
516
|
+
return val;
|
|
517
|
+
if (Array.isArray(val) && val.length > 0)
|
|
518
|
+
return String(val[0]);
|
|
519
|
+
return defaultVal;
|
|
520
|
+
};
|
|
521
|
+
const getStringArray = (key) => {
|
|
522
|
+
const val = attrs[key];
|
|
523
|
+
if (Array.isArray(val))
|
|
524
|
+
return val.map(String);
|
|
525
|
+
if (val !== undefined)
|
|
526
|
+
return [String(val)];
|
|
527
|
+
return [];
|
|
528
|
+
};
|
|
529
|
+
const getNumber = (key, defaultVal = 0) => {
|
|
530
|
+
const val = attrs[key];
|
|
531
|
+
if (typeof val === 'number')
|
|
532
|
+
return val;
|
|
533
|
+
return defaultVal;
|
|
534
|
+
};
|
|
535
|
+
const getNumberArray = (key) => {
|
|
536
|
+
const val = attrs[key];
|
|
537
|
+
if (Array.isArray(val))
|
|
538
|
+
return val.filter((v) => typeof v === 'number');
|
|
539
|
+
if (typeof val === 'number')
|
|
540
|
+
return [val];
|
|
541
|
+
return [];
|
|
542
|
+
};
|
|
543
|
+
const getBool = (key, defaultVal = false) => {
|
|
544
|
+
const val = attrs[key];
|
|
545
|
+
if (typeof val === 'boolean')
|
|
546
|
+
return val;
|
|
547
|
+
return defaultVal;
|
|
548
|
+
};
|
|
549
|
+
const getRange = (key) => {
|
|
550
|
+
const val = attrs[key];
|
|
551
|
+
if (val && typeof val === 'object' && 'lower' in val) {
|
|
552
|
+
return val;
|
|
553
|
+
}
|
|
554
|
+
return { lower: 1, upper: 1 };
|
|
555
|
+
};
|
|
556
|
+
const getResolutions = () => {
|
|
557
|
+
const val = attrs['printer-resolution-supported'];
|
|
558
|
+
if (!val)
|
|
559
|
+
return [];
|
|
560
|
+
const values = Array.isArray(val) ? val : [val];
|
|
561
|
+
return values
|
|
562
|
+
.filter((v) => typeof v === 'object' && v !== null && 'crossFeed' in v);
|
|
563
|
+
};
|
|
564
|
+
// Map printer state number to string
|
|
565
|
+
const printerState = getNumber('printer-state', PRINTER_STATE.IDLE);
|
|
566
|
+
const printerStateString = printerState === PRINTER_STATE.IDLE ? 'idle' :
|
|
567
|
+
printerState === PRINTER_STATE.PROCESSING ? 'processing' : 'stopped';
|
|
568
|
+
return {
|
|
569
|
+
printerName: getString('printer-name', 'Unknown Printer'),
|
|
570
|
+
printerInfo: getString('printer-info') || undefined,
|
|
571
|
+
printerMakeAndModel: getString('printer-make-and-model') || undefined,
|
|
572
|
+
printerLocation: getString('printer-location') || undefined,
|
|
573
|
+
printerUri: this.printerUri,
|
|
574
|
+
printerState: printerStateString,
|
|
575
|
+
printerStateReasons: getStringArray('printer-state-reasons'),
|
|
576
|
+
printerIsAcceptingJobs: getBool('printer-is-accepting-jobs', true),
|
|
577
|
+
queuedJobCount: getNumber('queued-job-count', 0),
|
|
578
|
+
documentFormatSupported: getStringArray('document-format-supported'),
|
|
579
|
+
documentFormatDefault: getString('document-format-default') || undefined,
|
|
580
|
+
mediaSizeSupported: getStringArray('media-supported'),
|
|
581
|
+
mediaDefault: getString('media-default') || undefined,
|
|
582
|
+
mediaTypeSupported: getStringArray('media-type-supported'),
|
|
583
|
+
colorSupported: getBool('color-supported', false),
|
|
584
|
+
sidesSupported: getStringArray('sides-supported'),
|
|
585
|
+
sidesDefault: getString('sides-default') || undefined,
|
|
586
|
+
copiesSupported: getRange('copies-supported'),
|
|
587
|
+
printQualitySupported: getNumberArray('print-quality-supported'),
|
|
588
|
+
resolutionsSupported: getResolutions(),
|
|
589
|
+
operationsSupported: getNumberArray('operations-supported'),
|
|
590
|
+
ippVersionsSupported: getStringArray('ipp-versions-supported'),
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
// ==========================================================================
|
|
594
|
+
// Print Job
|
|
595
|
+
// ==========================================================================
|
|
596
|
+
async printJob(data, options = {}) {
|
|
597
|
+
// Build operation attributes
|
|
145
598
|
const operationAttrs = {
|
|
146
|
-
'
|
|
147
|
-
'
|
|
148
|
-
'
|
|
599
|
+
'attributes-charset': 'utf-8',
|
|
600
|
+
'attributes-natural-language': 'en-us',
|
|
601
|
+
'printer-uri': this.printerUri,
|
|
602
|
+
'requesting-user-name': options.requestingUserName || 'devicemanager',
|
|
603
|
+
'job-name': options.jobName || 'Print Job',
|
|
604
|
+
'document-format': options.documentFormat || 'application/octet-stream',
|
|
149
605
|
};
|
|
606
|
+
// Build job attributes
|
|
150
607
|
const jobAttrs = {};
|
|
151
|
-
if (options
|
|
608
|
+
if (options.copies && options.copies > 1) {
|
|
152
609
|
jobAttrs['copies'] = options.copies;
|
|
153
610
|
}
|
|
154
|
-
if (options
|
|
155
|
-
jobAttrs['media'] = options.mediaSize;
|
|
156
|
-
}
|
|
157
|
-
if (options?.mediaType) {
|
|
158
|
-
jobAttrs['media-type'] = options.mediaType;
|
|
159
|
-
}
|
|
160
|
-
if (options?.sides) {
|
|
611
|
+
if (options.sides) {
|
|
161
612
|
jobAttrs['sides'] = options.sides;
|
|
162
613
|
}
|
|
163
|
-
if (options
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
jobAttrs['print-quality'] = qualityMap[options.quality] ?? 4;
|
|
614
|
+
if (options.media) {
|
|
615
|
+
jobAttrs['media'] = options.media;
|
|
616
|
+
}
|
|
617
|
+
if (options.printQuality) {
|
|
618
|
+
const qualityMap = { draft: 3, normal: 4, high: 5 };
|
|
619
|
+
jobAttrs['print-quality'] = qualityMap[options.printQuality];
|
|
170
620
|
}
|
|
171
|
-
if (options
|
|
621
|
+
if (options.colorMode) {
|
|
172
622
|
jobAttrs['print-color-mode'] = options.colorMode;
|
|
173
623
|
}
|
|
174
|
-
|
|
175
|
-
|
|
624
|
+
if (options.orientation) {
|
|
625
|
+
const orientationMap = {
|
|
626
|
+
portrait: 3,
|
|
627
|
+
landscape: 4,
|
|
628
|
+
'reverse-landscape': 5,
|
|
629
|
+
'reverse-portrait': 6,
|
|
630
|
+
};
|
|
631
|
+
jobAttrs['orientation-requested'] = orientationMap[options.orientation];
|
|
632
|
+
}
|
|
633
|
+
const message = {
|
|
634
|
+
version: IPP_VERSION.V2_0,
|
|
635
|
+
operationIdOrStatusCode: IPP_OPERATION.PRINT_JOB,
|
|
636
|
+
requestId: this.requestId++,
|
|
637
|
+
operationAttributes: operationAttrs,
|
|
638
|
+
jobAttributes: Object.keys(jobAttrs).length > 0 ? jobAttrs : undefined,
|
|
639
|
+
data,
|
|
176
640
|
};
|
|
177
|
-
|
|
178
|
-
|
|
641
|
+
const response = await this.request(message);
|
|
642
|
+
if (!isSuccessful(response.operationIdOrStatusCode)) {
|
|
643
|
+
throw new Error(`Print failed: ${statusCodeToString(response.operationIdOrStatusCode)}`);
|
|
179
644
|
}
|
|
180
|
-
return
|
|
645
|
+
return this.parseJob(response.jobAttributes || {});
|
|
181
646
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
return value;
|
|
198
|
-
if (typeof value === 'string')
|
|
199
|
-
return parseInt(value) || defaultVal;
|
|
200
|
-
return defaultVal;
|
|
647
|
+
// ==========================================================================
|
|
648
|
+
// Get Jobs
|
|
649
|
+
// ==========================================================================
|
|
650
|
+
async getJobs(whichJobs = 'not-completed') {
|
|
651
|
+
const message = {
|
|
652
|
+
version: IPP_VERSION.V2_0,
|
|
653
|
+
operationIdOrStatusCode: IPP_OPERATION.GET_JOBS,
|
|
654
|
+
requestId: this.requestId++,
|
|
655
|
+
operationAttributes: {
|
|
656
|
+
'attributes-charset': 'utf-8',
|
|
657
|
+
'attributes-natural-language': 'en-us',
|
|
658
|
+
'printer-uri': this.printerUri,
|
|
659
|
+
'requesting-user-name': 'devicemanager',
|
|
660
|
+
'which-jobs': whichJobs,
|
|
661
|
+
},
|
|
201
662
|
};
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
663
|
+
const response = await this.request(message);
|
|
664
|
+
if (!isSuccessful(response.operationIdOrStatusCode)) {
|
|
665
|
+
throw new Error(`Get jobs failed: ${statusCodeToString(response.operationIdOrStatusCode)}`);
|
|
666
|
+
}
|
|
667
|
+
// Jobs can come back as a single job-attributes-tag or multiple
|
|
668
|
+
// The decoder merges additional values into arrays
|
|
669
|
+
if (!response.jobAttributes) {
|
|
670
|
+
return [];
|
|
671
|
+
}
|
|
672
|
+
// If job-id is an array, we have multiple jobs encoded together
|
|
673
|
+
// This is a limitation of the simple decoder - in reality each job is a separate group
|
|
674
|
+
// For now, return single job if present
|
|
675
|
+
return [this.parseJob(response.jobAttributes)];
|
|
676
|
+
}
|
|
677
|
+
// ==========================================================================
|
|
678
|
+
// Get Job Attributes
|
|
679
|
+
// ==========================================================================
|
|
680
|
+
async getJobAttributes(jobId) {
|
|
681
|
+
const message = {
|
|
682
|
+
version: IPP_VERSION.V2_0,
|
|
683
|
+
operationIdOrStatusCode: IPP_OPERATION.GET_JOB_ATTRIBUTES,
|
|
684
|
+
requestId: this.requestId++,
|
|
685
|
+
operationAttributes: {
|
|
686
|
+
'attributes-charset': 'utf-8',
|
|
687
|
+
'attributes-natural-language': 'en-us',
|
|
688
|
+
'printer-uri': this.printerUri,
|
|
689
|
+
'job-id': jobId,
|
|
690
|
+
},
|
|
211
691
|
};
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (Array.isArray(resSupported)) {
|
|
216
|
-
for (const res of resSupported) {
|
|
217
|
-
if (typeof res === 'object' && res !== null && 'x' in res) {
|
|
218
|
-
resolutions.push(res.x);
|
|
219
|
-
}
|
|
220
|
-
else if (typeof res === 'number') {
|
|
221
|
-
resolutions.push(res);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
692
|
+
const response = await this.request(message);
|
|
693
|
+
if (!isSuccessful(response.operationIdOrStatusCode)) {
|
|
694
|
+
throw new Error(`Get job failed: ${statusCodeToString(response.operationIdOrStatusCode)}`);
|
|
224
695
|
}
|
|
225
|
-
|
|
226
|
-
|
|
696
|
+
return this.parseJob(response.jobAttributes || {});
|
|
697
|
+
}
|
|
698
|
+
// ==========================================================================
|
|
699
|
+
// Cancel Job
|
|
700
|
+
// ==========================================================================
|
|
701
|
+
async cancelJob(jobId) {
|
|
702
|
+
const message = {
|
|
703
|
+
version: IPP_VERSION.V2_0,
|
|
704
|
+
operationIdOrStatusCode: IPP_OPERATION.CANCEL_JOB,
|
|
705
|
+
requestId: this.requestId++,
|
|
706
|
+
operationAttributes: {
|
|
707
|
+
'attributes-charset': 'utf-8',
|
|
708
|
+
'attributes-natural-language': 'en-us',
|
|
709
|
+
'printer-uri': this.printerUri,
|
|
710
|
+
'job-id': jobId,
|
|
711
|
+
},
|
|
712
|
+
};
|
|
713
|
+
const response = await this.request(message);
|
|
714
|
+
if (!isSuccessful(response.operationIdOrStatusCode)) {
|
|
715
|
+
throw new Error(`Cancel job failed: ${statusCodeToString(response.operationIdOrStatusCode)}`);
|
|
227
716
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
717
|
+
}
|
|
718
|
+
// ==========================================================================
|
|
719
|
+
// Validate Job (check if job would succeed without actually printing)
|
|
720
|
+
// ==========================================================================
|
|
721
|
+
async validateJob(options = {}) {
|
|
722
|
+
const operationAttrs = {
|
|
723
|
+
'attributes-charset': 'utf-8',
|
|
724
|
+
'attributes-natural-language': 'en-us',
|
|
725
|
+
'printer-uri': this.printerUri,
|
|
726
|
+
'document-format': options.documentFormat || 'application/octet-stream',
|
|
727
|
+
};
|
|
728
|
+
const message = {
|
|
729
|
+
version: IPP_VERSION.V2_0,
|
|
730
|
+
operationIdOrStatusCode: IPP_OPERATION.VALIDATE_JOB,
|
|
731
|
+
requestId: this.requestId++,
|
|
732
|
+
operationAttributes: operationAttrs,
|
|
237
733
|
};
|
|
734
|
+
const response = await this.request(message);
|
|
735
|
+
return isSuccessful(response.operationIdOrStatusCode);
|
|
238
736
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
const
|
|
245
|
-
if (typeof
|
|
246
|
-
return
|
|
247
|
-
if (
|
|
248
|
-
return
|
|
737
|
+
// ==========================================================================
|
|
738
|
+
// Helper Methods
|
|
739
|
+
// ==========================================================================
|
|
740
|
+
parseJob(attrs) {
|
|
741
|
+
const getNumber = (key, defaultVal = 0) => {
|
|
742
|
+
const val = attrs[key];
|
|
743
|
+
if (typeof val === 'number')
|
|
744
|
+
return val;
|
|
745
|
+
if (Array.isArray(val) && typeof val[0] === 'number')
|
|
746
|
+
return val[0];
|
|
249
747
|
return defaultVal;
|
|
250
748
|
};
|
|
251
|
-
const
|
|
252
|
-
const
|
|
253
|
-
if (typeof
|
|
254
|
-
return
|
|
255
|
-
if (
|
|
256
|
-
return
|
|
749
|
+
const getString = (key, defaultVal = '') => {
|
|
750
|
+
const val = attrs[key];
|
|
751
|
+
if (typeof val === 'string')
|
|
752
|
+
return val;
|
|
753
|
+
if (Array.isArray(val) && val.length > 0)
|
|
754
|
+
return String(val[0]);
|
|
257
755
|
return defaultVal;
|
|
258
756
|
};
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
757
|
+
const getStringArray = (key) => {
|
|
758
|
+
const val = attrs[key];
|
|
759
|
+
if (Array.isArray(val))
|
|
760
|
+
return val.map(String);
|
|
761
|
+
if (val !== undefined)
|
|
762
|
+
return [String(val)];
|
|
763
|
+
return [];
|
|
764
|
+
};
|
|
765
|
+
const getDate = (key) => {
|
|
766
|
+
const val = attrs[key];
|
|
767
|
+
if (val instanceof Date)
|
|
768
|
+
return val;
|
|
769
|
+
return undefined;
|
|
770
|
+
};
|
|
771
|
+
// Map job state number to string
|
|
772
|
+
const jobState = getNumber('job-state', JOB_STATE.PENDING);
|
|
773
|
+
const jobStateMap = {
|
|
774
|
+
[JOB_STATE.PENDING]: 'pending',
|
|
775
|
+
[JOB_STATE.PENDING_HELD]: 'pending-held',
|
|
776
|
+
[JOB_STATE.PROCESSING]: 'processing',
|
|
777
|
+
[JOB_STATE.PROCESSING_STOPPED]: 'processing-stopped',
|
|
778
|
+
[JOB_STATE.CANCELED]: 'canceled',
|
|
779
|
+
[JOB_STATE.ABORTED]: 'aborted',
|
|
780
|
+
[JOB_STATE.COMPLETED]: 'completed',
|
|
269
781
|
};
|
|
270
|
-
const createdTime = attrs['time-at-creation'];
|
|
271
|
-
const completedTime = attrs['time-at-completed'];
|
|
272
782
|
return {
|
|
273
|
-
id: getNumber('job-id'
|
|
783
|
+
id: getNumber('job-id'),
|
|
784
|
+
uri: getString('job-uri'),
|
|
785
|
+
state: jobStateMap[jobState] || 'pending',
|
|
786
|
+
stateReasons: getStringArray('job-state-reasons'),
|
|
274
787
|
name: getString('job-name', 'Unknown Job'),
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
788
|
+
originatingUserName: getString('job-originating-user-name') || undefined,
|
|
789
|
+
createdAt: getDate('time-at-creation') || getDate('date-time-at-creation'),
|
|
790
|
+
completedAt: getDate('time-at-completed') || getDate('date-time-at-completed'),
|
|
791
|
+
processingAt: getDate('time-at-processing') || getDate('date-time-at-processing'),
|
|
792
|
+
impressionsCompleted: getNumber('job-impressions-completed') || undefined,
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
// ==========================================================================
|
|
796
|
+
// Convenience: Check if format is supported
|
|
797
|
+
// ==========================================================================
|
|
798
|
+
async isFormatSupported(mimeType) {
|
|
799
|
+
const caps = await this.getPrinterAttributes();
|
|
800
|
+
return caps.documentFormatSupported.includes(mimeType);
|
|
801
|
+
}
|
|
802
|
+
// ==========================================================================
|
|
803
|
+
// Convenience: Get best format for data
|
|
804
|
+
// ==========================================================================
|
|
805
|
+
async getBestFormat(preferredFormats) {
|
|
806
|
+
const caps = await this.getPrinterAttributes();
|
|
807
|
+
const supported = caps.documentFormatSupported;
|
|
808
|
+
for (const format of preferredFormats) {
|
|
809
|
+
if (supported.includes(format)) {
|
|
810
|
+
return format;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
// ==========================================================================
|
|
816
|
+
// Smart Print: Auto-detect format and convert if needed
|
|
817
|
+
// ==========================================================================
|
|
818
|
+
/**
|
|
819
|
+
* Smart print that auto-detects document format and converts if necessary.
|
|
820
|
+
*
|
|
821
|
+
* If the document format is not supported by the printer, it will attempt
|
|
822
|
+
* to convert to a supported format (e.g., PDF → JPEG).
|
|
823
|
+
*/
|
|
824
|
+
async smartPrint(data, options = {}) {
|
|
825
|
+
// Detect format from data
|
|
826
|
+
const detectedFormat = this.detectFormat(data);
|
|
827
|
+
console.log(`[IPP] Detected format: ${detectedFormat}`);
|
|
828
|
+
// Get printer capabilities
|
|
829
|
+
const caps = await this.getPrinterAttributes();
|
|
830
|
+
const supported = caps.documentFormatSupported;
|
|
831
|
+
// Check if detected format is supported
|
|
832
|
+
if (supported.includes(detectedFormat)) {
|
|
833
|
+
console.log(`[IPP] Format ${detectedFormat} is supported, printing directly`);
|
|
834
|
+
return this.printJob(data, {
|
|
835
|
+
...options,
|
|
836
|
+
documentFormat: detectedFormat,
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
// Format not supported - try to convert
|
|
840
|
+
console.log(`[IPP] Format ${detectedFormat} not supported, attempting conversion`);
|
|
841
|
+
// Determine best target format
|
|
842
|
+
const conversionTargets = ['image/jpeg', 'image/png', 'image/pwg-raster'];
|
|
843
|
+
const targetFormat = conversionTargets.find(f => supported.includes(f));
|
|
844
|
+
if (!targetFormat) {
|
|
845
|
+
throw new Error(`Document format ${detectedFormat} not supported and no conversion target available. ` +
|
|
846
|
+
`Printer supports: ${supported.join(', ')}`);
|
|
847
|
+
}
|
|
848
|
+
// Convert the document
|
|
849
|
+
const convertedData = await this.convertDocument(data, detectedFormat, targetFormat);
|
|
850
|
+
console.log(`[IPP] Converted to ${targetFormat} (${convertedData.length} bytes)`);
|
|
851
|
+
return this.printJob(convertedData, {
|
|
852
|
+
...options,
|
|
853
|
+
documentFormat: targetFormat,
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Detect document format from magic bytes
|
|
858
|
+
*/
|
|
859
|
+
detectFormat(data) {
|
|
860
|
+
if (data.length < 4) {
|
|
861
|
+
return 'application/octet-stream';
|
|
862
|
+
}
|
|
863
|
+
// PDF: starts with %PDF
|
|
864
|
+
if (data[0] === 0x25 && data[1] === 0x50 && data[2] === 0x44 && data[3] === 0x46) {
|
|
865
|
+
return 'application/pdf';
|
|
866
|
+
}
|
|
867
|
+
// JPEG: starts with FFD8FF
|
|
868
|
+
if (data[0] === 0xff && data[1] === 0xd8 && data[2] === 0xff) {
|
|
869
|
+
return 'image/jpeg';
|
|
870
|
+
}
|
|
871
|
+
// PNG: starts with 89504E47
|
|
872
|
+
if (data[0] === 0x89 && data[1] === 0x50 && data[2] === 0x4e && data[3] === 0x47) {
|
|
873
|
+
return 'image/png';
|
|
874
|
+
}
|
|
875
|
+
// TIFF: starts with 49492A00 (little endian) or 4D4D002A (big endian)
|
|
876
|
+
if ((data[0] === 0x49 && data[1] === 0x49 && data[2] === 0x2a && data[3] === 0x00) ||
|
|
877
|
+
(data[0] === 0x4d && data[1] === 0x4d && data[2] === 0x00 && data[3] === 0x2a)) {
|
|
878
|
+
return 'image/tiff';
|
|
879
|
+
}
|
|
880
|
+
// PostScript: starts with %!
|
|
881
|
+
if (data[0] === 0x25 && data[1] === 0x21) {
|
|
882
|
+
return 'application/postscript';
|
|
883
|
+
}
|
|
884
|
+
// PWG Raster: starts with "RaS2"
|
|
885
|
+
if (data[0] === 0x52 && data[1] === 0x61 && data[2] === 0x53 && data[3] === 0x32) {
|
|
886
|
+
return 'image/pwg-raster';
|
|
887
|
+
}
|
|
888
|
+
// URF (Apple Raster): starts with "UNIRAST"
|
|
889
|
+
if (data.length >= 8 &&
|
|
890
|
+
data[0] === 0x55 && data[1] === 0x4e && data[2] === 0x49 && data[3] === 0x52 &&
|
|
891
|
+
data[4] === 0x41 && data[5] === 0x53 && data[6] === 0x54) {
|
|
892
|
+
return 'image/urf';
|
|
893
|
+
}
|
|
894
|
+
return 'application/octet-stream';
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Convert document to target format
|
|
898
|
+
* Uses ImageMagick if available, otherwise throws
|
|
899
|
+
*/
|
|
900
|
+
async convertDocument(data, sourceFormat, targetFormat) {
|
|
901
|
+
// Try using ImageMagick via child_process
|
|
902
|
+
const { execSync, spawnSync } = await import('child_process');
|
|
903
|
+
const { writeFileSync, readFileSync, unlinkSync, mkdtempSync } = await import('fs');
|
|
904
|
+
const { join } = await import('path');
|
|
905
|
+
const { tmpdir } = await import('os');
|
|
906
|
+
// Check if ImageMagick is available
|
|
907
|
+
try {
|
|
908
|
+
execSync('which convert', { stdio: 'ignore' });
|
|
909
|
+
}
|
|
910
|
+
catch {
|
|
911
|
+
throw new Error(`Cannot convert ${sourceFormat} to ${targetFormat}: ImageMagick not available`);
|
|
912
|
+
}
|
|
913
|
+
// Create temp directory and files
|
|
914
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'ipp-convert-'));
|
|
915
|
+
const sourceExt = this.formatToExtension(sourceFormat);
|
|
916
|
+
const targetExt = this.formatToExtension(targetFormat);
|
|
917
|
+
const sourcePath = join(tempDir, `input${sourceExt}`);
|
|
918
|
+
const targetPath = join(tempDir, `output${targetExt}`);
|
|
919
|
+
try {
|
|
920
|
+
// Write source file
|
|
921
|
+
writeFileSync(sourcePath, data);
|
|
922
|
+
// Build convert command
|
|
923
|
+
const args = [
|
|
924
|
+
sourcePath,
|
|
925
|
+
'-density', '300', // Good DPI for print
|
|
926
|
+
'-quality', '90', // JPEG quality
|
|
927
|
+
'-background', 'white', // White background for transparency
|
|
928
|
+
'-flatten', // Flatten layers
|
|
929
|
+
targetPath,
|
|
930
|
+
];
|
|
931
|
+
// For multi-page PDFs, only convert first page
|
|
932
|
+
if (sourceFormat === 'application/pdf') {
|
|
933
|
+
args[0] = `${sourcePath}[0]`; // First page only
|
|
934
|
+
}
|
|
935
|
+
// Run conversion
|
|
936
|
+
const result = spawnSync('convert', args, {
|
|
937
|
+
timeout: 30000,
|
|
938
|
+
maxBuffer: 100 * 1024 * 1024, // 100MB
|
|
939
|
+
});
|
|
940
|
+
if (result.status !== 0) {
|
|
941
|
+
const stderr = result.stderr?.toString() || 'Unknown error';
|
|
942
|
+
throw new Error(`ImageMagick conversion failed: ${stderr}`);
|
|
943
|
+
}
|
|
944
|
+
// Read converted file
|
|
945
|
+
return readFileSync(targetPath);
|
|
946
|
+
}
|
|
947
|
+
finally {
|
|
948
|
+
// Cleanup temp files
|
|
949
|
+
try {
|
|
950
|
+
unlinkSync(sourcePath);
|
|
951
|
+
}
|
|
952
|
+
catch { }
|
|
953
|
+
try {
|
|
954
|
+
unlinkSync(targetPath);
|
|
955
|
+
}
|
|
956
|
+
catch { }
|
|
957
|
+
try {
|
|
958
|
+
const { rmdirSync } = await import('fs');
|
|
959
|
+
rmdirSync(tempDir);
|
|
960
|
+
}
|
|
961
|
+
catch { }
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Get file extension for MIME type
|
|
966
|
+
*/
|
|
967
|
+
formatToExtension(mimeType) {
|
|
968
|
+
const extensions = {
|
|
969
|
+
'application/pdf': '.pdf',
|
|
970
|
+
'image/jpeg': '.jpg',
|
|
971
|
+
'image/png': '.png',
|
|
972
|
+
'image/tiff': '.tiff',
|
|
973
|
+
'application/postscript': '.ps',
|
|
974
|
+
'image/pwg-raster': '.pwg',
|
|
975
|
+
'image/urf': '.urf',
|
|
976
|
+
'application/octet-stream': '.bin',
|
|
281
977
|
};
|
|
978
|
+
return extensions[mimeType] || '.bin';
|
|
282
979
|
}
|
|
283
980
|
}
|
|
284
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdG9jb2wuaXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvcHJvdG9jb2xzL3Byb3RvY29sLmlwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQU96Qzs7R0FFRztBQUNILE1BQU0sT0FBTyxXQUFXO0lBQ2QsVUFBVSxDQUFTO0lBQ25CLE9BQU8sQ0FBeUM7SUFFeEQsWUFBWSxPQUFlLEVBQUUsSUFBWSxFQUFFLE9BQWUsWUFBWTtRQUNwRSxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsT0FBTyxJQUFJLElBQUksR0FBRyxJQUFJLEVBQUUsQ0FBQztRQUNwRCxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsYUFBYTtRQUN4QixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUNsQix3QkFBd0IsRUFDeEIsSUFBSSxFQUNKLENBQUMsR0FBaUIsRUFBRSxHQUE0QixFQUFFLEVBQUU7Z0JBQ2xELElBQUksR0FBRyxFQUFFLENBQUM7b0JBQ1IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNaLE9BQU87Z0JBQ1QsQ0FBQztnQkFFRCxJQUFJLENBQUM7b0JBQ0gsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLHdCQUF3QixDQUE0QixJQUFJLEVBQUUsQ0FBQztvQkFDN0UsT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUN6QyxDQUFDO2dCQUFDLE9BQU8sUUFBUSxFQUFFLENBQUM7b0JBQ2xCLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDbkIsQ0FBQztZ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
|
|
981
|
+
// Export as IppProtocol for consistency with other protocols
|
|
982
|
+
export { IppClient as IppProtocol };
|
|
983
|
+
// ============================================================================
|
|
984
|
+
// Exports
|
|
985
|
+
// ============================================================================
|
|
986
|
+
export { IPP_VERSION, IPP_OPERATION, IPP_STATUS, JOB_STATE, PRINTER_STATE, isSuccessful, statusCodeToString, };
|
|
987
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdG9jb2wuaXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvcHJvdG9jb2xzL3Byb3RvY29sLmlwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCwrRUFBK0U7QUFDL0UsWUFBWTtBQUNaLCtFQUErRTtBQUUvRSxrQkFBa0I7QUFDbEIsTUFBTSxXQUFXLEdBQUc7SUFDbEIsSUFBSSxFQUFFLE1BQU07SUFDWixJQUFJLEVBQUUsTUFBTTtDQUNKLENBQUM7QUFFWCxxQkFBcUI7QUFDckIsTUFBTSxhQUFhLEdBQUc7SUFDcEIsU0FBUyxFQUFFLE1BQU07SUFDakIsWUFBWSxFQUFFLE1BQU07SUFDcEIsVUFBVSxFQUFFLE1BQU07SUFDbEIsa0JBQWtCLEVBQUUsTUFBTTtJQUMxQixRQUFRLEVBQUUsTUFBTTtJQUNoQixzQkFBc0IsRUFBRSxNQUFNO0NBQ3RCLENBQUM7QUFFWCx1QkFBdUI7QUFDdkIsTUFBTSxVQUFVLEdBQUc7SUFDakIsYUFBYTtJQUNiLGFBQWEsRUFBRSxNQUFNO0lBQ3JCLGdDQUFnQyxFQUFFLE1BQU07SUFDeEMsb0NBQW9DLEVBQUUsTUFBTTtJQUU1QyxnQkFBZ0I7SUFDaEIsd0JBQXdCLEVBQUUsTUFBTTtJQUNoQyxzQkFBc0IsRUFBRSxNQUFNO0lBQzlCLDhCQUE4QixFQUFFLE1BQU07SUFDdEMsMkJBQTJCLEVBQUUsTUFBTTtJQUNuQyx5QkFBeUIsRUFBRSxNQUFNO0lBQ2pDLG9CQUFvQixFQUFFLE1BQU07SUFDNUIsc0JBQXNCLEVBQUUsTUFBTTtJQUM5QiwwQ0FBMEMsRUFBRSxNQUFNO0lBRWxELGdCQUFnQjtJQUNoQixxQkFBcUIsRUFBRSxNQUFNO0lBQzdCLG9DQUFvQyxFQUFFLE1BQU07SUFDNUMsZ0NBQWdDLEVBQUUsTUFBTTtJQUN4Qyx5QkFBeUIsRUFBRSxNQUFNO0lBQ2pDLCtCQUErQixFQUFFLE1BQU07SUFDdkMsaUJBQWlCLEVBQUUsTUFBTTtDQUNqQixD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
|