node-hp-scan-to 1.9.7 → 1.10.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/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [![CodeFactor](https://www.codefactor.io/repository/github/manuc66/node-hp-scan-to/badge)](https://www.codefactor.io/repository/github/manuc66/node-hp-scan-to)
9
9
  [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fmanuc66%2Fnode-hp-scan-to.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fmanuc66%2Fnode-hp-scan-to?ref=badge_shield)
10
10
 
11
- **`node-hp-scan-to`** is a Node.js application that replicates HP's "_Scan to Computer_" functionality by [reverse engineering](protocol_doc/HP%20Officejet%206500%20E710n-z.md) the original protocol, allowing you to scan documents directly from your HP printer's scanner to your Linux, Windows, or macOS computer.
11
+ **`node-hp-scan-to`** is a Node.js application that replicates HP's "_Scan to Computer_" functionality by [reverse engineering HP's proprietary protocols](protocol_doc/HP%20Officejet%206500%20E710n-z.md) and supporting the standardized [eSCL protocol](protocol_doc/HP%20PageWide%20Pro%20477dw%20MFP.md), allowing you to scan documents directly from your HP printer's scanner to your Linux, Windows, or macOS computer.
12
12
 
13
13
 
14
14
  Unlike the original HP program, `node-hp-scan-to` is cross-platform and can be run on a bare-metal desktop or server, or in a container on Docker or Kubernetes. It can also be integrated with third-party document management solutions such as [Paperless-ngx](https://docs.paperless-ngx.com/) and [Nextcloud](https://Nextcloud.com/).
@@ -22,6 +22,8 @@ Unlike the original HP program, `node-hp-scan-to` is cross-platform and can be r
22
22
  - [Supported Devices](#supported-devices)
23
23
  - [Supported Functions](#supported-functions)
24
24
  - [App Features](#app-features)
25
+ - [Protocol Support](#protocol-support)
26
+ - [Emulated Duplex Scanning Feature](#emulated-duplex-scanning-feature)
25
27
  - [Installation](#installation)
26
28
  - [Using NodeJS](#using-nodejs)
27
29
  - [Using Docker](#using-docker)
@@ -83,6 +85,14 @@ There is a good chance it also works on other unlisted HP All-in-One Printer.
83
85
  - Local folders
84
86
  - [Paperless-ngx API](https://docs.paperless-ngx.com/api/) upload
85
87
  - [Nextcloud WebDAV](https://docs.Nextcloud.com/server/latest/user_manual/en/files/access_webdav.html) upload
88
+
89
+ ### Protocol Support
90
+
91
+ Supports both HP proprietary protocols (WalkupScanToComp, WalkupScan, ScanJob) and the standardized eSCL protocol.
92
+
93
+ - **eSCL-only devices** (e.g., HP ScanJet Pro 4500 fn1): Automatically detected and supported ([#1307](https://github.com/manuc66/node-hp-scan-to/issues/1307))
94
+ - **Dual-protocol devices**: Uses HP protocols by default; add `--prefer-eSCL` flag to use eSCL instead
95
+ - See [eSCL protocol documentation](protocol_doc/HP%20PageWide%20Pro%20477dw%20MFP.md) for technical details
86
96
 
87
97
  ### Emulated Duplex Scanning Feature
88
98
 
@@ -160,6 +170,9 @@ Run `npx node-hp-scan-to --help` to see the full list of options below:
160
170
  | `-p`, `--pattern` | Filename pattern (no extension). Use quotes for static text, supports date/time masks (see [dateformat docs](https://www.npmjs.com/package/dateformat#mask-options)). Defaults to `scan<increasing number>_page<page number>`. | `-p scan1_page1` |
161
171
  | `-r`, `--resolution` | Scan resolution in DPI. Defaults to 200. | `-r 200` |
162
172
  | `--mode <mode> ` | Selects the scan mode (default: Color) (choices: "Gray", "Color"). | `--mode Gray` |
173
+ | `--paper-size <size>` | Paper size preset: A4 (default), Letter, Legal, A5, B5, or Max (case-insensitive). Cannot be used with `--paper-dim`. | `--paper-size Letter` |
174
+ | `--paper-orientation <orientation>` | Paper orientation: portrait (default) or landscape. Applied to `--paper-size` only. | `--paper-orientation landscape` |
175
+ | `--paper-dim <dimensions>` | Custom paper dimensions with unit (e.g., 21x29.7cm, 8.5x11in, 210x297mm). Cannot be used with `--paper-size`. | `--paper-dim 8.5x11in` |
163
176
  | `-s`, `--paperless-post-document-url` | Paperless-ngx API URL for uploading documents. | `-s https://domain.tld/api/documents/post_document/` (no default) |
164
177
  | `-t`, `--temp-directory` | Temporary directory for processing. Defaults to `/tmp/scan-to-pc<random value>` if not set. | `-t /tmp/scan-to-pc5678` |
165
178
  | `-w`, `--width` | Scan width in pixels. Defaults to 2481. | `-w 2481` |
@@ -172,11 +185,97 @@ Run `npx node-hp-scan-to --help` to see the full list of options below:
172
185
 
173
186
  **Notes:**
174
187
 
175
- - Date/time patterns for `--pattern` follow the [dateformat](https://www.npmjs.com/package/dateformat) librarys Mask options section.
188
+ - Date/time patterns for `--pattern` follow the [dateformat](https://www.npmjs.com/package/dateformat) library's "Mask options" section.
176
189
 
177
190
  - Defaults like `/tmp/scan-to-pc<random value>` include a random suffix in practice (e.g., `/tmp/scan-to-pc1234`).
178
191
 
179
- #### CLI Commands
192
+ #### Paper Size Configuration
193
+
194
+ By default, scans use **A4 paper size** (210×297 mm). You can specify a different paper size or custom dimensions via CLI flags, environment variables, or the config file.
195
+
196
+ ##### Preset Paper Sizes
197
+
198
+ The following preset sizes are available (case-insensitive):
199
+
200
+ | Preset | Dimensions | Use Case |
201
+ |--------|-----------|----------|
202
+ | **A4** (default) | 210×297 mm | Standard European paper size |
203
+ | **Letter** | 215.9×279.4 mm | Standard US letter size |
204
+ | **Legal** | 215.9×355.6 mm | Standard US legal size |
205
+ | **A5** | 148×210 mm | Half of A4 size |
206
+ | **B5** | 176×250 mm | Between A4 and A5 |
207
+ | **Max** | Device maximum | Uses the device's maximum scannable area (not auto-detect) |
208
+
209
+ ##### Custom Sizes
210
+
211
+ You can specify custom paper dimensions with explicit units using the `--paper-dim` option:
212
+
213
+ ```bash
214
+ # Centimeters
215
+ npx node-hp-scan-to single-scan --paper-dim 21x29.7cm
216
+
217
+ # Inches
218
+ npx node-hp-scan-to single-scan --paper-dim 8.5x11in
219
+
220
+ # Millimeters
221
+ npx node-hp-scan-to single-scan --paper-dim 210x297mm
222
+ ```
223
+
224
+ **Supported units:** `cm`, `mm`, `in` (inches). Units are **required** and **case-insensitive**.
225
+
226
+ ##### Configuration Precedence
227
+
228
+ Paper size is resolved in the following order (highest to lowest priority):
229
+
230
+ 1. **CLI flags**: `--paper-size` or `--paper-dim`
231
+ 2. **Environment variables**: `PAPER_SIZE` or `PAPER_DIM`
232
+ 3. **Config file**: `paper_size` or `paper_dim` in `config/default.json`
233
+ 4. **Default**: A4 (210×297 mm)
234
+
235
+ ##### Important Rules
236
+
237
+ - **Cannot specify both `--paper-size` and `--paper-dim` simultaneously.** You must choose one; attempting to use both will result in an error.
238
+ - **Resolution (DPI) is independent** of paper size. You can specify both independently:
239
+ ```bash
240
+ npx node-hp-scan-to single-scan --paper-size Letter --resolution 300
241
+ ```
242
+ - **Device maximum is respected.** If your custom size exceeds the device's maximum scannable area, the scan will be clamped to the device's limits.
243
+ - **"Max" uses device capabilities, not auto-detection.** The `Max` preset uses the device's reported maximum scan area; it does **not** automatically detect the actual paper size in the scanner.
244
+
245
+ ##### Examples
246
+
247
+ ```bash
248
+ # Use Letter size
249
+ npx node-hp-scan-to single-scan --paper-size Letter
250
+
251
+ # Use A5 (smaller) size
252
+ npx node-hp-scan-to single-scan --paper-size A5
253
+
254
+ # Use maximum scannable area
255
+ npx node-hp-scan-to single-scan --paper-size Max
256
+
257
+ # Use custom size in centimeters
258
+ npx node-hp-scan-to single-scan --paper-dim 21x29.7cm
259
+
260
+ # Use custom size in inches (8.5" × 11")
261
+ npx node-hp-scan-to single-scan --paper-dim 8.5x11in
262
+
263
+ # With Docker (environment variable)
264
+ docker run -e PAPER_SIZE=Letter manuc66/node-hp-scan-to
265
+
266
+ # With Docker Compose
267
+ environment:
268
+ PAPER_SIZE: "Letter"
269
+ PAPER_DIM: null # Must be null if not using custom dimensions
270
+
271
+ # In config file (config/default.json)
272
+ {
273
+ "paper_size": "A4",
274
+ "paper_dim": null
275
+ }
276
+ ```
277
+
278
+
180
279
 
181
280
  ##### `listen`
182
281
 
@@ -200,6 +299,9 @@ Scan Options:
200
299
  --mode <mode> Selects the scan mode (default: Color) (choices: "Gray", "Color")
201
300
  -w, --width <width> Width in pixels of the scans (default: max)
202
301
  -h, --height <height> Height in pixels of the scans (default: max)
302
+ --paper-size <size> Paper size preset: A4 (default), Letter, Legal, A5, B5, or Max (case-insensitive)
303
+ --paper-orientation <orientation> Paper orientation: portrait (default) or landscape. Applied to --paper-size only. (choices: "portrait", "landscape")
304
+ --paper-dim <dimensions> Custom paper dimensions with unit (e.g., 21x29.7cm, 8.5x11in, 210x297mm). Cannot be used with --paper-size.
203
305
  -t, --temp-directory <dir> Temp directory used for processing (default: /tmp/scan-to-pcRANDOM)
204
306
  --prefer-eSCL Prefer eSCL protocol if available
205
307
 
@@ -265,6 +367,9 @@ Scan Options:
265
367
  --mode <mode> Selects the scan mode (default: Color) (choices: "Gray", "Color")
266
368
  -w, --width <width> Width in pixels of the scans (default: max)
267
369
  -h, --height <height> Height in pixels of the scans (default: max)
370
+ --paper-size <size> Paper size preset: A4 (default), Letter, Legal, A5, B5, or Max (case-insensitive)
371
+ --paper-orientation <orientation> Paper orientation: portrait (default) or landscape. Applied to --paper-size only. (choices: "portrait", "landscape")
372
+ --paper-dim <dimensions> Custom paper dimensions with unit (e.g., 21x29.7cm, 8.5x11in, 210x297mm). Cannot be used with --paper-size.
268
373
  -t, --temp-directory <dir> Temp directory used for processing (default: /tmp/scan-to-pcRANDOM)
269
374
  --prefer-eSCL Prefer eSCL protocol if available
270
375
  --duplex If specified, all the scans will be in duplex if the device support it
@@ -359,6 +464,9 @@ Scan Options:
359
464
  --mode <mode> Selects the scan mode (default: Color) (choices: "Gray", "Color")
360
465
  -w, --width <width> Width in pixels of the scans (default: max)
361
466
  -h, --height <height> Height in pixels of the scans (default: max)
467
+ --paper-size <size> Paper size preset: A4 (default), Letter, Legal, A5, B5, or Max (case-insensitive)
468
+ --paper-orientation <orientation> Paper orientation: portrait (default) or landscape. Applied to --paper-size only. (choices: "portrait", "landscape")
469
+ --paper-dim <dimensions> Custom paper dimensions with unit (e.g., 21x29.7cm, 8.5x11in, 210x297mm). Cannot be used with --paper-size.
362
470
  -t, --temp-directory <dir> Temp directory used for processing (default: /tmp/scan-to-pcRANDOM)
363
471
  --prefer-eSCL Prefer eSCL protocol if available
364
472
  --duplex If specified, all the scans will be in duplex if the device support it
@@ -437,6 +545,7 @@ List of supported environment variables and their meaning, or correspondence wit
437
545
  | `PUID` | ID of the user that will run the program | |
438
546
  | `RESOLUTION` | Resolution setting | `-r` / `--resolution` |
439
547
  | `MODE` | Scan mode setting | `--mode` |
548
+ | `PAPER_ORIENTATION` | Paper orientation: portrait (default) or landscape. Applied to `PAPER_SIZE` only. | `--paper-orientation` |
440
549
  | `TEMP_DIR` | Temporary directory | `-t` / `--temp-directory` |
441
550
 
442
551
  **Additional Notes:**
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Standard unit resolution (1/300 inch) used for eSCL ScanRegion (ThreeHundredthsOfInches)
3
+ * and potentially for non-eSCL legacy device configurations.
4
+ */
5
+ export declare const THREE_HUNDREDTHS_OF_INCH_DPI = 300;
6
+ /**
7
+ * Paper size in millimeters.
8
+ */
9
+ export interface PaperSizeMm {
10
+ widthMm: number;
11
+ heightMm: number;
12
+ }
13
+ /**
14
+ * Resolved paper size with its human-readable source label (for logging).
15
+ */
16
+ export interface ResolvedPaperSize {
17
+ resolvedMm: PaperSizeMm;
18
+ /** Human-readable label, e.g. "A4", "Custom (21x29.7cm)" */
19
+ source: string;
20
+ }
21
+ /**
22
+ * Scan region dimensions in device units (eSCL: 1/300", non-eSCL: pixels at scan DPI).
23
+ */
24
+ export interface ScanRegionUnits {
25
+ width: number;
26
+ height: number;
27
+ }
28
+ /**
29
+ * Converts millimeters to scan region units using the given unit resolution.
30
+ *
31
+ * @param mm - Dimension in millimeters
32
+ * @param unitResolution - Units per inch (300 for eSCL, scan DPI for non-eSCL)
33
+ */
34
+ export declare function mmToScanUnits(mm: number, unitResolution: number): number;
35
+ /**
36
+ * Converts a paper size preset name to dimensions in millimeters.
37
+ * Returns null for the "Max" pseudo-preset (caller must handle device max).
38
+ */
39
+ export declare function paperSizePresetToMm(preset: string): PaperSizeMm | null;
40
+ /**
41
+ * Parses a custom paper size string in the format "WxH<unit>".
42
+ * Supported units: mm, cm, in.
43
+ * Example: "21x29.7cm", "8.5x11in", "210x297mm"
44
+ */
45
+ export declare function parsePaperSize(input: string): PaperSizeMm | null;
46
+ /**
47
+ * Resolves a paper size configuration (preset name or custom dimension string)
48
+ * to millimeters, without any device clamping.
49
+ *
50
+ * - If both paperSizeInput and paperDimInput are provided, throws.
51
+ * - If "Max" preset is provided, returns null (caller owns device-max logic).
52
+ * - If neither is provided, returns null.
53
+ *
54
+ * @param paperSizeInput - Preset name (e.g. "A4", "Letter", "Max")
55
+ * @param paperDimInput - Custom dimension string (e.g. "21x29.7cm")
56
+ * @param orientation - Orientation ("portrait" or "landscape")
57
+ */
58
+ export declare function validateAndResolvePaperSize(paperSizeInput?: string | null, paperDimInput?: string | null, orientation?: "portrait" | "landscape" | null): ResolvedPaperSize | null;
59
+ /**
60
+ * Converts resolved paper size (in mm) to scan region units, clamped to device
61
+ * maximum dimensions (also expressed in the same unit space).
62
+ *
63
+ * This is the final step before submitting a ScanRegion to the device.
64
+ *
65
+ * @param resolvedMm - Paper size in millimeters (from validateAndResolvePaperSize)
66
+ * @param unitResolution - Units per inch: use THREE_HUNDREDTHS_OF_INCH_DPI (300) for eSCL,
67
+ * or the scan DPI for non-eSCL devices
68
+ * @param maxWidth - Device max width in device units (null = unconstrained)
69
+ * @param maxHeight - Device max height in device units (null = unconstrained)
70
+ */
71
+ export declare function paperSizeMmToScanRegion(resolvedMm: PaperSizeMm, unitResolution: number, maxWidth: number | null, maxHeight: number | null): ScanRegionUnits;
72
+ /**
73
+ * Returns the default paper size (A4).
74
+ */
75
+ export declare function getDefaultPaperSize(): PaperSizeMm;
76
+ /**
77
+ * Returns true if the given preset string is the "Max" pseudo-preset.
78
+ */
79
+ export declare function isMaxPreset(preset?: string | null): boolean;
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Standard unit resolution (1/300 inch) used for eSCL ScanRegion (ThreeHundredthsOfInches)
3
+ * and potentially for non-eSCL legacy device configurations.
4
+ */
5
+ export const THREE_HUNDREDTHS_OF_INCH_DPI = 300;
6
+ /**
7
+ * Paper size preset mapping to dimensions in millimeters.
8
+ */
9
+ const PAPER_SIZE_PRESETS = {
10
+ // ISO A-series
11
+ a3: { widthMm: 297, heightMm: 420 },
12
+ a4: { widthMm: 210, heightMm: 297 },
13
+ a5: { widthMm: 148, heightMm: 210 },
14
+ a6: { widthMm: 105, heightMm: 148 },
15
+ a7: { widthMm: 74, heightMm: 105 },
16
+ a8: { widthMm: 52, heightMm: 74 },
17
+ // ISO B-series (JIS)
18
+ b4: { widthMm: 250, heightMm: 353 },
19
+ b5: { widthMm: 176, heightMm: 250 },
20
+ b6: { widthMm: 125, heightMm: 176 },
21
+ // North American
22
+ letter: { widthMm: 215.9, heightMm: 279.4 },
23
+ legal: { widthMm: 215.9, heightMm: 355.6 },
24
+ executive: { widthMm: 184.2, heightMm: 266.7 },
25
+ statement: { widthMm: 139.7, heightMm: 215.9 },
26
+ tabloid: { widthMm: 279.4, heightMm: 431.8 },
27
+ ledger: { widthMm: 431.8, heightMm: 279.4 }, // tabloid landscape
28
+ oficio: { widthMm: 215.9, heightMm: 330.2 }, // Latin America
29
+ folio: { widthMm: 215.9, heightMm: 330.2 },
30
+ // Photo
31
+ "4x6": { widthMm: 101.6, heightMm: 152.4 },
32
+ "5x7": { widthMm: 127, heightMm: 177.8 },
33
+ "8x10": { widthMm: 203.2, heightMm: 254 },
34
+ "10x15": { widthMm: 100, heightMm: 150 },
35
+ // Autres
36
+ "business-card": { widthMm: 85.6, heightMm: 53.98 },
37
+ };
38
+ /**
39
+ * Converts millimeters to scan region units using the given unit resolution.
40
+ *
41
+ * @param mm - Dimension in millimeters
42
+ * @param unitResolution - Units per inch (300 for eSCL, scan DPI for non-eSCL)
43
+ */
44
+ export function mmToScanUnits(mm, unitResolution) {
45
+ return Math.round((mm / 25.4) * unitResolution);
46
+ }
47
+ /**
48
+ * Converts a paper size preset name to dimensions in millimeters.
49
+ * Returns null for the "Max" pseudo-preset (caller must handle device max).
50
+ */
51
+ export function paperSizePresetToMm(preset) {
52
+ const normalized = preset.toLowerCase().trim();
53
+ if (normalized === "max") {
54
+ return null;
55
+ }
56
+ return PAPER_SIZE_PRESETS[normalized] ?? null;
57
+ }
58
+ /**
59
+ * Parses a custom paper size string in the format "WxH<unit>".
60
+ * Supported units: mm, cm, in.
61
+ * Example: "21x29.7cm", "8.5x11in", "210x297mm"
62
+ */
63
+ export function parsePaperSize(input) {
64
+ const match = /^(\d+(?:\.\d+)?)\s*[xX]\s*(\d+(?:\.\d+)?)\s*(cm|mm|in)$/i.exec(input.trim());
65
+ if (!match) {
66
+ return null;
67
+ }
68
+ const width = parseFloat(match[1]);
69
+ const height = parseFloat(match[2]);
70
+ const unit = match[3].toLowerCase();
71
+ if (isNaN(width) || isNaN(height) || width <= 0 || height <= 0) {
72
+ return null;
73
+ }
74
+ switch (unit) {
75
+ case "cm":
76
+ return { widthMm: width * 10, heightMm: height * 10 };
77
+ case "in":
78
+ return { widthMm: width * 25.4, heightMm: height * 25.4 };
79
+ default:
80
+ return { widthMm: width, heightMm: height };
81
+ }
82
+ }
83
+ /**
84
+ * Resolves a paper size configuration (preset name or custom dimension string)
85
+ * to millimeters, without any device clamping.
86
+ *
87
+ * - If both paperSizeInput and paperDimInput are provided, throws.
88
+ * - If "Max" preset is provided, returns null (caller owns device-max logic).
89
+ * - If neither is provided, returns null.
90
+ *
91
+ * @param paperSizeInput - Preset name (e.g. "A4", "Letter", "Max")
92
+ * @param paperDimInput - Custom dimension string (e.g. "21x29.7cm")
93
+ * @param orientation - Orientation ("portrait" or "landscape")
94
+ */
95
+ export function validateAndResolvePaperSize(paperSizeInput, paperDimInput, orientation) {
96
+ const normalizedSize = typeof paperSizeInput === "string"
97
+ ? paperSizeInput.trim() || undefined
98
+ : undefined;
99
+ const normalizedDim = typeof paperDimInput === "string"
100
+ ? paperDimInput.trim() || undefined
101
+ : undefined;
102
+ if (normalizedSize !== undefined && normalizedDim !== undefined) {
103
+ throw new Error("Cannot specify both --paper-size and --paper-dim. Choose one.");
104
+ }
105
+ if (normalizedDim !== undefined) {
106
+ const parsed = parsePaperSize(normalizedDim);
107
+ if (!parsed) {
108
+ throw new Error(`Invalid paper dimension format: "${normalizedDim}". ` +
109
+ 'Use "21x29.7cm", "8.5x11in", or "210x297mm".');
110
+ }
111
+ return { resolvedMm: parsed, source: `Custom (${normalizedDim})` };
112
+ }
113
+ if (normalizedSize !== undefined) {
114
+ if (normalizedSize.toLowerCase() === "max") {
115
+ // Caller is responsible for substituting device max dimensions.
116
+ return null;
117
+ }
118
+ const preset = paperSizePresetToMm(normalizedSize);
119
+ if (!preset) {
120
+ throw new Error(`Unknown paper size preset: "${normalizedSize}".`);
121
+ }
122
+ let resolvedMm = { ...preset };
123
+ if (orientation === "landscape" &&
124
+ resolvedMm.widthMm < resolvedMm.heightMm) {
125
+ resolvedMm = {
126
+ widthMm: resolvedMm.heightMm,
127
+ heightMm: resolvedMm.widthMm,
128
+ };
129
+ }
130
+ else if (orientation === "portrait" &&
131
+ resolvedMm.widthMm > resolvedMm.heightMm) {
132
+ resolvedMm = {
133
+ widthMm: resolvedMm.heightMm,
134
+ heightMm: resolvedMm.widthMm,
135
+ };
136
+ }
137
+ return { resolvedMm, source: normalizedSize.toUpperCase() };
138
+ }
139
+ return null;
140
+ }
141
+ /**
142
+ * Converts resolved paper size (in mm) to scan region units, clamped to device
143
+ * maximum dimensions (also expressed in the same unit space).
144
+ *
145
+ * This is the final step before submitting a ScanRegion to the device.
146
+ *
147
+ * @param resolvedMm - Paper size in millimeters (from validateAndResolvePaperSize)
148
+ * @param unitResolution - Units per inch: use THREE_HUNDREDTHS_OF_INCH_DPI (300) for eSCL,
149
+ * or the scan DPI for non-eSCL devices
150
+ * @param maxWidth - Device max width in device units (null = unconstrained)
151
+ * @param maxHeight - Device max height in device units (null = unconstrained)
152
+ */
153
+ export function paperSizeMmToScanRegion(resolvedMm, unitResolution, maxWidth, maxHeight) {
154
+ let width = mmToScanUnits(resolvedMm.widthMm, unitResolution);
155
+ let height = mmToScanUnits(resolvedMm.heightMm, unitResolution);
156
+ if (maxWidth !== null) {
157
+ width = Math.min(width, maxWidth);
158
+ }
159
+ if (maxHeight !== null) {
160
+ height = Math.min(height, maxHeight);
161
+ }
162
+ return {
163
+ width: Math.max(1, width),
164
+ height: Math.max(1, height),
165
+ };
166
+ }
167
+ /**
168
+ * Returns the default paper size (A4).
169
+ */
170
+ export function getDefaultPaperSize() {
171
+ return { widthMm: 210, heightMm: 297 };
172
+ }
173
+ /**
174
+ * Returns true if the given preset string is the "Max" pseudo-preset.
175
+ */
176
+ export function isMaxPreset(preset) {
177
+ return preset?.toLowerCase().trim() === "max";
178
+ }
179
+ //# sourceMappingURL=PaperSize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PaperSize.js","sourceRoot":"","sources":["../src/PaperSize.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  {
2
- "commitId": "95dcb900e9a881e074db7f6a448822fcf6b3c54c"
2
+ "commitId": "ce94a1b2f34964a43eb808b85ae71a9a41afe64d"
3
3
  }
@@ -26,7 +26,8 @@ export interface JobData {
26
26
  export declare enum JobState {
27
27
  Completed = "Completed",
28
28
  Processing = "Processing",
29
- Canceled = "Canceled"
29
+ Canceled = "Canceled",
30
+ Blocked = "Blocked"
30
31
  }
31
32
  export declare enum PageState {
32
33
  ReadyToUpload = "ReadyToUpload",
@@ -6,6 +6,7 @@ export var JobState;
6
6
  JobState["Completed"] = "Completed";
7
7
  JobState["Processing"] = "Processing";
8
8
  JobState["Canceled"] = "Canceled";
9
+ JobState["Blocked"] = "Blocked";
9
10
  })(JobState || (JobState = {}));
10
11
  export var PageState;
11
12
  (function (PageState) {
@@ -1 +1 @@
1
- {"version":3,"file":"Job.js","sourceRoot":"","sources":["../../src/hpModels/Job.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Job.js","sourceRoot":"","sources":["../../src/hpModels/Job.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
File without changes
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,sDAAsD;AAEtD,YAAY,CAAC;AAEb,OAAO,MAAM,EAAE,EAAgB,MAAM,QAAQ,CAAC;AAC9C,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,UAAU,MAAM,mBAAmB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjE,OAAO,EAAE,YAAY,EAAmB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,cAAc,GAAG,CAAC,MAAe,EAAE,EAAE;IACzC,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,UAAU,GAAe,cAAc,CAAC,MAAM,CAAC,CAAC;IAEtD,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IAEzC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC;AAClE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,sDAAsD;AAEtD,YAAY,CAAC;AAEb,OAAO,MAAM,EAAE,EAAe,MAAM,QAAQ,CAAC;AAC7C,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,UAAU,MAAM,mBAAmB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACjE,OAAO,EAAE,YAAY,EAAmB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,cAAc,GAAG,CAAC,MAAc,EAAE,EAAE;IACxC,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,UAAU,GAAe,cAAc,CAAC,MAAM,CAAC,CAAC;IAEtD,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IAEzC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC;AAClE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC"}
package/dist/program.js CHANGED
@@ -43,8 +43,30 @@ function setupScanParameters(commandName) {
43
43
  .addOption(new Option("--mode <mode>", "Selects the scan mode (default: Color)")
44
44
  .choices(["Gray", "Color"])
45
45
  .helpGroup(HelpGroupsHeadings.scan))
46
- .addOption(new Option("-w, --width <width>", "Width in pixels of the scans (default: max)").helpGroup(HelpGroupsHeadings.scan))
47
- .addOption(new Option("-h, --height <height>", "Height in pixels of the scans (default: max)").helpGroup(HelpGroupsHeadings.scan))
46
+ .addOption(new Option("-w, --width <width>", "Width in pixels of the scans (default: max)")
47
+ .conflicts("paperSize")
48
+ .conflicts("paperDim")
49
+ .helpGroup(HelpGroupsHeadings.scan))
50
+ .addOption(new Option("-h, --height <height>", "Height in pixels of the scans (default: max)")
51
+ .conflicts("paperSize")
52
+ .conflicts("paperDim")
53
+ .helpGroup(HelpGroupsHeadings.scan))
54
+ .addOption(new Option("--paper-size <size>", "Paper size preset: A4 (default), Letter, Legal, A5, B5, or Max (case-insensitive)")
55
+ .conflicts("paperDim")
56
+ .conflicts("width")
57
+ .conflicts("height")
58
+ .helpGroup(HelpGroupsHeadings.scan))
59
+ .addOption(new Option("--paper-orientation <orientation>", "Paper orientation: portrait (default) or landscape. Applied to --paper-size only.")
60
+ .choices(["portrait", "landscape"])
61
+ .conflicts("paperDim")
62
+ .conflicts("width")
63
+ .conflicts("height")
64
+ .helpGroup(HelpGroupsHeadings.scan))
65
+ .addOption(new Option("--paper-dim <dimensions>", "Custom paper dimensions with unit (e.g., 21x29.7cm, 8.5x11in, 210x297mm). Cannot be used with --paper-size.")
66
+ .conflicts("paperSize")
67
+ .conflicts("width")
68
+ .conflicts("height")
69
+ .helpGroup(HelpGroupsHeadings.scan))
48
70
  .addOption(new Option("-t, --temp-directory <dir>", "Temp directory used for processing (default: /tmp/scan-to-pcRANDOM)").helpGroup(HelpGroupsHeadings.scan))
49
71
  .addOption(new Option("--prefer-eSCL", "Prefer eSCL protocol if available").helpGroup(HelpGroupsHeadings.scan))
50
72
  .option("--device-up-polling-interval <deviceUpPollingInterval>", "Device up polling interval in milliseconds", parseFloat)
@@ -176,24 +198,40 @@ function getScanConfiguration(options, fileConfig) {
176
198
  tempDirectory: getOptConfiguredValue(options.tempDirectory, fileConfig.tempDirectory),
177
199
  filePattern: getOptConfiguredValue(options.pattern, fileConfig.pattern),
178
200
  };
179
- const configWidth = getConfiguredValue(options.width, fileConfig.width?.toString(), "0");
180
- const width = configWidth.toLowerCase() === "max"
181
- ? Number.MAX_SAFE_INTEGER
182
- : parseInt(configWidth, 10);
183
- const configHeight = getConfiguredValue(options.height, fileConfig.height?.toString(), "0");
184
- const height = configHeight.toLowerCase() === "max"
185
- ? Number.MAX_SAFE_INTEGER
186
- : parseInt(configHeight, 10);
187
201
  const paperlessConfig = getPaperlessConfig(options, fileConfig);
188
202
  const nextcloudConfig = getNextcloudConfig(options, fileConfig);
189
203
  const resolution = parseInt(getConfiguredValue(options.resolution, fileConfig.resolution?.toString(), "200"), 10);
190
204
  const mode = getConfiguredValue(options.mode, fileConfig.mode, ScanMode.Color);
191
205
  const preferEscl = getConfiguredValue(options.preferESCL, fileConfig.prefer_escl, false);
206
+ // Paper size configuration with precedence: CLI > Config > default (A4)
207
+ const paperSize = getOptConfiguredValue(options.paperSize, fileConfig.paper_size);
208
+ const paperDim = getOptConfiguredValue(options.paperDim, fileConfig.paper_dim);
209
+ const paperOrientation = getOptConfiguredValue(options.paperOrientation, fileConfig.paper_orientation);
210
+ const hasPaperSizeConfig = paperSize !== undefined || paperDim !== undefined;
211
+ const configWidth = getOptConfiguredValue(options.width, fileConfig.width?.toString());
212
+ const configHeight = getOptConfiguredValue(options.height, fileConfig.height?.toString());
213
+ if (hasPaperSizeConfig &&
214
+ (configWidth !== undefined || configHeight !== undefined)) {
215
+ throw new Error("Cannot specify both width/height and paper size (paper_size/paper_dim). Choose one or the other.");
216
+ }
217
+ const providedWidth = configWidth === undefined
218
+ ? undefined
219
+ : configWidth.toLowerCase() === "max"
220
+ ? "max"
221
+ : parseInt(configWidth, 10);
222
+ const providedHeight = configHeight === undefined
223
+ ? undefined
224
+ : configHeight.toLowerCase() === "max"
225
+ ? undefined
226
+ : parseInt(configHeight, 10);
192
227
  const scanConfig = {
193
228
  resolution,
194
229
  mode,
195
- width: width,
196
- height: height,
230
+ width: providedWidth,
231
+ height: providedHeight,
232
+ paperSize,
233
+ paperDim,
234
+ paperOrientation,
197
235
  directoryConfig,
198
236
  paperlessConfig,
199
237
  nextcloudConfig,