pdfdancer-client-typescript 1.0.21 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/env-loader.d.ts +6 -0
- package/dist/env-loader.d.ts.map +1 -0
- package/dist/env-loader.js +55 -0
- package/dist/env-loader.js.map +1 -0
- package/dist/image-builder.d.ts +3 -3
- package/dist/image-builder.d.ts.map +1 -1
- package/dist/image-builder.js +6 -6
- package/dist/image-builder.js.map +1 -1
- package/dist/models.d.ts +13 -12
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +24 -23
- package/dist/models.js.map +1 -1
- package/dist/page-builder.d.ts +14 -2
- package/dist/page-builder.d.ts.map +1 -1
- package/dist/page-builder.js +23 -8
- package/dist/page-builder.js.map +1 -1
- package/dist/paragraph-builder.d.ts +3 -3
- package/dist/paragraph-builder.d.ts.map +1 -1
- package/dist/paragraph-builder.js +25 -25
- package/dist/paragraph-builder.js.map +1 -1
- package/dist/path-builder.d.ts +4 -4
- package/dist/path-builder.d.ts.map +1 -1
- package/dist/path-builder.js +6 -6
- package/dist/path-builder.js.map +1 -1
- package/dist/pdfdancer_v1.d.ts +47 -19
- package/dist/pdfdancer_v1.d.ts.map +1 -1
- package/dist/pdfdancer_v1.js +138 -103
- package/dist/pdfdancer_v1.js.map +1 -1
- package/dist/types.js +5 -5
- package/dist/types.js.map +1 -1
- package/package.json +4 -2
package/dist/pdfdancer_v1.js
CHANGED
|
@@ -13,6 +13,7 @@ const exceptions_1 = require("./exceptions");
|
|
|
13
13
|
const models_1 = require("./models");
|
|
14
14
|
const paragraph_builder_1 = require("./paragraph-builder");
|
|
15
15
|
const page_builder_1 = require("./page-builder");
|
|
16
|
+
const env_loader_1 = require("./env-loader");
|
|
16
17
|
const types_1 = require("./types");
|
|
17
18
|
const image_builder_1 = require("./image-builder");
|
|
18
19
|
const path_builder_1 = require("./path-builder");
|
|
@@ -165,35 +166,35 @@ function generateTimestamp() {
|
|
|
165
166
|
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${microseconds}Z`;
|
|
166
167
|
}
|
|
167
168
|
class PageClient {
|
|
168
|
-
constructor(client,
|
|
169
|
+
constructor(client, pageNumber, pageRef) {
|
|
169
170
|
this.type = models_1.ObjectType.PAGE;
|
|
170
171
|
this._client = client;
|
|
171
|
-
this.
|
|
172
|
-
this.internalId = pageRef?.internalId ?? `PAGE-${this.
|
|
173
|
-
this.position = pageRef?.position ?? models_1.Position.atPage(this.
|
|
172
|
+
this._pageNumber = pageNumber;
|
|
173
|
+
this.internalId = pageRef?.internalId ?? `PAGE-${this._pageNumber}`;
|
|
174
|
+
this.position = pageRef?.position ?? models_1.Position.atPage(this._pageNumber);
|
|
174
175
|
this.pageSize = pageRef?.pageSize;
|
|
175
176
|
this.orientation = pageRef?.orientation;
|
|
176
177
|
// Cast to the internal interface to get access
|
|
177
178
|
this._internals = this._client;
|
|
178
179
|
}
|
|
179
180
|
async selectPathsAt(x, y, tolerance = 0) {
|
|
180
|
-
return this._internals.toPathObjects(await this._internals.findPaths(models_1.Position.atPageCoordinates(this.
|
|
181
|
+
return this._internals.toPathObjects(await this._internals.findPaths(models_1.Position.atPageCoordinates(this._pageNumber, x, y, tolerance)));
|
|
181
182
|
}
|
|
182
183
|
async selectPaths() {
|
|
183
|
-
return this._internals.toPathObjects(await this._internals.findPaths(models_1.Position.atPage(this.
|
|
184
|
+
return this._internals.toPathObjects(await this._internals.findPaths(models_1.Position.atPage(this._pageNumber)));
|
|
184
185
|
}
|
|
185
186
|
async selectImages() {
|
|
186
|
-
return this._internals.toImageObjects(await this._internals._findImages(models_1.Position.atPage(this.
|
|
187
|
+
return this._internals.toImageObjects(await this._internals._findImages(models_1.Position.atPage(this._pageNumber)));
|
|
187
188
|
}
|
|
188
189
|
async selectImagesAt(x, y, tolerance = 0) {
|
|
189
|
-
return this._internals.toImageObjects(await this._internals._findImages(models_1.Position.atPageCoordinates(this.
|
|
190
|
+
return this._internals.toImageObjects(await this._internals._findImages(models_1.Position.atPageCoordinates(this._pageNumber, x, y, tolerance)));
|
|
190
191
|
}
|
|
191
192
|
async delete() {
|
|
192
|
-
return this._client.deletePage(this.
|
|
193
|
+
return this._client.deletePage(this._pageNumber);
|
|
193
194
|
}
|
|
194
|
-
async moveTo(
|
|
195
|
-
const pageRef = await this._client.movePage(this.
|
|
196
|
-
this.
|
|
195
|
+
async moveTo(targetPageNumber) {
|
|
196
|
+
const pageRef = await this._client.movePage(this._pageNumber, targetPageNumber);
|
|
197
|
+
this._pageNumber = pageRef.position.pageNumber !== undefined ? pageRef.position.pageNumber + 1 : targetPageNumber;
|
|
197
198
|
this.position = pageRef.position;
|
|
198
199
|
this.internalId = pageRef.internalId;
|
|
199
200
|
this.pageSize = pageRef.pageSize;
|
|
@@ -202,82 +203,82 @@ class PageClient {
|
|
|
202
203
|
}
|
|
203
204
|
// noinspection JSUnusedGlobalSymbols
|
|
204
205
|
async selectForms() {
|
|
205
|
-
return this._internals.toFormXObjects(await this._internals.findFormXObjects(models_1.Position.atPage(this.
|
|
206
|
+
return this._internals.toFormXObjects(await this._internals.findFormXObjects(models_1.Position.atPage(this._pageNumber)));
|
|
206
207
|
}
|
|
207
208
|
async selectFormsAt(x, y, tolerance = 0) {
|
|
208
|
-
return this._internals.toFormXObjects(await this._internals.findFormXObjects(models_1.Position.atPageCoordinates(this.
|
|
209
|
+
return this._internals.toFormXObjects(await this._internals.findFormXObjects(models_1.Position.atPageCoordinates(this._pageNumber, x, y, tolerance)));
|
|
209
210
|
}
|
|
210
211
|
async selectFormFields() {
|
|
211
|
-
return this._internals.toFormFields(await this._internals.findFormFields(models_1.Position.atPage(this.
|
|
212
|
+
return this._internals.toFormFields(await this._internals.findFormFields(models_1.Position.atPage(this._pageNumber)));
|
|
212
213
|
}
|
|
213
214
|
async selectFormFieldsAt(x, y, tolerance = 0) {
|
|
214
|
-
return this._internals.toFormFields(await this._internals.findFormFields(models_1.Position.atPageCoordinates(this.
|
|
215
|
+
return this._internals.toFormFields(await this._internals.findFormFields(models_1.Position.atPageCoordinates(this._pageNumber, x, y, tolerance)));
|
|
215
216
|
}
|
|
216
217
|
// noinspection JSUnusedGlobalSymbols
|
|
217
218
|
async selectFormFieldsByName(fieldName) {
|
|
218
|
-
let pos = models_1.Position.atPage(this.
|
|
219
|
+
let pos = models_1.Position.atPage(this._pageNumber);
|
|
219
220
|
pos.name = fieldName;
|
|
220
221
|
return this._internals.toFormFields(await this._internals.findFormFields(pos));
|
|
221
222
|
}
|
|
222
223
|
async selectParagraphs() {
|
|
223
|
-
return this._internals.toParagraphObjects(await this._internals.findParagraphs(models_1.Position.atPage(this.
|
|
224
|
+
return this._internals.toParagraphObjects(await this._internals.findParagraphs(models_1.Position.atPage(this._pageNumber)));
|
|
224
225
|
}
|
|
225
226
|
async selectElements(types) {
|
|
226
|
-
const snapshot = await this._client.getPageSnapshot(this.
|
|
227
|
+
const snapshot = await this._client.getPageSnapshot(this._pageNumber, types);
|
|
227
228
|
return snapshot.elements;
|
|
228
229
|
}
|
|
229
230
|
async selectParagraphsStartingWith(text) {
|
|
230
|
-
let pos = models_1.Position.atPage(this.
|
|
231
|
+
let pos = models_1.Position.atPage(this._pageNumber);
|
|
231
232
|
pos.textStartsWith = text;
|
|
232
233
|
return this._internals.toParagraphObjects(await this._internals.findParagraphs(pos));
|
|
233
234
|
}
|
|
234
235
|
async selectParagraphsMatching(pattern) {
|
|
235
|
-
let pos = models_1.Position.atPage(this.
|
|
236
|
+
let pos = models_1.Position.atPage(this._pageNumber);
|
|
236
237
|
pos.textPattern = pattern;
|
|
237
238
|
return this._internals.toParagraphObjects(await this._internals.findParagraphs(pos));
|
|
238
239
|
}
|
|
239
240
|
async selectParagraphsAt(x, y, tolerance = DEFAULT_TOLERANCE) {
|
|
240
|
-
return this._internals.toParagraphObjects(await this._internals.findParagraphs(models_1.Position.atPageCoordinates(this.
|
|
241
|
+
return this._internals.toParagraphObjects(await this._internals.findParagraphs(models_1.Position.atPageCoordinates(this._pageNumber, x, y, tolerance)));
|
|
241
242
|
}
|
|
242
243
|
async selectTextLinesStartingWith(text) {
|
|
243
|
-
let pos = models_1.Position.atPage(this.
|
|
244
|
+
let pos = models_1.Position.atPage(this._pageNumber);
|
|
244
245
|
pos.textStartsWith = text;
|
|
245
246
|
return this._internals.toTextLineObjects(await this._internals.findTextLines(pos));
|
|
246
247
|
}
|
|
247
248
|
/**
|
|
248
249
|
* Creates a new ParagraphBuilder for fluent paragraph construction.
|
|
249
250
|
*/
|
|
250
|
-
newParagraph(
|
|
251
|
-
const targetIndex =
|
|
251
|
+
newParagraph(pageNumber) {
|
|
252
|
+
const targetIndex = pageNumber ?? this.position.pageNumber;
|
|
252
253
|
return new paragraph_builder_1.ParagraphBuilder(this._client, targetIndex);
|
|
253
254
|
}
|
|
254
|
-
newImage(
|
|
255
|
-
const targetIndex =
|
|
255
|
+
newImage(pageNumber) {
|
|
256
|
+
const targetIndex = pageNumber ?? this.position.pageNumber;
|
|
256
257
|
return new image_builder_1.ImageBuilder(this._client, targetIndex);
|
|
257
258
|
}
|
|
258
|
-
newPath(
|
|
259
|
-
const targetIndex =
|
|
259
|
+
newPath(pageNumber) {
|
|
260
|
+
const targetIndex = pageNumber ?? this.position.pageNumber;
|
|
260
261
|
return new path_builder_1.PathBuilder(this._client, targetIndex);
|
|
261
262
|
}
|
|
262
263
|
async selectTextLines() {
|
|
263
|
-
return this._internals.toTextLineObjects(await this._internals.findTextLines(models_1.Position.atPage(this.
|
|
264
|
+
return this._internals.toTextLineObjects(await this._internals.findTextLines(models_1.Position.atPage(this._pageNumber)));
|
|
264
265
|
}
|
|
265
266
|
// noinspection JSUnusedGlobalSymbols
|
|
266
267
|
async selectTextLinesMatching(pattern) {
|
|
267
|
-
let pos = models_1.Position.atPage(this.
|
|
268
|
+
let pos = models_1.Position.atPage(this._pageNumber);
|
|
268
269
|
pos.textPattern = pattern;
|
|
269
270
|
return this._internals.toTextLineObjects(await this._internals.findTextLines(pos));
|
|
270
271
|
}
|
|
271
272
|
// noinspection JSUnusedGlobalSymbols
|
|
272
273
|
async selectTextLinesAt(x, y, tolerance = DEFAULT_TOLERANCE) {
|
|
273
|
-
return this._internals.toTextLineObjects(await this._internals.findTextLines(models_1.Position.atPageCoordinates(this.
|
|
274
|
+
return this._internals.toTextLineObjects(await this._internals.findTextLines(models_1.Position.atPageCoordinates(this._pageNumber, x, y, tolerance)));
|
|
274
275
|
}
|
|
275
276
|
/**
|
|
276
277
|
* Gets a snapshot of this page, including all elements.
|
|
277
278
|
* Optionally filter by object types.
|
|
278
279
|
*/
|
|
279
280
|
async getSnapshot(types) {
|
|
280
|
-
return this._client.getPageSnapshot(this.
|
|
281
|
+
return this._client.getPageSnapshot(this._pageNumber, types);
|
|
281
282
|
}
|
|
282
283
|
// Singular convenience methods - return the first element or null
|
|
283
284
|
async selectPath() {
|
|
@@ -405,7 +406,18 @@ class PDFDancer {
|
|
|
405
406
|
this._sessionId = await this._createSession();
|
|
406
407
|
return this;
|
|
407
408
|
}
|
|
409
|
+
/**
|
|
410
|
+
* Opens a PDF document for manipulation.
|
|
411
|
+
*
|
|
412
|
+
* @param pdfData PDF data as Uint8Array (raw bytes) or string (filepath)
|
|
413
|
+
* @param token Authentication token (optional, can use PDFDANCER_TOKEN env var)
|
|
414
|
+
* @param baseUrl Base URL for the PDFDancer API (optional)
|
|
415
|
+
* @param timeout Request timeout in milliseconds (default: 60000)
|
|
416
|
+
* @param retryConfig Retry configuration (optional, uses defaults if not specified)
|
|
417
|
+
* @returns A PDFDancer client instance
|
|
418
|
+
*/
|
|
408
419
|
static async open(pdfData, token, baseUrl, timeout, retryConfig) {
|
|
420
|
+
(0, env_loader_1.loadEnv)();
|
|
409
421
|
const resolvedBaseUrl = baseUrl ??
|
|
410
422
|
process.env.PDFDANCER_BASE_URL ??
|
|
411
423
|
"https://api.pdfdancer.com";
|
|
@@ -430,6 +442,7 @@ class PDFDancer {
|
|
|
430
442
|
* @param retryConfig Retry configuration (optional, uses defaults if not specified)
|
|
431
443
|
*/
|
|
432
444
|
static async new(options, token, baseUrl, timeout, retryConfig) {
|
|
445
|
+
(0, env_loader_1.loadEnv)();
|
|
433
446
|
const resolvedBaseUrl = baseUrl ??
|
|
434
447
|
process.env.PDFDANCER_BASE_URL ??
|
|
435
448
|
"https://api.pdfdancer.com";
|
|
@@ -539,7 +552,7 @@ class PDFDancer {
|
|
|
539
552
|
throw new exceptions_1.ValidationException("PDF data cannot be null");
|
|
540
553
|
}
|
|
541
554
|
try {
|
|
542
|
-
if (pdfData && pdfData.constructor === Uint8Array) {
|
|
555
|
+
if (pdfData && (pdfData.constructor === Uint8Array || Buffer.isBuffer(pdfData))) {
|
|
543
556
|
if (pdfData.length === 0) {
|
|
544
557
|
throw new exceptions_1.ValidationException("PDF data cannot be empty");
|
|
545
558
|
}
|
|
@@ -557,6 +570,7 @@ class PDFDancer {
|
|
|
557
570
|
return new Uint8Array(); // Placeholder, will be replaced in _createSession
|
|
558
571
|
}
|
|
559
572
|
else if (typeof pdfData === 'string') {
|
|
573
|
+
// TODO why is this different to `instanceof File`?
|
|
560
574
|
// Handle string as filepath
|
|
561
575
|
if (!fs_1.default.existsSync(pdfData)) {
|
|
562
576
|
throw new exceptions_1.ValidationException(`PDF file not found: ${pdfData}`);
|
|
@@ -711,7 +725,8 @@ class PDFDancer {
|
|
|
711
725
|
'X-Session-Id': this._sessionId,
|
|
712
726
|
'Content-Type': 'application/json',
|
|
713
727
|
'X-Generated-At': generateTimestamp(),
|
|
714
|
-
'X-Fingerprint': fingerprint
|
|
728
|
+
'X-Fingerprint': fingerprint,
|
|
729
|
+
'X-API-VERSION': '1'
|
|
715
730
|
};
|
|
716
731
|
try {
|
|
717
732
|
const response = await this._fetchWithRetry(url.toString(), {
|
|
@@ -771,9 +786,9 @@ class PDFDancer {
|
|
|
771
786
|
}
|
|
772
787
|
// Use snapshot-based search
|
|
773
788
|
let elements;
|
|
774
|
-
if (position?.
|
|
789
|
+
if (position?.pageNumber !== undefined) {
|
|
775
790
|
// Page-specific query - use page snapshot
|
|
776
|
-
const pageSnapshot = await this._getOrFetchPageSnapshot(position.
|
|
791
|
+
const pageSnapshot = await this._getOrFetchPageSnapshot(position.pageNumber);
|
|
777
792
|
elements = pageSnapshot.elements;
|
|
778
793
|
}
|
|
779
794
|
else {
|
|
@@ -842,9 +857,9 @@ class PDFDancer {
|
|
|
842
857
|
async findFormFields(position) {
|
|
843
858
|
// Use snapshot-based search
|
|
844
859
|
let elements;
|
|
845
|
-
if (position?.
|
|
860
|
+
if (position?.pageNumber !== undefined) {
|
|
846
861
|
// Page-specific query - use page snapshot
|
|
847
|
-
const pageSnapshot = await this._getOrFetchPageSnapshot(position.
|
|
862
|
+
const pageSnapshot = await this._getOrFetchPageSnapshot(position.pageNumber);
|
|
848
863
|
elements = pageSnapshot.elements;
|
|
849
864
|
}
|
|
850
865
|
else {
|
|
@@ -887,68 +902,76 @@ class PDFDancer {
|
|
|
887
902
|
* Retrieves a reference to a specific page by its page index.
|
|
888
903
|
* Now uses snapshot caching to avoid HTTP requests.
|
|
889
904
|
*/
|
|
890
|
-
async _getPage(
|
|
891
|
-
if (
|
|
892
|
-
throw new exceptions_1.ValidationException(`Page index must be >= 0, got ${
|
|
905
|
+
async _getPage(pageNumber) {
|
|
906
|
+
if (pageNumber < 0) {
|
|
907
|
+
throw new exceptions_1.ValidationException(`Page index must be >= 0, got ${pageNumber}`);
|
|
893
908
|
}
|
|
894
909
|
// Try page snapshot cache first
|
|
895
|
-
if (this._pageSnapshotCache.has(
|
|
896
|
-
return this._pageSnapshotCache.get(
|
|
910
|
+
if (this._pageSnapshotCache.has(pageNumber)) {
|
|
911
|
+
return this._pageSnapshotCache.get(pageNumber).pageRef;
|
|
897
912
|
}
|
|
898
913
|
// Try document snapshot cache
|
|
899
914
|
if (this._documentSnapshotCache) {
|
|
900
|
-
const pageSnapshot = this._documentSnapshotCache.getPageSnapshot(
|
|
915
|
+
const pageSnapshot = this._documentSnapshotCache.getPageSnapshot(pageNumber);
|
|
901
916
|
if (pageSnapshot) {
|
|
902
917
|
return pageSnapshot.pageRef;
|
|
903
918
|
}
|
|
904
919
|
}
|
|
905
920
|
// Fetch document snapshot to get page (this will cache it)
|
|
906
921
|
const docSnapshot = await this._getOrFetchDocumentSnapshot();
|
|
907
|
-
const pageSnapshot = docSnapshot.getPageSnapshot(
|
|
922
|
+
const pageSnapshot = docSnapshot.getPageSnapshot(pageNumber);
|
|
908
923
|
return pageSnapshot?.pageRef ?? null;
|
|
909
924
|
}
|
|
910
925
|
/**
|
|
911
|
-
* Moves an existing page to a new
|
|
926
|
+
* Moves an existing page to a new position.
|
|
927
|
+
*
|
|
928
|
+
* @param fromPage - The source page number (1-based, page 1 is first page)
|
|
929
|
+
* @param toPage - The target page number (1-based)
|
|
930
|
+
* @returns The page reference at the new position
|
|
931
|
+
* @throws ValidationException if fromPage or toPage is less than 1
|
|
912
932
|
*/
|
|
913
|
-
async movePage(
|
|
914
|
-
this.
|
|
915
|
-
this.
|
|
933
|
+
async movePage(fromPage, toPage) {
|
|
934
|
+
this._validatePageNumber(fromPage, 'fromPage');
|
|
935
|
+
this._validatePageNumber(toPage, 'toPage');
|
|
916
936
|
// Ensure the source page exists before attempting the move
|
|
917
|
-
await this._requirePageRef(
|
|
918
|
-
const request = new models_1.MovePageRequest(
|
|
937
|
+
await this._requirePageRef(fromPage);
|
|
938
|
+
const request = new models_1.MovePageRequest(fromPage, toPage).toDict();
|
|
919
939
|
const response = await this._makeRequest('PUT', '/pdf/page/move', request);
|
|
920
940
|
const success = await response.json();
|
|
921
941
|
if (!success) {
|
|
922
|
-
throw new exceptions_1.HttpClientException(`Failed to move page from ${
|
|
942
|
+
throw new exceptions_1.HttpClientException(`Failed to move page from ${fromPage} to ${toPage}`, response);
|
|
923
943
|
}
|
|
924
944
|
// Invalidate cache after mutation
|
|
925
945
|
this._invalidateCache();
|
|
926
946
|
// Fetch the page again at its new position for up-to-date metadata
|
|
927
|
-
return await this._requirePageRef(
|
|
947
|
+
return await this._requirePageRef(toPage);
|
|
928
948
|
}
|
|
929
949
|
/**
|
|
930
|
-
* Deletes the page at the specified
|
|
950
|
+
* Deletes the page at the specified page number.
|
|
951
|
+
*
|
|
952
|
+
* @param pageNumber - The page number to delete (1-based, page 1 is first page)
|
|
953
|
+
* @throws ValidationException if pageNumber is less than 1
|
|
931
954
|
*/
|
|
932
|
-
async deletePage(
|
|
933
|
-
this.
|
|
934
|
-
const pageRef = await this._requirePageRef(
|
|
955
|
+
async deletePage(pageNumber) {
|
|
956
|
+
this._validatePageNumber(pageNumber, 'pageNumber');
|
|
957
|
+
const pageRef = await this._requirePageRef(pageNumber);
|
|
935
958
|
const result = await this._deletePage(pageRef);
|
|
936
959
|
// Invalidate cache after mutation
|
|
937
960
|
this._invalidateCache();
|
|
938
961
|
return result;
|
|
939
962
|
}
|
|
940
|
-
|
|
941
|
-
if (!Number.isInteger(
|
|
942
|
-
throw new exceptions_1.ValidationException(`${fieldName} must be an integer, got ${
|
|
963
|
+
_validatePageNumber(pageNumber, fieldName) {
|
|
964
|
+
if (!Number.isInteger(pageNumber)) {
|
|
965
|
+
throw new exceptions_1.ValidationException(`${fieldName} must be an integer, got ${pageNumber}`);
|
|
943
966
|
}
|
|
944
|
-
if (
|
|
945
|
-
throw new exceptions_1.ValidationException(`${fieldName} must be >=
|
|
967
|
+
if (pageNumber < 1) {
|
|
968
|
+
throw new exceptions_1.ValidationException(`${fieldName} must be >= 1 (1-based indexing), got ${pageNumber}`);
|
|
946
969
|
}
|
|
947
970
|
}
|
|
948
|
-
async _requirePageRef(
|
|
949
|
-
const pageRef = await this._getPage(
|
|
971
|
+
async _requirePageRef(pageNumber) {
|
|
972
|
+
const pageRef = await this._getPage(pageNumber);
|
|
950
973
|
if (!pageRef) {
|
|
951
|
-
throw new exceptions_1.ValidationException(`Page not found at
|
|
974
|
+
throw new exceptions_1.ValidationException(`Page not found at page number ${pageNumber}`);
|
|
952
975
|
}
|
|
953
976
|
return pageRef;
|
|
954
977
|
}
|
|
@@ -984,17 +1007,18 @@ class PDFDancer {
|
|
|
984
1007
|
* Gets a snapshot of a specific page.
|
|
985
1008
|
* Returns the page reference and all elements on that page.
|
|
986
1009
|
*
|
|
987
|
-
* @param
|
|
988
|
-
* @param types Optional array of ObjectType to filter elements by type
|
|
1010
|
+
* @param pageNumber - The page number to retrieve (1-based, page 1 is first page)
|
|
1011
|
+
* @param types - Optional array of ObjectType to filter elements by type
|
|
989
1012
|
* @returns PageSnapshot containing page information and elements
|
|
1013
|
+
* @throws ValidationException if pageNumber is less than 1
|
|
990
1014
|
*/
|
|
991
|
-
async getPageSnapshot(
|
|
992
|
-
this.
|
|
1015
|
+
async getPageSnapshot(pageNumber, types) {
|
|
1016
|
+
this._validatePageNumber(pageNumber, 'pageNumber');
|
|
993
1017
|
const params = {};
|
|
994
1018
|
if (types && types.length > 0) {
|
|
995
1019
|
params.types = types.join(',');
|
|
996
1020
|
}
|
|
997
|
-
const response = await this._makeRequest('GET', `/pdf/page/${
|
|
1021
|
+
const response = await this._makeRequest('GET', `/pdf/page/${pageNumber}/snapshot`, undefined, params);
|
|
998
1022
|
const data = await response.json();
|
|
999
1023
|
return this._parsePageSnapshot(data);
|
|
1000
1024
|
}
|
|
@@ -1002,24 +1026,27 @@ class PDFDancer {
|
|
|
1002
1026
|
/**
|
|
1003
1027
|
* Gets a page snapshot from cache or fetches it.
|
|
1004
1028
|
* First checks page cache, then document cache, then fetches from server.
|
|
1029
|
+
*
|
|
1030
|
+
* @param pageNumber - 1-based page number
|
|
1005
1031
|
*/
|
|
1006
|
-
async _getOrFetchPageSnapshot(
|
|
1032
|
+
async _getOrFetchPageSnapshot(pageNumber) {
|
|
1007
1033
|
// Check page cache first
|
|
1008
|
-
if (this._pageSnapshotCache.has(
|
|
1009
|
-
return this._pageSnapshotCache.get(
|
|
1034
|
+
if (this._pageSnapshotCache.has(pageNumber)) {
|
|
1035
|
+
return this._pageSnapshotCache.get(pageNumber);
|
|
1010
1036
|
}
|
|
1011
1037
|
// Check if we have document snapshot and can extract the page
|
|
1038
|
+
// Convert 1-based page number to 0-based index for array access
|
|
1012
1039
|
if (this._documentSnapshotCache) {
|
|
1013
|
-
const pageSnapshot = this._documentSnapshotCache.getPageSnapshot(
|
|
1040
|
+
const pageSnapshot = this._documentSnapshotCache.getPageSnapshot(pageNumber);
|
|
1014
1041
|
if (pageSnapshot) {
|
|
1015
1042
|
// Cache it for future use
|
|
1016
|
-
this._pageSnapshotCache.set(
|
|
1043
|
+
this._pageSnapshotCache.set(pageNumber, pageSnapshot);
|
|
1017
1044
|
return pageSnapshot;
|
|
1018
1045
|
}
|
|
1019
1046
|
}
|
|
1020
1047
|
// Fetch page snapshot from server
|
|
1021
|
-
const pageSnapshot = await this.getPageSnapshot(
|
|
1022
|
-
this._pageSnapshotCache.set(
|
|
1048
|
+
const pageSnapshot = await this.getPageSnapshot(pageNumber);
|
|
1049
|
+
this._pageSnapshotCache.set(pageNumber, pageSnapshot);
|
|
1023
1050
|
return pageSnapshot;
|
|
1024
1051
|
}
|
|
1025
1052
|
/**
|
|
@@ -1050,8 +1077,8 @@ class PDFDancer {
|
|
|
1050
1077
|
}
|
|
1051
1078
|
let filtered = elements;
|
|
1052
1079
|
// Filter by page index
|
|
1053
|
-
if (position.
|
|
1054
|
-
filtered = filtered.filter(el => el.position.
|
|
1080
|
+
if (position.pageNumber !== undefined) {
|
|
1081
|
+
filtered = filtered.filter(el => el.position.pageNumber === position.pageNumber);
|
|
1055
1082
|
}
|
|
1056
1083
|
// Filter by coordinates (point containment with tolerance)
|
|
1057
1084
|
if (position.boundingRect && position.shape === models_1.ShapeType.POINT) {
|
|
@@ -1193,11 +1220,11 @@ class PDFDancer {
|
|
|
1193
1220
|
if (!paragraph.getPosition()) {
|
|
1194
1221
|
throw new exceptions_1.ValidationException("Paragraph position is null, you need to specify a position for the new paragraph, using .at(x,y)");
|
|
1195
1222
|
}
|
|
1196
|
-
if (paragraph.getPosition().
|
|
1197
|
-
throw new exceptions_1.ValidationException("Paragraph position page
|
|
1223
|
+
if (paragraph.getPosition().pageNumber === undefined) {
|
|
1224
|
+
throw new exceptions_1.ValidationException("Paragraph position page number is null");
|
|
1198
1225
|
}
|
|
1199
|
-
if (paragraph.getPosition().
|
|
1200
|
-
throw new exceptions_1.ValidationException("Paragraph position page
|
|
1226
|
+
if (paragraph.getPosition().pageNumber < 1) {
|
|
1227
|
+
throw new exceptions_1.ValidationException("Paragraph position page number is less than 1");
|
|
1201
1228
|
}
|
|
1202
1229
|
return this._addObject(paragraph);
|
|
1203
1230
|
}
|
|
@@ -1211,11 +1238,11 @@ class PDFDancer {
|
|
|
1211
1238
|
if (!path.getPosition()) {
|
|
1212
1239
|
throw new exceptions_1.ValidationException("Path position is null, you need to specify a position for the new path, using .at(x,y)");
|
|
1213
1240
|
}
|
|
1214
|
-
if (path.getPosition().
|
|
1215
|
-
throw new exceptions_1.ValidationException("Path position page
|
|
1241
|
+
if (path.getPosition().pageNumber === undefined) {
|
|
1242
|
+
throw new exceptions_1.ValidationException("Path position page number is null");
|
|
1216
1243
|
}
|
|
1217
|
-
if (path.getPosition().
|
|
1218
|
-
throw new exceptions_1.ValidationException("Path position page
|
|
1244
|
+
if (path.getPosition().pageNumber < 1) {
|
|
1245
|
+
throw new exceptions_1.ValidationException("Path position page number is less than 1");
|
|
1219
1246
|
}
|
|
1220
1247
|
return await this._addObject(path);
|
|
1221
1248
|
}
|
|
@@ -1530,7 +1557,7 @@ class PDFDancer {
|
|
|
1530
1557
|
*/
|
|
1531
1558
|
_parsePosition(posData) {
|
|
1532
1559
|
const position = new models_1.Position();
|
|
1533
|
-
position.
|
|
1560
|
+
position.pageNumber = posData.pageNumber;
|
|
1534
1561
|
position.textStartsWith = posData.textStartsWith;
|
|
1535
1562
|
if (posData.shape) {
|
|
1536
1563
|
position.shape = models_1.ShapeType[posData.shape];
|
|
@@ -1584,9 +1611,9 @@ class PDFDancer {
|
|
|
1584
1611
|
if (Array.isArray(data.elements)) {
|
|
1585
1612
|
for (const elementData of data.elements) {
|
|
1586
1613
|
const element = this._parseObjectRef(elementData);
|
|
1587
|
-
// If the element's position doesn't have a
|
|
1588
|
-
if (element.position && element.position.
|
|
1589
|
-
element.position.
|
|
1614
|
+
// If the element's position doesn't have a pageNumber, inherit it from the page
|
|
1615
|
+
if (element.position && element.position.pageNumber === undefined) {
|
|
1616
|
+
element.position.pageNumber = pageRef.position.pageNumber;
|
|
1590
1617
|
}
|
|
1591
1618
|
elements.push(element);
|
|
1592
1619
|
}
|
|
@@ -1603,27 +1630,35 @@ class PDFDancer {
|
|
|
1603
1630
|
toImageObjects(objectRefs) {
|
|
1604
1631
|
return objectRefs.map(ref => types_1.ImageObject.fromRef(this, ref));
|
|
1605
1632
|
}
|
|
1606
|
-
newImage(
|
|
1607
|
-
return new image_builder_1.ImageBuilder(this,
|
|
1633
|
+
newImage(pageNumber) {
|
|
1634
|
+
return new image_builder_1.ImageBuilder(this, pageNumber);
|
|
1608
1635
|
}
|
|
1609
|
-
newParagraph(
|
|
1610
|
-
return new paragraph_builder_1.ParagraphBuilder(this,
|
|
1636
|
+
newParagraph(pageNumber) {
|
|
1637
|
+
return new paragraph_builder_1.ParagraphBuilder(this, pageNumber);
|
|
1611
1638
|
}
|
|
1612
|
-
newPath(
|
|
1613
|
-
return new path_builder_1.PathBuilder(this,
|
|
1639
|
+
newPath(pageNumber) {
|
|
1640
|
+
return new path_builder_1.PathBuilder(this, pageNumber);
|
|
1614
1641
|
}
|
|
1615
1642
|
newPage() {
|
|
1616
1643
|
return new page_builder_1.PageBuilder(this);
|
|
1617
1644
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1645
|
+
/**
|
|
1646
|
+
* Creates a client for working with a specific page.
|
|
1647
|
+
*
|
|
1648
|
+
* @param pageNumber - The page number (1-based, page 1 is first page)
|
|
1649
|
+
* @returns A PageClient for the specified page
|
|
1650
|
+
* @throws ValidationException if pageNumber is less than 1
|
|
1651
|
+
*/
|
|
1652
|
+
page(pageNumber) {
|
|
1653
|
+
if (pageNumber < 1) {
|
|
1654
|
+
throw new exceptions_1.ValidationException(`Page number must be >= 1 (1-based indexing), got ${pageNumber}`);
|
|
1621
1655
|
}
|
|
1622
|
-
return new PageClient(this,
|
|
1656
|
+
return new PageClient(this, pageNumber);
|
|
1623
1657
|
}
|
|
1624
1658
|
async pages() {
|
|
1625
1659
|
const pageRefs = await this.getPages();
|
|
1626
|
-
|
|
1660
|
+
// Page numbers are 1-based
|
|
1661
|
+
return pageRefs.map((pageRef, index) => new PageClient(this, index + 1, pageRef));
|
|
1627
1662
|
}
|
|
1628
1663
|
toFormFields(objectRefs) {
|
|
1629
1664
|
return objectRefs.map(ref => types_1.FormFieldObject.fromRef(this, ref));
|