pdfdancer-client-typescript 2.0.5 → 2.0.7

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 (48) hide show
  1. package/README.md +10 -4
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +3 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/models.d.ts +9 -2
  7. package/dist/models.d.ts.map +1 -1
  8. package/dist/models.js +23 -1
  9. package/dist/models.js.map +1 -1
  10. package/dist/pdfdancer_v1.d.ts +14 -0
  11. package/dist/pdfdancer_v1.d.ts.map +1 -1
  12. package/dist/pdfdancer_v1.js +65 -1
  13. package/dist/pdfdancer_v1.js.map +1 -1
  14. package/dist/replacement-builder.d.ts +78 -0
  15. package/dist/replacement-builder.d.ts.map +1 -0
  16. package/dist/replacement-builder.js +117 -0
  17. package/dist/replacement-builder.js.map +1 -0
  18. package/dist/types.d.ts +38 -3
  19. package/dist/types.d.ts.map +1 -1
  20. package/dist/types.js +158 -2
  21. package/dist/types.js.map +1 -1
  22. package/dist/version.d.ts +1 -1
  23. package/dist/version.js +1 -1
  24. package/package.json +1 -1
  25. package/dist/__tests__/assertions.d.ts +0 -2
  26. package/dist/__tests__/assertions.d.ts.map +0 -1
  27. package/dist/__tests__/assertions.js +0 -11
  28. package/dist/__tests__/assertions.js.map +0 -1
  29. package/dist/__tests__/e2e/pdf-assertions.d.ts +0 -36
  30. package/dist/__tests__/e2e/pdf-assertions.d.ts.map +0 -1
  31. package/dist/__tests__/e2e/pdf-assertions.js +0 -218
  32. package/dist/__tests__/e2e/pdf-assertions.js.map +0 -1
  33. package/dist/__tests__/e2e/test-drawing-helpers.d.ts +0 -148
  34. package/dist/__tests__/e2e/test-drawing-helpers.d.ts.map +0 -1
  35. package/dist/__tests__/e2e/test-drawing-helpers.js +0 -343
  36. package/dist/__tests__/e2e/test-drawing-helpers.js.map +0 -1
  37. package/dist/__tests__/e2e/test-helpers.d.ts +0 -44
  38. package/dist/__tests__/e2e/test-helpers.d.ts.map +0 -1
  39. package/dist/__tests__/e2e/test-helpers.js +0 -233
  40. package/dist/__tests__/e2e/test-helpers.js.map +0 -1
  41. package/dist/client-v1.d.ts +0 -157
  42. package/dist/client-v1.d.ts.map +0 -1
  43. package/dist/client-v1.js +0 -576
  44. package/dist/client-v1.js.map +0 -1
  45. package/dist/client-v2.d.ts +0 -129
  46. package/dist/client-v2.d.ts.map +0 -1
  47. package/dist/client-v2.js +0 -696
  48. package/dist/client-v2.js.map +0 -1
