@chr33s/pdf-common 5.0.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.
Files changed (77) hide show
  1. package/dist/base64.d.ts +7 -0
  2. package/dist/base64.js +24 -0
  3. package/dist/base64.js.map +1 -0
  4. package/dist/brotli.d.ts +9 -0
  5. package/dist/brotli.js +2015 -0
  6. package/dist/brotli.js.map +1 -0
  7. package/dist/compression.d.ts +3 -0
  8. package/dist/compression.js +31 -0
  9. package/dist/compression.js.map +1 -0
  10. package/dist/crypto/aes.d.ts +17 -0
  11. package/dist/crypto/aes.js +60 -0
  12. package/dist/crypto/aes.js.map +1 -0
  13. package/dist/crypto/index.d.ts +7 -0
  14. package/dist/crypto/index.js +8 -0
  15. package/dist/crypto/index.js.map +1 -0
  16. package/dist/crypto/md5.d.ts +3 -0
  17. package/dist/crypto/md5.js +9 -0
  18. package/dist/crypto/md5.js.map +1 -0
  19. package/dist/crypto/mode.d.ts +5 -0
  20. package/dist/crypto/mode.js +7 -0
  21. package/dist/crypto/mode.js.map +1 -0
  22. package/dist/crypto/padding.d.ts +7 -0
  23. package/dist/crypto/padding.js +27 -0
  24. package/dist/crypto/padding.js.map +1 -0
  25. package/dist/crypto/rc4.d.ts +10 -0
  26. package/dist/crypto/rc4.js +48 -0
  27. package/dist/crypto/rc4.js.map +1 -0
  28. package/dist/crypto/sha256.d.ts +3 -0
  29. package/dist/crypto/sha256.js +9 -0
  30. package/dist/crypto/sha256.js.map +1 -0
  31. package/dist/crypto/word-array.d.ts +28 -0
  32. package/dist/crypto/word-array.js +116 -0
  33. package/dist/crypto/word-array.js.map +1 -0
  34. package/dist/index.d.ts +4 -0
  35. package/dist/index.js +5 -0
  36. package/dist/index.js.map +1 -0
  37. package/package.json +34 -0
  38. package/src/base64.ts +34 -0
  39. package/src/brotli.ts +2158 -0
  40. package/src/compression.ts +35 -0
  41. package/src/crypto/aes.ts +93 -0
  42. package/src/crypto/index.ts +7 -0
  43. package/src/crypto/md5.ts +10 -0
  44. package/src/crypto/mode.ts +11 -0
  45. package/src/crypto/padding.ts +36 -0
  46. package/src/crypto/rc4.ts +65 -0
  47. package/src/crypto/sha256.ts +10 -0
  48. package/src/crypto/word-array.ts +147 -0
  49. package/src/index.ts +4 -0
  50. package/test/base64.test.ts +173 -0
  51. package/test/brotli.test.data/0000000000000000.empty.br +1 -0
  52. package/test/brotli.test.data/126d9a84a3d1b3ad.xyzzy.br +2 -0
  53. package/test/brotli.test.data/1f39ef98802627d5.bref65536.br +0 -0
  54. package/test/brotli.test.data/24b2c7600b8207e2.random.br +0 -0
  55. package/test/brotli.test.data/5b5eb8c2e54aa1c4.fox.br +1 -0
  56. package/test/brotli.test.data/5ea84b0ab2a9d2f3.ascii.br +0 -0
  57. package/test/brotli.test.data/62652dac985a31f1.monkey.br +0 -0
  58. package/test/brotli.test.data/68333cc8433f3ab8.16k_minus_one.br +0 -0
  59. package/test/brotli.test.data/7da01857468c3de8.buffer_sized_chunks.br +0 -0
  60. package/test/brotli.test.data/89988757bded53ae.x10y10.br +0 -0
  61. package/test/brotli.test.data/940493692ce62466.E.coli.br +0 -0
  62. package/test/brotli.test.data/c3f720395238182c.world192.br +0 -0
  63. package/test/brotli.test.data/c5a4246584d690a7.16k_plus_one.br +0 -0
  64. package/test/brotli.test.data/c895e0c1b11448fa.ukkonooa.br +0 -0
  65. package/test/brotli.test.data/d238c71341928567.allbytevalues_twice.br +0 -0
  66. package/test/brotli.test.data/d38da8261aedc293.bible.br +0 -0
  67. package/test/brotli.test.data/d6a9c5da7ba30f21.allbytevalues_16k.br +0 -0
  68. package/test/brotli.test.data/f121ac88218962d7.x.br +0 -0
  69. package/test/brotli.test.data/f6083a8a3754518c.x64.br +0 -0
  70. package/test/brotli.test.file +201 -0
  71. package/test/brotli.test.file.br +0 -0
  72. package/test/brotli.test.ts +2197 -0
  73. package/test/compression.test.ts +93 -0
  74. package/test/crypto.test.ts +157 -0
  75. package/tsconfig.json +10 -0
  76. package/tsconfig.typecheck.json +14 -0
  77. package/vitest.config.ts +8 -0
