pdfdancer-client-typescript 1.0.4 → 1.0.6

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 (54) hide show
  1. package/README.md +5 -5
  2. package/dist/__tests__/e2e/test-helpers.d.ts +2 -1
  3. package/dist/__tests__/e2e/test-helpers.d.ts.map +1 -1
  4. package/dist/__tests__/e2e/test-helpers.js +7 -3
  5. package/dist/__tests__/e2e/test-helpers.js.map +1 -1
  6. package/dist/client-v1.js +1 -1
  7. package/dist/client-v1.js.map +1 -1
  8. package/dist/client-v2.d.ts +129 -0
  9. package/dist/client-v2.d.ts.map +1 -0
  10. package/dist/client-v2.js +696 -0
  11. package/dist/client-v2.js.map +1 -0
  12. package/dist/image-builder.d.ts +13 -0
  13. package/dist/image-builder.d.ts.map +1 -0
  14. package/dist/image-builder.js +44 -0
  15. package/dist/image-builder.js.map +1 -0
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +3 -3
  19. package/dist/index.js.map +1 -1
  20. package/dist/models.d.ts +5 -10
  21. package/dist/models.d.ts.map +1 -1
  22. package/dist/models.js +3 -13
  23. package/dist/models.js.map +1 -1
  24. package/dist/paragraph-builder.d.ts +19 -10
  25. package/dist/paragraph-builder.d.ts.map +1 -1
  26. package/dist/paragraph-builder.js +65 -26
  27. package/dist/paragraph-builder.js.map +1 -1
  28. package/dist/pdfdancer_v1.d.ts +202 -0
  29. package/dist/pdfdancer_v1.d.ts.map +1 -0
  30. package/dist/pdfdancer_v1.js +702 -0
  31. package/dist/pdfdancer_v1.js.map +1 -0
  32. package/dist/types.d.ts +56 -0
  33. package/dist/types.d.ts.map +1 -0
  34. package/dist/types.js +92 -0
  35. package/dist/types.js.map +1 -0
  36. package/package.json +1 -1
  37. package/scripts/release.js +1 -1
  38. package/src/__tests__/client-v1.test.ts +46 -87
  39. package/src/__tests__/e2e/acroform.test.ts +60 -57
  40. package/src/__tests__/e2e/form_x_object.test.ts +17 -16
  41. package/src/__tests__/e2e/image.test.ts +53 -56
  42. package/src/__tests__/e2e/line.test.ts +47 -48
  43. package/src/__tests__/e2e/page.test.ts +37 -36
  44. package/src/__tests__/e2e/paragraph.test.ts +107 -101
  45. package/src/__tests__/e2e/path.test.ts +67 -64
  46. package/src/__tests__/e2e/test-helpers.ts +71 -67
  47. package/src/__tests__/e2e/token_from_env.test.ts +35 -0
  48. package/src/image-builder.ts +52 -0
  49. package/src/index.ts +1 -1
  50. package/src/models.ts +5 -21
  51. package/src/paragraph-builder.ts +217 -162
  52. package/src/{client-v1.ts → pdfdancer_v1.ts} +248 -53
  53. package/src/types.ts +133 -0
  54. package/example.ts +0 -99
@@ -31,7 +31,153 @@ import {
31
31
  ShapeType
32
32
  } from './models';
33
33
  import {ParagraphBuilder} from './paragraph-builder';
34
+ import {FormFieldObject, FormXObject, ImageObject, ParagraphObject, PathObject, TextLineObject} from "./types";
35
+ import {ImageBuilder} from "./image-builder";
36
+ import fs from "fs";
34
37
 
