@gohcltech/edge-print-client 2.0.81-develop → 2.0.89-develop
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 +159 -25
- package/dist/edge-print.d.ts +104 -5
- package/dist/edge-print.js +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,10 @@ Intended as a drop-in replacement for qz-tray.js with a simpler token-based auth
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
> **Upgrading from 1.x?** See [MIGRATING.md](../MIGRATING.md). `print()`'s
|
|
10
|
+
> return type changed, printed output changes on both platforms, and the
|
|
11
|
+
> `virtual` field you may be filtering on never worked.
|
|
12
|
+
|
|
9
13
|
## Prerequisites
|
|
10
14
|
|
|
11
15
|
1. **Edge Printing agent** must be installed and running on the user's machine. The agent listens on `wss://127.0.0.1:8181` by default.
|
|
@@ -136,9 +140,11 @@ the substitution this release exists to remove. Three things soften it:
|
|
|
136
140
|
- **The rejection tells you what would work.** `unsupported_value` carries
|
|
137
141
|
`field` and a `supported` array of the printer's real values.
|
|
138
142
|
|
|
139
|
-
`paperSize` and `tray` are only
|
|
140
|
-
`html` and network targets
|
|
141
|
-
|
|
143
|
+
`paperSize` and `tray` are only *validated* on paths that can act on them, so
|
|
144
|
+
`raw` and `html` content and network targets do not start failing. Validated is
|
|
145
|
+
not the same as unused: on macOS both settings are still passed to CUPS as
|
|
146
|
+
`media=` and `InputSlot=` for raw and HTML jobs, as they were in 1.x. On
|
|
147
|
+
Windows those paths genuinely do discard them.
|
|
142
148
|
|
|
143
149
|
**On `mediaTypes`.** The field is usually absent. Of eleven drivers surveyed,
|
|
144
150
|
eight listed no stock types at all, and a ninth listed them only under a
|
|
@@ -192,10 +198,13 @@ const { jobId, warnings } = await ep.print(config, data)
|
|
|
192
198
|
| `jobId` | `string` | The agent's id for the job, matching its entry in the job history |
|
|
193
199
|
| `warnings` | `JobWarning[]` | Caveats the agent recorded about a job it printed anyway. Empty in the common case |
|
|
194
200
|
|
|
195
|
-
Each `JobWarning` is `{ code, message }`.
|
|
196
|
-
`capability_unverified
|
|
197
|
-
skipped the check and passed the request through
|
|
198
|
-
|
|
201
|
+
Each `JobWarning` is `{ code, message }`. Two codes are raised today:
|
|
202
|
+
`capability_unverified`, where the agent could not determine a capability so it
|
|
203
|
+
skipped the check and passed the request through, and `content_scaled_to_fit`,
|
|
204
|
+
where content that did not fit was scaled down rather than clipped. What it had
|
|
205
|
+
to fit is the sheet when you sent no `margins` and the margin box when you did,
|
|
206
|
+
so content well inside the sheet can still warn. Treat the set as open-ended: log or surface
|
|
207
|
+
`message` rather than branching on every code.
|
|
199
208
|
|
|
200
209
|
> **Breaking change.** `print()` used to resolve to the job id string. It now
|
|
201
210
|
> resolves to an object. Destructure it (`const { jobId } = await ep.print(…)`),
|
|
@@ -249,9 +258,13 @@ Two limits worth knowing before you build on this:
|
|
|
249
258
|
| `orientation` | `'portrait' \| 'landscape'?` | Page orientation |
|
|
250
259
|
| `jobName` | `string?` | Name shown in the OS print queue |
|
|
251
260
|
| `colorType` | `'color' \| 'grayscale' \| 'black-white'?` | Color mode |
|
|
252
|
-
| `paperSize` | `string?` | Paper size from `PrinterInfo.papers` (e.g. `"Letter"`). Rejects if the printer lists paper sizes and this is not one
|
|
253
|
-
| `tray` | `string?` | Tray name from `TrayInfo.name` (e.g. `"Tray 1"`). Rejects if the printer lists trays and this is not one
|
|
254
|
-
| `mediaType` | `string?` | Stock type from `PrinterInfo.mediaTypes` (e.g. `"Bond"`).
|
|
261
|
+
| `paperSize` | `string?` | Paper size from `PrinterInfo.papers` (e.g. `"Letter"`). Rejects with `unsupported_value` if the printer lists paper sizes and this is not one |
|
|
262
|
+
| `tray` | `string?` | Tray name from `TrayInfo.name` (e.g. `"Tray 1"`). Rejects with `unsupported_value` if the printer lists trays and this is not one |
|
|
263
|
+
| `mediaType` | `string?` | Stock type from `PrinterInfo.mediaTypes` (e.g. `"Bond"`). Rejects with `unsupported_value` if the printer lists stock types and this is not one; rejected for `raw`/`html` content and network targets |
|
|
264
|
+
| `scaling` | `'actual' \| 'fit' \| 'shrink-to-fit'?` | How content is sized against the media. **Default `'actual'`** — see below |
|
|
265
|
+
| `scalePercent` | `number?` | Explicit scale, 10–400. Overrides `scaling` when both are sent |
|
|
266
|
+
| `margins` | `Margins?` | Inset from the physical sheet edge. `{ top?, right?, bottom?, left?, units }`, `units` required |
|
|
267
|
+
| `anchor` | `'center' \| 'top-left'?` | Where content sits in the margin box. Default `'center'` |
|
|
255
268
|
|
|
256
269
|
**`data`** — `PrintData[]`
|
|
257
270
|
|
|
@@ -265,6 +278,102 @@ Each item in the array is one unit of content (page, label, etc.).
|
|
|
265
278
|
| `data` | `string` | The content, encoded per `flavor` |
|
|
266
279
|
| `options` | `Record<string, unknown>?` | Format-specific options forwarded to the agent renderer |
|
|
267
280
|
|
|
281
|
+
#### Scaling, margins and anchoring
|
|
282
|
+
|
|
283
|
+
These four settings control where content lands on the sheet. They apply to
|
|
284
|
+
`pdf` and `image` content sent to a named printer.
|
|
285
|
+
|
|
286
|
+
**The default is actual size.** Content prints at its intrinsic size, centred,
|
|
287
|
+
with no scaling applied:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
// A 4x6 label prints 4x6, wherever the sheet is bigger.
|
|
291
|
+
await ep.print({ printer: 'Office Laser' }, [label])
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**This changed in 2.0, and it changes output.** Windows previously stretched
|
|
295
|
+
every page to fill the printable area and had no actual-size path at all. If a
|
|
296
|
+
job depended on that stretch, the nearest equivalent is:
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
await ep.print({ printer: 'Office Laser', scaling: 'fit' }, [doc])
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
`'fit'` scales to fill the margin box **preserving aspect ratio**, which the
|
|
303
|
+
old Windows path did not — it stretched to fill the printable area regardless
|
|
304
|
+
of shape. Any unprintable band changes that area's proportions, an even band as
|
|
305
|
+
much as an uneven one, so even a document matching its media is slightly
|
|
306
|
+
letterboxed under `'fit'` where it used to be stretched to fill exactly.
|
|
307
|
+
`'shrink-to-fit'` is actual size that scales down only when content overflows —
|
|
308
|
+
it never scales up.
|
|
309
|
+
|
|
310
|
+
**Margins are measured from the physical sheet edge**, not from the printable
|
|
311
|
+
area, so the same numbers mean the same place on paper across printers whose
|
|
312
|
+
unprintable bands differ. Import `inches` or `mm` rather than converting by
|
|
313
|
+
hand:
|
|
314
|
+
|
|
315
|
+
```ts
|
|
316
|
+
import { inches, mm } from '@gohcltech/edge-print-client'
|
|
317
|
+
|
|
318
|
+
await ep.print(
|
|
319
|
+
{ printer: 'Office Laser', margins: inches({ top: 0.5, right: 0.5, bottom: 0.5, left: 0.5 }) },
|
|
320
|
+
[doc],
|
|
321
|
+
)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
`units` is required — there is no safe default. A value meant as inches and
|
|
325
|
+
read as points is a near-invisible 1/72" margin.
|
|
326
|
+
|
|
327
|
+
**Set all four edges.** An omitted edge is a deliberate zero, not "leave this
|
|
328
|
+
one alone" — and zero is below the unprintable band on most real printers, so a
|
|
329
|
+
partial object is usually *rejected*:
|
|
330
|
+
|
|
331
|
+
```ts
|
|
332
|
+
// Rejected on any printer with a hardware margin:
|
|
333
|
+
// invalid_geometry — margins.right 0.00pt is below the hardware minimum
|
|
334
|
+
// 18.00pt (0.25in) for 'Office Laser'
|
|
335
|
+
await ep.print({ printer: 'Office Laser', margins: inches({ top: 0.5 }) }, [doc])
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Sending no `margins` key at all is different again, and always fine — it means
|
|
339
|
+
no margin control rather than four zero margins.
|
|
340
|
+
|
|
341
|
+
An explicit `scalePercent` (10–400) **silently overrides** `scaling` when both
|
|
342
|
+
are sent. It also changes how overflow is treated: content that does not fit
|
|
343
|
+
rejects with `content_overflow` under an explicit `scalePercent`, where without
|
|
344
|
+
one it is scaled down and reports a `content_scaled_to_fit` warning instead.
|
|
345
|
+
|
|
346
|
+
What "does not fit" is measured against depends on whether you sent `margins`.
|
|
347
|
+
With them, it is the margin box. Without, it is the whole physical sheet —
|
|
348
|
+
because with no margins the box is the hardware printable area, which an
|
|
349
|
+
ordinary Letter page on a Letter queue already exceeds on any printer with an
|
|
350
|
+
unprintable edge.
|
|
351
|
+
|
|
352
|
+
**Where these are refused rather than ignored.** A setting that provably cannot
|
|
353
|
+
work on the requested path is rejected, because silently dropping it is the
|
|
354
|
+
failure this release exists to remove:
|
|
355
|
+
|
|
356
|
+
| Situation | Code |
|
|
357
|
+
|---|---|
|
|
358
|
+
| `raw` or `html` content, or a network target | `unsupported_for_path` |
|
|
359
|
+
| The PDF is encrypted (its pages cannot be re-composed) | `encrypted_pdf` |
|
|
360
|
+
| `scalePercent` outside 10–400 | `invalid_geometry`, `field: 'scalePercent'` |
|
|
361
|
+
| A negative margin edge | `invalid_geometry`, `field: 'margins.top'` etc. |
|
|
362
|
+
| A margin inside the printer's unprintable band | `invalid_geometry`, naming the hardware minimum |
|
|
363
|
+
|
|
364
|
+
**All of this needs a measurable sheet.** Margins are placed from the sheet
|
|
365
|
+
edge, the hardware minimum is checked against the unprintable band, and
|
|
366
|
+
overflow is judged against the sheet — so the agent has to ask the queue for
|
|
367
|
+
its geometry. Windows reads it locally; macOS asks over IPP, and a queue that
|
|
368
|
+
will not answer yields nothing. The placement rules are then skipped and the
|
|
369
|
+
document goes to the printer as supplied, logged by the agent but carrying no
|
|
370
|
+
warning on the job.
|
|
371
|
+
|
|
372
|
+
Developer Printers skip the *path* checks above, since their job is to show
|
|
373
|
+
what was asked for. They are not exempt from the rules that need no printer: an
|
|
374
|
+
encrypted PDF, an out-of-range `scalePercent` and a negative margin edge all
|
|
375
|
+
still reject.
|
|
376
|
+
|
|
268
377
|
#### Image sizing
|
|
269
378
|
|
|
270
379
|
An image prints at its **intrinsic physical size**, taken from the resolution
|
|
@@ -276,10 +385,14 @@ resolution metadata prints at 12.5 x 6.25 inches rather than being sized to the
|
|
|
276
385
|
paper. Send a file that declares its resolution if you need a specific size.
|
|
277
386
|
|
|
278
387
|
An image too large for the sheet is scaled down to fit and the job reports a
|
|
279
|
-
`content_scaled_to_fit` warning
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
388
|
+
`content_scaled_to_fit` warning, so nothing is silently cropped — **as long as
|
|
389
|
+
the agent could measure the sheet.** That means asking the queue for its
|
|
390
|
+
geometry, which Windows reads locally and macOS asks for over IPP. A macOS
|
|
391
|
+
queue that will not answer skips the overflow rule along with the margin rules,
|
|
392
|
+
and an oversized image is clipped instead, with no warning on the job because
|
|
393
|
+
nothing was decided. Worth knowing on macOS specifically: CUPS used to fit an
|
|
394
|
+
image to the page by itself, and does not do that for a PDF, which is what an
|
|
395
|
+
image becomes on the way to the spooler in 2.0.
|
|
283
396
|
|
|
284
397
|
#### Print examples
|
|
285
398
|
|
|
@@ -301,6 +414,18 @@ await ep.print(
|
|
|
301
414
|
{ printer: 'Office Laser', paperSize: 'Letter' },
|
|
302
415
|
[{ type: 'pixel', format: 'image', flavor: 'file', data: 'C:\\Reports\\invoice.png' }],
|
|
303
416
|
)
|
|
417
|
+
|
|
418
|
+
// Actual size, half-inch margins, anchored top-left, on card stock
|
|
419
|
+
await ep.print(
|
|
420
|
+
{
|
|
421
|
+
printer: 'Office Laser',
|
|
422
|
+
scaling: 'actual',
|
|
423
|
+
margins: inches({ top: 0.5, right: 0.5, bottom: 0.5, left: 0.5 }),
|
|
424
|
+
anchor: 'top-left',
|
|
425
|
+
mediaType: 'Bond',
|
|
426
|
+
},
|
|
427
|
+
[{ type: 'pixel', format: 'pdf', flavor: 'base64', data: pdfBase64 }],
|
|
428
|
+
)
|
|
304
429
|
```
|
|
305
430
|
|
|
306
431
|
---
|
|
@@ -427,11 +552,14 @@ Sent by the agent:
|
|
|
427
552
|
| `not_authenticated` | A request was sent before `connect()` finished authenticating |
|
|
428
553
|
| `invalid_token` | The token is unknown, or still awaiting approval in the agent UI |
|
|
429
554
|
| `invalid_request` | The agent could not parse the request |
|
|
555
|
+
| `unsupported_value` | `paperSize`, `tray` or `mediaType` names a value the printer does not list. Carries `supported` |
|
|
430
556
|
| `unsupported_capability` | A capability the printer explicitly reports it lacks |
|
|
431
557
|
| `invalid_geometry` | A scale or margin outside what the protocol accepts |
|
|
432
|
-
| `unsupported_for_path` |
|
|
433
|
-
| `
|
|
434
|
-
| `
|
|
558
|
+
| `unsupported_for_path` | Geometry or `mediaType` on a path that cannot honour it — `field` is `mediaType`, absent for geometry |
|
|
559
|
+
| `content_overflow` | Content exceeds the margin box under an explicit `scalePercent` |
|
|
560
|
+
| `encrypted_pdf` | Scaling, margins or anchoring were asked for on an encrypted PDF |
|
|
561
|
+
| `printer_not_found` | `defaultPrinter()` found no default configured on the machine. **Not** raised for a `print()` to a missing printer — see below |
|
|
562
|
+
| `print_failed` | The backend failed after the job was accepted and recorded — including a `printer` naming a queue that no longer exists |
|
|
435
563
|
| `internal_error` | The agent itself failed — not the caller's doing |
|
|
436
564
|
|
|
437
565
|
Raised locally by this library, never sent by the agent:
|
|
@@ -448,19 +576,25 @@ Raised locally by this library, never sent by the agent:
|
|
|
448
576
|
cannot parse, and here for a `config` or `data` value that cannot be serialised
|
|
449
577
|
to JSON at all — a circular reference, say. Neither is retryable.
|
|
450
578
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
579
|
+
Four of those five — `not_connected`, `unreachable`, `connection_closed` and
|
|
580
|
+
`timeout` — are never accepted *from* the agent. A frame claiming
|
|
581
|
+
`code: "timeout"` is read as `unknown`, so a failure the agent considers final
|
|
582
|
+
cannot arrive labelled retryable. `protocol_mismatch` is the exception: it
|
|
583
|
+
belongs to the agent's own set and would be accepted off the wire, but nothing
|
|
584
|
+
in the agent raises it, so in practice it only ever comes from here.
|
|
585
|
+
|
|
586
|
+
**A print to a printer that no longer exists arrives as `print_failed`, not
|
|
587
|
+
`printer_not_found`.** Neither platform backend can separate a missing queue
|
|
588
|
+
from any other spooling failure, so an app that caches printer names cannot
|
|
589
|
+
detect a stale one by code alone — `printer_not_found` covers only the
|
|
590
|
+
`defaultPrinter()` lookup. Re-read `printers()` when a `print_failed` looks
|
|
591
|
+
like it might be a vanished queue.
|
|
454
592
|
|
|
455
593
|
`unsupported_value` is raised when `paperSize`, `tray` or `mediaType` names a
|
|
456
594
|
value the printer does not list, and it is the one code that populates
|
|
457
595
|
`supported` — read that array rather than parsing the message, and offer the
|
|
458
596
|
values it names.
|
|
459
597
|
|
|
460
|
-
Two more are still **reserved**: `content_overflow` and `encrypted_pdf` are part
|
|
461
|
-
of the closed set and typed here, so code written today handles them, but no
|
|
462
|
-
agent sends them yet.
|
|
463
|
-
|
|
464
598
|
And `unknown`, the fallback for a code this client does not recognise — which
|
|
465
599
|
is what lets a client built today keep working against a future agent. Treat an
|
|
466
600
|
unfamiliar code as a plain failure rather than a bug.
|
|
@@ -499,7 +633,7 @@ The client does not reconnect automatically after a connection drop. A simple
|
|
|
499
633
|
exponential-backoff reconnect loop:
|
|
500
634
|
|
|
501
635
|
```ts
|
|
502
|
-
import ep, { ConnectOptions } from '@gohcltech/edge-print-client'
|
|
636
|
+
import ep, { type ConnectOptions } from '@gohcltech/edge-print-client'
|
|
503
637
|
|
|
504
638
|
async function connectWithBackoff(opts: ConnectOptions, maxMs = 30_000) {
|
|
505
639
|
let delay = 1_000
|
package/dist/edge-print.d.ts
CHANGED
|
@@ -26,6 +26,61 @@ export type PrinterTarget = string | {
|
|
|
26
26
|
host: string;
|
|
27
27
|
port: number;
|
|
28
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* How content is sized relative to the media.
|
|
31
|
+
*
|
|
32
|
+
* - `'actual'` — the document's intrinsic size, 1:1. The default.
|
|
33
|
+
* - `'fit'` — scaled to fill the margin box, preserving aspect ratio.
|
|
34
|
+
* - `'shrink-to-fit'` — actual size, scaled down only when content overflows.
|
|
35
|
+
*/
|
|
36
|
+
export type ScalingMode = 'actual' | 'fit' | 'shrink-to-fit';
|
|
37
|
+
/**
|
|
38
|
+
* Where content sits inside the margin box when it does not fill it.
|
|
39
|
+
* Defaults to `'center'`.
|
|
40
|
+
*/
|
|
41
|
+
export type ContentAnchor = 'center' | 'top-left';
|
|
42
|
+
/** The unit a {@link Margins} value is expressed in. */
|
|
43
|
+
export type MarginUnits = 'pt' | 'in' | 'mm';
|
|
44
|
+
/**
|
|
45
|
+
* Margins measured inward from the **physical sheet edge** — not from the
|
|
46
|
+
* printable area, so the same numbers describe the same place on paper
|
|
47
|
+
* whatever unprintable band a given printer has.
|
|
48
|
+
*
|
|
49
|
+
* Every edge is optional, but **set all four in practice.** An omitted edge is
|
|
50
|
+
* a deliberate zero rather than "leave this one alone", and zero falls inside
|
|
51
|
+
* the unprintable band on most real printers — so a partial object is usually
|
|
52
|
+
* rejected with `invalid_geometry` naming an edge you never set. Omitting the
|
|
53
|
+
* whole `margins` key is different, and always fine: it means no margin
|
|
54
|
+
* control at all.
|
|
55
|
+
*
|
|
56
|
+
* Each edge must be zero or greater, or the job rejects with
|
|
57
|
+
* `invalid_geometry` naming it — `margins.top`, `margins.right`,
|
|
58
|
+
* `margins.bottom`, `margins.left`. A margin inside the printer's unprintable
|
|
59
|
+
* band is refused with the same code, naming both the requested value and the
|
|
60
|
+
* hardware minimum.
|
|
61
|
+
*
|
|
62
|
+
* `units` is required here. There is no safe default: a value meant as inches
|
|
63
|
+
* and read as points is a near-invisible ~1/72" margin. Use {@link inches} or
|
|
64
|
+
* {@link mm} to say it once. (The agent itself defaults to points when a
|
|
65
|
+
* hand-rolled client omits the field; this type declines to rely on that.)
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const margins = inches({ top: 0.5, right: 0.5, bottom: 0.5, left: 0.5 })
|
|
70
|
+
* await ep.print({ printer: 'Office Laser', margins }, data)
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export interface Margins {
|
|
74
|
+
top?: number;
|
|
75
|
+
right?: number;
|
|
76
|
+
bottom?: number;
|
|
77
|
+
left?: number;
|
|
78
|
+
units: MarginUnits;
|
|
79
|
+
}
|
|
80
|
+
/** Builds {@link Margins} in millimetres. */
|
|
81
|
+
export declare const mm: (m: Omit<Margins, "units">) => Margins;
|
|
82
|
+
/** Builds {@link Margins} in inches. */
|
|
83
|
+
export declare const inches: (m: Omit<Margins, "units">) => Margins;
|
|
29
84
|
/**
|
|
30
85
|
* Configuration options for a print job.
|
|
31
86
|
*
|
|
@@ -81,11 +136,59 @@ export interface PrintConfig {
|
|
|
81
136
|
* (e.g. `"Plain"`, `"Bond"`, `"Thermal"`). Changes how the printer feeds and
|
|
82
137
|
* fuses the page. Omit to use the printer's current default.
|
|
83
138
|
*
|
|
139
|
+
* Rejects with `unsupported_value` when the printer lists stock types and
|
|
140
|
+
* this is not one of them — the error's `supported` array names the real
|
|
141
|
+
* ones. A printer that lists none accepts anything, with a
|
|
142
|
+
* `capability_unverified` warning. Matching ignores case.
|
|
143
|
+
*
|
|
84
144
|
* Not supported for `raw` or `html` content, or a network target — those
|
|
85
145
|
* paths never reach the printer's driver. Requesting it there rejects with
|
|
86
|
-
* `unsupported_for_path`.
|
|
146
|
+
* `unsupported_for_path` and a `field` of `mediaType`.
|
|
87
147
|
*/
|
|
88
148
|
mediaType?: string;
|
|
149
|
+
/**
|
|
150
|
+
* How content is sized relative to the media. Defaults to `'actual'`.
|
|
151
|
+
*
|
|
152
|
+
* **This default changed in 2.0.** Windows previously stretched every page
|
|
153
|
+
* to fill the printable area and had no actual-size path at all; a job that
|
|
154
|
+
* relied on that stretch needs `scaling: 'fit'` to keep it.
|
|
155
|
+
*
|
|
156
|
+
* `scaling`, {@link PrintConfig.scalePercent}, {@link PrintConfig.margins}
|
|
157
|
+
* and {@link PrintConfig.anchor} are refused rather than silently dropped on
|
|
158
|
+
* paths that cannot honour them: `raw` or `html` content, and network
|
|
159
|
+
* targets, all reject with `unsupported_for_path`. Asking for any of them on
|
|
160
|
+
* an encrypted PDF rejects with `encrypted_pdf`, since honouring them means
|
|
161
|
+
* re-composing pages the agent cannot open. Developer Printers skip the path
|
|
162
|
+
* check only — the encrypted-PDF and range rules still apply to them.
|
|
163
|
+
*/
|
|
164
|
+
scaling?: ScalingMode;
|
|
165
|
+
/**
|
|
166
|
+
* Explicit scale percentage, 10–400 inclusive. Outside that range rejects
|
|
167
|
+
* with `invalid_geometry` and a `field` of `scalePercent`.
|
|
168
|
+
*
|
|
169
|
+
* **Overrides {@link PrintConfig.scaling} when both are present**, silently
|
|
170
|
+
* rather than erroring.
|
|
171
|
+
*
|
|
172
|
+
* It also changes what happens to oversized content. Content that does not
|
|
173
|
+
* fit rejects with `content_overflow` under an explicit `scalePercent`;
|
|
174
|
+
* without one, it is scaled down and the job reports a
|
|
175
|
+
* `content_scaled_to_fit` warning instead of failing.
|
|
176
|
+
*
|
|
177
|
+
* What it must fit depends on {@link PrintConfig.margins}: the margin box
|
|
178
|
+
* when margins were sent, the whole physical sheet when they were not.
|
|
179
|
+
*/
|
|
180
|
+
scalePercent?: number;
|
|
181
|
+
/**
|
|
182
|
+
* Margins measured inward from the physical sheet edge. Omit entirely for no
|
|
183
|
+
* margin control; present with an edge omitted makes that edge a deliberate
|
|
184
|
+
* zero.
|
|
185
|
+
*/
|
|
186
|
+
margins?: Margins;
|
|
187
|
+
/**
|
|
188
|
+
* Where content sits inside the margin box when it does not fill it.
|
|
189
|
+
* Defaults to `'center'`.
|
|
190
|
+
*/
|
|
191
|
+
anchor?: ContentAnchor;
|
|
89
192
|
}
|
|
90
193
|
/**
|
|
91
194
|
* A single unit of content to be printed.
|
|
@@ -136,10 +239,6 @@ export interface PrintData {
|
|
|
136
239
|
*
|
|
137
240
|
* An image too large for the sheet is scaled down to fit, and the job
|
|
138
241
|
* reports a `content_scaled_to_fit` warning.
|
|
139
|
-
*
|
|
140
|
-
* This applies on Windows. On macOS the image is handed to the system print
|
|
141
|
-
* system, which fits it to the page instead; the two converge in a later
|
|
142
|
-
* release.
|
|
143
242
|
*/
|
|
144
243
|
format: 'command' | 'pdf' | 'html' | 'image';
|
|
145
244
|
/**
|
package/dist/edge-print.js
CHANGED
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
* )
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
+
/** Builds {@link Margins} in millimetres. */
|
|
20
|
+
export const mm = (m) => ({ ...m, units: 'mm' });
|
|
21
|
+
/** Builds {@link Margins} in inches. */
|
|
22
|
+
export const inches = (m) => ({ ...m, units: 'in' });
|
|
19
23
|
/**
|
|
20
24
|
* Every failure code this client understands.
|
|
21
25
|
*
|