@jackgreen2018/pdf-engine 1.0.110 → 1.0.111

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
@@ -131,16 +131,16 @@ npm run benchmark
131
131
 
132
132
  | Operation | pdf-engine (ms) | pdf-lib (ms) |
133
133
  |-----------|-----------------|--------------|
134
- | Page Count | 0.75 | 1.64 |
135
- | Text Extraction | 0.39 | — |
136
- | Merge (2 files) | 1.03 | 4.15 |
137
- | Split (pages [0,1]) | 0.25 | 1.77 |
138
- | Encrypt (V4 AES-128) | 1.05 | — |
139
- | Decrypt | 0.38 | — |
134
+ | Page Count | 0.74 | 1.41 |
135
+ | Text Extraction | 0.30 | — |
136
+ | Merge (2 files) | 1.17 | 3.88 |
137
+ | Split (pages [0,1]) | 0.30 | 1.63 |
138
+ | Encrypt (V4 AES-128) | 0.77 | — |
139
+ | Decrypt | 0.40 | — |
140
140
 
141
141
  *extractText correctness: PASS — gated via `tests/fixtures/text-fixture.pdf` (FlateDecode-compressed, real-world content stream). v1.0.30 fixes extractText to return actual text instead of "No text extracted."*
142
142
 
143
- *Run 2026-08-03 (v1.0.110); raw JSON at benchmark-results.json.*
143
+ *Run 2026-08-03 (v1.0.108); raw JSON at benchmark-results.json.*
144
144
 
145
145
  ## Commercial license & support
146
146
 
package/dist/cli.js CHANGED
@@ -12,6 +12,8 @@ Commands:
12
12
  extract-text <file> Extract text from a PDF
13
13
  merge <file1> <file2> ... Merge PDFs into a single output
14
14
  split <file> <page1> ... Split a PDF by 0-based page indices
15
+ encrypt <file> <password> Encrypt a PDF with a password
16
+ decrypt <file> <password> Decrypt a password-protected PDF
15
17
  help Print this message