38
+ // 👇 Internal view of PDFDancer methods, not exported
39
+ interface PDFDancerInternals {
40
+
41
+ toImageObjects(objectRefs: ObjectRef[]): ImageObject[];
42
+
43
+ toPathObjects(objectRefs: ObjectRef[]): PathObject[];
44
+
45
+ toFormXObjects(objectRefs: ObjectRef[]): FormXObject[];
46
+
47
+ deletePage(objectRef: ObjectRef): Promise<boolean>;
48
+
49
+ toTextLineObjects(objectRefs: ObjectRef[]): TextLineObject[];
50
+
51
+ toFormFields(formFieldRefs: FormFieldRef[]): FormFieldObject[];
52
+
53
+ toParagraphObjects(objectRefs: ObjectRef[]): ParagraphObject[];
54
+
55
+ findFormFields(position?: Position): Promise<FormFieldRef[]>;
56
+
57
+ findPaths(position?: Position): Promise<ObjectRef[]>;
58
+
59
+ findFormXObjects(position?: Position): Promise<ObjectRef[]>;
60
+
61
+ findParagraphs(position?: Position): Promise<ObjectRef[]>;
62
+
63
+ findTextLines(pos?: Position): Promise<ObjectRef[]>;
64
+
65
+ _findImages(position?: Position): Promise<ObjectRef[]>;
66
+ }
67
+
68
+ class PageClient {
69
+
70
+ private _pageIndex: number;
71
+ private _client: PDFDancer;
72
+ type: ObjectType = ObjectType.PAGE;
73
+ position: Position;
74
+ internalId: string;
75
+ private _internals: PDFDancerInternals;
76
+
77
+ constructor(client: PDFDancer, pageIndex: number) {
78
+ this._client = client;
79
+ this._pageIndex = pageIndex;
80
+ this.internalId = `PAGE-${this._pageIndex}`;
81
+ this.position = Position.atPage(this._pageIndex);
82
+ // Cast to the internal interface to get access
83
+ this._internals = this._client as unknown as PDFDancerInternals;
84
+ }
85
+
86
+ async selectPathsAt(x: number, y: number) {
87
+ return this._internals.toPathObjects(await this._internals.findPaths(Position.atPageCoordinates(this._pageIndex, x, y)));
88
+ }
89
+
90
+ async selectImages() {
91
+ return this._internals.toImageObjects(await this._internals._findImages(Position.atPage(this._pageIndex)));
92
+ }
93
+
94
+ async selectImagesAt(x: number, y: number) {
95
+ return this._internals.toImageObjects(await this._internals._findImages(Position.atPageCoordinates(this._pageIndex, x, y)));
96
+ }
97
+
98
+ async delete() {
99
+ return this._internals.deletePage(this.ref());
100
+ }
101
+
102
+ private ref() {
103
+ return new ObjectRef(this.internalId, this.position, this.type);
104
+ }
105
+
106
+ // noinspection JSUnusedGlobalSymbols
107
+ async selectForms() {
108
+ return this._internals.toFormXObjects(await this._internals.findFormXObjects(Position.atPage(this._pageIndex)));
109
+ }
110
+
111
+ async selectFormsAt(x: number, y: number) {
112
+ return this._internals.toFormXObjects(await this._internals.findFormXObjects(Position.atPageCoordinates(this._pageIndex, x, y)));
113
+ }
114
+
115
+ async selectFormFields() {
116
+ return this._internals.toFormFields(await this._internals.findFormFields(Position.atPage(this._pageIndex)));
117
+ }
118
+
119
+ async selectFormFieldsAt(x: number, y: number) {
120
+ return this._internals.toFormFields(await this._internals.findFormFields(Position.atPageCoordinates(this._pageIndex, x, y)));
121
+ }
122
+
123
+ // noinspection JSUnusedGlobalSymbols
124
+ async selectFormFieldsByName(fieldName: string) {
125
+ let pos = Position.atPage(this._pageIndex);
126
+ pos.name = fieldName;
127
+ return this._internals.toFormFields(await this._internals.findFormFields(pos));
128
+ }
129
+
130
+ async selectParagraphs() {
131
+ return this._internals.toParagraphObjects(await this._internals.findParagraphs(Position.atPage(this._pageIndex)));
132
+ }
133
+
134
+ async selectParagraphsStartingWith(text: string) {
135
+ let pos = Position.atPage(this._pageIndex);
136
+ pos.textStartsWith = text;
137
+ return this._internals.toParagraphObjects(await this._internals.findParagraphs(pos));
138
+ }
139
+
140
+ async selectParagraphsMatching(pattern: string) {
141
+ let pos = Position.atPage(this._pageIndex);
142
+ pos.textPattern = pattern;
143
+ return this._internals.toParagraphObjects(await this._internals.findParagraphs(pos));
144
+ }
145
+
146
+ async selectParagraphsAt(x: number, y: number) {
147
+ return this._internals.toParagraphObjects(await this._internals.findParagraphs(Position.atPageCoordinates(this._pageIndex, x, y)));
148
+ }
149
+
150
+ async selectTextLinesStartingWith(text: string) {
151
+ let pos = Position.atPage(this._pageIndex);
152
+ pos.textStartsWith = text;
153
+ return this._internals.toTextLineObjects(await this._internals.findTextLines(pos));
154
+ }
155
+
156
+ /**
157
+ * Creates a new ParagraphBuilder for fluent paragraph construction.
158
+ */
159
+ newParagraph(): ParagraphBuilder {
160
+ return new ParagraphBuilder(this._client, this.position.pageIndex);
161
+ }
162
+
163
+ async selectTextLines() {
164
+ return this._internals.toTextLineObjects(await this._internals.findTextLines(Position.atPage(this._pageIndex)));
165
+ }
166
+
167
+ // noinspection JSUnusedGlobalSymbols
168
+ async selectTextLinesMatching(pattern: string) {
169
+ let pos = Position.atPage(this._pageIndex);
170
+ pos.textPattern = pattern;
171
+ return this._internals.toTextLineObjects(await this._internals.findTextLines(pos));
172
+ }
173
+
174
+ // noinspection JSUnusedGlobalSymbols
175
+ async selectTextLinesAt(x: number, y: number) {
176
+ return this._internals.toTextLineObjects(await this._internals.findTextLines(Position.atPageCoordinates(this._pageIndex, x, y)));
177
+ }
178
+ }
179
+
180
+ // noinspection ExceptionCaughtLocallyJS,JSUnusedLocalSymbols
35
181
  /**
36
182
  * REST API client for interacting with the PDFDancer PDF manipulation service.
37
183
  * This client provides a convenient TypeScript interface for performing PDF operations
@@ -39,7 +185,7 @@ import {ParagraphBuilder} from './paragraph-builder';
39
185
  * Handles authentication, session lifecycle, and HTTP communication transparently.
40
186
  *
41
187
  */
