pdfdancer-client-typescript 1.0.1
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 +19 -0
- package/README.md +267 -0
- package/dist/__tests__/e2e/test-helpers.d.ts +32 -0
- package/dist/__tests__/e2e/test-helpers.d.ts.map +1 -0
- package/dist/__tests__/e2e/test-helpers.js +157 -0
- package/dist/__tests__/e2e/test-helpers.js.map +1 -0
- package/dist/client-v1.d.ts +169 -0
- package/dist/client-v1.d.ts.map +1 -0
- package/dist/client-v1.js +558 -0
- package/dist/client-v1.js.map +1 -0
- package/dist/exceptions.d.ts +43 -0
- package/dist/exceptions.d.ts.map +1 -0
- package/dist/exceptions.js +66 -0
- package/dist/exceptions.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/models.d.ts +216 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +427 -0
- package/dist/models.js.map +1 -0
- package/dist/paragraph-builder.d.ts +67 -0
- package/dist/paragraph-builder.d.ts.map +1 -0
- package/dist/paragraph-builder.js +160 -0
- package/dist/paragraph-builder.js.map +1 -0
- package/example.ts +103 -0
- package/fixtures/DancingScript-Regular.ttf +0 -0
- package/fixtures/JetBrainsMono-Regular.ttf +0 -0
- package/fixtures/ObviouslyAwesome.pdf +0 -0
- package/fixtures/README.md +25 -0
- package/fixtures/basic-paths.pdf +0 -0
- package/fixtures/logo-80.png +0 -0
- package/fixtures/mixed-form-types.pdf +0 -0
- package/jest.config.js +26 -0
- package/package.json +38 -0
- package/scripts/release.js +91 -0
- package/scripts/test-release.js +59 -0
- package/src/__tests__/client-v1.test.ts +111 -0
- package/src/__tests__/e2e/form.test.ts +51 -0
- package/src/__tests__/e2e/image.test.ts +108 -0
- package/src/__tests__/e2e/line.test.ts +134 -0
- package/src/__tests__/e2e/page.test.ts +45 -0
- package/src/__tests__/e2e/paragraph.test.ts +210 -0
- package/src/__tests__/e2e/path.test.ts +72 -0
- package/src/__tests__/e2e/test-helpers.ts +132 -0
- package/src/client-v1.ts +673 -0
- package/src/exceptions.ts +67 -0
- package/src/index.ts +34 -0
- package/src/models.ts +476 -0
- package/src/paragraph-builder.ts +184 -0
- package/tsconfig.json +20 -0
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
parser: '@typescript-eslint/parser',
|
|
3
|
+
plugins: ['@typescript-eslint'],
|
|
4
|
+
extends: [
|
|
5
|
+
'eslint:recommended',
|
|
6
|
+
],
|
|
7
|
+
root: true,
|
|
8
|
+
env: {
|
|
9
|
+
node: true,
|
|
10
|
+
jest: true,
|
|
11
|
+
},
|
|
12
|
+
ignorePatterns: ['.eslintrc.js', 'dist/', 'node_modules/'],
|
|
13
|
+
rules: {
|
|
14
|
+
'@typescript-eslint/interface-name-prefix': 'off',
|
|
15
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
16
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
17
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
18
|
+
},
|
|
19
|
+
};
|
package/README.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# PDFDancer TypeScript Client
|
|
2
|
+
|
|
3
|
+
A TypeScript client library for the PDFDancer PDF manipulation API. This client provides a clean, TypeScript interface for PDF operations that closely mirrors the Python client structure and functionality.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Session-based PDF manipulation** - Upload PDF, perform operations, download modified PDF
|
|
8
|
+
- **Type-safe API** - Full TypeScript support with proper types and interfaces
|
|
9
|
+
- **Fluent Builder Pattern** - Easy paragraph construction with method chaining
|
|
10
|
+
- **Comprehensive Search** - Find PDF objects by type, position, and other criteria
|
|
11
|
+
- **Custom Font Support** - Register and use custom TTF fonts
|
|
12
|
+
- **Error Handling** - Detailed exceptions for different error scenarios
|
|
13
|
+
- **Browser Compatible** - Works in both Node.js and browser environments
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install pdfdancer-client-typescript
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Basic Usage
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { ClientV1, Position, Color, Font } from 'pdfdancer-client-typescript';
|
|
25
|
+
|
|
26
|
+
async function example() {
|
|
27
|
+
// Load PDF data (from file upload, fetch, etc.)
|
|
28
|
+
const pdfData = new Uint8Array(/* your PDF data */);
|
|
29
|
+
|
|
30
|
+
// Create client with authentication token
|
|
31
|
+
const client = new ClientV1('your-auth-token', pdfData);
|
|
32
|
+
|
|
33
|
+
// Initialize session (required before using the client)
|
|
34
|
+
await client.init();
|
|
35
|
+
|
|
36
|
+
// Find all paragraphs on page 1
|
|
37
|
+
const paragraphs = await client.findParagraphs(Position.fromPageIndex(1));
|
|
38
|
+
|
|
39
|
+
// Add a new paragraph
|
|
40
|
+
const newParagraph = client.paragraphBuilder()
|
|
41
|
+
.fromString('Hello, PDFDancer!', new Color(255, 0, 0))
|
|
42
|
+
.withFont(new Font('Arial', 12))
|
|
43
|
+
.withPosition(Position.onPageCoordinates(1, 100, 200))
|
|
44
|
+
.build();
|
|
45
|
+
|
|
46
|
+
await client.addParagraph(newParagraph);
|
|
47
|
+
|
|
48
|
+
// Get the modified PDF
|
|
49
|
+
const modifiedPdf = await client.getPdfFile();
|
|
50
|
+
|
|
51
|
+
// Save PDF (browser environment)
|
|
52
|
+
await client.savePdf('modified-document.pdf');
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## API Overview
|
|
57
|
+
|
|
58
|
+
### Client Initialization
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const client = new ClientV1(
|
|
62
|
+
token, // Authentication token
|
|
63
|
+
pdfData, // PDF data as Uint8Array, File, or ArrayBuffer
|
|
64
|
+
baseUrl, // Optional: API server URL (default: http://localhost:8080)
|
|
65
|
+
readTimeout // Optional: Request timeout in ms (default: 30000)
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
await client.init(); // Required before using the client
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Search Operations
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// Find objects by type and position
|
|
75
|
+
const objects = await client.find(ObjectType.PARAGRAPH, position);
|
|
76
|
+
|
|
77
|
+
// Convenience methods for specific object types
|
|
78
|
+
const paragraphs = await client.findParagraphs(position);
|
|
79
|
+
const images = await client.findImages(position);
|
|
80
|
+
const forms = await client.findForms(position);
|
|
81
|
+
const paths = await client.findPaths(position);
|
|
82
|
+
const textLines = await client.findTextLines(position);
|
|
83
|
+
|
|
84
|
+
// Page operations
|
|
85
|
+
const pages = await client.getPages();
|
|
86
|
+
const page = await client.getPage(1); // 1-based index
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Position Specification
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// Page-based position
|
|
93
|
+
const pagePosition = Position.fromPageIndex(1);
|
|
94
|
+
|
|
95
|
+
// Coordinate-based position
|
|
96
|
+
const coordPosition = Position.onPageCoordinates(1, 100, 200);
|
|
97
|
+
|
|
98
|
+
// Position with movement
|
|
99
|
+
const movedPosition = coordPosition.copy().moveX(50).moveY(30);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Adding Content
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// Add paragraph using builder pattern
|
|
106
|
+
const paragraph = client.paragraphBuilder()
|
|
107
|
+
.fromString('Your text here')
|
|
108
|
+
.withFont(new Font('Arial', 12))
|
|
109
|
+
.withColor(new Color(0, 0, 0))
|
|
110
|
+
.withPosition(Position.onPageCoordinates(1, 100, 200))
|
|
111
|
+
.withLineSpacing(1.2)
|
|
112
|
+
.build();
|
|
113
|
+
|
|
114
|
+
await client.addParagraph(paragraph);
|
|
115
|
+
|
|
116
|
+
// Add image
|
|
117
|
+
const image = new Image(position, 'PNG', 100, 50, imageData);
|
|
118
|
+
await client.addImage(image);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Modifying Content
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// Modify paragraph text
|
|
125
|
+
await client.modifyParagraph(paragraphRef, 'New text content');
|
|
126
|
+
|
|
127
|
+
// Modify text line
|
|
128
|
+
await client.modifyTextLine(textLineRef, 'New line content');
|
|
129
|
+
|
|
130
|
+
// Move object to new position
|
|
131
|
+
await client.move(objectRef, newPosition);
|
|
132
|
+
|
|
133
|
+
// Delete object
|
|
134
|
+
await client.delete(objectRef);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Font Management
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
// Find available fonts
|
|
141
|
+
const fonts = await client.findFonts('Arial', 12);
|
|
142
|
+
|
|
143
|
+
// Register custom font
|
|
144
|
+
const ttfData = new Uint8Array(/* TTF font data */);
|
|
145
|
+
const fontName = await client.registerFont(ttfData);
|
|
146
|
+
|
|
147
|
+
// Use custom font
|
|
148
|
+
const customFont = new Font(fontName, 14);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Document Operations
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
// Get modified PDF data
|
|
155
|
+
const pdfBytes = await client.getPdfFile();
|
|
156
|
+
|
|
157
|
+
// Save PDF file (browser)
|
|
158
|
+
await client.savePdf('output.pdf');
|
|
159
|
+
|
|
160
|
+
// Delete page
|
|
161
|
+
await client.deletePage(pageRef);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Error Handling
|
|
165
|
+
|
|
166
|
+
The client provides specific exception types for different error scenarios:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import {
|
|
170
|
+
ValidationException,
|
|
171
|
+
HttpClientException,
|
|
172
|
+
SessionException,
|
|
173
|
+
FontNotFoundException,
|
|
174
|
+
PdfDancerException
|
|
175
|
+
} from 'pdfdancer-client-typescript';
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
await client.addParagraph(paragraph);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
if (error instanceof ValidationException) {
|
|
181
|
+
console.error('Invalid input:', error.message);
|
|
182
|
+
} else if (error instanceof HttpClientException) {
|
|
183
|
+
console.error('API error:', error.message, 'Status:', error.statusCode);
|
|
184
|
+
} else if (error instanceof FontNotFoundException) {
|
|
185
|
+
console.error('Font not found:', error.message);
|
|
186
|
+
} else if (error instanceof SessionException) {
|
|
187
|
+
console.error('Session error:', error.message);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Types and Enums
|
|
193
|
+
|
|
194
|
+
### ObjectType
|
|
195
|
+
- `IMAGE` - Image objects
|
|
196
|
+
- `FORM` - Form field objects
|
|
197
|
+
- `PATH` - Vector path objects
|
|
198
|
+
- `PARAGRAPH` - Paragraph objects
|
|
199
|
+
- `TEXT_LINE` - Text line objects
|
|
200
|
+
- `PAGE` - Page objects
|
|
201
|
+
|
|
202
|
+
### PositionMode
|
|
203
|
+
- `INTERSECT` - Objects that intersect with the specified area
|
|
204
|
+
- `CONTAINS` - Objects completely contained within the specified area
|
|
205
|
+
|
|
206
|
+
### ShapeType
|
|
207
|
+
- `POINT` - Single point coordinate
|
|
208
|
+
- `LINE` - Linear shape between two points
|
|
209
|
+
- `CIRCLE` - Circular area with radius
|
|
210
|
+
- `RECT` - Rectangular area with width and height
|
|
211
|
+
|
|
212
|
+
## Development
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# Install dependencies
|
|
216
|
+
npm install
|
|
217
|
+
|
|
218
|
+
# Build the project
|
|
219
|
+
npm run build
|
|
220
|
+
|
|
221
|
+
# Run all tests
|
|
222
|
+
npm test
|
|
223
|
+
|
|
224
|
+
# Run only unit tests
|
|
225
|
+
npm run test:unit
|
|
226
|
+
|
|
227
|
+
# Run only e2e tests (requires fixtures and server)
|
|
228
|
+
npm run test:e2e
|
|
229
|
+
|
|
230
|
+
# Run linter
|
|
231
|
+
npm run lint
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### E2E Tests
|
|
235
|
+
|
|
236
|
+
The project includes comprehensive end-to-end tests that mirror the Python client test suite. To run e2e tests:
|
|
237
|
+
|
|
238
|
+
1. **Start PDFDancer server** at `http://localhost:8080` (or set `PDFDANCER_BASE_URL`)
|
|
239
|
+
|
|
240
|
+
2. **Set authentication token**:
|
|
241
|
+
- Environment variable: `export PDFDANCER_TOKEN=your-token`
|
|
242
|
+
- Or place a `jwt-token-*.txt` file in the project root
|
|
243
|
+
|
|
244
|
+
3. **Add test fixtures** in the `fixtures/` directory:
|
|
245
|
+
- `ObviouslyAwesome.pdf` - Main test document
|
|
246
|
+
- `mixed-form-types.pdf` - Document with form fields
|
|
247
|
+
- `basic-paths.pdf` - Document with vector paths
|
|
248
|
+
- `logo-80.png` - Test image file
|
|
249
|
+
- `DancingScript-Regular.ttf` - Test font file
|
|
250
|
+
|
|
251
|
+
4. **Run e2e tests**: `npm run test:e2e`
|
|
252
|
+
|
|
253
|
+
The e2e tests cover:
|
|
254
|
+
- **Paragraph operations**: Find, add, modify, delete paragraphs with custom fonts
|
|
255
|
+
- **Page operations**: Get pages, delete pages
|
|
256
|
+
- **Text line operations**: Find, modify, move, delete text lines
|
|
257
|
+
- **Image operations**: Find, add, move, delete images
|
|
258
|
+
- **Form operations**: Find and delete form fields
|
|
259
|
+
- **Path operations**: Find, move, delete vector paths
|
|
260
|
+
|
|
261
|
+
## Compatibility
|
|
262
|
+
|
|
263
|
+
This TypeScript client is designed to be functionally equivalent to the PDFDancer Python client, providing the same API patterns and capabilities with TypeScript type safety and modern JavaScript features.
|
|
264
|
+
|
|
265
|
+
## License
|
|
266
|
+
|
|
267
|
+
MIT
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper functions for e2e tests
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get the base URL from environment variable or default
|
|
6
|
+
*/
|
|
7
|
+
export declare function getBaseUrl(): string;
|
|
8
|
+
/**
|
|
9
|
+
* Read authentication token from environment or token files
|
|
10
|
+
*/
|
|
11
|
+
export declare function readToken(): string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Check if server is up and running
|
|
14
|
+
*/
|
|
15
|
+
export declare function serverUp(baseUrl: string): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Require environment variables and PDF fixture for testing
|
|
18
|
+
*/
|
|
19
|
+
export declare function requireEnvAndFixture(pdfFilename: string): Promise<[string, string, Uint8Array]>;
|
|
20
|
+
/**
|
|
21
|
+
* Helper to create temporary file path (for Node.js environment)
|
|
22
|
+
*/
|
|
23
|
+
export declare function createTempPath(filename: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Helper to read image file for tests
|
|
26
|
+
*/
|
|
27
|
+
export declare function readImageFixture(filename: string): Uint8Array;
|
|
28
|
+
/**
|
|
29
|
+
* Helper to read font file for tests
|
|
30
|
+
*/
|
|
31
|
+
export declare function readFontFixture(filename: string): Uint8Array;
|
|
32
|
+
//# sourceMappingURL=test-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-helpers.d.ts","sourceRoot":"","sources":["../../../src/__tests__/e2e/test-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAmBzC;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUhE;AAiBD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAsBrG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAU7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAU5D"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Helper functions for e2e tests
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.getBaseUrl = getBaseUrl;
|
|
40
|
+
exports.readToken = readToken;
|
|
41
|
+
exports.serverUp = serverUp;
|
|
42
|
+
exports.requireEnvAndFixture = requireEnvAndFixture;
|
|
43
|
+
exports.createTempPath = createTempPath;
|
|
44
|
+
exports.readImageFixture = readImageFixture;
|
|
45
|
+
exports.readFontFixture = readFontFixture;
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
/**
|
|
49
|
+
* Get the base URL from environment variable or default
|
|
50
|
+
*/
|
|
51
|
+
function getBaseUrl() {
|
|
52
|
+
return process.env.PDFDANCER_BASE_URL || 'http://localhost:8080';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Read authentication token from environment or token files
|
|
56
|
+
*/
|
|
57
|
+
function readToken() {
|
|
58
|
+
const token = process.env.PDFDANCER_TOKEN;
|
|
59
|
+
if (token) {
|
|
60
|
+
return token.trim();
|
|
61
|
+
}
|
|
62
|
+
// Try common token files in project root
|
|
63
|
+
const projectRoot = path.resolve(__dirname, '../../..');
|
|
64
|
+
const candidates = findFiles(projectRoot, 'jwt-token-*.txt');
|
|
65
|
+
for (const file of candidates) {
|
|
66
|
+
try {
|
|
67
|
+
return fs.readFileSync(file, 'utf-8').trim();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Check if server is up and running
|
|
77
|
+
*/
|
|
78
|
+
async function serverUp(baseUrl) {
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch(`${baseUrl}/ping`, {
|
|
81
|
+
signal: AbortSignal.timeout(3000)
|
|
82
|
+
});
|
|
83
|
+
const text = await response.text();
|
|
84
|
+
return response.status === 200 && text.includes('Pong');
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Helper to find files matching a pattern
|
|
92
|
+
*/
|
|
93
|
+
function findFiles(dir, pattern) {
|
|
94
|
+
try {
|
|
95
|
+
const files = fs.readdirSync(dir);
|
|
96
|
+
const regex = new RegExp(pattern.replace('*', '.*'));
|
|
97
|
+
return files
|
|
98
|
+
.filter(file => regex.test(file))
|
|
99
|
+
.map(file => path.join(dir, file));
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Require environment variables and PDF fixture for testing
|
|
107
|
+
*/
|
|
108
|
+
async function requireEnvAndFixture(pdfFilename) {
|
|
109
|
+
const baseUrl = getBaseUrl();
|
|
110
|
+
const token = readToken();
|
|
111
|
+
if (!await serverUp(baseUrl)) {
|
|
112
|
+
throw new Error(`PDFDancer server not reachable at ${baseUrl}; set PDFDANCER_BASE_URL or start server`);
|
|
113
|
+
}
|
|
114
|
+
if (!token) {
|
|
115
|
+
throw new Error('PDFDANCER_TOKEN not set and no token file found; set env or place jwt-token-*.txt in repo');
|
|
116
|
+
}
|
|
117
|
+
// Look for PDF fixture file
|
|
118
|
+
const fixturesDir = path.resolve(__dirname, '../../../fixtures');
|
|
119
|
+
const pdfPath = path.join(fixturesDir, pdfFilename);
|
|
120
|
+
if (!fs.existsSync(pdfPath)) {
|
|
121
|
+
throw new Error(`${pdfFilename} fixture not found at ${pdfPath}`);
|
|
122
|
+
}
|
|
123
|
+
const pdfData = fs.readFileSync(pdfPath);
|
|
124
|
+
return [baseUrl, token, new Uint8Array(pdfData)];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Helper to create temporary file path (for Node.js environment)
|
|
128
|
+
*/
|
|
129
|
+
function createTempPath(filename) {
|
|
130
|
+
const tmpDir = process.env.TMPDIR || '/tmp';
|
|
131
|
+
return path.join(tmpDir, filename);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Helper to read image file for tests
|
|
135
|
+
*/
|
|
136
|
+
function readImageFixture(filename) {
|
|
137
|
+
const fixturesDir = path.resolve(__dirname, '../../../fixtures');
|
|
138
|
+
const imagePath = path.join(fixturesDir, filename);
|
|
139
|
+
if (!fs.existsSync(imagePath)) {
|
|
140
|
+
throw new Error(`Image fixture not found: ${filename}`);
|
|
141
|
+
}
|
|
142
|
+
const imageData = fs.readFileSync(imagePath);
|
|
143
|
+
return new Uint8Array(imageData);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Helper to read font file for tests
|
|
147
|
+
*/
|
|
148
|
+
function readFontFixture(filename) {
|
|
149
|
+
const fixturesDir = path.resolve(__dirname, '../../../fixtures');
|
|
150
|
+
const fontPath = path.join(fixturesDir, filename);
|
|
151
|
+
if (!fs.existsSync(fontPath)) {
|
|
152
|
+
throw new Error(`Font fixture not found: ${filename}`);
|
|
153
|
+
}
|
|
154
|
+
const fontData = fs.readFileSync(fontPath);
|
|
155
|
+
return new Uint8Array(fontData);
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=test-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/test-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDFDancer TypeScript Client V1
|
|
3
|
+
*
|
|
4
|
+
* A TypeScript client that closely mirrors the Python Client class structure and functionality.
|
|
5
|
+
* Provides session-based PDF manipulation operations with strict validation.
|
|
6
|
+
*/
|
|
7
|
+
import { ObjectRef, Position, ObjectType, Font, Image, Paragraph } from './models';
|
|
8
|
+
import { ParagraphBuilder } from './paragraph-builder';
|
|
9
|
+
/**
|
|
10
|
+
* REST API client for interacting with the PDFDancer PDF manipulation service.
|
|
11
|
+
* This client provides a convenient TypeScript interface for performing PDF operations
|
|
12
|
+
* including session management, object searching, manipulation, and retrieval.
|
|
13
|
+
* Handles authentication, session lifecycle, and HTTP communication transparently.
|
|
14
|
+
*
|
|
15
|
+
* Mirrors the Python Client class functionality exactly.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ClientV1 {
|
|
18
|
+
private _token;
|
|
19
|
+
private _baseUrl;
|
|
20
|
+
private _readTimeout;
|
|
21
|
+
private _pdfBytes;
|
|
22
|
+
private _sessionId;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new client with PDF data.
|
|
25
|
+
* This constructor initializes the client, uploads the PDF data to create
|
|
26
|
+
* a new session, and prepares the client for PDF manipulation operations.
|
|
27
|
+
*/
|
|
28
|
+
constructor(token: string, pdfData: Uint8Array | File | ArrayBuffer, baseUrl?: string, readTimeout?: number);
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the client by creating a session.
|
|
31
|
+
* Must be called after constructor before using the client.
|
|
32
|
+
*/
|
|
33
|
+
init(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Process PDF data from various input types with strict validation.
|
|
36
|
+
* Equivalent to readFile() method in Python client.
|
|
37
|
+
*/
|
|
38
|
+
private _processPdfData;
|
|
39
|
+
/**
|
|
40
|
+
* Extract meaningful error messages from API response.
|
|
41
|
+
* Parses JSON error responses with _embedded.errors structure.
|
|
42
|
+
*/
|
|
43
|
+
private _extractErrorMessage;
|
|
44
|
+
/**
|
|
45
|
+
* Creates a new PDF processing session by uploading the PDF data.
|
|
46
|
+
* Equivalent to createSession() method in Python client.
|
|
47
|
+
*/
|
|
48
|
+
private _createSession;
|
|
49
|
+
/**
|
|
50
|
+
* Make HTTP request with session headers and error handling.
|
|
51
|
+
* Equivalent to retrieve() method pattern in Python client.
|
|
52
|
+
*/
|
|
53
|
+
private _makeRequest;
|
|
54
|
+
/**
|
|
55
|
+
* Searches for PDF objects matching the specified criteria.
|
|
56
|
+
* This method provides flexible search capabilities across all PDF content,
|
|
57
|
+
* allowing filtering by object type and position constraints.
|
|
58
|
+
*/
|
|
59
|
+
find(objectType?: ObjectType, position?: Position): Promise<ObjectRef[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Searches for paragraph objects at the specified position.
|
|
62
|
+
* Equivalent to findParagraphs() in Python client.
|
|
63
|
+
*/
|
|
64
|
+
findParagraphs(position?: Position): Promise<ObjectRef[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Searches for image objects at the specified position.
|
|
67
|
+
* Equivalent to findImages() in Python client.
|
|
68
|
+
*/
|
|
69
|
+
findImages(position?: Position): Promise<ObjectRef[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Searches for form field objects at the specified position.
|
|
72
|
+
* Equivalent to findForms() in Python client.
|
|
73
|
+
*/
|
|
74
|
+
findForms(position?: Position): Promise<ObjectRef[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Searches for vector path objects at the specified position.
|
|
77
|
+
* Equivalent to findPaths() in Python client.
|
|
78
|
+
*/
|
|
79
|
+
findPaths(position?: Position): Promise<ObjectRef[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Searches for text line objects at the specified position.
|
|
82
|
+
* Equivalent to findTextLines() in Python client.
|
|
83
|
+
*/
|
|
84
|
+
findTextLines(position?: Position): Promise<ObjectRef[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Retrieves references to all pages in the PDF document.
|
|
87
|
+
* Equivalent to getPages() in Python client.
|
|
88
|
+
*/
|
|
89
|
+
getPages(): Promise<ObjectRef[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Retrieves a reference to a specific page by its page index.
|
|
92
|
+
* Equivalent to getPage() in Python client.
|
|
93
|
+
*/
|
|
94
|
+
getPage(pageIndex: number): Promise<ObjectRef | null>;
|
|
95
|
+
/**
|
|
96
|
+
* Deletes a page from the PDF document.
|
|
97
|
+
* Equivalent to deletePage() in Python client.
|
|
98
|
+
*/
|
|
99
|
+
deletePage(pageRef: ObjectRef): Promise<boolean>;
|
|
100
|
+
/**
|
|
101
|
+
* Deletes the specified PDF object from the document.
|
|
102
|
+
* Equivalent to delete() in Python client.
|
|
103
|
+
*/
|
|
104
|
+
delete(objectRef: ObjectRef): Promise<boolean>;
|
|
105
|
+
/**
|
|
106
|
+
* Moves a PDF object to a new position within the document.
|
|
107
|
+
* Equivalent to move() in Python client.
|
|
108
|
+
*/
|
|
109
|
+
move(objectRef: ObjectRef, position: Position): Promise<boolean>;
|
|
110
|
+
/**
|
|
111
|
+
* Adds an image to the PDF document.
|
|
112
|
+
* Equivalent to addImage() methods in Python client.
|
|
113
|
+
*/
|
|
114
|
+
addImage(image: Image, position?: Position): Promise<boolean>;
|
|
115
|
+
/**
|
|
116
|
+
* Adds a paragraph to the PDF document.
|
|
117
|
+
* Equivalent to addParagraph() in Python client with validation.
|
|
118
|
+
*/
|
|
119
|
+
addParagraph(paragraph: Paragraph): Promise<boolean>;
|
|
120
|
+
/**
|
|
121
|
+
* Internal method to add any PDF object.
|
|
122
|
+
* Equivalent to addObject() in Python client.
|
|
123
|
+
*/
|
|
124
|
+
private _addObject;
|
|
125
|
+
/**
|
|
126
|
+
* Modifies a paragraph object or its text content.
|
|
127
|
+
* Equivalent to modifyParagraph() methods in Python client.
|
|
128
|
+
*/
|
|
129
|
+
modifyParagraph(objectRef: ObjectRef, newParagraph: Paragraph | string): Promise<boolean>;
|
|
130
|
+
/**
|
|
131
|
+
* Modifies a text line object.
|
|
132
|
+
* Equivalent to modifyTextLine() in Python client.
|
|
133
|
+
*/
|
|
134
|
+
modifyTextLine(objectRef: ObjectRef, newText: string): Promise<boolean>;
|
|
135
|
+
/**
|
|
136
|
+
* Finds available fonts matching the specified name and size.
|
|
137
|
+
* Equivalent to findFonts() in Python client.
|
|
138
|
+
*/
|
|
139
|
+
findFonts(fontName: string, fontSize: number): Promise<Font[]>;
|
|
140
|
+
/**
|
|
141
|
+
* Registers a custom font for use in PDF operations.
|
|
142
|
+
* Equivalent to registerFont() in Python client.
|
|
143
|
+
*/
|
|
144
|
+
registerFont(ttfFile: Uint8Array | File): Promise<string>;
|
|
145
|
+
/**
|
|
146
|
+
* Downloads the current state of the PDF document with all modifications applied.
|
|
147
|
+
* Equivalent to getPDFFile() in Python client.
|
|
148
|
+
*/
|
|
149
|
+
getPdfFile(): Promise<Uint8Array>;
|
|
150
|
+
/**
|
|
151
|
+
* Saves the current PDF to a file (browser environment).
|
|
152
|
+
* Downloads the PDF in the browser.
|
|
153
|
+
*/
|
|
154
|
+
savePdf(filename?: string): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* Parse JSON object data into ObjectRef instance.
|
|
157
|
+
*/
|
|
158
|
+
private _parseObjectRef;
|
|
159
|
+
/**
|
|
160
|
+
* Parse JSON position data into Position instance.
|
|
161
|
+
*/
|
|
162
|
+
private _parsePosition;
|
|
163
|
+
/**
|
|
164
|
+
* Creates a new ParagraphBuilder for fluent paragraph construction.
|
|
165
|
+
* Equivalent to paragraphBuilder() in Python client.
|
|
166
|
+
*/
|
|
167
|
+
paragraphBuilder(): ParagraphBuilder;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=client-v1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-v1.d.ts","sourceRoot":"","sources":["../src/client-v1.ts"],"names":[],"mappings":"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"}
|