@@ -0,0 +1,93 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { deflate, inflate } from "../src/compression.js";
3
+
4
+ const testData = new TextEncoder().encode("Hello, World! This is a test string for compression.");
5
+ const largeData = new Uint8Array(10_000).fill(65); // 10KB of 'A's
6
+
7
+ describe("deflate/inflate", () => {
8
+ test("should compress and decompress data", async () => {
9
+ const compressed = await deflate(testData);
10
+ // Small data may not compress smaller due to overhead
11
+ expect(compressed.length).toBeGreaterThan(0);
12
+
13
+ const decompressed = await inflate(compressed);
14
+ expect(decompressed).toEqual(testData);
15
+ });
16
+
17
+ test("should handle large data", async () => {
18
+ const compressed = await deflate(largeData);
19
+ expect(compressed.length).toBeLessThan(largeData.length);
20
+
21
+ const decompressed = await inflate(compressed);
22
+ expect(decompressed).toEqual(largeData);
23
+ });
24
+
25
+ test("should handle empty data", async () => {
26
+ const emptyData = new Uint8Array(0);
27
+ const compressed = await deflate(emptyData);
28
+ const decompressed = await inflate(compressed);
29
+ expect(decompressed).toEqual(emptyData);
30
+ });
31
+
32
+ test("should achieve good compression on repetitive data", async () => {
33
+ const repetitiveData = new TextEncoder().encode("AAAAAAAAAAAAAAAAAAAA".repeat(100));
34
+ const compressed = await deflate(repetitiveData);
35
+
36
+ // Should achieve at least 50% compression on highly repetitive data
37
+ expect(compressed.length).toBeLessThan(repetitiveData.length * 0.5);
38
+ });
39
+ });
40
+
41
+ describe("deflateRaw/inflateRaw", () => {
42
+ test("should compress and decompress data", async () => {
43
+ const compressed = await deflate(testData, "deflate-raw");
44
+ // Small data may not compress smaller due to overhead
45
+ expect(compressed.length).toBeGreaterThan(0);
46
+
47
+ const decompressed = await inflate(compressed, "deflate-raw");
48
+ expect(decompressed).toEqual(testData);
49
+ });
50
+
51
+ test("should handle large data", async () => {
52
+ const compressed = await deflate(largeData, "deflate-raw");
53
+ expect(compressed.length).toBeLessThan(largeData.length);
54
+
55
+ const decompressed = await inflate(compressed, "deflate-raw");
56
+ expect(decompressed).toEqual(largeData);
57
+ });
58
+
59
+ test("should achieve good compression on repetitive data", async () => {
60
+ const repetitiveData = new TextEncoder().encode("AAAAAAAAAAAAAAAAAAAA".repeat(100));
61
+ const compressed = await deflate(repetitiveData, "deflate-raw");
62
+
63
+ // Should achieve at least 50% compression on highly repetitive data
64
+ expect(compressed.length).toBeLessThan(repetitiveData.length * 0.5);
65
+ });
66
+ });
67
+
68
+ describe("gzip/gunzip", () => {
69
+ test("should compress and decompress data", async () => {
70
+ const compressed = await deflate(testData, "gzip");
71
+ // gzip adds header, so small data won't be smaller
72
+ expect(compressed.length).toBeGreaterThan(0);
73
+
74
+ const decompressed = await inflate(compressed, "gzip");
75
+ expect(decompressed).toEqual(testData);
76
+ });
77
+
78
+ test("should handle large data", async () => {
79
+ const compressed = await deflate(largeData, "gzip");
80
+ expect(compressed.length).toBeLessThan(largeData.length);
81
+
82
+ const decompressed = await inflate(compressed, "gzip");
83
+ expect(decompressed).toEqual(largeData);
84
+ });
85
+
86
+ test("should achieve good compression on repetitive data", async () => {
87
+ const repetitiveData = new TextEncoder().encode("AAAAAAAAAAAAAAAAAAAA".repeat(100));
88
+ const compressed = await deflate(repetitiveData, "gzip");
89
+
90
+ // Should achieve at least 50% compression on highly repetitive data
91
+ expect(compressed.length).toBeLessThan(repetitiveData.length * 0.5);
92
+ });
93
+ });
@@ -0,0 +1,157 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { AES, MD5, mode, padding, RC4, SHA256, WordArray } from "../src/crypto/index.js";
3
+
4
+ describe("WordArray", () => {
5
+ test("should create from words", () => {
6
+ const wa = new WordArray([0x48656c6c, 0x6f000000], 5);
7
+ expect(wa.sigBytes).toBe(5);
8
+ expect(wa.words).toEqual([0x48656c6c, 0x6f000000]);
9
+ });
10
+
11
+ test("should convert to/from Uint8Array", () => {
12
+ const bytes = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]); // "Hello"
13
+ const wa = WordArray.fromUint8Array(bytes);
14
+ expect(wa.sigBytes).toBe(5);
15
+ expect(wa.toUint8Array()).toEqual(bytes);
16
+ });
17
+
18
+ test("should generate random bytes", () => {
19
+ const wa = WordArray.random(16);
20
+ expect(wa.sigBytes).toBe(16);
21
+ expect(wa.toUint8Array().length).toBe(16);
22
+ });
23
+
24
+ test("should concat word arrays", () => {
25
+ const wa1 = WordArray.fromUint8Array(new Uint8Array([0x01, 0x02]));
26
+ const wa2 = WordArray.fromUint8Array(new Uint8Array([0x03, 0x04]));
27
+ wa1.concat(wa2);
28
+ expect(wa1.sigBytes).toBe(4);
29
+ expect(wa1.toUint8Array()).toEqual(new Uint8Array([0x01, 0x02, 0x03, 0x04]));
30
+ });
31
+
32
+ test("should clone", () => {
33
+ const wa1 = WordArray.fromUint8Array(new Uint8Array([0x01, 0x02, 0x03]));
34
+ const wa2 = wa1.clone();
35
+ expect(wa2.sigBytes).toBe(wa1.sigBytes);
36
+ expect(wa2.words).toEqual(wa1.words);
37
+ expect(wa2.words).not.toBe(wa1.words);
38
+ });
39
+ });
40
+
41
+ describe("MD5", () => {
42
+ test("should hash empty string", () => {
43
+ const hash = MD5("");
44
+ expect(hash.toString()).toBe("d41d8cd98f00b204e9800998ecf8427e");
45
+ });
46
+
47
+ test("should hash 'message'", () => {
48
+ const hash = MD5("message");
49
+ expect(hash.toString()).toBe("78e731027d8fd50ed642340b7c9a63b3");
50
+ });
51
+
52
+ test("should hash WordArray", () => {
53
+ const wa = WordArray.fromUint8Array(new TextEncoder().encode("message"));
54
+ const hash = MD5(wa);
55
+ expect(hash.toString()).toBe("78e731027d8fd50ed642340b7c9a63b3");
56
+ });
57
+ });
58
+
59
+ describe("SHA256", () => {
60
+ test("should hash empty string", () => {
61
+ const hash = SHA256("");
62
+ expect(hash.toString()).toBe(
63
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
64
+ );
65
+ });
66
+
67
+ test("should hash 'message'", () => {
68
+ const hash = SHA256("message");
69
+ expect(hash.toString()).toBe(
70
+ "ab530a13e45914982b79f9b7e3fba994cfd1f3fb22f71cea1afbf02b460c6d1d",
71
+ );
72
+ });
73
+
74
+ test("should hash WordArray", () => {
75
+ const wa = WordArray.fromUint8Array(new TextEncoder().encode("message"));
76
+ const hash = SHA256(wa);
77
+ expect(hash.toString()).toBe(
78
+ "ab530a13e45914982b79f9b7e3fba994cfd1f3fb22f71cea1afbf02b460c6d1d",
79
+ );
80
+ });
81
+ });
82
+
83
+ describe("RC4", () => {
84
+ test("should encrypt data", () => {
85
+ const key = WordArray.fromUint8Array(new TextEncoder().encode("Secret"));
86
+ const message = WordArray.fromUint8Array(new TextEncoder().encode("Message"));
87
+ const result = RC4.encrypt(message, key);
88
+ expect(result.ciphertext).toBeDefined();
89
+ expect(result.ciphertext.sigBytes).toBeGreaterThan(0);
90
+ });
91
+
92
+ test("should decrypt to original", () => {
93
+ const key = WordArray.fromUint8Array(new TextEncoder().encode("Secret"));
94
+ const message = WordArray.fromUint8Array(new TextEncoder().encode("Message"));
95
+ const encrypted = RC4.encrypt(message, key);
96
+ const decrypted = RC4.decrypt(encrypted.ciphertext, key);
97
+ expect(decrypted.ciphertext.toUint8Array()).toEqual(message.toUint8Array());
98
+ });
99
+ });
100
+
101
+ describe("AES", () => {
102
+ test("should encrypt with CBC mode", () => {
103
+ const key = WordArray.fromUint8Array(new Uint8Array(16).fill(0x00));
104
+ const iv = WordArray.fromUint8Array(new Uint8Array(16).fill(0x00));
105
+ const message = WordArray.fromUint8Array(new TextEncoder().encode("Hello World!"));
106
+
107
+ const result = AES.encrypt(message, key, { mode: mode.CBC, iv });
108
+ expect(result.ciphertext).toBeDefined();
109
+ expect(result.ciphertext.sigBytes).toBeGreaterThan(0);
110
+ });
111
+
112
+ test("should decrypt to original with CBC mode", () => {
113
+ const key = WordArray.fromUint8Array(new Uint8Array(16).fill(0x00));
114
+ const iv = WordArray.fromUint8Array(new Uint8Array(16).fill(0x00));
115
+ const message = WordArray.fromUint8Array(new TextEncoder().encode("Hello World!"));
116
+
117
+ const encrypted = AES.encrypt(message, key, { mode: mode.CBC, iv });
118
+ const decrypted = AES.decrypt(encrypted.ciphertext, key, { mode: mode.CBC, iv });
119
+
120
+ // Compare the decrypted text
121
+ const decoder = new TextDecoder();
122
+ expect(decoder.decode(decrypted.ciphertext.toUint8Array())).toBe("Hello World!");
123
+ });
124
+
125
+ test("should encrypt with ECB mode", () => {
126
+ const key = WordArray.fromUint8Array(new Uint8Array(16).fill(0x00));
127
+ const message = WordArray.fromUint8Array(new Uint8Array(16).fill(0x41)); // 16 bytes of 'A'
128
+
129
+ const result = AES.encrypt(message, key, { mode: mode.ECB, padding: padding.NoPadding });
130
+ expect(result.ciphertext).toBeDefined();
131
+ });
132
+
133
+ test("should decrypt to original with ECB mode", () => {
134
+ const key = WordArray.fromUint8Array(new Uint8Array(16).fill(0x00));
135
+ const message = WordArray.fromUint8Array(new Uint8Array(16).fill(0x41)); // 16 bytes of 'A'
136
+
137
+ const encrypted = AES.encrypt(message, key, { mode: mode.ECB, padding: padding.NoPadding });
138
+ const decrypted = AES.decrypt(encrypted.ciphertext, key, {
139
+ mode: mode.ECB,
140
+ padding: padding.NoPadding,
141
+ });
142
+
143
+ expect(decrypted.ciphertext.toUint8Array()).toEqual(message.toUint8Array());
144
+ });
145
+
146
+ test("should work with 256-bit key", () => {
147
+ const key = WordArray.fromUint8Array(new Uint8Array(32).fill(0x00));
148
+ const iv = WordArray.fromUint8Array(new Uint8Array(16).fill(0x00));
149
+ const message = WordArray.fromUint8Array(new TextEncoder().encode("Test message"));
150
+
151
+ const encrypted = AES.encrypt(message, key, { mode: mode.CBC, iv });
152
+ const decrypted = AES.decrypt(encrypted.ciphertext, key, { mode: mode.CBC, iv });
153
+
154
+ const decoder = new TextDecoder();
155
+ expect(decoder.decode(decrypted.ciphertext.toUint8Array())).toBe("Test message");
156
+ });
157
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "dist",
6
+ "declarationDir": "dist"
7
+ },
8
+ "include": ["src/**/*"],
9
+ "exclude": ["dist", "node_modules"]
10
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": true,
5
+ "rootDir": "."
6
+ },
7
+ "include": [
8
+ "**/*.ts",
9
+ ],
10
+ "exclude": [
11
+ "dist",
12
+ "node_modules"
13
+ ]
14
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: "node",
6
+ include: ["test/**/*.test.ts"],
7
+ },
8
+ });