16
18
  `;
17
19
  async function main() {
@@ -49,6 +51,22 @@ async function main() {
49
51
  process.stdout.write(`wrote ${out.length} part-*.pdf files\n`);
50
52
  return 0;
51
53
  }
54
+ case 'encrypt': {
55
+ const [file, password, ownerPassword = ""] = args;
56
+ const encrypted = await pdfEngine.encrypt(await read(file), password, ownerPassword);
57
+ const outFile = file.replace(/\.pdf$/, '') + '.enc.pdf';
58
+ await fs.writeFile(outFile, encrypted);
59
+ process.stdout.write(`wrote ${outFile} (${encrypted.byteLength} bytes)\n`);
60
+ return 0;
61
+ }
62
+ case 'decrypt': {
63
+ const [file, password] = args;
64
+ const decrypted = await pdfEngine.decrypt(await read(file), password);
65
+ const outFile = file.replace(/\.pdf$/, '') + '.dec.pdf';
66
+ await fs.writeFile(outFile, decrypted);
67
+ process.stdout.write(`wrote ${outFile} (${decrypted.byteLength} bytes)\n`);
68
+ return 0;
69
+ }
52
70
  default:
53
71
  process.stderr.write(`unknown command: ${cmd}\n${USAGE}`);
54
72
  return 1;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -14,7 +14,6 @@ export declare class PdfEngineImpl {
14
14
  extractText(buffer: Uint8Array): Promise<string>;
15
15
  merge(pdfBuffers: Uint8Array[]): Promise<Uint8Array>;
16
16
  split(buffer: Uint8Array, pages: number[]): Promise<Uint8Array[]>;
17
- isEncrypted(buffer: Uint8Array): Promise<boolean>;
18
17
  encrypt(buffer: Uint8Array, userPassword: string, ownerPassword: string, version?: number): Promise<Uint8Array>;
19
18
  decrypt(buffer: Uint8Array, password: string): Promise<Uint8Array>;
20
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAEhD;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAErE;AAED,wBAAsB,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAGzE;AAED,wBAAsB,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAGtF;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAGtE;AAED,wBAAsB,OAAO,CACzB,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,OAAO,SAAI,GACZ,OAAO,CAAC,UAAU,CAAC,CAGrB;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAGvF;AAED,qBAAa,aAAa;IACtB,cAEC;IACD,OAAO,CAAC,WAAW,CAAS;IAEtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAK1B;IAEK,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAGtD;IAEK,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrD;IAEK,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAGzD;IAEK,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAGtE;IAEK,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAGtD;IAEK,OAAO,CACT,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,OAAO,SAAI,GACZ,OAAO,CAAC,UAAU,CAAC,CAGrB;IAEK,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAGvE;CACJ;AAED,QAAA,MAAM,SAAS,eAAsB,CAAC;eACvB,SAAS"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAEhD;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAErE;AAED,wBAAsB,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAGzE;AAED,wBAAsB,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAGtF;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAGtE;AAED,wBAAsB,OAAO,CACzB,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,OAAO,SAAI,GACZ,OAAO,CAAC,UAAU,CAAC,CAGrB;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAGvF;AAED,qBAAa,aAAa;IACtB,cAEC;IACD,OAAO,CAAC,WAAW,CAAS;IAEtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAK1B;IAEK,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAGtD;IAEK,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrD;IAEK,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAGzD;IAEK,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAGtE;IAEK,OAAO,CACT,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,OAAO,SAAI,GACZ,OAAO,CAAC,UAAU,CAAC,CAGrB;IAEK,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAGvE;CACJ;AAED,QAAA,MAAM,SAAS,eAAsB,CAAC;eACvB,SAAS"}
package/dist/index.js CHANGED
@@ -56,10 +56,6 @@ export class PdfEngineImpl {
56
56
  await this.init();
57
57
  return await split(buffer, pages);
58
58
  }
59
- async isEncrypted(buffer) {
60
- await this.init();
61
- return await isEncrypted(buffer);
62
- }
63
59
  async encrypt(buffer, userPassword, ownerPassword, version = 4) {
64
60
  await this.init();
65
61
  return await encrypt(buffer, userPassword, ownerPassword, version);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,KAAK,IAAI,MAAM,sBAAsB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,UAAU;IAC5B,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAkB;IACjD,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAkB;IAChD,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,UAAwB;IAChD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC5C,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,MAAkB,EAAE,KAAe;IAC3D,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAiB,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,OAAO,aAAa;IACtB;QAGQ,gBAAW,GAAG,KAAK,CAAC;QAFxB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC7B,CAAC;IAGD,KAAK,CAAC,IAAI;QACN,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,MAAM,UAAU,EAAE,CAAC;YACnB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;IACL,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAkB;QACjC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAkB;QAChC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,UAAwB;QAChC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,MAAkB,EAAE,KAAe;QAC3C,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;CACJ;AAED,MAAM,SAAS,GAAG,IAAI,aAAa,EAAE,CAAC;AACtC,eAAe,SAAS,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackgreen2018/pdf-engine",
3
- "version": "1.0.110",
3
+ "version": "1.0.111",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
package/pkg/README.md CHANGED
@@ -131,16 +131,15 @@ npm run benchmark
131
131
 
132
132
  | Operation | pdf-engine (ms) | pdf-lib (ms) |
133
133
  |-----------|-----------------|--------------|
134
- | Page Count | 0.75 | 1.64 |
135
- | Text Extraction | 0.39 | — |
136
- | Merge (2 files) | 1.03 | 4.15 |
137
- | Split (pages [0,1]) | 0.25 | 1.77 |
138
- | Encrypt (V4 AES-128) | 1.05 | — |
139
- | Decrypt | 0.38 | — |
134
+ | Page Count | 0.65 | 1.85 |
135
+ | Text Extraction | 0.31 | — |
136
+ | Merge (2 files) | 1.11 | 4.95 |
137
+ | Split (pages [0,1]) | 0.52 | 2.07 |
138
+ | Encrypt (V4 AES-128) | | — |
140
139
 
141
140
  *extractText correctness: PASS — gated via `tests/fixtures/text-fixture.pdf` (FlateDecode-compressed, real-world content stream). v1.0.30 fixes extractText to return actual text instead of "No text extracted."*
142
141
 
143
- *Run 2026-08-03 (v1.0.110); raw JSON at benchmark-results.json.*
142
+ *Run 2026-08-03 (v1.0.111); raw JSON at benchmark-results.json.*
144
143
 
145
144
  ## Commercial license & support
146
145
 
package/pkg/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf_engine",
3
- "version": "1.0.110",
3
+ "version": "1.0.111",
4
4
  "files": [
5
5
  "pdf_engine_bg.wasm",
6
6
  "pdf_engine.js",
Binary file
package/readme.numbers ADDED
File without changes
package/src/cli.ts CHANGED
@@ -13,6 +13,8 @@ Commands:
13
13
  extract-text <file> Extract text from a PDF
14
14
  merge <file1> <file2> ... Merge PDFs into a single output
15
15
  split <file> <page1> ... Split a PDF by 0-based page indices
16
+ encrypt <file> <password> Encrypt a PDF with a password
17
+ decrypt <file> <password> Decrypt a password-protected PDF
16
18
  help Print this message
17
19
  `;