package/dist/client-v2.js DELETED
@@ -1,696 +0,0 @@
1
- "use strict";
2
- /**
3
- * PDFDancer TypeScript Client V2
4
- *
5
- * New typed API with the pattern: open → select{Type}(criteria) → edit(properties) → save
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.PDFDancer = exports.ParagraphBuilderV2 = exports.PDFDocument = exports.PDFPage = exports.PathObject = exports.ImageObject = exports.TextObject = void 0;
9
- const exceptions_1 = require("./exceptions");
10
- const models_1 = require("./models");
11
- // ============================================================================
12
- // Internal HTTP Client
13
- // ============================================================================
14
- class HttpClient {
15
- constructor(token, sessionId, baseUrl, timeout) {
16
- this.token = token;
17
- this.sessionId = sessionId;
18
- this.baseUrl = baseUrl;
19
- this.timeout = timeout;
20
- }
21
- async request(method, path, data, params) {
22
- const url = new URL(`${this.baseUrl}${path}`);
23
- if (params) {
24
- Object.entries(params).forEach(([key, value]) => {
25
- url.searchParams.append(key, value);
26
- });
27
- }
28
- const headers = {
29
- 'Authorization': `Bearer ${this.token}`,
30
- 'X-Session-Id': this.sessionId,
31
- 'Content-Type': 'application/json'
32
- };
33
- try {
34
- const response = await fetch(url.toString(), {
35
- method,
36
- headers,
37
- body: data ? JSON.stringify(data) : undefined,
38
- signal: this.timeout > 0 ? AbortSignal.timeout(this.timeout) : undefined
39
- });
40
- if (response.status === 404) {
41
- try {
42
- const errorData = await response.json();
43
- if (errorData.error === 'FontNotFoundException') {
44
- throw new exceptions_1.FontNotFoundException(errorData.message || 'Font not found');
45
- }
46
- }
47
- catch (e) {
48
- if (e instanceof exceptions_1.FontNotFoundException)
49
- throw e;
50
- }
51
- }
52
- if (!response.ok) {
53
- const errorMessage = await this.extractErrorMessage(response);
54
- throw new exceptions_1.HttpClientException(`API request failed: ${errorMessage}`, response);
55
- }
56
- return response;
57
- }
58
- catch (error) {
59
- if (error instanceof exceptions_1.FontNotFoundException || error instanceof exceptions_1.HttpClientException) {
60
- throw error;
61
- }
62
- const errorMessage = error instanceof Error ? error.message : String(error);
63
- throw new exceptions_1.HttpClientException(`API request failed: ${errorMessage}`, undefined, error);
64
- }
65
- }
66
- async extractErrorMessage(response) {
67
- if (!response)
68
- return "Unknown error";
69
- try {
70
- const errorData = await response.json();
71
- if (errorData._embedded?.errors) {
72
- const errors = errorData._embedded.errors;
73
- if (Array.isArray(errors)) {
74
- const messages = errors
75
- .filter(error => error.message)
76
- .map(error => error.message);
77
- if (messages.length > 0)
78
- return messages.join("; ");
79
- }
80
- }
81
- if (errorData.message)
82
- return errorData.message;
83
- return await response.text() || `HTTP ${response.status}`;
84
- }
85
- catch {
86
- try {
87
- return await response.text() || `HTTP ${response.status}`;
88
- }
89
- catch {
90
- return `HTTP ${response.status}`;
91
- }
92
- }
93
- }
94
- }
95
- // ============================================================================
96
- // TextObject
97
- // ============================================================================
98
- class TextObject {
99
- constructor(objectRef, client, objectType) {
100
- this.objectRef = objectRef;
101
- this.client = client;
102
- this.objectType = objectType;
103
- }
104
- async edit(options) {
105
- if (options.replace !== undefined) {
106
- // Text replacement using ModifyTextRequest
107
- const requestData = new models_1.ModifyTextRequest(this.objectRef, options.replace).toDict();
108
- const endpoint = this.objectType === models_1.ObjectType.TEXT_LINE
109
- ? '/pdf/text/line'
110
- : '/pdf/text/paragraph';
111
- await this.client.request('PUT', endpoint, requestData);
112
- }
113
- // Handle formatting changes (font, size, lineSpacing, color)
114
- if (options.font || options.size !== undefined || options.lineSpacing !== undefined || options.color) {
115
- const paragraph = new models_1.Paragraph();
116
- // Set textLines to empty array - required by API
117
- paragraph.textLines = [];
118
- if (options.font) {
119
- paragraph.font = new models_1.Font(options.font, options.size || 12);
120
- }
121
- if (options.lineSpacing !== undefined) {
122
- paragraph.lineSpacing = options.lineSpacing;
123
- }
124
- if (options.color) {
125
- // Parse hex color string to RGB
126
- const hex = options.color.replace('#', '');
127
- const r = parseInt(hex.substring(0, 2), 16);
128
- const g = parseInt(hex.substring(2, 4), 16);
129
- const b = parseInt(hex.substring(4, 6), 16);
130
- paragraph.color = new models_1.Color(r, g, b);
131
- }
132
- // Use ModifyRequest for object modifications
133
- const requestData = new models_1.ModifyRequest(this.objectRef, paragraph).toDict();
134
- await this.client.request('PUT', '/pdf/modify', requestData);
135
- }
136
- }
137
- }
138
- exports.TextObject = TextObject;
139
- // ============================================================================
140
- // ImageObject
141
- // ============================================================================
142
- class ImageObject {
143
- constructor(objectRef, client) {
144
- this.objectRef = objectRef;
145
- this.client = client;
146
- }
147
- async edit(options) {
148
- // For now, we'll need to map this to the existing modify API
149
- // The current API doesn't have direct image transform support,
150
- // so we'll use the move operation for translate
151
- if (options.translate) {
152
- const currentPos = this.objectRef.getPosition();
153
- const newPos = new models_1.Position();
154
- newPos.pageIndex = currentPos.pageIndex;
155
- if (currentPos.boundingRect) {
156
- newPos.boundingRect = new models_1.BoundingRect(currentPos.boundingRect.x + options.translate[0], currentPos.boundingRect.y + options.translate[1], currentPos.boundingRect.width, currentPos.boundingRect.height);
157
- }
158
- // Use MoveRequest for proper format
159
- const requestData = new models_1.MoveRequest(this.objectRef, newPos).toDict();
160
- await this.client.request('PUT', '/pdf/move', requestData);
161
- }
162
- // Note: scale and rotate are not directly supported by current API
163
- // These would need backend implementation
164
- if (options.scale !== undefined || options.rotate !== undefined) {
165
- throw new exceptions_1.PdfDancerException('Image scale and rotate operations are not yet supported by the backend API');
166
- }
167
- }
168
- }
169
- exports.ImageObject = ImageObject;
170
- // ============================================================================
171
- // PathObject
172
- // ============================================================================
173
- class PathObject {
174
- constructor(objectRef, client) {
175
- this.objectRef = objectRef;
176
- this.client = client;
177
- }
178
- async edit(options) {
179
- // Path editing would require backend support for vector manipulation
180
- // Current API doesn't have path modification endpoints
181
- throw new exceptions_1.PdfDancerException('Path editing is not yet supported by the backend API');
182
- }
183
- }
184
- exports.PathObject = PathObject;
185
- // ============================================================================
186
- // PDFPage
187
- // ============================================================================
188
- class PDFPage {
189
- constructor(pageIndex, client) {
190
- this.pageIndex = pageIndex;
191
- this.client = client;
192
- }
193
- async selectText(criteria) {
194
- const position = this.buildPositionFromCriteria(criteria);
195
- // Try paragraph first, then text line
196
- let objectRefs = await this.findObjects(models_1.ObjectType.PARAGRAPH, position);
197
- let objectType = models_1.ObjectType.PARAGRAPH;
198
- if (objectRefs.length === 0) {
199
- objectRefs = await this.findObjects(models_1.ObjectType.TEXT_LINE, position);
200
- objectType = models_1.ObjectType.TEXT_LINE;
201
- }
202
- if (objectRefs.length === 0) {
203
- throw new exceptions_1.PdfDancerException('No text object found matching criteria');
204
- }
205
- return new TextObject(objectRefs[0], this.client, objectType);
206
- }
207
- async selectImage(criteria) {
208
- const position = this.buildPositionFromImageCriteria(criteria);
209
- const objectRefs = await this.findObjects(models_1.ObjectType.IMAGE, position);
210
- if (objectRefs.length === 0) {
211
- throw new exceptions_1.PdfDancerException('No image found matching criteria');
212
- }
213
- // If index specified, return that index, otherwise return first
214
- const index = criteria.index !== undefined ? criteria.index : 0;
215
- if (index >= objectRefs.length) {
216
- throw new exceptions_1.PdfDancerException(`Image index ${index} out of range (found ${objectRefs.length} images)`);
217
- }
218
- return new ImageObject(objectRefs[index], this.client);
219
- }
220
- async selectPath(criteria) {
221
- const position = this.buildPositionFromPathCriteria(criteria);
222
- const objectRefs = await this.findObjects(models_1.ObjectType.PATH, position);
223
- if (objectRefs.length === 0) {
224
- throw new exceptions_1.PdfDancerException('No path found matching criteria');
225
- }
226
- return new PathObject(objectRefs[0], this.client);
227
- }
228
- buildPositionFromCriteria(criteria) {
229
- const position = new models_1.Position();
230
- position.pageIndex = this.pageIndex;
231
- if (criteria.containing) {
232
- position.textStartsWith = criteria.containing;
233
- }
234
- if (criteria.at) {
235
- position.boundingRect = new models_1.BoundingRect(criteria.at[0], criteria.at[1], 0, 0);
236
- position.mode = models_1.PositionMode.CONTAINS;
237
- }
238
- if (criteria.withinBbox) {
239
- position.boundingRect = new models_1.BoundingRect(criteria.withinBbox[0], criteria.withinBbox[1], criteria.withinBbox[2], criteria.withinBbox[3]);
240
- position.mode = models_1.PositionMode.CONTAINS;
241
- }
242
- return position;
243
- }
244
- buildPositionFromImageCriteria(criteria) {
245
- const position = new models_1.Position();
246
- position.pageIndex = this.pageIndex;
247
- if (criteria.at) {
248
- position.boundingRect = new models_1.BoundingRect(criteria.at[0], criteria.at[1], 0, 0);
249
- position.mode = models_1.PositionMode.CONTAINS;
250
- }
251
- return position;
252
- }
253
- buildPositionFromPathCriteria(criteria) {
254
- const position = new models_1.Position();
255
- position.pageIndex = this.pageIndex;
256
- if (criteria.at) {
257
- position.boundingRect = new models_1.BoundingRect(criteria.at[0], criteria.at[1], 0, 0);
258
- position.mode = models_1.PositionMode.CONTAINS;
259
- }
260
- return position;
261
- }
262
- async findObjects(objectType, position) {
263
- const requestData = {
264
- kind: objectType,
265
- position: (0, models_1.positionToDict)(position)
266
- };
267
- const response = await this.client.request('POST', '/pdf/find', requestData);
268
- const objectsData = await response.json();
269
- return objectsData.map((objData) => this.parseObjectRef(objData));
270
- }
271
- parseObjectRef(objData) {
272
- if (!objData) {
273
- throw new exceptions_1.PdfDancerException('Invalid object data: received null or undefined');
274
- }
275
- const positionData = objData.position || {};
276
- const position = this.parsePosition(positionData);
277
- const objectType = objData.type;
278
- return new models_1.ObjectRef(objData.internalId, position, objectType);
279
- }
280
- parsePosition(posData) {
281
- const position = new models_1.Position();
282
- position.pageIndex = posData.pageIndex;
283
- position.textStartsWith = posData.textStartsWith;
284
- if (posData.shape) {
285
- position.shape = models_1.ShapeType[posData.shape];
286
- }
287
- if (posData.mode) {
288
- position.mode = models_1.PositionMode[posData.mode];
289
- }
290
- if (posData.boundingRect) {
291
- const rectData = posData.boundingRect;
292
- position.boundingRect = new models_1.BoundingRect(rectData.x, rectData.y, rectData.width, rectData.height);
293
- }
294
- return position;
295
- }
296
- }
297
- exports.PDFPage = PDFPage;
298
- // ============================================================================
299
- // PDFDocument
300
- // ============================================================================
301
- class PDFDocument {
302
- constructor(client, sessionId) {
303
- this.client = client;
304
- this.sessionId = sessionId;
305
- }
306
- page(index) {
307
- if (index < 0) {
308
- throw new exceptions_1.ValidationException(`Page index must be >= 0, got ${index}`);
309
- }
310
- return new PDFPage(index, this.client);
311
- }
312
- // Document-level find operations
313
- async findParagraphs(position) {
314
- return this.findObjects(models_1.ObjectType.PARAGRAPH, position);
315
- }
316
- async findImages(position) {
317
- return this.findObjects(models_1.ObjectType.IMAGE, position);
318
- }
319
- async findTextLines(position) {
320
- return this.findObjects(models_1.ObjectType.TEXT_LINE, position);
321
- }
322
- async findPaths(position) {
323
- return this.findObjects(models_1.ObjectType.PATH, position);
324
- }
325
- async findFormXObjects(position) {
326
- return this.findObjects(models_1.ObjectType.FORM_X_OBJECT, position);
327
- }
328
- async findObjects(objectType, position) {
329
- const requestData = {
330
- kind: objectType,
331
- position: position ? (0, models_1.positionToDict)(position) : null
332
- };
333
- const response = await this.client.request('POST', '/pdf/find', requestData);
334
- const objectsData = await response.json();
335
- // Filter out null entries and filter by objectType
336
- return objectsData
337
- .filter((objData) => objData !== null && objData.type === objectType)
338
- .map((objData) => this.parseObjectRef(objData));
339
- }
340
- parseObjectRef(objData) {
341
- if (!objData) {
342
- throw new exceptions_1.PdfDancerException('Invalid object data: received null or undefined');
343
- }
344
- const positionData = objData.position || {};
345
- const position = this.parsePosition(positionData);
346
- const objectType = objData.type;
347
- return new models_1.ObjectRef(objData.internalId, position, objectType);
348
- }
349
- parsePosition(posData) {
350
- const position = new models_1.Position();
351
- position.pageIndex = posData.pageIndex;
352
- position.textStartsWith = posData.textStartsWith;
353
- if (posData.shape) {
354
- position.shape = models_1.ShapeType[posData.shape];
355
- }
356
- if (posData.mode) {
357
- position.mode = models_1.PositionMode[posData.mode];
358
- }
359
- if (posData.boundingRect) {
360
- const rectData = posData.boundingRect;
361
- position.boundingRect = new models_1.BoundingRect(rectData.x, rectData.y, rectData.width, rectData.height);
362
- }
363
- return position;
364
- }
365
- // Delete operation
366
- async delete(objectRef) {
367
- if (!objectRef) {
368
- throw new exceptions_1.ValidationException("Object reference cannot be null");
369
- }
370
- const requestData = {
371
- objectRef: {
372
- internalId: objectRef.internalId,
373
- position: (0, models_1.positionToDict)(objectRef.position),
374
- type: objectRef.type
375
- }
376
- };
377
- const response = await this.client.request('DELETE', '/pdf/delete', requestData);
378
- return await response.json();
379
- }
380
- // Move operation
381
- async move(objectRef, position) {
382
- if (!objectRef) {
383
- throw new exceptions_1.ValidationException("Object reference cannot be null");
384
- }
385
- if (!position) {
386
- throw new exceptions_1.ValidationException("Position cannot be null");
387
- }
388
- const requestData = new models_1.MoveRequest(objectRef, position).toDict();
389
- const response = await this.client.request('PUT', '/pdf/move', requestData);
390
- return await response.json();
391
- }
392
- // Add paragraph operation
393
- async addParagraph(paragraph) {
394
- if (!paragraph) {
395
- throw new exceptions_1.ValidationException("Paragraph cannot be null");
396
- }
397
- if (!paragraph.getPosition()) {
398
- throw new exceptions_1.ValidationException("Paragraph position is null");
399
- }
400
- if (paragraph.getPosition().pageIndex === undefined) {
401
- throw new exceptions_1.ValidationException("Paragraph position page index is null");
402
- }
403
- if (paragraph.getPosition().pageIndex < 0) {
404
- throw new exceptions_1.ValidationException("Paragraph position page index is less than 0");
405
- }
406
- const requestData = new models_1.AddRequest(paragraph).toDict();
407
- const response = await this.client.request('POST', '/pdf/add', requestData);
408
- return await response.json();
409
- }
410
- // Modify paragraph operation
411
- async modifyParagraph(objectRef, newParagraph) {
412
- if (!objectRef) {
413
- throw new exceptions_1.ValidationException("Object reference cannot be null");
414
- }
415
- if (newParagraph === null || newParagraph === undefined) {
416
- throw new exceptions_1.ValidationException("New paragraph cannot be null");
417
- }
418
- if (typeof newParagraph === 'string') {
419
- // Text modification
420
- const requestData = new models_1.ModifyTextRequest(objectRef, newParagraph).toDict();
421
- const response = await this.client.request('PUT', '/pdf/text/paragraph', requestData);
422
- return await response.json();
423
- }
424
- else {
425
- // Object modification
426
- const requestData = new models_1.ModifyRequest(objectRef, newParagraph).toDict();
427
- const response = await this.client.request('PUT', '/pdf/modify', requestData);
428
- return await response.json();
429
- }
430
- }
431
- // Font operations
432
- async findFonts(fontName, fontSize) {
433
- if (!fontName || !fontName.trim()) {
434
- throw new exceptions_1.ValidationException("Font name cannot be null or empty");
435
- }
436
- if (fontSize <= 0) {
437
- throw new exceptions_1.ValidationException(`Font size must be positive, got ${fontSize}`);
438
- }
439
- const params = { fontName: fontName.trim() };
440
- const response = await this.client.request('GET', '/font/find', undefined, params);
441
- const fontNames = await response.json();
442
- return fontNames.map((name) => new models_1.Font(name, fontSize));
443
- }
444
- async registerFont(ttfFile) {
445
- if (!ttfFile) {
446
- throw new exceptions_1.ValidationException("TTF file cannot be null");
447
- }
448
- try {
449
- let fontData;
450
- let filename;
451
- if (ttfFile instanceof Uint8Array) {
452
- if (ttfFile.length === 0) {
453
- throw new exceptions_1.ValidationException("Font data cannot be empty");
454
- }
455
- fontData = ttfFile;
456
- filename = 'font.ttf';
457
- }
458
- else if (ttfFile instanceof File) {
459
- if (ttfFile.size === 0) {
460
- throw new exceptions_1.ValidationException("Font file is empty");
461
- }
462
- fontData = new Uint8Array(await ttfFile.arrayBuffer());
463
- filename = ttfFile.name;
464
- }
465
- else {
466
- throw new exceptions_1.ValidationException(`Unsupported font file type: ${typeof ttfFile}`);
467
- }
468
- const formData = new FormData();
469
- const blob = new Blob([fontData.buffer], { type: 'font/ttf' });
470
- formData.append('ttfFile', blob, filename);
471
- const response = await fetch(`${this.client['baseUrl']}/font/register`, {
472
- method: 'POST',
473
- headers: {
474
- 'Authorization': `Bearer ${this.client['token']}`,
475
- 'X-Session-Id': this.sessionId
476
- },
477
- body: formData,
478
- signal: AbortSignal.timeout(30000)
479
- });
480
- if (!response.ok) {
481
- const errorMessage = await this.extractErrorMessage(response);
482
- throw new exceptions_1.HttpClientException(`Font registration failed: ${errorMessage}`, response);
483
- }
484
- return (await response.text()).trim();
485
- }
486
- catch (error) {
487
- if (error instanceof exceptions_1.ValidationException || error instanceof exceptions_1.HttpClientException) {
488
- throw error;
489
- }
490
- const errorMessage = error instanceof Error ? error.message : String(error);
491
- throw new exceptions_1.PdfDancerException(`Failed to read font file: ${errorMessage}`, error);
492
- }
493
- }
494
- async extractErrorMessage(response) {
495
- if (!response)
496
- return "Unknown error";
497
- try {
498
- const errorData = await response.json();
499
- if (errorData._embedded?.errors) {
500
- const errors = errorData._embedded.errors;
501
- if (Array.isArray(errors)) {
502
- const messages = errors
503
- .filter((error) => error.message)
504
- .map((error) => error.message);
505
- if (messages.length > 0)
506
- return messages.join("; ");
507
- }
508
- }
509
- if (errorData.message)
510
- return errorData.message;
511
- return await response.text() || `HTTP ${response.status}`;
512
- }
513
- catch {
514
- try {
515
- return await response.text() || `HTTP ${response.status}`;
516
- }
517
- catch {
518
- return `HTTP ${response.status}`;
519
- }
520
- }
521
- }
522
- // Paragraph builder
523
- paragraphBuilder() {
524
- return new ParagraphBuilderV2(this);
525
- }
526
- async save(filename = 'document.pdf') {
527
- if (!filename) {
528
- throw new exceptions_1.ValidationException("Filename cannot be null or empty");
529
- }
530
- try {
531
- const response = await this.client.request('GET', `/session/${this.sessionId}/pdf`);
532
- const pdfData = new Uint8Array(await response.arrayBuffer());
533
- // Browser download
534
- const blob = new Blob([pdfData.buffer], { type: 'application/pdf' });
535
- const url = URL.createObjectURL(blob);
536
- const link = document.createElement('a');
537
- link.href = url;
538
- link.download = filename;
539
- document.body.appendChild(link);
540
- link.click();
541
- document.body.removeChild(link);
542
- URL.revokeObjectURL(url);
543
- }
544
- catch (error) {
545
- const errorMessage = error instanceof Error ? error.message : String(error);
546
- throw new exceptions_1.PdfDancerException(`Failed to save PDF file: ${errorMessage}`, error);
547
- }
548
- }
549
- }
550
- exports.PDFDocument = PDFDocument;
551
- // ============================================================================
552
- // ParagraphBuilderV2
553
- // ============================================================================
554
- class ParagraphBuilderV2 {
555
- constructor(document) {
556
- this.document = document;
557
- this.paragraph = new models_1.Paragraph();
558
- }
559
- fromString(text) {
560
- this.paragraph.textLines = text.split('\\n');
561
- return this;
562
- }
563
- withFont(font) {
564
- this.paragraph.font = font;
565
- return this;
566
- }
567
- withLineSpacing(lineSpacing) {
568
- this.paragraph.lineSpacing = lineSpacing;
569
- return this;
570
- }
571
- withColor(color) {
572
- this.paragraph.color = color;
573
- return this;
574
- }
575
- withPosition(position) {
576
- this.paragraph.position = position;
577
- return this;
578
- }
579
- async withFontFile(ttfData, fontSize) {
580
- const fontName = await this.document.registerFont(ttfData);
581
- this.paragraph.font = new models_1.Font(fontName, fontSize);
582
- return this;
583
- }
584
- build() {
585
- return this.paragraph;
586
- }
587
- }
588
- exports.ParagraphBuilderV2 = ParagraphBuilderV2;
589
- // ============================================================================
590
- // PDFDancer
591
- // ============================================================================
592
- class PDFDancer {
593
- static async open(pdfData, options) {
594
- const { token, baseUrl = "http://localhost:8080", timeout = 30000 } = options;
595
- if (!token || !token.trim()) {
596
- throw new exceptions_1.ValidationException("Authentication token cannot be null or empty");
597
- }
598
- if (!pdfData) {
599
- throw new exceptions_1.ValidationException("PDF data cannot be null");
600
- }
601
- // Process PDF data
602
- const pdfBytes = PDFDancer.processPdfData(pdfData);
603
- // Create session
604
- const sessionId = await PDFDancer.createSession(pdfBytes, token.trim(), baseUrl.replace(/\/$/, ''), timeout);
605
- // Create HTTP client
606
- const client = new HttpClient(token.trim(), sessionId, baseUrl.replace(/\/$/, ''), timeout);
607
- return new PDFDocument(client, sessionId);
608
- }
609
- static processPdfData(pdfData) {
610
- if (pdfData instanceof Uint8Array) {
611
- if (pdfData.length === 0) {
612
- throw new exceptions_1.ValidationException("PDF data cannot be empty");
613
- }
614
- return pdfData;
615
- }
616
- else if (pdfData instanceof ArrayBuffer) {
617
- const uint8Array = new Uint8Array(pdfData);
618
- if (uint8Array.length === 0) {
619
- throw new exceptions_1.ValidationException("PDF data cannot be empty");
620
- }
621
- return uint8Array;
622
- }
623
- else if (pdfData instanceof File) {
624
- return pdfData;
625
- }
626
- else {
627
- throw new exceptions_1.ValidationException(`Unsupported PDF data type: ${typeof pdfData}`);
628
- }
629
- }
630
- static async createSession(pdfBytes, token, baseUrl, timeout) {
631
- try {
632
- const formData = new FormData();
633
- if (pdfBytes instanceof File) {
634
- formData.append('pdf', pdfBytes, 'document.pdf');
635
- }
636
- else {
637
- const blob = new Blob([pdfBytes.buffer], { type: 'application/pdf' });
638
- formData.append('pdf', blob, 'document.pdf');
639
- }
640
- const response = await fetch(`${baseUrl}/session/create`, {
641
- method: 'POST',
642
- headers: {
643
- 'Authorization': `Bearer ${token}`
644
- },
645
- body: formData,
646
- signal: timeout > 0 ? AbortSignal.timeout(timeout) : undefined
647
- });
648
- if (!response.ok) {
649
- const errorMessage = await PDFDancer.extractErrorMessage(response);
650
- throw new exceptions_1.HttpClientException(`Failed to create session: ${errorMessage}`, response);
651
- }
652
- const sessionId = (await response.text()).trim();
653
- if (!sessionId) {
654
- throw new exceptions_1.SessionException("Server returned empty session ID");
655
- }
656
- return sessionId;
657
- }
658
- catch (error) {
659
- if (error instanceof exceptions_1.HttpClientException || error instanceof exceptions_1.SessionException) {
660
- throw error;
661
- }
662
- const errorMessage = error instanceof Error ? error.message : String(error);
663
- throw new exceptions_1.HttpClientException(`Failed to create session: ${errorMessage}`, undefined, error);
664
- }
665
- }
666
- static async extractErrorMessage(response) {
667
- if (!response)
668
- return "Unknown error";
669
- try {
670
- const errorData = await response.json();
671
- if (errorData._embedded?.errors) {
672
- const errors = errorData._embedded.errors;
673
- if (Array.isArray(errors)) {
674
- const messages = errors
675
- .filter((error) => error.message)
676
- .map((error) => error.message);
677
- if (messages.length > 0)
678
- return messages.join("; ");
679
- }
680
- }
681
- if (errorData.message)
682
- return errorData.message;
683
- return await response.text() || `HTTP ${response.status}`;
684
- }
685
- catch {
686
- try {
687
- return await response.text() || `HTTP ${response.status}`;
688
- }
689
- catch {
690
- return `HTTP ${response.status}`;
691
- }
692
- }
693
- }
694
- }
695
- exports.PDFDancer = PDFDancer;
696
- //# sourceMappingURL=client-v2.js.map