pdfdancer-client-typescript 1.0.22 → 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.
@@ -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, pageIndex, pageRef) {
169
+ constructor(client, pageNumber, pageRef) {
169
170
  this.type = models_1.ObjectType.PAGE;
170
171
  this._client = client;
171
- this._pageIndex = pageIndex;
172
- this.internalId = pageRef?.internalId ?? `PAGE-${this._pageIndex}`;
173
- this.position = pageRef?.position ?? models_1.Position.atPage(this._pageIndex);
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._pageIndex, x, y, tolerance)));
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._pageIndex)));
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._pageIndex)));
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._pageIndex, x, y, tolerance)));
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._pageIndex);
193
+ return this._client.deletePage(this._pageNumber);
193
194
  }
194
- async moveTo(targetPageIndex) {
195
- const pageRef = await this._client.movePage(this._pageIndex, targetPageIndex);
196
- this._pageIndex = pageRef.position.pageIndex ?? targetPageIndex;
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._pageIndex)));
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._pageIndex, x, y, tolerance)));
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._pageIndex)));
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._pageIndex, x, y, tolerance)));
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._pageIndex);
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._pageIndex)));
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._pageIndex, types);
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._pageIndex);
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._pageIndex);
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._pageIndex, x, y, tolerance)));
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._pageIndex);
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(pageIndex) {
251
- const targetIndex = pageIndex ?? this.position.pageIndex;
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(pageIndex) {
255
- const targetIndex = pageIndex ?? this.position.pageIndex;
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(pageIndex) {
259
- const targetIndex = pageIndex ?? this.position.pageIndex;
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._pageIndex)));
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._pageIndex);
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._pageIndex, x, y, tolerance)));
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._pageIndex, types);
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() {
@@ -416,6 +417,7 @@ class PDFDancer {
416
417
  * @returns A PDFDancer client instance
417
418
  */
418
419
  static async open(pdfData, token, baseUrl, timeout, retryConfig) {
420
+ (0, env_loader_1.loadEnv)();
419
421
  const resolvedBaseUrl = baseUrl ??
420
422
  process.env.PDFDANCER_BASE_URL ??
421
423
  "https://api.pdfdancer.com";
@@ -440,6 +442,7 @@ class PDFDancer {
440
442
  * @param retryConfig Retry configuration (optional, uses defaults if not specified)
441
443
  */
442
444
  static async new(options, token, baseUrl, timeout, retryConfig) {
445
+ (0, env_loader_1.loadEnv)();
443
446
  const resolvedBaseUrl = baseUrl ??
444
447
  process.env.PDFDANCER_BASE_URL ??
445
448
  "https://api.pdfdancer.com";
@@ -722,7 +725,8 @@ class PDFDancer {
722
725
  'X-Session-Id': this._sessionId,
723
726
  'Content-Type': 'application/json',
724
727
  'X-Generated-At': generateTimestamp(),
725
- 'X-Fingerprint': fingerprint
728
+ 'X-Fingerprint': fingerprint,
729
+ 'X-API-VERSION': '1'
726
730
  };
727
731
  try {
728
732
  const response = await this._fetchWithRetry(url.toString(), {
@@ -782,9 +786,9 @@ class PDFDancer {
782
786
  }
783
787
  // Use snapshot-based search
784
788
  let elements;
785
- if (position?.pageIndex !== undefined) {
789
+ if (position?.pageNumber !== undefined) {
786
790
  // Page-specific query - use page snapshot
787
- const pageSnapshot = await this._getOrFetchPageSnapshot(position.pageIndex);
791
+ const pageSnapshot = await this._getOrFetchPageSnapshot(position.pageNumber);
788
792
  elements = pageSnapshot.elements;
789
793
  }
790
794
  else {
@@ -853,9 +857,9 @@ class PDFDancer {
853
857
  async findFormFields(position) {
854
858
  // Use snapshot-based search
855
859
  let elements;
856
- if (position?.pageIndex !== undefined) {
860
+ if (position?.pageNumber !== undefined) {
857
861
  // Page-specific query - use page snapshot
858
- const pageSnapshot = await this._getOrFetchPageSnapshot(position.pageIndex);
862
+ const pageSnapshot = await this._getOrFetchPageSnapshot(position.pageNumber);
859
863
  elements = pageSnapshot.elements;
860
864
  }
861
865
  else {
@@ -898,68 +902,76 @@ class PDFDancer {
898
902
  * Retrieves a reference to a specific page by its page index.
899
903
  * Now uses snapshot caching to avoid HTTP requests.
900
904
  */
901
- async _getPage(pageIndex) {
902
- if (pageIndex < 0) {
903
- throw new exceptions_1.ValidationException(`Page index must be >= 0, got ${pageIndex}`);
905
+ async _getPage(pageNumber) {
906
+ if (pageNumber < 0) {
907
+ throw new exceptions_1.ValidationException(`Page index must be >= 0, got ${pageNumber}`);
904
908
  }
905
909
  // Try page snapshot cache first
906
- if (this._pageSnapshotCache.has(pageIndex)) {
907
- return this._pageSnapshotCache.get(pageIndex).pageRef;
910
+ if (this._pageSnapshotCache.has(pageNumber)) {
911
+ return this._pageSnapshotCache.get(pageNumber).pageRef;
908
912
  }
909
913
  // Try document snapshot cache
910
914
  if (this._documentSnapshotCache) {
911
- const pageSnapshot = this._documentSnapshotCache.getPageSnapshot(pageIndex);
915
+ const pageSnapshot = this._documentSnapshotCache.getPageSnapshot(pageNumber);
912
916
  if (pageSnapshot) {
913
917
  return pageSnapshot.pageRef;
914
918
  }
915
919
  }
916
920
  // Fetch document snapshot to get page (this will cache it)
917
921
  const docSnapshot = await this._getOrFetchDocumentSnapshot();
918
- const pageSnapshot = docSnapshot.getPageSnapshot(pageIndex);
922
+ const pageSnapshot = docSnapshot.getPageSnapshot(pageNumber);
919
923
  return pageSnapshot?.pageRef ?? null;
920
924
  }
921
925
  /**
922
- * Moves an existing page to a new index.
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
923
932
  */
924
- async movePage(pageIndex, targetPageIndex) {
925
- this._validatePageIndex(pageIndex, 'pageIndex');
926
- this._validatePageIndex(targetPageIndex, 'targetPageIndex');
933
+ async movePage(fromPage, toPage) {
934
+ this._validatePageNumber(fromPage, 'fromPage');
935
+ this._validatePageNumber(toPage, 'toPage');
927
936
  // Ensure the source page exists before attempting the move
928
- await this._requirePageRef(pageIndex);
929
- const request = new models_1.MovePageRequest(pageIndex, targetPageIndex).toDict();
937
+ await this._requirePageRef(fromPage);
938
+ const request = new models_1.MovePageRequest(fromPage, toPage).toDict();
930
939
  const response = await this._makeRequest('PUT', '/pdf/page/move', request);
931
940
  const success = await response.json();
932
941
  if (!success) {
933
- throw new exceptions_1.HttpClientException(`Failed to move page from ${pageIndex} to ${targetPageIndex}`, response);
942
+ throw new exceptions_1.HttpClientException(`Failed to move page from ${fromPage} to ${toPage}`, response);
934
943
  }
935
944
  // Invalidate cache after mutation
936
945
  this._invalidateCache();
937
946
  // Fetch the page again at its new position for up-to-date metadata
938
- return await this._requirePageRef(targetPageIndex);
947
+ return await this._requirePageRef(toPage);
939
948
  }
940
949
  /**
941
- * Deletes the page at the specified index.
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
942
954
  */
943
- async deletePage(pageIndex) {
944
- this._validatePageIndex(pageIndex, 'pageIndex');
945
- const pageRef = await this._requirePageRef(pageIndex);
955
+ async deletePage(pageNumber) {
956
+ this._validatePageNumber(pageNumber, 'pageNumber');
957
+ const pageRef = await this._requirePageRef(pageNumber);
946
958
  const result = await this._deletePage(pageRef);
947
959
  // Invalidate cache after mutation
948
960
  this._invalidateCache();
949
961
  return result;
950
962
  }
951
- _validatePageIndex(pageIndex, fieldName) {
952
- if (!Number.isInteger(pageIndex)) {
953
- throw new exceptions_1.ValidationException(`${fieldName} must be an integer, got ${pageIndex}`);
963
+ _validatePageNumber(pageNumber, fieldName) {
964
+ if (!Number.isInteger(pageNumber)) {
965
+ throw new exceptions_1.ValidationException(`${fieldName} must be an integer, got ${pageNumber}`);
954
966
  }
955
- if (pageIndex < 0) {
956
- throw new exceptions_1.ValidationException(`${fieldName} must be >= 0, got ${pageIndex}`);
967
+ if (pageNumber < 1) {
968
+ throw new exceptions_1.ValidationException(`${fieldName} must be >= 1 (1-based indexing), got ${pageNumber}`);
957
969
  }
958
970
  }
959
- async _requirePageRef(pageIndex) {
960
- const pageRef = await this._getPage(pageIndex);
971
+ async _requirePageRef(pageNumber) {
972
+ const pageRef = await this._getPage(pageNumber);
961
973
  if (!pageRef) {
962
- throw new exceptions_1.ValidationException(`Page not found at index ${pageIndex}`);
974
+ throw new exceptions_1.ValidationException(`Page not found at page number ${pageNumber}`);
963
975
  }
964
976
  return pageRef;
965
977
  }
@@ -995,17 +1007,18 @@ class PDFDancer {
995
1007
  * Gets a snapshot of a specific page.
996
1008
  * Returns the page reference and all elements on that page.
997
1009
  *
998
- * @param pageIndex Zero-based page index
999
- * @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
1000
1012
  * @returns PageSnapshot containing page information and elements
1013
+ * @throws ValidationException if pageNumber is less than 1
1001
1014
  */
1002
- async getPageSnapshot(pageIndex, types) {
1003
- this._validatePageIndex(pageIndex, 'pageIndex');
1015
+ async getPageSnapshot(pageNumber, types) {
1016
+ this._validatePageNumber(pageNumber, 'pageNumber');
1004
1017
  const params = {};
1005
1018
  if (types && types.length > 0) {
1006
1019
  params.types = types.join(',');
1007
1020
  }
1008
- const response = await this._makeRequest('GET', `/pdf/page/${pageIndex}/snapshot`, undefined, params);
1021
+ const response = await this._makeRequest('GET', `/pdf/page/${pageNumber}/snapshot`, undefined, params);
1009
1022
  const data = await response.json();
1010
1023
  return this._parsePageSnapshot(data);
1011
1024
  }
@@ -1013,24 +1026,27 @@ class PDFDancer {
1013
1026
  /**
1014
1027
  * Gets a page snapshot from cache or fetches it.
1015
1028
  * First checks page cache, then document cache, then fetches from server.
1029
+ *
1030
+ * @param pageNumber - 1-based page number
1016
1031
  */
1017
- async _getOrFetchPageSnapshot(pageIndex) {
1032
+ async _getOrFetchPageSnapshot(pageNumber) {
1018
1033
  // Check page cache first
1019
- if (this._pageSnapshotCache.has(pageIndex)) {
1020
- return this._pageSnapshotCache.get(pageIndex);
1034
+ if (this._pageSnapshotCache.has(pageNumber)) {
1035
+ return this._pageSnapshotCache.get(pageNumber);
1021
1036
  }
1022
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
1023
1039
  if (this._documentSnapshotCache) {
1024
- const pageSnapshot = this._documentSnapshotCache.getPageSnapshot(pageIndex);
1040
+ const pageSnapshot = this._documentSnapshotCache.getPageSnapshot(pageNumber);
1025
1041
  if (pageSnapshot) {
1026
1042
  // Cache it for future use
1027
- this._pageSnapshotCache.set(pageIndex, pageSnapshot);
1043
+ this._pageSnapshotCache.set(pageNumber, pageSnapshot);
1028
1044
  return pageSnapshot;
1029
1045
  }
1030
1046
  }
1031
1047
  // Fetch page snapshot from server
1032
- const pageSnapshot = await this.getPageSnapshot(pageIndex);
1033
- this._pageSnapshotCache.set(pageIndex, pageSnapshot);
1048
+ const pageSnapshot = await this.getPageSnapshot(pageNumber);
1049
+ this._pageSnapshotCache.set(pageNumber, pageSnapshot);
1034
1050
  return pageSnapshot;
1035
1051
  }
1036
1052
  /**
@@ -1061,8 +1077,8 @@ class PDFDancer {
1061
1077
  }
1062
1078
  let filtered = elements;
1063
1079
  // Filter by page index
1064
- if (position.pageIndex !== undefined) {
1065
- filtered = filtered.filter(el => el.position.pageIndex === position.pageIndex);
1080
+ if (position.pageNumber !== undefined) {
1081
+ filtered = filtered.filter(el => el.position.pageNumber === position.pageNumber);
1066
1082
  }
1067
1083
  // Filter by coordinates (point containment with tolerance)
1068
1084
  if (position.boundingRect && position.shape === models_1.ShapeType.POINT) {
@@ -1204,11 +1220,11 @@ class PDFDancer {
1204
1220
  if (!paragraph.getPosition()) {
1205
1221
  throw new exceptions_1.ValidationException("Paragraph position is null, you need to specify a position for the new paragraph, using .at(x,y)");
1206
1222
  }
1207
- if (paragraph.getPosition().pageIndex === undefined) {
1208
- throw new exceptions_1.ValidationException("Paragraph position page index is null");
1223
+ if (paragraph.getPosition().pageNumber === undefined) {
1224
+ throw new exceptions_1.ValidationException("Paragraph position page number is null");
1209
1225
  }
1210
- if (paragraph.getPosition().pageIndex < 0) {
1211
- throw new exceptions_1.ValidationException("Paragraph position page index is less than 0");
1226
+ if (paragraph.getPosition().pageNumber < 1) {
1227
+ throw new exceptions_1.ValidationException("Paragraph position page number is less than 1");
1212
1228
  }
1213
1229
  return this._addObject(paragraph);
1214
1230
  }
@@ -1222,11 +1238,11 @@ class PDFDancer {
1222
1238
  if (!path.getPosition()) {
1223
1239
  throw new exceptions_1.ValidationException("Path position is null, you need to specify a position for the new path, using .at(x,y)");
1224
1240
  }
1225
- if (path.getPosition().pageIndex === undefined) {
1226
- throw new exceptions_1.ValidationException("Path position page index is null");
1241
+ if (path.getPosition().pageNumber === undefined) {
1242
+ throw new exceptions_1.ValidationException("Path position page number is null");
1227
1243
  }
1228
- if (path.getPosition().pageIndex < 0) {
1229
- throw new exceptions_1.ValidationException("Path position page index is less than 0");
1244
+ if (path.getPosition().pageNumber < 1) {
1245
+ throw new exceptions_1.ValidationException("Path position page number is less than 1");
1230
1246
  }
1231
1247
  return await this._addObject(path);
1232
1248
  }
@@ -1541,7 +1557,7 @@ class PDFDancer {
1541
1557
  */
1542
1558
  _parsePosition(posData) {
1543
1559
  const position = new models_1.Position();
1544
- position.pageIndex = posData.pageIndex;
1560
+ position.pageNumber = posData.pageNumber;
1545
1561
  position.textStartsWith = posData.textStartsWith;
1546
1562
  if (posData.shape) {
1547
1563
  position.shape = models_1.ShapeType[posData.shape];
@@ -1595,9 +1611,9 @@ class PDFDancer {
1595
1611
  if (Array.isArray(data.elements)) {
1596
1612
  for (const elementData of data.elements) {
1597
1613
  const element = this._parseObjectRef(elementData);
1598
- // If the element's position doesn't have a pageIndex, inherit it from the page
1599
- if (element.position && element.position.pageIndex === undefined) {
1600
- element.position.pageIndex = pageRef.position.pageIndex;
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;
1601
1617
  }
1602
1618
  elements.push(element);
1603
1619
  }
@@ -1614,27 +1630,35 @@ class PDFDancer {
1614
1630
  toImageObjects(objectRefs) {
1615
1631
  return objectRefs.map(ref => types_1.ImageObject.fromRef(this, ref));
1616
1632
  }
1617
- newImage(pageIndex) {
1618
- return new image_builder_1.ImageBuilder(this, pageIndex);
1633
+ newImage(pageNumber) {
1634
+ return new image_builder_1.ImageBuilder(this, pageNumber);
1619
1635
  }
1620
- newParagraph(pageIndex) {
1621
- return new paragraph_builder_1.ParagraphBuilder(this, pageIndex);
1636
+ newParagraph(pageNumber) {
1637
+ return new paragraph_builder_1.ParagraphBuilder(this, pageNumber);
1622
1638
  }
1623
- newPath(pageIndex) {
1624
- return new path_builder_1.PathBuilder(this, pageIndex);
1639
+ newPath(pageNumber) {
1640
+ return new path_builder_1.PathBuilder(this, pageNumber);
1625
1641
  }
1626
1642
  newPage() {
1627
1643
  return new page_builder_1.PageBuilder(this);
1628
1644
  }
1629
- page(pageIndex) {
1630
- if (pageIndex < 0) {
1631
- throw new exceptions_1.ValidationException(`Page index must be >= 0, got ${pageIndex}`);
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}`);
1632
1655
  }
1633
- return new PageClient(this, pageIndex);
1656
+ return new PageClient(this, pageNumber);
1634
1657
  }
1635
1658
  async pages() {
1636
1659
  const pageRefs = await this.getPages();
1637
- return pageRefs.map((pageRef, pageIndex) => new PageClient(this, pageIndex, pageRef));
1660
+ // Page numbers are 1-based
1661
+ return pageRefs.map((pageRef, index) => new PageClient(this, index + 1, pageRef));
1638
1662
  }
1639
1663
  toFormFields(objectRefs) {
1640
1664
  return objectRefs.map(ref => types_1.FormFieldObject.fromRef(this, ref));