@jackgreen2018/pdf-engine 1.0.108 → 1.0.110

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.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 | — |
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 | — |
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.108); raw JSON at benchmark-results.json.*
143
+ *Run 2026-08-03 (v1.0.110); raw JSON at benchmark-results.json.*
144
144
 
145
145
  ## Commercial license & support
146
146
 
package/dist/cli.js CHANGED
@@ -12,8 +12,6 @@ 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
17
15
  help Print this message
18
16
  `;
19
17
  async function main() {
@@ -51,22 +49,6 @@ async function main() {
51
49
  process.stdout.write(`wrote ${out.length} part-*.pdf files\n`);
52
50
  return 0;
53
51
  }
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
- }
70
52
  default:
71
53
  process.stderr.write(`unknown command: ${cmd}\n${USAGE}`);
72
54
  return 1;
package/dist/index.d.ts CHANGED
@@ -14,6 +14,7 @@ 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>;
17
18
  encrypt(buffer: Uint8Array, userPassword: string, ownerPassword: string, version?: number): Promise<Uint8Array>;
18
19
  decrypt(buffer: Uint8Array, password: string): Promise<Uint8Array>;
19
20
  }
@@ -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,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,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"}
package/dist/index.js CHANGED
@@ -56,6 +56,10 @@ 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
+ }
59
63
  async encrypt(buffer, userPassword, ownerPassword, version = 4) {
60
64
  await this.init();
61
65
  return await encrypt(buffer, userPassword, ownerPassword, version);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackgreen2018/pdf-engine",
3
- "version": "1.0.108",
3
+ "version": "1.0.110",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
package/pkg/README.md CHANGED
@@ -131,15 +131,16 @@ npm run benchmark
131
131
 
132
132
  | Operation | pdf-engine (ms) | pdf-lib (ms) |
133
133
  |-----------|-----------------|--------------|
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) | | — |
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 | — |
139
140
 
140
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."*
141
142
 
142
- *Run 2026-08-03 (v1.0.108); raw JSON at benchmark-results.json.*
143
+ *Run 2026-08-03 (v1.0.110); raw JSON at benchmark-results.json.*
143
144
 
144
145
  ## Commercial license & support
145
146
 
package/pkg/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf_engine",
3
- "version": "1.0.108",
3
+ "version": "1.0.110",
4
4
  "files": [
5
5
  "pdf_engine_bg.wasm",
6
6
  "pdf_engine.js",
Binary file
package/src/cli.ts CHANGED
@@ -13,8 +13,6 @@ 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
18
16
  help Print this message
19
17
  `;
20
18
 
@@ -56,22 +54,6 @@ async function main(): Promise<number> {
56
54
  process.stdout.write(`wrote ${out.length} part-*.pdf files\n`);
57
55
  return 0;
58
56
  }
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
- }
75
57
  default:
76
58
  process.stderr.write(`unknown command: ${cmd}\n${USAGE}`);
77
59
  return 1;
package/src/index.ts CHANGED
@@ -77,6 +77,11 @@ 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
+
80
85
  async encrypt(
81
86
  buffer: Uint8Array,
82
87
  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;
5
3
  use lopdf::{Document, Object, ObjectId, encryption::{EncryptionState, EncryptionVersion, Permissions}};
6
4
  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,7 +301,6 @@ 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
305
304
  let mut doc = doc;
306
305
  if doc.trailer.get(b"ID").is_err() {
307
306
  doc.trailer.set(b"ID", Object::Array(vec![
@@ -311,7 +310,7 @@ pub fn encrypt(
311
310
  }
312
311
 
313
312
  // ponytail: version arg maps 1→V1/RC4, 2→V2/RC4-40bit, 4→V4/AES-128
314
- // V5 requires raw file_encryption_key from user; omit for now (not used by any client)
313
+ // V5 requires raw file_encryption_key from user; omitted for now
315
314
  let state = match version {
316
315
  1 => {
317
316
  EncryptionState::try_from(EncryptionVersion::V1 {