@laminapdf/wasm 0.2.0-alpha.6 → 0.2.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 +1 -1
- package/dist/lamina_pdf_base.d.ts +438 -1
- package/dist/lamina_pdf_base.js +84 -0
- package/dist/lamina_pdf_base.wasm +0 -0
- package/dist/lamina_pdf_extract.d.ts +438 -1
- package/dist/lamina_pdf_extract.js +84 -0
- package/dist/lamina_pdf_extract.wasm +0 -0
- package/dist/lamina_pdf_render_hayro.wasm +0 -0
- package/dist/lamina_pdf_text.d.ts +496 -1
- package/dist/lamina_pdf_text.js +164 -0
- package/dist/lamina_pdf_text.wasm +0 -0
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `@laminapdf/wasm`
|
|
2
2
|
|
|
3
|
-
Lamina PDF's WebAssembly modules and their [wasm-bindgen](https://github.com/wasm-bindgen/wasm-bindgen) glue.
|
|
3
|
+
Lamina PDF's WebAssembly modules and their [wasm-bindgen](https://github.com/wasm-bindgen/wasm-bindgen) glue. Use [`@laminapdf/sdk`](../sdk/README.md), which is built on it and gives the modules a typed API: create, read, edit and save PDFs and extract their text. This package is its raw layer.
|
|
4
4
|
|
|
5
5
|
| Export | File | What it has |
|
|
6
6
|
| --- | --- | --- |
|
|
@@ -14,11 +14,117 @@ export interface Diagnostic {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* A change a signature's restriction forbids.
|
|
19
|
+
*/
|
|
20
|
+
export interface ViolationJs {
|
|
21
|
+
/**
|
|
22
|
+
* The kind of change.
|
|
23
|
+
*/
|
|
24
|
+
class: ModificationClass;
|
|
25
|
+
/**
|
|
26
|
+
* `docMdp`, `fieldMdp`, `usageRights`, `signedBytes` or `signedWidget`.
|
|
27
|
+
*/
|
|
28
|
+
restriction: string;
|
|
29
|
+
/**
|
|
30
|
+
* The certification's `/P` (1, 2 or 3), for a `docMdp` restriction.
|
|
31
|
+
*/
|
|
32
|
+
permission?: number;
|
|
33
|
+
/**
|
|
34
|
+
* The signature that carries the restriction.
|
|
35
|
+
*/
|
|
36
|
+
signature: SignatureJs;
|
|
37
|
+
/**
|
|
38
|
+
* The form field whose widget a page edit deletes or reshows (its ID), for a
|
|
39
|
+
* `signedWidget` restriction or a `fieldMdp` one that a page edit breaks.
|
|
40
|
+
*/
|
|
41
|
+
field?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* A conformance claim the document's metadata no longer meets.
|
|
46
|
+
*
|
|
47
|
+
* Added in 0.2.0.
|
|
48
|
+
*/
|
|
49
|
+
export type ConformanceWarning = { code: "pdfa-one-author"; authors: number } | { code: "pdfua-title-missing" } | { code: "pdfa-info-mismatch"; keys: MetadataKey[] };
|
|
50
|
+
|
|
17
51
|
/**
|
|
18
52
|
* A conformance profile.
|
|
19
53
|
*/
|
|
20
54
|
export type ProfileInit = "PDF/UA-1" | "PDF/A-2b" | "PDF/A-2u" | "PDF/A-3b";
|
|
21
55
|
|
|
56
|
+
/**
|
|
57
|
+
* A document's metadata as one record, read from the Info dictionary and the XMP packet.
|
|
58
|
+
*
|
|
59
|
+
* When the two disagree, the values come from the XMP packet in a PDF 2.0 file (ISO 32000-2
|
|
60
|
+
* §14.3.3 deprecates the Info entries) or a file that claims PDF/A (whose packet is
|
|
61
|
+
* authoritative, ISO 19005-2 §6.6.2.3.1), and otherwise from the side whose modification date
|
|
62
|
+
* is newer, Info winning a tie. A field the winning side lacks is taken from the other.
|
|
63
|
+
* [`disagreements`](DocumentMetadata::disagreements) names the fields where the two differ, so
|
|
64
|
+
* a properties view can say so.
|
|
65
|
+
*
|
|
66
|
+
* Added in 0.2.0.
|
|
67
|
+
*/
|
|
68
|
+
export interface DocumentMetadata {
|
|
69
|
+
/**
|
|
70
|
+
* The title.
|
|
71
|
+
*/
|
|
72
|
+
title?: string;
|
|
73
|
+
/**
|
|
74
|
+
* The authors, in order (Info's `/Author` split at `;`).
|
|
75
|
+
*/
|
|
76
|
+
authors: string[];
|
|
77
|
+
/**
|
|
78
|
+
* The subject.
|
|
79
|
+
*/
|
|
80
|
+
subject?: string;
|
|
81
|
+
/**
|
|
82
|
+
* The keywords.
|
|
83
|
+
*/
|
|
84
|
+
keywords?: string;
|
|
85
|
+
/**
|
|
86
|
+
* The application the content came from.
|
|
87
|
+
*/
|
|
88
|
+
creator?: string;
|
|
89
|
+
/**
|
|
90
|
+
* The application that wrote the PDF.
|
|
91
|
+
*/
|
|
92
|
+
producer?: string;
|
|
93
|
+
/**
|
|
94
|
+
* The creation date (a PDF date string on the wire).
|
|
95
|
+
*/
|
|
96
|
+
created?: string;
|
|
97
|
+
/**
|
|
98
|
+
* The modification date.
|
|
99
|
+
*/
|
|
100
|
+
modified?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Which side the values come from.
|
|
103
|
+
*/
|
|
104
|
+
source: MetadataSource;
|
|
105
|
+
/**
|
|
106
|
+
* The fields where Info and XMP hold different values.
|
|
107
|
+
*/
|
|
108
|
+
disagreements: MetadataKey[];
|
|
109
|
+
/**
|
|
110
|
+
* What `/Metadata` holds.
|
|
111
|
+
*/
|
|
112
|
+
packet: PacketStatus;
|
|
113
|
+
/**
|
|
114
|
+
* The PDF/A part and conformance the packet claims (`pdfaid:`), e.g. `"2B"`.
|
|
115
|
+
*/
|
|
116
|
+
pdfa?: string;
|
|
117
|
+
/**
|
|
118
|
+
* The PDF/UA part the packet claims (`pdfuaid:part`).
|
|
119
|
+
*/
|
|
120
|
+
pdfua?: number;
|
|
121
|
+
/**
|
|
122
|
+
* In a PDF 2.0 file, the Info entries besides the two dates: deprecated, kept as they
|
|
123
|
+
* were for older readers, and never written by an edit.
|
|
124
|
+
*/
|
|
125
|
+
keptInfoKeys: MetadataKey[];
|
|
126
|
+
}
|
|
127
|
+
|
|
22
128
|
/**
|
|
23
129
|
* A job's progress (`laminapdf::Step::Progress`).
|
|
24
130
|
*/
|
|
@@ -52,17 +158,56 @@ export interface ProgressJs {
|
|
|
52
158
|
* ```
|
|
53
159
|
*
|
|
54
160
|
* [ADR 0006]: https://github.com/laudebugs/laminapdf/blob/main/docs/decisions/0006-op-log-and-undo.md
|
|
161
|
+
*
|
|
162
|
+
* Added in 0.2.0.
|
|
55
163
|
*/
|
|
56
164
|
export interface OpLog {
|
|
57
165
|
v: 1;
|
|
58
166
|
ops: Op[];
|
|
59
167
|
}
|
|
60
168
|
|
|
169
|
+
/**
|
|
170
|
+
* A metadata field Lamina PDF keeps in step in the Info dictionary and the XMP packet: what
|
|
171
|
+
* [`RemoveMetadata`] removes and [`DocumentMetadata::disagreements`] names.
|
|
172
|
+
*
|
|
173
|
+
* | Key | Info | XMP |
|
|
174
|
+
* | --- | --- | --- |
|
|
175
|
+
* | `title` | `/Title` | `dc:title` |
|
|
176
|
+
* | `authors` | `/Author` (joined with `; `) | `dc:creator` |
|
|
177
|
+
* | `subject` | `/Subject` | `dc:description` |
|
|
178
|
+
* | `keywords` | `/Keywords` | `pdf:Keywords` |
|
|
179
|
+
* | `creator` | `/Creator` | `xmp:CreatorTool` |
|
|
180
|
+
* | `producer` | `/Producer` | `pdf:Producer` |
|
|
181
|
+
* | `created` | `/CreationDate` | `xmp:CreateDate` |
|
|
182
|
+
* | `modified` | `/ModDate` | `xmp:ModifyDate` |
|
|
183
|
+
*
|
|
184
|
+
* Added in 0.2.0.
|
|
185
|
+
*/
|
|
186
|
+
export type MetadataKey = "title" | "authors" | "subject" | "keywords" | "creator" | "producer" | "created" | "modified";
|
|
187
|
+
|
|
61
188
|
/**
|
|
62
189
|
* A page-label numbering style.
|
|
63
190
|
*/
|
|
64
191
|
export type LabelStyleInit = "decimal" | "upperRoman" | "lowerRoman" | "upperLetters" | "lowerLetters";
|
|
65
192
|
|
|
193
|
+
/**
|
|
194
|
+
* A signature the planner found.
|
|
195
|
+
*/
|
|
196
|
+
export interface SignatureJs {
|
|
197
|
+
/**
|
|
198
|
+
* `approval`, `certification`, `docTimeStamp` or `usageRights`.
|
|
199
|
+
*/
|
|
200
|
+
kind: string;
|
|
201
|
+
/**
|
|
202
|
+
* The signature field's ID, when a field holds it.
|
|
203
|
+
*/
|
|
204
|
+
field?: string;
|
|
205
|
+
/**
|
|
206
|
+
* The 1-based revision the signature closes, when known.
|
|
207
|
+
*/
|
|
208
|
+
revision?: number;
|
|
209
|
+
}
|
|
210
|
+
|
|
66
211
|
/**
|
|
67
212
|
* An attached file's options.
|
|
68
213
|
*/
|
|
@@ -101,8 +246,10 @@ export interface AttachmentInit {
|
|
|
101
246
|
* ```
|
|
102
247
|
*
|
|
103
248
|
* [ADR 0006]: https://github.com/laudebugs/laminapdf/blob/main/docs/decisions/0006-op-log-and-undo.md
|
|
249
|
+
*
|
|
250
|
+
* Added in 0.2.0.
|
|
104
251
|
*/
|
|
105
|
-
export type Op = { op: "setInfo"; args: SetInfo } | { op: "rotatePage"; args: RotatePage };
|
|
252
|
+
export type Op = { op: "setInfo"; args: SetInfo } | { op: "rotatePage"; args: RotatePage } | { op: "setMetadata"; args: SetMetadata } | { op: "removeMetadata"; args: RemoveMetadata };
|
|
106
253
|
|
|
107
254
|
/**
|
|
108
255
|
* Changes to the Info dictionary's text entries. For each field, `None` leaves the entry
|
|
@@ -111,6 +258,8 @@ export type Op = { op: "setInfo"; args: SetInfo } | { op: "rotatePage"; args: Ro
|
|
|
111
258
|
*
|
|
112
259
|
* On the wire an absent field is left alone and `null` clears: `{ "title": "Report",
|
|
113
260
|
* "author": null }`.
|
|
261
|
+
*
|
|
262
|
+
* Added in 0.2.0.
|
|
114
263
|
*/
|
|
115
264
|
export interface InfoPatch {
|
|
116
265
|
/**
|
|
@@ -139,13 +288,75 @@ export interface InfoPatch {
|
|
|
139
288
|
producer?: string | null;
|
|
140
289
|
}
|
|
141
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Changes to the document's metadata. For each field, `None` leaves it alone, `Some(None)`
|
|
293
|
+
* removes it and `Some(Some(value))` sets it, in Info and XMP alike.
|
|
294
|
+
*
|
|
295
|
+
* On the wire an absent field is left alone and `null` removes: `{ "title": "Report",
|
|
296
|
+
* "authors": ["Ada Lovelace", "Charles Babbage"], "keywords": null }`; dates are PDF date
|
|
297
|
+
* strings (`"D:20261110093000+01'00'"`).
|
|
298
|
+
*
|
|
299
|
+
* ```
|
|
300
|
+
* use laminapdf_ops::MetadataPatch;
|
|
301
|
+
*
|
|
302
|
+
* let patch = MetadataPatch::new().title(Some("Quarterly figures")).authors(&["Ada Lovelace", "Charles Babbage"]);
|
|
303
|
+
* assert_eq!(patch.authors, Some(Some(vec!["Ada Lovelace".to_owned(), "Charles Babbage".to_owned()])));
|
|
304
|
+
* assert_eq!(serde_json::to_string(&patch)?, r#"{"title":"Quarterly figures","authors":["Ada Lovelace","Charles Babbage"]}"#);
|
|
305
|
+
* # Ok::<(), serde_json::Error>(())
|
|
306
|
+
* ```
|
|
307
|
+
*
|
|
308
|
+
* Added in 0.2.0.
|
|
309
|
+
*/
|
|
310
|
+
export interface MetadataPatch {
|
|
311
|
+
/**
|
|
312
|
+
* `/Title`, `dc:title`.
|
|
313
|
+
*/
|
|
314
|
+
title?: string | null;
|
|
315
|
+
/**
|
|
316
|
+
* `/Author` (joined with `; `), `dc:creator` (in order). An empty list removes them.
|
|
317
|
+
*/
|
|
318
|
+
authors?: string[] | null;
|
|
319
|
+
/**
|
|
320
|
+
* `/Subject`, `dc:description`.
|
|
321
|
+
*/
|
|
322
|
+
subject?: string | null;
|
|
323
|
+
/**
|
|
324
|
+
* `/Keywords`, `pdf:Keywords`.
|
|
325
|
+
*/
|
|
326
|
+
keywords?: string | null;
|
|
327
|
+
/**
|
|
328
|
+
* `/Creator`, `xmp:CreatorTool`: the application the content came from.
|
|
329
|
+
*/
|
|
330
|
+
creator?: string | null;
|
|
331
|
+
/**
|
|
332
|
+
* `/Producer`, `pdf:Producer`: the application that wrote the PDF.
|
|
333
|
+
*/
|
|
334
|
+
producer?: string | null;
|
|
335
|
+
/**
|
|
336
|
+
* `/CreationDate`, `xmp:CreateDate`.
|
|
337
|
+
*/
|
|
338
|
+
created?: string | null;
|
|
339
|
+
/**
|
|
340
|
+
* `/ModDate`, `xmp:ModifyDate`.
|
|
341
|
+
*/
|
|
342
|
+
modified?: string | null;
|
|
343
|
+
}
|
|
344
|
+
|
|
142
345
|
/**
|
|
143
346
|
* Edits the Info dictionary: applies `patch` and, when `at` is given, sets `/ModDate` to it.
|
|
347
|
+
*
|
|
348
|
+
* **Deprecated:** use [`SetMetadata`](crate::SetMetadata), which writes authors as a list and
|
|
349
|
+
* the dates, and edits files whose metadata is in XMP alone. `SetInfo` stays, with its v1 wire
|
|
350
|
+
* form (`setInfo`) and meaning, so op logs already written still apply (ADR 0006 §6). It now
|
|
351
|
+
* goes through the same writer, so a document's XMP packet, when it has one, changes with it.
|
|
352
|
+
* It adds a packet only to a PDF 2.0 file, where the fields other than the dates belong in XMP.
|
|
144
353
|
* The date is part of the op, never read from a clock, so the same op gives the same bytes
|
|
145
354
|
* everywhere (ADR 0006 §1).
|
|
146
355
|
*
|
|
147
356
|
* An Info dictionary written directly in the trailer, or missing, becomes a new indirect
|
|
148
357
|
* object that the trailer's `/Info` points to (the first time the op changes something).
|
|
358
|
+
*
|
|
359
|
+
* Added in 0.2.0.
|
|
149
360
|
*/
|
|
150
361
|
export interface SetInfo {
|
|
151
362
|
/**
|
|
@@ -158,11 +369,106 @@ export interface SetInfo {
|
|
|
158
369
|
at?: string;
|
|
159
370
|
}
|
|
160
371
|
|
|
372
|
+
/**
|
|
373
|
+
* Edits the document's metadata: applies `patch` to the Info dictionary and the XMP packet
|
|
374
|
+
* together and, when `at` is given, records it as the modification date (`/ModDate`,
|
|
375
|
+
* `xmp:ModifyDate`) and as `xmp:MetadataDate`, unless the patch sets the modification date
|
|
376
|
+
* itself. The date is part of the op, never read from a clock (ADR 0006 §1).
|
|
377
|
+
*
|
|
378
|
+
* ```
|
|
379
|
+
* use laminapdf_ops::{MetadataPatch, Op, SetMetadata};
|
|
380
|
+
*
|
|
381
|
+
* let op = Op::from(SetMetadata::new(MetadataPatch::new().title(Some("Minutes")), Some("D:20261110093000Z".parse()?)));
|
|
382
|
+
* assert_eq!(
|
|
383
|
+
* serde_json::to_string(&op)?,
|
|
384
|
+
* r#"{"op":"setMetadata","args":{"patch":{"title":"Minutes"},"at":"D:20261110093000Z"}}"#
|
|
385
|
+
* );
|
|
386
|
+
* # Ok::<(), Box<dyn std::error::Error>>(())
|
|
387
|
+
* ```
|
|
388
|
+
*
|
|
389
|
+
* Added in 0.2.0.
|
|
390
|
+
*/
|
|
391
|
+
export interface SetMetadata {
|
|
392
|
+
/**
|
|
393
|
+
* The fields to set or remove.
|
|
394
|
+
*/
|
|
395
|
+
patch?: MetadataPatch;
|
|
396
|
+
/**
|
|
397
|
+
* The modification date the edit writes.
|
|
398
|
+
*/
|
|
399
|
+
at?: string;
|
|
400
|
+
/**
|
|
401
|
+
* Replace an XMP packet that can't be read with a new one, losing whatever it held.
|
|
402
|
+
* Without it, such a packet makes the op fail with `malformed-xmp`, so nothing is lost
|
|
403
|
+
* without the user saying so.
|
|
404
|
+
*/
|
|
405
|
+
replaceMalformed?: boolean;
|
|
406
|
+
}
|
|
407
|
+
|
|
161
408
|
/**
|
|
162
409
|
* How a destination shows its page (§12.3.2.2).
|
|
163
410
|
*/
|
|
164
411
|
export type FitInit = { type: "page" } | { type: "width"; top?: number } | { type: "height"; left?: number } | { type: "xyz"; left?: number; top?: number; zoom?: number } | { type: "rect"; x: number; y: number; width: number; height: number } | { type: "bounds" };
|
|
165
412
|
|
|
413
|
+
/**
|
|
414
|
+
* How a save would go (`laminapdf::PlannedSave`).
|
|
415
|
+
*/
|
|
416
|
+
export interface PlannedSaveJs {
|
|
417
|
+
/**
|
|
418
|
+
* The mode the save resolves to; absent when it would be refused.
|
|
419
|
+
*/
|
|
420
|
+
mode?: SaveModeJs;
|
|
421
|
+
/**
|
|
422
|
+
* The code the save would be refused with.
|
|
423
|
+
*/
|
|
424
|
+
refusal?: string;
|
|
425
|
+
/**
|
|
426
|
+
* `free`, `appendOnly`, `requiresRewrite` or `conflict`.
|
|
427
|
+
*/
|
|
428
|
+
constraint: string;
|
|
429
|
+
/**
|
|
430
|
+
* Every signature, in the order found.
|
|
431
|
+
*/
|
|
432
|
+
signatures: SignatureJs[];
|
|
433
|
+
/**
|
|
434
|
+
* The certification's `/P` (1, 2 or 3), when the document is certified.
|
|
435
|
+
*/
|
|
436
|
+
docMdp?: number;
|
|
437
|
+
/**
|
|
438
|
+
* Why only a full rewrite is safe: `repairedBase`, `encryptedBase`, `noBase`,
|
|
439
|
+
* `opRequiresRewrite`.
|
|
440
|
+
*/
|
|
441
|
+
rewriteReasons: string[];
|
|
442
|
+
/**
|
|
443
|
+
* The pending changes a signature's restriction forbids.
|
|
444
|
+
*/
|
|
445
|
+
violations: ViolationJs[];
|
|
446
|
+
/**
|
|
447
|
+
* The signatures the save would invalidate (only with `invalidateSignatures`).
|
|
448
|
+
*/
|
|
449
|
+
wouldInvalidate: SignatureJs[];
|
|
450
|
+
/**
|
|
451
|
+
* Whether the save writes an encrypted document as plaintext.
|
|
452
|
+
*/
|
|
453
|
+
removesEncryption: boolean;
|
|
454
|
+
/**
|
|
455
|
+
* What the save does with the save-time metadata: `none`, `stamp` or `skipped`.
|
|
456
|
+
*/
|
|
457
|
+
metadata: string;
|
|
458
|
+
/**
|
|
459
|
+
* Whether an edit to save rewrote the XMP packet whole.
|
|
460
|
+
*/
|
|
461
|
+
packetRewritten: boolean;
|
|
462
|
+
/**
|
|
463
|
+
* The PDF/A and PDF/UA claims the edited metadata breaks (warnings that never block).
|
|
464
|
+
*/
|
|
465
|
+
conformanceWarnings: Diagnostic[];
|
|
466
|
+
/**
|
|
467
|
+
* The document has no changes.
|
|
468
|
+
*/
|
|
469
|
+
unchanged: boolean;
|
|
470
|
+
}
|
|
471
|
+
|
|
166
472
|
/**
|
|
167
473
|
* How a viewer lays pages out.
|
|
168
474
|
*/
|
|
@@ -370,6 +676,48 @@ export interface SaveOptionsInit {
|
|
|
370
676
|
* The cross-reference form.
|
|
371
677
|
*/
|
|
372
678
|
xref?: XrefJs;
|
|
679
|
+
/**
|
|
680
|
+
* When the save happens, as the app's clock reads it: a PDF date (`D:20261110093000Z`)
|
|
681
|
+
* or an ISO 8601 date-time. A save that writes changes stamps it as the modification and
|
|
682
|
+
* metadata dates and gives the XMP packet a new instance ID.
|
|
683
|
+
*/
|
|
684
|
+
metadataDate?: string;
|
|
685
|
+
/**
|
|
686
|
+
* The XMP instance ID the save writes, a UUID (`uuid:` optional); without it, one is
|
|
687
|
+
* derived from the content.
|
|
688
|
+
*/
|
|
689
|
+
instanceId?: string;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Removes metadata fields from the Info dictionary and the XMP packet; the packet's other
|
|
694
|
+
* properties stay (J.10).
|
|
695
|
+
*
|
|
696
|
+
* The values stay in the file's earlier revisions until a full rewrite: an incremental save
|
|
697
|
+
* appends the change and keeps the original bytes. When it removed anything, the op's result
|
|
698
|
+
* says so ([`Applied::still_in_earlier_revisions`](crate::Applied::still_in_earlier_revisions)),
|
|
699
|
+
* so the caller can offer a full rewrite (on a signed file, the override that removes the
|
|
700
|
+
* signatures).
|
|
701
|
+
*
|
|
702
|
+
* ```
|
|
703
|
+
* use laminapdf_ops::{MetadataKey, Op, RemoveMetadata};
|
|
704
|
+
*
|
|
705
|
+
* let op = Op::from(RemoveMetadata::new(vec![MetadataKey::Authors, MetadataKey::Creator]));
|
|
706
|
+
* assert_eq!(serde_json::to_string(&op)?, r#"{"op":"removeMetadata","args":{"keys":["authors","creator"]}}"#);
|
|
707
|
+
* # Ok::<(), serde_json::Error>(())
|
|
708
|
+
* ```
|
|
709
|
+
*
|
|
710
|
+
* Added in 0.2.0.
|
|
711
|
+
*/
|
|
712
|
+
export interface RemoveMetadata {
|
|
713
|
+
/**
|
|
714
|
+
* The fields to remove.
|
|
715
|
+
*/
|
|
716
|
+
keys: MetadataKey[];
|
|
717
|
+
/**
|
|
718
|
+
* As [`SetMetadata::replace_malformed`].
|
|
719
|
+
*/
|
|
720
|
+
replaceMalformed?: boolean;
|
|
373
721
|
}
|
|
374
722
|
|
|
375
723
|
/**
|
|
@@ -384,6 +732,8 @@ export interface SaveOptionsInit {
|
|
|
384
732
|
* On the wire: `{ "op": "rotatePage", "args": { "page": "p12.0", "rotate": 90 } }`.
|
|
385
733
|
*
|
|
386
734
|
* [ADR 0005]: https://github.com/laudebugs/laminapdf/blob/main/docs/decisions/0005-document-model.md
|
|
735
|
+
*
|
|
736
|
+
* Added in 0.2.0.
|
|
387
737
|
*/
|
|
388
738
|
export interface RotatePage {
|
|
389
739
|
/**
|
|
@@ -479,6 +829,8 @@ export interface MetadataInit {
|
|
|
479
829
|
* permissions and the document's `SaveConstraint` ([ADR 0007]).
|
|
480
830
|
*
|
|
481
831
|
* [ADR 0007]: https://github.com/laudebugs/laminapdf/blob/main/docs/decisions/0007-save-planner.md
|
|
832
|
+
*
|
|
833
|
+
* Added in 0.2.0.
|
|
482
834
|
*/
|
|
483
835
|
export type ModificationClass = "metadata" | "formFill" | "annotation" | "signature" | "pageStructure" | "content" | "document";
|
|
484
836
|
|
|
@@ -490,6 +842,15 @@ export interface EditedJs {
|
|
|
490
842
|
* IDs of the pages whose content or attributes changed.
|
|
491
843
|
*/
|
|
492
844
|
touchedPages: string[];
|
|
845
|
+
/**
|
|
846
|
+
* A metadata edit rewrote the XMP packet whole (UTF-16, or marked read-only).
|
|
847
|
+
*/
|
|
848
|
+
packetRewritten: boolean;
|
|
849
|
+
/**
|
|
850
|
+
* A metadata edit removed values the file's earlier revisions still hold, which only a
|
|
851
|
+
* full rewrite drops.
|
|
852
|
+
*/
|
|
853
|
+
stillInEarlierRevisions: boolean;
|
|
493
854
|
/**
|
|
494
855
|
* Whether the edit changed the document: one that only set values they already had leaves
|
|
495
856
|
* no step to undo.
|
|
@@ -535,6 +896,24 @@ export interface SaveReportJs {
|
|
|
535
896
|
* Whether encryption was removed.
|
|
536
897
|
*/
|
|
537
898
|
encryptionRemoved: boolean;
|
|
899
|
+
/**
|
|
900
|
+
* Whether the save stamped the save-time metadata (`metadataDate`, `instanceId`).
|
|
901
|
+
*/
|
|
902
|
+
metadataUpdated: boolean;
|
|
903
|
+
/**
|
|
904
|
+
* Whether the options asked for the stamp and the save left it out, because it would have
|
|
905
|
+
* broken a signature's restriction the saved changes keep.
|
|
906
|
+
*/
|
|
907
|
+
metadataNotUpdated: boolean;
|
|
908
|
+
/**
|
|
909
|
+
* Whether an edit saved here rewrote the XMP packet whole.
|
|
910
|
+
*/
|
|
911
|
+
packetRewritten: boolean;
|
|
912
|
+
/**
|
|
913
|
+
* Whether the save emptied the undo history (a full rewrite, or an incremental save that
|
|
914
|
+
* freed objects); for a copy, whether adopting it would.
|
|
915
|
+
*/
|
|
916
|
+
historyCleared: boolean;
|
|
538
917
|
}
|
|
539
918
|
|
|
540
919
|
/**
|
|
@@ -556,11 +935,25 @@ export interface RevertedJs {
|
|
|
556
935
|
touchedPages: string[];
|
|
557
936
|
}
|
|
558
937
|
|
|
938
|
+
/**
|
|
939
|
+
* What the document's `/Metadata` holds.
|
|
940
|
+
*
|
|
941
|
+
* Added in 0.2.0.
|
|
942
|
+
*/
|
|
943
|
+
export type PacketStatus = "absent" | "parsed" | "malformed";
|
|
944
|
+
|
|
559
945
|
/**
|
|
560
946
|
* Where a link or outline item goes.
|
|
561
947
|
*/
|
|
562
948
|
export type LinkTargetInit = { type: "uri"; uri: string } | { type: "page"; index: number; fit?: FitInit } | { type: "named"; name: string };
|
|
563
949
|
|
|
950
|
+
/**
|
|
951
|
+
* Which side [`DocumentMetadata`]'s values come from.
|
|
952
|
+
*
|
|
953
|
+
* Added in 0.2.0.
|
|
954
|
+
*/
|
|
955
|
+
export type MetadataSource = "info" | "xmp";
|
|
956
|
+
|
|
564
957
|
/**
|
|
565
958
|
* `Limits` with every field optional (ADR 0003 §3; names as in Rust, camelCase).
|
|
566
959
|
*/
|
|
@@ -715,6 +1108,15 @@ export class WasmDocument {
|
|
|
715
1108
|
private constructor();
|
|
716
1109
|
free(): void;
|
|
717
1110
|
[Symbol.dispose](): void;
|
|
1111
|
+
/**
|
|
1112
|
+
* Makes `bytes`, the whole output of `saveCopy`, the document's saved file (it rebases onto
|
|
1113
|
+
* them), once they are written where the document lives; `historyCleared` is the copy's
|
|
1114
|
+
* report's.
|
|
1115
|
+
*
|
|
1116
|
+
* # Errors
|
|
1117
|
+
* `nested-transaction`, `saved-not-rebased`; `not-rebased` when `bytes` can't be read.
|
|
1118
|
+
*/
|
|
1119
|
+
adoptCopy(bytes: Uint8Array, historyCleared: boolean): void;
|
|
718
1120
|
/**
|
|
719
1121
|
* Applies an op log (`{ "v": 1, "ops": [ … ] }`) as one transaction.
|
|
720
1122
|
*
|
|
@@ -745,6 +1147,14 @@ export class WasmDocument {
|
|
|
745
1147
|
* Whether the file is encrypted (it opened with its password, or the empty one).
|
|
746
1148
|
*/
|
|
747
1149
|
isEncrypted(): boolean;
|
|
1150
|
+
/**
|
|
1151
|
+
* The document's metadata, read from Info and XMP together, with the fields where they
|
|
1152
|
+
* disagree.
|
|
1153
|
+
*
|
|
1154
|
+
* # Errors
|
|
1155
|
+
* Reading errors.
|
|
1156
|
+
*/
|
|
1157
|
+
metadata(): DocumentMetadata;
|
|
748
1158
|
/**
|
|
749
1159
|
* Opens a document from its bytes.
|
|
750
1160
|
*
|
|
@@ -797,6 +1207,13 @@ export class WasmDocument {
|
|
|
797
1207
|
* `page-index-out-of-range`; reading errors.
|
|
798
1208
|
*/
|
|
799
1209
|
page(index: number): WasmPage;
|
|
1210
|
+
/**
|
|
1211
|
+
* How a save with `options` would go, without saving.
|
|
1212
|
+
*
|
|
1213
|
+
* # Errors
|
|
1214
|
+
* `invalid-argument` / `unknown-option` for bad options; reading errors.
|
|
1215
|
+
*/
|
|
1216
|
+
plan(options: SaveOptionsInit | undefined): PlannedSaveJs;
|
|
800
1217
|
/**
|
|
801
1218
|
* Rebases onto `bytes`, the output of a save whose rebase failed (`not-rebased`).
|
|
802
1219
|
*
|
|
@@ -812,6 +1229,14 @@ export class WasmDocument {
|
|
|
812
1229
|
* As [`WasmDocument::undo`].
|
|
813
1230
|
*/
|
|
814
1231
|
redo(): RevertedJs | undefined;
|
|
1232
|
+
/**
|
|
1233
|
+
* Writes what `save` would and leaves the document as it was: not rebased, its changes
|
|
1234
|
+
* still unsaved, the save-time stamp in the copy only (Save a copy).
|
|
1235
|
+
*
|
|
1236
|
+
* # Errors
|
|
1237
|
+
* As `save`; the document is unchanged either way.
|
|
1238
|
+
*/
|
|
1239
|
+
saveCopy(options: SaveOptionsInit | undefined): { bytes: Uint8Array<ArrayBuffer>; report: SaveReportJs };
|
|
815
1240
|
/**
|
|
816
1241
|
* A save as a job, stepped with a budget of work units (ADR 0028 §3, §4).
|
|
817
1242
|
*
|
|
@@ -838,6 +1263,13 @@ export class WasmDocument {
|
|
|
838
1263
|
* A cursor over the warnings so far (build warnings first), each as the §1 object.
|
|
839
1264
|
*/
|
|
840
1265
|
warnings(): WasmWarningCursor;
|
|
1266
|
+
/**
|
|
1267
|
+
* The signature restrictions `op` would break if it were applied and saved.
|
|
1268
|
+
*
|
|
1269
|
+
* # Errors
|
|
1270
|
+
* `invalid-argument` for a value that isn't an op; reading errors.
|
|
1271
|
+
*/
|
|
1272
|
+
wouldViolate(op: Op): ViolationJs[];
|
|
841
1273
|
}
|
|
842
1274
|
|
|
843
1275
|
/**
|
|
@@ -1205,11 +1637,13 @@ export interface InitOutput {
|
|
|
1205
1637
|
readonly wasmbuilder_page: (a: number, b: number, c: number) => number;
|
|
1206
1638
|
readonly wasmbuilder_pageLabels: (a: number, b: any) => [number, number];
|
|
1207
1639
|
readonly wasmbuilder_viewerPreferences: (a: number, b: any) => [number, number];
|
|
1640
|
+
readonly wasmdocument_adoptCopy: (a: number, b: number, c: number, d: number) => [number, number];
|
|
1208
1641
|
readonly wasmdocument_apply: (a: number, b: any) => [number, number, number];
|
|
1209
1642
|
readonly wasmdocument_applyLog: (a: number, b: number, c: number) => [number, number, number];
|
|
1210
1643
|
readonly wasmdocument_hasUnsavedChanges: (a: number) => number;
|
|
1211
1644
|
readonly wasmdocument_info: (a: number) => [number, number, number];
|
|
1212
1645
|
readonly wasmdocument_isEncrypted: (a: number) => number;
|
|
1646
|
+
readonly wasmdocument_metadata: (a: number) => [number, number, number];
|
|
1213
1647
|
readonly wasmdocument_openBytes: (a: number, b: number, c: any) => [number, number, number];
|
|
1214
1648
|
readonly wasmdocument_openSource: (a: number, b: any) => [number, number, number];
|
|
1215
1649
|
readonly wasmdocument_page: (a: number, b: number) => [number, number, number];
|
|
@@ -1217,12 +1651,15 @@ export interface InitOutput {
|
|
|
1217
1651
|
readonly wasmdocument_pageCount: (a: number) => [number, number, number];
|
|
1218
1652
|
readonly wasmdocument_pageInfo: (a: number, b: number) => [number, number, number];
|
|
1219
1653
|
readonly wasmdocument_pageInfos: (a: number) => [number, number, number];
|
|
1654
|
+
readonly wasmdocument_plan: (a: number, b: any) => [number, number, number];
|
|
1220
1655
|
readonly wasmdocument_rebase: (a: number, b: number, c: number) => [number, number];
|
|
1221
1656
|
readonly wasmdocument_redo: (a: number) => [number, number, number];
|
|
1222
1657
|
readonly wasmdocument_save: (a: number, b: any) => [number, number, number];
|
|
1658
|
+
readonly wasmdocument_saveCopy: (a: number, b: any) => [number, number, number];
|
|
1223
1659
|
readonly wasmdocument_saveJob: (a: number, b: any) => [number, number, number];
|
|
1224
1660
|
readonly wasmdocument_undo: (a: number) => [number, number, number];
|
|
1225
1661
|
readonly wasmdocument_warnings: (a: number) => number;
|
|
1662
|
+
readonly wasmdocument_wouldViolate: (a: number, b: any) => [number, number, number];
|
|
1226
1663
|
readonly wasmimage_height: (a: number) => number;
|
|
1227
1664
|
readonly wasmimage_jpeg: (a: number, b: number) => [number, number, number];
|
|
1228
1665
|
readonly wasmimage_png: (a: number, b: number) => [number, number, number];
|