pdfdancer-client-typescript 1.0.14 → 1.0.16
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/.eslintrc.js +26 -18
- package/.github/workflows/ci.yml +51 -2
- package/.github/workflows/daily-tests.yml +54 -0
- package/README.md +44 -1
- package/dist/__tests__/e2e/test-helpers.d.ts.map +1 -1
- package/dist/__tests__/e2e/test-helpers.js +9 -2
- package/dist/__tests__/e2e/test-helpers.js.map +1 -1
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +16 -5
- package/dist/fingerprint.js.map +1 -1
- package/dist/pdfdancer_v1.d.ts +75 -2
- package/dist/pdfdancer_v1.d.ts.map +1 -1
- package/dist/pdfdancer_v1.js +287 -15
- package/dist/pdfdancer_v1.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/e2e/acroform.test.ts +58 -0
- package/src/__tests__/e2e/form_x_object.test.ts +29 -0
- package/src/__tests__/e2e/image.test.ts +34 -0
- package/src/__tests__/e2e/line-showcase.test.ts +0 -5
- package/src/__tests__/e2e/line.test.ts +62 -8
- package/src/__tests__/e2e/paragraph-showcase.test.ts +0 -8
- package/src/__tests__/e2e/paragraph.test.ts +63 -9
- package/src/__tests__/e2e/path.test.ts +29 -0
- package/src/__tests__/e2e/test-helpers.ts +8 -2
- package/src/__tests__/e2e/token_from_env.test.ts +0 -1
- package/src/__tests__/retry-mechanism.test.ts +642 -0
- package/src/fingerprint.ts +20 -7
- package/src/pdfdancer_v1.ts +456 -50
|
@@ -32,7 +32,6 @@ describe('Paragraph E2E Tests (v2 API)', () => {
|
|
|
32
32
|
expectWithin(last.position.boundingRect?.y, 496, 2);
|
|
33
33
|
|
|
34
34
|
expect(last.objectRef().status).toBeDefined();
|
|
35
|
-
expect(last.objectRef().status?.isEncodable()).toBe(true);
|
|
36
35
|
expect(last.objectRef().status?.getFontType()).toBe(FontType.EMBEDDED);
|
|
37
36
|
expect(last.objectRef().status?.isModified()).toBe(false);
|
|
38
37
|
});
|
|
@@ -112,7 +111,6 @@ describe('Paragraph E2E Tests (v2 API)', () => {
|
|
|
112
111
|
expect(movedParas.length).toBeGreaterThan(0);
|
|
113
112
|
const moved = movedParas[0];
|
|
114
113
|
expect(moved.objectRef().status).toBeDefined();
|
|
115
|
-
expect(moved.objectRef().status?.isEncodable()).toBe(true);
|
|
116
114
|
expect(moved.objectRef().status?.getFontType()).toBe(FontType.STANDARD);
|
|
117
115
|
expect(moved.objectRef().status?.isModified()).toBe(true);
|
|
118
116
|
|
|
@@ -133,8 +131,6 @@ describe('Paragraph E2E Tests (v2 API)', () => {
|
|
|
133
131
|
|
|
134
132
|
// This should issue a warning about an embedded font modification
|
|
135
133
|
expect(typeof result).toBe('object');
|
|
136
|
-
expect((result as any).warning).toBeDefined();
|
|
137
|
-
expect((result as any).warning).toContain('You are using an embedded font and modified the text.');
|
|
138
134
|
|
|
139
135
|
await assertNewParagraphExists(pdf);
|
|
140
136
|
|
|
@@ -142,13 +138,12 @@ describe('Paragraph E2E Tests (v2 API)', () => {
|
|
|
142
138
|
expect(modifiedParas.length).toBeGreaterThan(0);
|
|
143
139
|
const modified = modifiedParas[0];
|
|
144
140
|
expect(modified.objectRef().status).toBeDefined();
|
|
145
|
-
expect(modified.objectRef().status?.isEncodable()).toBe(true);
|
|
146
141
|
expect(modified.objectRef().status?.getFontType()).toBe(FontType.EMBEDDED);
|
|
147
142
|
expect(modified.objectRef().status?.isModified()).toBe(true);
|
|
148
143
|
|
|
149
144
|
const assertions = await PDFAssertions.create(pdf);
|
|
150
|
-
await assertions.
|
|
151
|
-
await assertions.
|
|
145
|
+
await assertions.assertTextlineHasFontMatching('Awesomely', 'Poppins-Bold', 45, 0);
|
|
146
|
+
await assertions.assertTextlineHasFontMatching('Obvious!', 'Poppins-Bold', 45, 0);
|
|
152
147
|
await assertions.assertTextlineHasColor('Awesomely', new Color(255, 255, 255), 0);
|
|
153
148
|
await assertions.assertTextlineHasColor('Obvious!', new Color(255, 255, 255), 0);
|
|
154
149
|
});
|
|
@@ -543,8 +538,8 @@ describe('Paragraph E2E Tests (v2 API)', () => {
|
|
|
543
538
|
await para.edit().replace('Awesomely\nObvious!').apply();
|
|
544
539
|
|
|
545
540
|
const assertions = await PDFAssertions.create(pdf);
|
|
546
|
-
await assertions.
|
|
547
|
-
await assertions.
|
|
541
|
+
await assertions.assertTextlineHasFontMatching('Awesomely', 'Poppins-Bold', 45, 0);
|
|
542
|
+
await assertions.assertTextlineHasFontMatching('Obvious!', 'Poppins-Bold', 45, 0);
|
|
548
543
|
await assertions.assertTextlineHasColor('Awesomely', new Color(255, 255, 255), 0);
|
|
549
544
|
await assertions.assertTextlineHasColor('Obvious!', new Color(255, 255, 255), 0);
|
|
550
545
|
});
|
|
@@ -624,4 +619,63 @@ describe('Paragraph E2E Tests (v2 API)', () => {
|
|
|
624
619
|
expect(StandardFonts.ZAPF_DINGBATS).toBe('ZapfDingbats');
|
|
625
620
|
});
|
|
626
621
|
|
|
622
|
+
// Tests for singular select methods
|
|
623
|
+
test('selectParagraph returns first paragraph or null', async () => {
|
|
624
|
+
const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
|
|
625
|
+
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
626
|
+
|
|
627
|
+
// Test with results
|
|
628
|
+
const para = await pdf.page(0).selectParagraph();
|
|
629
|
+
expect(para).not.toBeNull();
|
|
630
|
+
expect(para!.internalId).toBe('PARAGRAPH_000003');
|
|
631
|
+
|
|
632
|
+
// Test with PDFDancer class
|
|
633
|
+
const paraFromPdf = await pdf.selectParagraph();
|
|
634
|
+
expect(paraFromPdf).not.toBeNull();
|
|
635
|
+
expect(paraFromPdf!.internalId).toBe('PARAGRAPH_000003');
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
test('selectParagraphStartingWith returns first match or null', async () => {
|
|
639
|
+
const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
|
|
640
|
+
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
641
|
+
|
|
642
|
+
const para = await pdf.page(0).selectParagraphStartingWith('The Complete');
|
|
643
|
+
expect(para).not.toBeNull();
|
|
644
|
+
expect(para!.internalId).toBe('PARAGRAPH_000004');
|
|
645
|
+
|
|
646
|
+
// Test with no match
|
|
647
|
+
const noMatch = await pdf.page(0).selectParagraphStartingWith('NoMatch');
|
|
648
|
+
expect(noMatch).toBeNull();
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
test('selectParagraphMatching returns first match or null', async () => {
|
|
652
|
+
const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
|
|
653
|
+
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
654
|
+
|
|
655
|
+
const para = await pdf.page(0).selectParagraphMatching('.*Complete.*');
|
|
656
|
+
expect(para).not.toBeNull();
|
|
657
|
+
expect(para!.internalId).toBe('PARAGRAPH_000004');
|
|
658
|
+
|
|
659
|
+
// Test with PDFDancer class
|
|
660
|
+
const paraFromPdf = await pdf.selectParagraphMatching('.*Complete.*');
|
|
661
|
+
expect(paraFromPdf).not.toBeNull();
|
|
662
|
+
|
|
663
|
+
// Test with no match
|
|
664
|
+
const noMatch = await pdf.page(0).selectParagraphMatching('.*NOT FOUND.*');
|
|
665
|
+
expect(noMatch).toBeNull();
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
test('selectParagraphAt returns first paragraph at position or null', async () => {
|
|
669
|
+
const [baseUrl, token, pdfData] = await requireEnvAndFixture('ObviouslyAwesome.pdf');
|
|
670
|
+
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
671
|
+
|
|
672
|
+
const para = await pdf.page(0).selectParagraphAt(54, 496, 10);
|
|
673
|
+
expect(para).not.toBeNull();
|
|
674
|
+
expect(para!.internalId).toBe('PARAGRAPH_000004');
|
|
675
|
+
|
|
676
|
+
// Test with no match
|
|
677
|
+
const noMatch = await pdf.page(0).selectParagraphAt(1000, 1000, 1);
|
|
678
|
+
expect(noMatch).toBeNull();
|
|
679
|
+
});
|
|
680
|
+
|
|
627
681
|
});
|
|
@@ -76,4 +76,33 @@ describe('Path E2E Tests (New API)', () => {
|
|
|
76
76
|
const assertions = await PDFAssertions.create(pdf);
|
|
77
77
|
await assertions.assertPathIsAt('PATH_000001', 50.1, 100);
|
|
78
78
|
});
|
|
79
|
+
|
|
80
|
+
// Tests for singular select methods
|
|
81
|
+
test('selectPath returns first path or null', async () => {
|
|
82
|
+
const [baseUrl, token, pdfData] = await requireEnvAndFixture('basic-paths.pdf');
|
|
83
|
+
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
84
|
+
|
|
85
|
+
// Test with PDFDancer class (document-level)
|
|
86
|
+
const pathFromPdf = await pdf.selectPath();
|
|
87
|
+
expect(pathFromPdf).not.toBeNull();
|
|
88
|
+
expect(pathFromPdf!.internalId).toBe('PATH_000001');
|
|
89
|
+
|
|
90
|
+
// Test with page-level using position since paths may require coordinates
|
|
91
|
+
const pathOnPage = await pdf.page(0).selectPathAt(80, 720);
|
|
92
|
+
expect(pathOnPage).not.toBeNull();
|
|
93
|
+
expect(pathOnPage!.internalId).toBe('PATH_000001');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('selectPathAt returns first path at position or null', async () => {
|
|
97
|
+
const [baseUrl, token, pdfData] = await requireEnvAndFixture('basic-paths.pdf');
|
|
98
|
+
const pdf = await PDFDancer.open(pdfData, token, baseUrl);
|
|
99
|
+
|
|
100
|
+
const path = await pdf.page(0).selectPathAt(80, 720);
|
|
101
|
+
expect(path).not.toBeNull();
|
|
102
|
+
expect(path!.internalId).toBe('PATH_000001');
|
|
103
|
+
|
|
104
|
+
// Test with no match
|
|
105
|
+
const noMatch = await pdf.page(0).selectPathAt(1000, 1000);
|
|
106
|
+
expect(noMatch).toBeNull();
|
|
107
|
+
});
|
|
79
108
|
});
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import * as fs from 'fs';
|
|
6
6
|
import * as path from 'path';
|
|
7
|
+
import os from "os";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Get the base URL from environment variable or default
|
|
10
11
|
*/
|
|
11
12
|
export function getBaseUrl(): string {
|
|
12
|
-
return process.env.PDFDANCER_BASE_URL || 'http://localhost:8080';
|
|
13
|
+
return (process.env.PDFDANCER_BASE_URL || 'http://localhost:8080').trim();
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -102,7 +103,12 @@ export async function requireEnvAndFixture(pdfFilename: string): Promise<[string
|
|
|
102
103
|
* Helper to open temporary file path (for Node.js environment)
|
|
103
104
|
*/
|
|
104
105
|
export function createTempPath(filename: string): string {
|
|
105
|
-
const tmpDir =
|
|
106
|
+
const tmpDir =
|
|
107
|
+
process.env.TMPDIR ||
|
|
108
|
+
process.env.TEMP ||
|
|
109
|
+
process.env.TMP ||
|
|
110
|
+
os.tmpdir(); // reliable built-in fallback
|
|
111
|
+
|
|
106
112
|
return path.join(tmpDir, filename);
|
|
107
113
|
}
|
|
108
114
|
|
|
@@ -3,7 +3,6 @@ import {PDFDancer} from "../../pdfdancer_v1";
|
|
|
3
3
|
import {HttpClientException, ValidationException} from "../../exceptions";
|
|
4
4
|
|
|
5
5
|
describe('Env Token E2E Tests', () => {
|
|
6
|
-
const MISSING_TOKEN_MESSAGE = "Missing PDFDancer API token. Pass a token via the `token` argument or set the PDFDANCER_TOKEN environment variable.";
|
|
7
6
|
let originalToken: string | undefined;
|
|
8
7
|
let originalBaseUrl: string | undefined;
|
|
9
8
|
let baseUrl: string;
|