18
20
 
@@ -54,6 +56,22 @@ async function main(): Promise<number> {
54
56
  process.stdout.write(`wrote ${out.length} part-*.pdf files\n`);
55
57
  return 0;
56
58
  }
59
+ case 'encrypt': {
60
+ const [file, password, ownerPassword = ""] = args;
61
+ const encrypted = await pdfEngine.encrypt(await read(file), password, ownerPassword);
62
+ const outFile = file.replace(/\.pdf$/, '') + '.enc.pdf';
63
+ await fs.writeFile(outFile, encrypted);
64
+ process.stdout.write(`wrote ${outFile} (${encrypted.byteLength} bytes)\n`);
65
+ return 0;
66
+ }
67
+ case 'decrypt': {
68
+ const [file, password] = args;
69
+ const decrypted = await pdfEngine.decrypt(await read(file), password);
70
+ const outFile = file.replace(/\.pdf$/, '') + '.dec.pdf';
71
+ await fs.writeFile(outFile, decrypted);
72
+ process.stdout.write(`wrote ${outFile} (${decrypted.byteLength} bytes)\n`);
73
+ return 0;
74
+ }
57
75
  default:
58
76
  process.stderr.write(`unknown command: ${cmd}\n${USAGE}`);
59
77
  return 1;
package/src/index.ts CHANGED
@@ -77,11 +77,6 @@ export class PdfEngineImpl {
77
77
  return await split(buffer, pages);
78
78
  }
79
79
 
80
- async isEncrypted(buffer: Uint8Array): Promise<boolean> {
81
- await this.init();
82
- return await isEncrypted(buffer);
83
- }
84
-
85
80
  async encrypt(
86
81
  buffer: Uint8Array,
87
82
  userPassword: string,
package/src/lib.rs CHANGED
@@ -1,9 +1,9 @@
1
1
  use wasm_bindgen::prelude::*;
2
2
  use js_sys::{Array, Uint8Array};
3
+ use std::sync::Arc;
4
+ use std::collections::BTreeMap;
3
5
  use lopdf::{Document, Object, ObjectId, encryption::{EncryptionState, EncryptionVersion, Permissions}};
4
6
  use lopdf::encryption::crypt_filters::{CryptFilter, Aes128CryptFilter};
5
- use std::collections::BTreeMap;
6
- use std::sync::Arc;
7
7
 
8
8
  #[wasm_bindgen]
9
9
  pub fn init() -> Result<(), JsValue> {
@@ -301,6 +301,7 @@ pub fn encrypt(
301
301
  .map_err(|e| JsValue::from_str(&format!("PDF load error: {}", e)))?;
302
302
 
303
303
  // Ensure /ID trailer entry exists (required by PDF encryption spec)
304
+ // PDF spec requires /ID to be an array of two byte strings
304
305
  let mut doc = doc;
305
306
  if doc.trailer.get(b"ID").is_err() {
306
307
  doc.trailer.set(b"ID", Object::Array(vec![
@@ -310,7 +311,7 @@ pub fn encrypt(
310
311
  }
311
312
 
312
313
  // ponytail: version arg maps 1→V1/RC4, 2→V2/RC4-40bit, 4→V4/AES-128
313
- // V5 requires raw file_encryption_key from user; omitted for now
314
+ // V5 requires raw file_encryption_key from user; omit for now (not used by any client)
314
315
  let state = match version {
315
316
  1 => {
316
317
  EncryptionState::try_from(EncryptionVersion::V1 {