@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
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { IPrinterCapabilities, IPrintOptions, IPrintJob } from '../interfaces/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* IPP protocol wrapper using the ipp npm package
|
|
4
|
+
*/
|
|
5
|
+
export declare class IppProtocol {
|
|
6
|
+
private printerUrl;
|
|
7
|
+
private printer;
|
|
8
|
+
constructor(address: string, port: number, path?: string);
|
|
9
|
+
/**
|
|
10
|
+
* Get printer attributes/capabilities
|
|
11
|
+
*/
|
|
12
|
+
getAttributes(): Promise<IPrinterCapabilities>;
|
|
13
|
+
/**
|
|
14
|
+
* Print a document
|
|
15
|
+
*/
|
|
16
|
+
print(data: Buffer, options?: IPrintOptions): Promise<IPrintJob>;
|
|
17
|
+
/**
|
|
18
|
+
* Get all jobs
|
|
19
|
+
*/
|
|
20
|
+
getJobs(): Promise<IPrintJob[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Get specific job info
|
|
23
|
+
*/
|
|
24
|
+
getJobInfo(jobId: number): Promise<IPrintJob>;
|
|
25
|
+
/**
|
|
26
|
+
* Cancel a job
|
|
27
|
+
*/
|
|
28
|
+
cancelJob(jobId: number): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Check if printer is available
|
|
31
|
+
*/
|
|
32
|
+
checkAvailability(): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Build IPP print message from options
|
|
35
|
+
*/
|
|
36
|
+
private buildPrintMessage;
|
|
37
|
+
/**
|
|
38
|
+
* Parse printer capabilities from attributes
|
|
39
|
+
*/
|
|
40
|
+
private parseCapabilities;
|
|
41
|
+
/**
|
|
42
|
+
* Parse job info from attributes
|
|
43
|
+
*/
|
|
44
|
+
private parseJobInfo;
|
|
45
|
+
}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
/**
|
|
3
|
+
* IPP protocol wrapper using the ipp npm package
|
|
4
|
+
*/
|
|
5
|
+
export class IppProtocol {
|
|
6
|
+
printerUrl;
|
|
7
|
+
printer;
|
|
8
|
+
constructor(address, port, path = '/ipp/print') {
|
|
9
|
+
this.printerUrl = `ipp://${address}:${port}${path}`;
|
|
10
|
+
this.printer = plugins.ipp.Printer(this.printerUrl);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get printer attributes/capabilities
|
|
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
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Print a document
|
|
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
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get all jobs
|
|
55
|
+
*/
|
|
56
|
+
async getJobs() {
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
this.printer.execute('Get-Jobs', {
|
|
59
|
+
'operation-attributes-tag': {
|
|
60
|
+
'requesting-user-name': 'devicemanager',
|
|
61
|
+
'which-jobs': 'not-completed',
|
|
62
|
+
},
|
|
63
|
+
}, (err, res) => {
|
|
64
|
+
if (err) {
|
|
65
|
+
reject(err);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const jobs = [];
|
|
70
|
+
const jobTags = res['job-attributes-tag'];
|
|
71
|
+
if (Array.isArray(jobTags)) {
|
|
72
|
+
for (const jobAttrs of jobTags) {
|
|
73
|
+
jobs.push(this.parseJobInfo(jobAttrs));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else if (jobTags && typeof jobTags === 'object') {
|
|
77
|
+
jobs.push(this.parseJobInfo(jobTags));
|
|
78
|
+
}
|
|
79
|
+
resolve(jobs);
|
|
80
|
+
}
|
|
81
|
+
catch (parseErr) {
|
|
82
|
+
reject(parseErr);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get specific job info
|
|
89
|
+
*/
|
|
90
|
+
async getJobInfo(jobId) {
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
this.printer.execute('Get-Job-Attributes', {
|
|
93
|
+
'operation-attributes-tag': {
|
|
94
|
+
'job-id': jobId,
|
|
95
|
+
},
|
|
96
|
+
}, (err, res) => {
|
|
97
|
+
if (err) {
|
|
98
|
+
reject(err);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const jobAttrs = res['job-attributes-tag'] || {};
|
|
103
|
+
resolve(this.parseJobInfo(jobAttrs));
|
|
104
|
+
}
|
|
105
|
+
catch (parseErr) {
|
|
106
|
+
reject(parseErr);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Cancel a job
|
|
113
|
+
*/
|
|
114
|
+
async cancelJob(jobId) {
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
116
|
+
this.printer.execute('Cancel-Job', {
|
|
117
|
+
'operation-attributes-tag': {
|
|
118
|
+
'job-id': jobId,
|
|
119
|
+
},
|
|
120
|
+
}, (err, _res) => {
|
|
121
|
+
if (err) {
|
|
122
|
+
reject(err);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
resolve();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if printer is available
|
|
131
|
+
*/
|
|
132
|
+
async checkAvailability() {
|
|
133
|
+
try {
|
|
134
|
+
await this.getAttributes();
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Build IPP print message from options
|
|
143
|
+
*/
|
|
144
|
+
buildPrintMessage(options) {
|
|
145
|
+
const operationAttrs = {
|
|
146
|
+
'requesting-user-name': 'devicemanager',
|
|
147
|
+
'job-name': options?.jobName ?? 'Print Job',
|
|
148
|
+
'document-format': 'application/octet-stream',
|
|
149
|
+
};
|
|
150
|
+
const jobAttrs = {};
|
|
151
|
+
if (options?.copies && options.copies > 1) {
|
|
152
|
+
jobAttrs['copies'] = options.copies;
|
|
153
|
+
}
|
|
154
|
+
if (options?.mediaSize) {
|
|
155
|
+
jobAttrs['media'] = options.mediaSize;
|
|
156
|
+
}
|
|
157
|
+
if (options?.mediaType) {
|
|
158
|
+
jobAttrs['media-type'] = options.mediaType;
|
|
159
|
+
}
|
|
160
|
+
if (options?.sides) {
|
|
161
|
+
jobAttrs['sides'] = options.sides;
|
|
162
|
+
}
|
|
163
|
+
if (options?.quality) {
|
|
164
|
+
const qualityMap = {
|
|
165
|
+
draft: 3,
|
|
166
|
+
normal: 4,
|
|
167
|
+
high: 5,
|
|
168
|
+
};
|
|
169
|
+
jobAttrs['print-quality'] = qualityMap[options.quality] ?? 4;
|
|
170
|
+
}
|
|
171
|
+
if (options?.colorMode) {
|
|
172
|
+
jobAttrs['print-color-mode'] = options.colorMode;
|
|
173
|
+
}
|
|
174
|
+
const msg = {
|
|
175
|
+
'operation-attributes-tag': operationAttrs,
|
|
176
|
+
};
|
|
177
|
+
if (Object.keys(jobAttrs).length > 0) {
|
|
178
|
+
msg['job-attributes-tag'] = jobAttrs;
|
|
179
|
+
}
|
|
180
|
+
return msg;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Parse printer capabilities from attributes
|
|
184
|
+
*/
|
|
185
|
+
parseCapabilities(attrs) {
|
|
186
|
+
const getArray = (key) => {
|
|
187
|
+
const value = attrs[key];
|
|
188
|
+
if (Array.isArray(value))
|
|
189
|
+
return value.map(String);
|
|
190
|
+
if (value !== undefined)
|
|
191
|
+
return [String(value)];
|
|
192
|
+
return [];
|
|
193
|
+
};
|
|
194
|
+
const getNumber = (key, defaultVal) => {
|
|
195
|
+
const value = attrs[key];
|
|
196
|
+
if (typeof value === 'number')
|
|
197
|
+
return value;
|
|
198
|
+
if (typeof value === 'string')
|
|
199
|
+
return parseInt(value) || defaultVal;
|
|
200
|
+
return defaultVal;
|
|
201
|
+
};
|
|
202
|
+
const getBool = (key, defaultVal) => {
|
|
203
|
+
const value = attrs[key];
|
|
204
|
+
if (typeof value === 'boolean')
|
|
205
|
+
return value;
|
|
206
|
+
if (value === 'true' || value === 1)
|
|
207
|
+
return true;
|
|
208
|
+
if (value === 'false' || value === 0)
|
|
209
|
+
return false;
|
|
210
|
+
return defaultVal;
|
|
211
|
+
};
|
|
212
|
+
// Parse resolutions
|
|
213
|
+
const resolutions = [];
|
|
214
|
+
const resSupported = attrs['printer-resolution-supported'];
|
|
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
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (resolutions.length === 0) {
|
|
226
|
+
resolutions.push(300, 600);
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
colorSupported: getBool('color-supported', false),
|
|
230
|
+
duplexSupported: getArray('sides-supported').some((s) => s.includes('two-sided')),
|
|
231
|
+
mediaSizes: getArray('media-supported'),
|
|
232
|
+
mediaTypes: getArray('media-type-supported'),
|
|
233
|
+
resolutions: [...new Set(resolutions)],
|
|
234
|
+
maxCopies: getNumber('copies-supported', 99),
|
|
235
|
+
sidesSupported: getArray('sides-supported'),
|
|
236
|
+
qualitySupported: getArray('print-quality-supported').map(String),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Parse job info from attributes
|
|
241
|
+
*/
|
|
242
|
+
parseJobInfo(attrs) {
|
|
243
|
+
const getString = (key, defaultVal) => {
|
|
244
|
+
const value = attrs[key];
|
|
245
|
+
if (typeof value === 'string')
|
|
246
|
+
return value;
|
|
247
|
+
if (value !== undefined)
|
|
248
|
+
return String(value);
|
|
249
|
+
return defaultVal;
|
|
250
|
+
};
|
|
251
|
+
const getNumber = (key, defaultVal) => {
|
|
252
|
+
const value = attrs[key];
|
|
253
|
+
if (typeof value === 'number')
|
|
254
|
+
return value;
|
|
255
|
+
if (typeof value === 'string')
|
|
256
|
+
return parseInt(value) || defaultVal;
|
|
257
|
+
return defaultVal;
|
|
258
|
+
};
|
|
259
|
+
// Map IPP job state to our state
|
|
260
|
+
const ippState = getNumber('job-state', 3);
|
|
261
|
+
const stateMap = {
|
|
262
|
+
3: 'pending', // pending
|
|
263
|
+
4: 'pending', // pending-held
|
|
264
|
+
5: 'processing', // processing
|
|
265
|
+
6: 'processing', // processing-stopped
|
|
266
|
+
7: 'canceled', // canceled
|
|
267
|
+
8: 'aborted', // aborted
|
|
268
|
+
9: 'completed', // completed
|
|
269
|
+
};
|
|
270
|
+
const createdTime = attrs['time-at-creation'];
|
|
271
|
+
const completedTime = attrs['time-at-completed'];
|
|
272
|
+
return {
|
|
273
|
+
id: getNumber('job-id', 0),
|
|
274
|
+
name: getString('job-name', 'Unknown Job'),
|
|
275
|
+
state: stateMap[ippState] ?? 'pending',
|
|
276
|
+
stateReason: getString('job-state-reasons', undefined),
|
|
277
|
+
createdAt: createdTime ? new Date(createdTime * 1000) : new Date(),
|
|
278
|
+
completedAt: completedTime ? new Date(completedTime * 1000) : undefined,
|
|
279
|
+
pagesPrinted: getNumber('job-media-sheets-completed', undefined),
|
|
280
|
+
pagesTotal: getNumber('job-media-sheets', undefined),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdG9jb2wuaXBwLm9sZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3Byb3RvY29scy9wcm90b2NvbC5pcHAub2xkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBT3pDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFDZCxVQUFVLENBQVM7SUFDbkIsT0FBTyxDQUF5QztJQUV4RCxZQUFZLE9BQWUsRUFBRSxJQUFZLEVBQUUsT0FBZSxZQUFZO1FBQ3BFLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxPQUFPLElBQUksSUFBSSxHQUFHLElBQUksRUFBRSxDQUFDO1FBQ3BELElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3RELENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxhQUFhO1FBQ3hCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQ2xCLHdCQUF3QixFQUN4QixJQUFJLEVBQ0osQ0FBQyxHQUFpQixFQUFFLEdBQTRCLEVBQUUsRUFBRTtnQkFDbEQsSUFBSSxHQUFHLEVBQUUsQ0FBQztvQkFDUixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ1osT0FBTztnQkFDVCxDQUFDO2dCQUVELElBQUksQ0FBQztvQkFDSCxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsd0JBQXdCLENBQTRCLElBQUksRUFBRSxDQUFDO29CQUM3RSxPQUFPLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ3pDLENBQUM7Z0JBQUMsT0FBTyxRQUFRLEVBQUUsQ0FBQztvQkFDbEIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNu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
|
package/package.json
CHANGED
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Feature, type TDeviceReference } from './feature.abstract.js';
|
|
7
|
-
import { IppProtocol } from '../protocols/index.js';
|
|
7
|
+
import { IppProtocol, type IIppPrinterCapabilities, type IIppJob } from '../protocols/index.js';
|
|
8
8
|
import type {
|
|
9
9
|
TPrintProtocol,
|
|
10
10
|
TPrintSides,
|
|
@@ -16,7 +16,6 @@ import type {
|
|
|
16
16
|
IPrintFeatureInfo,
|
|
17
17
|
IFeatureOptions,
|
|
18
18
|
} from '../interfaces/feature.interfaces.js';
|
|
19
|
-
import type { IPrinterCapabilities } from '../interfaces/index.js';
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* Options for creating a PrintFeature
|
|
@@ -101,7 +100,7 @@ export class PrintFeature extends Feature {
|
|
|
101
100
|
|
|
102
101
|
this.ippClient = new IppProtocol(address, port, path);
|
|
103
102
|
// Verify connection by getting printer attributes
|
|
104
|
-
const attrs = await this.ippClient.
|
|
103
|
+
const attrs = await this.ippClient.getPrinterAttributes();
|
|
105
104
|
this.updateCapabilitiesFromIpp(attrs);
|
|
106
105
|
}
|
|
107
106
|
// JetDirect and LPD don't need connection verification
|
|
@@ -154,7 +153,8 @@ export class PrintFeature extends Feature {
|
|
|
154
153
|
throw new Error('Print feature not connected');
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
|
|
156
|
+
const jobs = await this.ippClient.getJobs();
|
|
157
|
+
return jobs.map(job => this.mapIppJobToInternal(job));
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/**
|
|
@@ -165,7 +165,8 @@ export class PrintFeature extends Feature {
|
|
|
165
165
|
throw new Error('Print feature not connected');
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
const job = await this.ippClient.getJobAttributes(jobId);
|
|
169
|
+
return this.mapIppJobToInternal(job);
|
|
169
170
|
}
|
|
170
171
|
|
|
171
172
|
/**
|
|
@@ -191,9 +192,17 @@ export class PrintFeature extends Feature {
|
|
|
191
192
|
|
|
192
193
|
this.emit('print:started', options);
|
|
193
194
|
|
|
194
|
-
//
|
|
195
|
-
const
|
|
195
|
+
// Use smartPrint for auto format detection and conversion
|
|
196
|
+
const ippJob = await this.ippClient.smartPrint(data, {
|
|
197
|
+
jobName: options?.jobName,
|
|
198
|
+
copies: options?.copies,
|
|
199
|
+
media: options?.mediaSize,
|
|
200
|
+
sides: options?.sides,
|
|
201
|
+
printQuality: options?.quality,
|
|
202
|
+
colorMode: options?.colorMode,
|
|
203
|
+
});
|
|
196
204
|
|
|
205
|
+
const job = this.mapIppJobToInternal(ippJob);
|
|
197
206
|
this.emit('print:submitted', job);
|
|
198
207
|
return job;
|
|
199
208
|
}
|
|
@@ -202,58 +211,57 @@ export class PrintFeature extends Feature {
|
|
|
202
211
|
// Helper Methods
|
|
203
212
|
// ============================================================================
|
|
204
213
|
|
|
205
|
-
private updateCapabilitiesFromIpp(caps:
|
|
214
|
+
private updateCapabilitiesFromIpp(caps: IIppPrinterCapabilities): void {
|
|
206
215
|
this.supportsColor = caps.colorSupported;
|
|
207
|
-
|
|
208
|
-
this.
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
// Derive duplexSupported from sidesSupported
|
|
217
|
+
this.supportsDuplex = caps.sidesSupported?.some(s =>
|
|
218
|
+
s.includes('two-sided')
|
|
219
|
+
) ?? false;
|
|
220
|
+
// Get max copies from range
|
|
221
|
+
this.maxCopies = caps.copiesSupported?.upper ?? 99;
|
|
222
|
+
|
|
223
|
+
if (caps.mediaSizeSupported && caps.mediaSizeSupported.length > 0) {
|
|
224
|
+
this.supportedMediaSizes = caps.mediaSizeSupported;
|
|
212
225
|
}
|
|
213
|
-
if (caps.
|
|
214
|
-
this.supportedMediaTypes = caps.
|
|
226
|
+
if (caps.mediaTypeSupported && caps.mediaTypeSupported.length > 0) {
|
|
227
|
+
this.supportedMediaTypes = caps.mediaTypeSupported;
|
|
215
228
|
}
|
|
216
229
|
if (caps.sidesSupported && caps.sidesSupported.length > 0) {
|
|
217
230
|
this.supportedSides = caps.sidesSupported.filter((s): s is TPrintSides =>
|
|
218
231
|
['one-sided', 'two-sided-long-edge', 'two-sided-short-edge'].includes(s)
|
|
219
232
|
);
|
|
220
233
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
private qualityToIpp(quality: TPrintQuality): number {
|
|
229
|
-
switch (quality) {
|
|
230
|
-
case 'draft': return 3;
|
|
231
|
-
case 'normal': return 4;
|
|
232
|
-
case 'high': return 5;
|
|
233
|
-
default: return 4;
|
|
234
|
+
// Map IPP quality values (3=draft, 4=normal, 5=high) to strings
|
|
235
|
+
if (caps.printQualitySupported && caps.printQualitySupported.length > 0) {
|
|
236
|
+
const qualityMap: Record<number, TPrintQuality> = { 3: 'draft', 4: 'normal', 5: 'high' };
|
|
237
|
+
this.supportedQualities = caps.printQualitySupported
|
|
238
|
+
.map(q => qualityMap[q])
|
|
239
|
+
.filter((q): q is TPrintQuality => q !== undefined);
|
|
234
240
|
}
|
|
235
241
|
}
|
|
236
242
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
/**
|
|
244
|
+
* Map IIppJob to IPrintJob, normalizing extended states
|
|
245
|
+
*/
|
|
246
|
+
private mapIppJobToInternal(job: IIppJob): IPrintJob {
|
|
247
|
+
// Map extended IPP states to simpler internal states
|
|
248
|
+
const stateMap: Record<IIppJob['state'], IPrintJob['state']> = {
|
|
249
|
+
'pending': 'pending',
|
|
250
|
+
'pending-held': 'pending',
|
|
251
|
+
'processing': 'processing',
|
|
252
|
+
'processing-stopped': 'processing',
|
|
253
|
+
'canceled': 'canceled',
|
|
254
|
+
'aborted': 'aborted',
|
|
255
|
+
'completed': 'completed',
|
|
246
256
|
};
|
|
247
257
|
|
|
248
258
|
return {
|
|
249
|
-
id: job
|
|
250
|
-
name: job
|
|
251
|
-
state: stateMap[
|
|
252
|
-
stateReason:
|
|
253
|
-
createdAt:
|
|
254
|
-
completedAt: job
|
|
255
|
-
? new Date((job['time-at-completed'] as number) * 1000)
|
|
256
|
-
: undefined,
|
|
259
|
+
id: job.id,
|
|
260
|
+
name: job.name,
|
|
261
|
+
state: stateMap[job.state],
|
|
262
|
+
stateReason: job.stateReasons?.[0],
|
|
263
|
+
createdAt: job.createdAt,
|
|
264
|
+
completedAt: job.completedAt,
|
|
257
265
|
};
|
|
258
266
|
}
|
|
259
267
|
|
package/ts/protocols/index.ts
CHANGED
|
@@ -10,7 +10,12 @@ export { EsclProtocol } from './protocol.escl.js';
|
|
|
10
10
|
export { SaneProtocol } from './protocol.sane.js';
|
|
11
11
|
|
|
12
12
|
// IPP printer protocol
|
|
13
|
-
export {
|
|
13
|
+
export {
|
|
14
|
+
IppProtocol,
|
|
15
|
+
type IIppPrinterCapabilities,
|
|
16
|
+
type IIppJob,
|
|
17
|
+
type IIppPrintOptions,
|
|
18
|
+
} from './protocol.ipp.js';
|
|
14
19
|
|
|
15
20
|
// SNMP query protocol
|
|
16
21
|
export {
|