42
- export class ClientV1 {
188
+ export class PDFDancer {
43
189
  private _token: string;
44
190
  private _baseUrl: string;
45
191
  private _readTimeout: number;
@@ -48,10 +194,10 @@ export class ClientV1 {
48
194
 
49
195
  /**
50
196
  * Creates a new client with PDF data.
51
- * This constructor initializes the client, uploads the PDF data to create
197
+ * This constructor initializes the client, uploads the PDF data to open
52
198
  * a new session, and prepares the client for PDF manipulation operations.
53
199
  */
54
- constructor(
200
+ private constructor(
55
201
  token: string,
56
202
  pdfData: Uint8Array | File | ArrayBuffer,
57
203
  baseUrl: string = "http://localhost:8080",
@@ -78,8 +224,19 @@ export class ClientV1 {
78
224
  return this;
79
225
  }
80
226
 
81
- static async create(token: string, pdfData: Uint8Array, baseUrl: string, timeout: number = 0): Promise<ClientV1> {
82
- const client = new ClientV1(token, pdfData, baseUrl, timeout);
227
+ static async open(pdfData: Uint8Array, token?: string, baseUrl?: string, timeout?: number): Promise<PDFDancer> {
228
+ const resolvedToken = token ?? process.env.PDFDANCER_TOKEN;
229
+ const resolvedBaseUrl =
230
+ baseUrl ??
231
+ process.env.PDFDANCER_BASE_URL ??
232
+ "https://api.pdfdancer.com";
233
+ const resolvedTimeout = timeout ?? 30000;
234
+
235
+ if (!resolvedToken) {
236
+ throw new Error("Missing PDFDancer token (pass it explicitly or set PDFDANCER_TOKEN in environment).");
237
+ }
238
+
239
+ const client = new PDFDancer(resolvedToken, pdfData, resolvedBaseUrl, resolvedTimeout);
83
240
  return await client.init();
84
241
  }
85
242
 
@@ -272,7 +429,7 @@ export class ClientV1 {
272
429
  * This method provides flexible search capabilities across all PDF content,
273
430
  * allowing filtering by object type and position constraints.
274
431
  */
275
- async find(objectType?: ObjectType, position?: Position): Promise<ObjectRef[]> {
432
+ private async find(objectType?: ObjectType, position?: Position): Promise<ObjectRef[]> {
276
433
  const requestData = new FindRequest(objectType, position).toDict();
277
434
  const response = await this._makeRequest('POST', '/pdf/find', requestData);
278
435
 
@@ -283,35 +440,55 @@ export class ClientV1 {
283
440
  /**
284
441
  * Searches for paragraph objects at the specified position.
285
442
  */
286
- async findParagraphs(position?: Position): Promise<ObjectRef[]> {
443
+ private async findParagraphs(position?: Position): Promise<ObjectRef[]> {
287
444
  return this.find(ObjectType.PARAGRAPH, position);
288
445
  }
289
446
 
290
447
  /**
291
448
  * Searches for image objects at the specified position.
292
449
  */
293
- async findImages(position?: Position): Promise<ObjectRef[]> {
450
+ private async _findImages(position?: Position): Promise<ObjectRef[]> {
294
451
  return this.find(ObjectType.IMAGE, position);
295
452
  }
296
453
 
454
+ async selectImages(): Promise<ImageObject[]> {
455
+ return this.toImageObjects(await this.find(ObjectType.IMAGE));
456
+ }
457
+
297
458
  /**
298
459
  * Searches for form X objects at the specified position.
299
460
  */
300
- async findFormXObjects(position?: Position): Promise<ObjectRef[]> {
461
+ private async findFormXObjects(position?: Position): Promise<ObjectRef[]> {
301
462
  return this.find(ObjectType.FORM_X_OBJECT, position);
302
463
  }
303
464
 
304
465
  /**
305
466
  * Searches for vector path objects at the specified position.
306
467
  */
307
- async findPaths(position?: Position): Promise<ObjectRef[]> {
468
+ private async findPaths(position?: Position): Promise<ObjectRef[]> {
308
469
  return this.find(ObjectType.PATH, position);
309
470
  }
310
471
 
472
+ async selectPaths() {
473
+ return this.toPathObjects(await this.find(ObjectType.PATH));
474
+ }
475
+
476
+ async selectForms() {
477
+ return this.toFormXObjects(await this.find(ObjectType.FORM_X_OBJECT));
478
+ }
479
+
480
+ async selectFormFields() {
481
+ return this.toFormFields(await this.findFormFields());
482
+ }
483
+
484
+ async selectFieldsByName(fieldName: string) {
485
+ return this.toFormFields(await this.findFormFields(Position.byName(fieldName)));
486
+ }
487
+
311
488
  /**
312
489
  * Searches for text line objects at the specified position.
313
490
  */
314
- async findTextLines(position?: Position): Promise<ObjectRef[]> {
491
+ private async findTextLines(position?: Position): Promise<ObjectRef[]> {
315
492
  return this.find(ObjectType.TEXT_LINE, position);
316
493
  }
317
494
 
@@ -319,7 +496,7 @@ export class ClientV1 {
319
496
  * Searches for form fields at the specified position.
320
497
  * Returns FormFieldRef objects with name and value properties.
321
498
  */
322
- async findFormFields(position?: Position): Promise<FormFieldRef[]> {
499
+ private async findFormFields(position?: Position): Promise<FormFieldRef[]> {
323
500
  const requestData = new FindRequest(ObjectType.FORM_FIELD, position).toDict();
324
501
  const response = await this._makeRequest('POST', '/pdf/find', requestData);
325
502
 
@@ -332,7 +509,7 @@ export class ClientV1 {
332
509
  /**
333
510
  * Retrieves references to all pages in the PDF document.
334
511
  */
335
- async getPages(): Promise<ObjectRef[]> {
512
+ private async getPages(): Promise<ObjectRef[]> {
336
513
  const response = await this._makeRequest('POST', '/pdf/page/find');
337
514
  const pagesData = await response.json() as any[];
338
515
  return pagesData.map((pageData: any) => this._parseObjectRef(pageData));
@@ -341,7 +518,7 @@ export class ClientV1 {
341
518
  /**
342
519
  * Retrieves a reference to a specific page by its page index.
343
520
  */
344
- async getPage(pageIndex: number): Promise<ObjectRef | null> {
521
+ private async _getPage(pageIndex: number): Promise<ObjectRef | null> {
345
522
  if (pageIndex < 0) {
346
523
  throw new ValidationException(`Page index must be >= 0, got ${pageIndex}`);
347
524
  }
@@ -360,7 +537,7 @@ export class ClientV1 {
360
537
  /**
361
538
  * Deletes a page from the PDF document.
362
539
  */
363
- async deletePage(pageRef: ObjectRef): Promise<boolean> {
540
+ private async deletePage(pageRef: ObjectRef): Promise<boolean> {
364
541
  if (!pageRef) {
365
542
  throw new ValidationException("Page reference cannot be null");
366
543
  }
@@ -375,7 +552,7 @@ export class ClientV1 {
375
552
  /**
376
553
  * Deletes the specified PDF object from the document.
377
554
  */
378
- async delete(objectRef: ObjectRef): Promise<boolean> {
555
+ private async delete(objectRef: ObjectRef): Promise<boolean> {
379
556
  if (!objectRef) {
380
557
  throw new ValidationException("Object reference cannot be null");
381
558
  }
@@ -388,7 +565,7 @@ export class ClientV1 {
388
565
  /**
389
566
  * Moves a PDF object to a new position within the document.
390
567
  */
391
- async move(objectRef: ObjectRef, position: Position): Promise<boolean> {
568
+ private async move(objectRef: ObjectRef, position: Position): Promise<boolean> {
392
569
  if (!objectRef) {
393
570
  throw new ValidationException("Object reference cannot be null");
394
571
  }
@@ -404,7 +581,7 @@ export class ClientV1 {
404
581
  /**
405
582
  * Changes the value of a form field.
406
583
  */
407
- async changeFormField(formFieldRef: FormFieldRef, newValue: string): Promise<boolean> {
584
+ private async changeFormField(formFieldRef: FormFieldRef, newValue: string): Promise<boolean> {
408
585
  if (!formFieldRef) {
409
586
  throw new ValidationException("Form field reference cannot be null");
410
587
  }
@@ -419,7 +596,7 @@ export class ClientV1 {
419
596
  /**
420
597
  * Adds an image to the PDF document.
421
598
  */
422
- async addImage(image: Image, position?: Position): Promise<boolean> {
599
+ private async addImage(image: Image, position?: Position): Promise<boolean> {
423
600
  if (!image) {
424
601
  throw new ValidationException("Image cannot be null");
425
602
  }
@@ -438,7 +615,7 @@ export class ClientV1 {
438
615
  /**
439
616
  * Adds a paragraph to the PDF document.
440
617
  */
441
- async addParagraph(paragraph: Paragraph): Promise<boolean> {
618
+ private async addParagraph(paragraph: Paragraph): Promise<boolean> {
442
619
  if (!paragraph) {
443
620
  throw new ValidationException("Paragraph cannot be null");
444
621
  }
@@ -469,7 +646,7 @@ export class ClientV1 {
469
646
  /**
470
647
  * Modifies a paragraph object or its text content.
471
648
  */
472
- async modifyParagraph(objectRef: ObjectRef, newParagraph: Paragraph | string): Promise<boolean> {
649
+ private async modifyParagraph(objectRef: ObjectRef, newParagraph: Paragraph | string): Promise<boolean> {
473
650
  if (!objectRef) {
474
651
  throw new ValidationException("Object reference cannot be null");
475
652
  }
@@ -493,7 +670,7 @@ export class ClientV1 {
493
670
  /**
494
671
  * Modifies a text line object.
495
672
  */
496
- async modifyTextLine(objectRef: ObjectRef, newText: string): Promise<boolean> {
673
+ private async modifyTextLine(objectRef: ObjectRef, newText: string): Promise<boolean> {
497
674
  if (!objectRef) {
498
675
  throw new ValidationException("Object reference cannot be null");
499
676
  }
@@ -594,42 +771,18 @@ export class ClientV1 {
594
771
  return new Uint8Array(await response.arrayBuffer());
595
772
  }
596
773
 
597
- async getXmlFile(): Promise<String> {
598
- const response = await fetch(`${this._baseUrl}/xml`, {
599
- method: 'POST',
600
- headers: {
601
- 'Authorization': `Bearer ${this._token}`,
602
- 'X-Session-Id': this._sessionId
603
- },
604
- signal: AbortSignal.timeout(30000)
605
- });
606
- return response.text()
607
- }
608
-
609
774
  /**
610
775
  * Saves the current PDF to a file (browser environment).
611
776
  * Downloads the PDF in the browser.
612
777
  */
613
- async savePdf(filename: string = 'document.pdf'): Promise<void> {
778
+ async save(filename: string): Promise<void> {
614
779
  if (!filename) {
615
780
  throw new ValidationException("Filename cannot be null or empty");
616
781
  }
617
782
 
618
783
  try {
619
784
  const pdfData = await this.getPdfFile();
620
-
621
- // Create blob and download link
622
- const blob = new Blob([pdfData.buffer as ArrayBuffer], {type: 'application/pdf'});
623
- const url = URL.createObjectURL(blob);
624
-
625
- const link = document.createElement('a');
626
- link.href = url;
627
- link.download = filename;
628
- document.body.appendChild(link);
629
- link.click();
630
- document.body.removeChild(link);
631
-
632
- URL.revokeObjectURL(url);
785
+ fs.writeFileSync(filename, pdfData);
633
786
  } catch (error) {
634
787
  const errorMessage = error instanceof Error ? error.message : String(error);
635
788
  throw new PdfDancerException(`Failed to save PDF file: ${errorMessage}`, error as Error);
@@ -699,10 +852,52 @@ export class ClientV1 {
699
852
 
700
853
  // Builder Pattern Support
701
854
 
702
- /**
703
- * Creates a new ParagraphBuilder for fluent paragraph construction.
704
- */
705
- paragraphBuilder(): ParagraphBuilder {
706
- return new ParagraphBuilder(this);
855
+
856
+ private toPathObjects(objectRefs: ObjectRef[]) {
857
+ return objectRefs.map(ref => PathObject.fromRef(this, ref));
858
+ }
859
+
860
+ private toFormXObjects(objectRefs: ObjectRef[]) {
861
+ return objectRefs.map(ref => FormXObject.fromRef(this, ref));
862
+ }
863
+
864
+ private toImageObjects(objectRefs: ObjectRef[]) {
865
+ return objectRefs.map(ref => ImageObject.fromRef(this, ref));
866
+ }
867
+
868
+ newImage() {
869
+ return new ImageBuilder(this);
870
+ }
871
+
872
+ page(pageIndex: number) {
873
+ if (pageIndex < 0) {
874
+ throw new ValidationException(`Page index must be >= 0, got ${pageIndex}`);
875
+ }
876
+ return new PageClient(this, pageIndex);
877
+ }
878
+
879
+ async pages() {
880
+ let pageRefs = await this.getPages();
881
+ return pageRefs.map((_, pageIndex) => new PageClient(this, pageIndex));
882
+ }
883
+
884
+ private toFormFields(objectRefs: FormFieldRef[]) {
885
+ return objectRefs.map(ref => FormFieldObject.fromRef(this, ref));
886
+ }
887
+
888
+ async selectParagraphs() {
889
+ return this.toParagraphObjects(await this.findParagraphs());
890
+ }
891
+
892
+ private toParagraphObjects(objectRefs: ObjectRef[]) {
893
+ return objectRefs.map(ref => ParagraphObject.fromRef(this, ref));
894
+ }
895
+
896
+ private toTextLineObjects(objectRefs: ObjectRef[]) {
897
+ return objectRefs.map(ref => TextLineObject.fromRef(this, ref));
898
+ }
899
+
900
+ async selectLines() {
901
+ return this.toTextLineObjects(await this.findTextLines());
707
902
  }
708
903
  }
package/src/types.ts ADDED
@@ -0,0 +1,133 @@
1
+ import {FormFieldRef, ObjectRef, ObjectType, Position} from "./models";
2
+ import {PDFDancer} from "./pdfdancer_v1";
3
+ import {ParagraphBuilder} from "./paragraph-builder";
4
+
5
+ // 👇 Internal view of PDFDancer methods, not exported
6
+ interface PDFDancerInternals {
7
+ delete(objectRef: ObjectRef): Promise<boolean>;
8
+
9
+ move(objectRef: ObjectRef, position: Position): Promise<boolean>;
10
+
11
+ changeFormField(formFieldRef: FormFieldRef, value: string): Promise<boolean>;
12
+
13
+ modifyTextLine(objectRef: ObjectRef, newText: string): Promise<boolean>;
14
+ }
15
+
16
+ export class BaseObject<TRef extends ObjectRef = ObjectRef> {
17
+
18
+ _client: PDFDancer;
19
+
20
+ internalId: string;
21
+ type: ObjectType;
22
+ position: Position;
23
+ protected _internals: PDFDancerInternals;
24
+
25
+ constructor(client: PDFDancer, internalId: string, type: ObjectType, position: Position) {
26
+ this.internalId = internalId;
27
+ this.type = type;
28
+ this.position = position;
29
+ this._client = client;
30
+ this._internals = this._client as unknown as PDFDancerInternals;
31
+ }
32
+
33
+ async delete() {
34
+ return this._internals.delete(this.ref());
35
+ }
36
+
37
+ protected ref(): TRef {
38
+ return new ObjectRef(this.internalId, this.position, this.type) as TRef;
39
+ }
40
+
41
+ async moveTo(x: number, y: number) {
42
+ return this._internals.move(this.ref(), Position.atPageCoordinates(this.position.pageIndex!, x, y));
43
+ }
44
+ }
45
+
46
+ export class PathObject extends BaseObject {
47
+
48
+ static fromRef(_client: PDFDancer, objectRef: ObjectRef) {
49
+ return new PathObject(_client, objectRef.internalId, objectRef.type, objectRef.position);
50
+ }
51
+ }
52
+
53
+ export class ImageObject extends BaseObject {
54
+
55
+ static fromRef(_client: PDFDancer, objectRef: ObjectRef) {
56
+ return new ImageObject(_client, objectRef.internalId, objectRef.type, objectRef.position);
57
+ }
58
+ }
59
+
60
+ export class FormXObject extends BaseObject {
61
+
62
+ static fromRef(_client: PDFDancer, objectRef: ObjectRef) {
63
+ return new FormXObject(_client, objectRef.internalId, objectRef.type, objectRef.position);
64
+ }
65
+ }
66
+
67
+ export class FormFieldObject extends BaseObject<FormFieldRef> {
68
+ name: string;
69
+ value: string | null;
70
+
71
+ constructor(client: PDFDancer, internalId: string, type: ObjectType, position: Position, name: string, value: string | null) {
72
+ super(client, internalId, type, position);
73
+ this.name = name;
74
+ this.value = value;
75
+ }
76
+
77
+ async fill(value: string) {
78
+ return await this._internals.changeFormField(this.ref(), value);
79
+ }
80
+
81
+ protected ref() {
82
+ return new FormFieldRef(this.internalId, this.position, this.type, this.name, this.value);
83
+ }
84
+
85
+ static fromRef(_client: PDFDancer, objectRef: FormFieldRef) {
86
+ return new FormFieldObject(_client, objectRef.internalId, objectRef.type, objectRef.position, objectRef.name, objectRef.value);
87
+ }
88
+ }
89
+
90
+ export class ParagraphObject extends BaseObject {
91
+
92
+ static fromRef(_client: PDFDancer, objectRef: ObjectRef) {
93
+ return new ParagraphObject(_client, objectRef.internalId, objectRef.type, objectRef.position);
94
+ }
95
+
96
+ edit() {
97
+ return new ParagraphBuilder(this._client, this.ref());
98
+ }
99
+ }
100
+
101
+ export class TextLineObject extends BaseObject {
102
+ static fromRef(_client: PDFDancer, objectRef: ObjectRef) {
103
+ return new TextLineObject(_client, objectRef.internalId, objectRef.type, objectRef.position);
104
+ }
105
+
106
+ edit() {
107
+ return new TextLineBuilder(this._client, this.ref());
108
+ }
109
+ }
110
+
111
+
112
+ class TextLineBuilder {
113
+
114
+ private _text: string | undefined;
115
+ private _objectRef: ObjectRef;
116
+ private _client: PDFDancer
117
+ private _internals: PDFDancerInternals;
118
+
119
+ constructor(client: PDFDancer, objectRef: ObjectRef) {
120
+ this._objectRef = objectRef;
121
+ this._client = client;
122
+ this._internals = this._client as unknown as PDFDancerInternals;
123
+ }
124
+
125
+ text(newText: string) {
126
+ this._text = newText;
127
+ return this;
128
+ }
129
+
130
+ async apply() {
131
+ return await this._internals.modifyTextLine(this._objectRef, this._text!);
132
+ }
133
+ }
package/example.ts DELETED
@@ -1,99 +0,0 @@
1
- /**
2
- * Example usage of the PDFDancer TypeScript client
3
- */
4
-
5
- import {
6
- ClientV1,
7
- Position,
8
- Color,
9
- Font,
10
- ValidationException,
11
- HttpClientException
12
- } from './src/index';
13
-
14
- async function exampleUsage() {
15
- try {
16
- // Create a sample PDF data (in a real application, this would be loaded from a file)
17
- const pdfData = new Uint8Array([
18
- 0x25, 0x50, 0x44, 0x46, // %PDF header
19
- // ... rest of PDF data would go here
20
- ]);
21
-
22
- // Initialize the client with authentication token and PDF data
23
- const client = await ClientV1.create('your-auth-token', pdfData, 'http://localhost:8080', 30000);
24
-
25
- // Example 1: Find all paragraphs on page 1
26
- const page1Position = Position.atPage(1);
27
- const paragraphs = await client.findParagraphs(page1Position);
28
- console.log(`Found ${paragraphs.length} paragraphs on page 1`);
29
-
30
- // Example 2: Add a new paragraph using the builder pattern
31
- const newParagraph = client.paragraphBuilder()
32
- .fromString('Hello, PDFDancer!', new Color(255, 0, 0)) // Red text
33
- .withFont(new Font('Arial', 12))
34
- .withPosition(Position.atPageCoordinates(1, 100, 200))
35
- .withLineSpacing(1.5)
36
- .build();
37
-
38
- await client.addParagraph(newParagraph);
39
- console.log('Added new paragraph successfully');
40
-
41
- // Example 3: Find and modify existing text
42
- const textLines = await client.findTextLines(page1Position);
43
- if (textLines.length > 0) {
44
- await client.modifyTextLine(textLines[0], 'Modified text content');
45
- console.log('Modified first text line');
46
- }
47
-
48
- // Example 4: Get the modified PDF
49
- const modifiedPdf = await client.getPdfFile();
50
- console.log(`Generated PDF size: ${modifiedPdf.length} bytes`);
51
-
52
- // Example 5: Save PDF (in browser environment)
53
- // await client.savePdf('modified-document.pdf');
54
-
55
- } catch (error) {
56
- if (error instanceof ValidationException) {
57
- console.error('Validation error:', error.message);
58
- } else if (error instanceof HttpClientException) {
59
- console.error('HTTP error:', error.message, 'Status:', error.statusCode);
60
- } else {
61
- console.error('Unexpected error:', error);
62
- }
63
- }
64
- }
65
-
66
- // Example of using with custom font
67
- async function exampleWithCustomFont() {
68
- try {
69
- const pdfData = new Uint8Array([0x25, 0x50, 0x44, 0x46]);
70
- const client = await ClientV1.create('your-auth-token', pdfData, undefined, 30000);
71
-
72
- // Register a custom font (example with dummy TTF data)
73
- const customFontData = new Uint8Array([/* TTF font data here */]);
74
- const fontName = await client.registerFont(customFontData);
75
- console.log(`Registered font: ${fontName}`);
76
-
77
- // Use the custom font in a paragraph
78
- const paragraph = client.paragraphBuilder()
79
- .fromString('Text with custom font')
80
- .withFont(new Font(fontName, 14))
81
- .withPosition(Position.atPageCoordinates(1, 50, 300))
82
- .build();
83
-
84
- await client.addParagraph(paragraph);
85
- console.log('Added paragraph with custom font');
86
-
87
- } catch (error) {
88
- console.error('Error with custom font:', error);
89
- }
90
- }
91
-
92
- // Note: These examples show the API usage patterns.
93
- // In a real application, you would need:
94
- // 1. A valid authentication token
95
- // 2. Actual PDF data
96
- // 3. A running PDFDancer server at the specified URL
97
- // 4. Proper error handling for your use case
98
-
99
- export { exampleUsage, exampleWithCustomFont };