townshipamerica 1.0.1 → 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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm](https://img.shields.io/npm/v/townshipamerica)](https://www.npmjs.com/package/townshipamerica)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
5
5
 
6
- Official TypeScript SDK for the [Township America API](https://townshipamerica.com/api) — convert US PLSS (Public Land Survey System) legal land descriptions to GPS coordinates and back.
6
+ Official TypeScript SDK for the [Township America API](https://townshipamerica.com/api) — convert US PLSS (Public Land Survey System) and Texas TXSS legal land descriptions to GPS coordinates and back.
7
7
 
8
8
  [Documentation](https://townshipamerica.com/api) · [GitHub](https://github.com/townshipamerica/typescript-sdk) · [npm](https://www.npmjs.com/package/townshipamerica)
9
9
 
@@ -21,23 +21,27 @@ import { TownshipClient } from "townshipamerica";
21
21
  const client = new TownshipClient({ apiKey: "YOUR_API_KEY" });
22
22
 
23
23
  // PLSS to GPS
24
- const result = await client.search("NW 25 24N 1E 6th Meridian");
25
- console.log(result.latitude, result.longitude); // 41.077932 -104.01924
26
- console.log(result.state); // "Colorado"
27
- console.log(result.county); // "Weld"
24
+ const plss = await client.search("NW 25 24N 1E 6th Meridian");
25
+ console.log(plss.latitude, plss.longitude); // 41.077932 -104.01924
26
+ console.log(plss.surveySystem); // "PLSS"
28
27
 
29
- // GPS to PLSS
28
+ // Texas TXSS to GPS
29
+ const tx = await client.search("A-175 Reeves County");
30
+ console.log(tx.surveySystem); // "TXSS"
31
+ console.log(tx.state); // "TX"
32
+
33
+ // GPS to legal description (PLSS or TXSS depending on location)
30
34
  const reverse = await client.reverse(-104.01924, 41.077932);
31
- console.log(reverse.legalLocation); // "NW 25 24N 1E 6th Meridian"
35
+ console.log(reverse.legalLocation);
32
36
 
33
- // Autocomplete
34
- const suggestions = await client.autocomplete("NW 25", { limit: 5 });
37
+ // Autocomplete (PLSS or TXSS)
38
+ const suggestions = await client.autocomplete("A-175", { limit: 5 });
35
39
  console.log(suggestions.features[0].properties.legal_location);
36
40
 
37
- // Batch (up to 100 per request, auto-chunks larger arrays)
41
+ // Batch — mix PLSS and TXSS in one call (up to 100 per request, auto-chunks larger arrays)
38
42
  const batch = await client.batchSearch([
39
43
  "NW 25 24N 1E 6th Meridian",
40
- "NE 12 4N 5E Indian Meridian"
44
+ "A-175 Reeves County"
41
45
  ]);
42
46
  ```
43
47
 
@@ -55,10 +59,11 @@ const batch = await client.batchSearch([
55
59
 
56
60
  ### `client.search(legalLocation)`
57
61
 
58
- Convert a PLSS legal land description to GPS coordinates.
62
+ Convert a PLSS or Texas TXSS legal land description to GPS coordinates.
59
63
 
60
64
  ```typescript
61
- const result = await client.search("NE 12 4N 5E Indian Meridian");
65
+ const plss = await client.search("NE 12 4N 5E Indian Meridian");
66
+ const tx = await client.search("A-175 Reeves County");
62
67
  ```
63
68
 
64
69
  **Returns:** `SearchResult`
@@ -70,17 +75,19 @@ const result = await client.search("NE 12 4N 5E Indian Meridian");
70
75
  | `longitude` | `number` | Centroid longitude |
71
76
  | `state` | `string` | US state |
72
77
  | `county` | `string` | County |
73
- | `unit` | `string` | `Township`, `First Division`, or `Second Division` |
74
- | `surveySystem` | `string` | `PLSS` |
78
+ | `unit` | `string \| null` | PLSS unit, or `null` for TXSS |
79
+ | `surveySystem` | `"PLSS" \| "TXSS"` | Survey system |
75
80
  | `alternateLegalLocation` | `string` | Alternate description format |
76
- | `boundary` | `GeoJSONPolygon \| null` | Grid boundary polygon |
81
+ | `boundary` | `GeoJSONBoundary \| null` | Grid boundary polygon (Polygon or MultiPolygon) |
77
82
  | `raw` | `GeoJSONFeatureCollection` | Raw API response |
78
83
 
84
+ TXSS responses also include `abstract_no`, `block_no`, `survey_name`, and `acreage` on feature properties when available.
85
+
79
86
  ---
80
87
 
81
88
  ### `client.reverse(longitude, latitude, options?)`
82
89
 
83
- Find the PLSS description at GPS coordinates.
90
+ Find the legal land description at GPS coordinates (PLSS or Texas TXSS).
84
91
 
85
92
  ```typescript
86
93
  const result = await client.reverse(-104.01924, 41.077932, {
@@ -100,7 +107,7 @@ const result = await client.reverse(-104.01924, 41.077932, {
100
107
 
101
108
  ### `client.autocomplete(query, options?)`
102
109
 
103
- Get autocomplete suggestions for a partial PLSS description.
110
+ Get autocomplete suggestions for a partial PLSS or Texas TXSS description.
104
111
 
105
112
  ```typescript
106
113
  const fc = await client.autocomplete("NW 25", { limit: 5 });
@@ -171,7 +178,7 @@ const polygon = await client.boundary("NW 25 24N 1E 6th Meridian");
171
178
  // polygon.coordinates === [[[lng, lat], ...]]
172
179
  ```
173
180
 
174
- **Returns:** `GeoJSONPolygon | null`
181
+ **Returns:** `GeoJSONPolygon | GeoJSONMultiPolygon | null`
175
182
 
176
183
  ---
177
184
 
@@ -187,6 +194,131 @@ const fc = await client.raw("NW 25 24N 1E 6th Meridian");
187
194
 
188
195
  ---
189
196
 
197
+ ### `client.energyReport(legalLocation, options?)`
198
+
199
+ Energy parcel report for a PLSS section — state-regulator wells, operators,
200
+ BLM federal leases, ONRR county royalties, orphaned wells, pipelines,
201
+ FracFocus disclosures, and development constraints.
202
+
203
+ ```typescript
204
+ const report = await client.energyReport("25 24N 1E 6th Meridian");
205
+ console.log(report.summary.wells_in_section);
206
+ console.log(report.wells?.in_section.rows[0]?.api_number);
207
+
208
+ // Only the sections you need — the rest are never queried
209
+ const slim = await client.energyReport("25 24N 1E 6th Meridian", {
210
+ include: ["wells", "pipelines"]
211
+ });
212
+
213
+ // Attach the parcel boundary under parcel.geometry
214
+ const withGeometry = await client.energyReport("25 24N 1E 6th Meridian", {
215
+ include: ["geometry"]
216
+ });
217
+ ```
218
+
219
+ **Options:** `include` — any of `wells`, `operators`, `leases`, `royalties`,
220
+ `orphaned_wells`, `pipelines`, `fracfocus`, `constraints`, `geometry`.
221
+
222
+ **Returns:** `EnergyReport`. Array sections are
223
+ `{total, returned, truncated, more, rows}` envelopes; a failed section lands
224
+ in `meta.unavailable` instead of failing the report.
225
+
226
+ ---
227
+
228
+ ### `client.federalLandReport(legalLocation, options?)`
229
+
230
+ Federal-land parcel report for a PLSS tract — surface management, BLM O&G and
231
+ geothermal leases, rights-of-way, flood zones, mining claims, wetlands,
232
+ firesheds, soils, crop history, orphaned wells, critical habitat, public
233
+ access, wildfire risk, and elevation.
234
+
235
+ ```typescript
236
+ const report = await client.federalLandReport("NW 25 24N 1E 6th Meridian");
237
+ console.log(report.surface_management?.rows[0]?.agency);
238
+
239
+ const slim = await client.federalLandReport("NW 25 24N 1E 6th Meridian", {
240
+ include: ["og_leases", "flood_zones"]
241
+ });
242
+ ```
243
+
244
+ **Options:** `include` — any of `surface_management`, `og_leases`,
245
+ `geothermal_leases`, `rights_of_way`, `flood_zones`, `mining_claims`,
246
+ `wetlands`, `fireshed`, `soils`, `crop_history`, `orphaned_wells`,
247
+ `critical_habitat`, `public_access`, `wildfire_risk_communities`,
248
+ `elevation`, `geometry`.
249
+
250
+ **Returns:** `FederalLandReport`. `report_scope` is `"containing_section"`
251
+ when the tract is finer than the stored grid (the section is named by
252
+ `report_section`); a layer the state has no data for is listed in
253
+ `meta.unavailable` with reason `no_state_coverage`.
254
+
255
+ ---
256
+
257
+ ### `client.texasReport(legalLocation, options?)`
258
+
259
+ Texas abstract report for a TXSS legal description — GLO state leases and
260
+ pooled units, PSF lands, state-agency lands, upland leases, RRC wells and T-4
261
+ pipelines, pending permits, coastal erosion, federal overlays (flood zones,
262
+ wetlands, firesheds, soils, orphaned wells, critical habitat, wildfire risk),
263
+ elevation, and RRC lease production.
264
+
265
+ ```typescript
266
+ const report = await client.texasReport("A-175 Reeves County");
267
+ console.log(report.active_wells?.rows[0]?.api_number);
268
+ console.log(report.production?.summary.total_cum_boe);
269
+
270
+ const slim = await client.texasReport("A-175 Reeves County", {
271
+ include: ["state_leases", "production"]
272
+ });
273
+ ```
274
+
275
+ **Options:** `include` — any of `state_leases`, `state_units`, `psf_lands`,
276
+ `state_agency_lands`, `upland_leases`, `active_wells`, `pipelines`,
277
+ `pending_permits`, `coastal_erosion`, `flood_zones`, `wetlands`, `fireshed`,
278
+ `soils`, `orphaned_wells`, `critical_habitat`, `wildfire_risk_communities`,
279
+ `elevation`, `production`, `geometry`.
280
+
281
+ **Returns:** `TexasReport`
282
+
283
+ ---
284
+
285
+ ### `client.texasProduction(options)`
286
+
287
+ RRC lease production for a Texas abstract — per-lease lifetime totals,
288
+ trailing-12-month volumes, and the 60-month monthly series. Key by a legal
289
+ description OR the registry ids.
290
+
291
+ ```typescript
292
+ const byLocation = await client.texasProduction({ legalLocation: "A-175 Reeves County" });
293
+ const byKeys = await client.texasProduction({ countyFips: "48389", abstractNo: "175" });
294
+ console.log(byKeys.summary.total_cum_boe);
295
+ ```
296
+
297
+ **Options:** `{ legalLocation }` or `{ countyFips, abstractNo, blockNo? }`
298
+
299
+ **Returns:** `TexasProduction`. Production is reported by RRC at the lease
300
+ level — rows are the leases whose wells fall on the abstract, never
301
+ sub-allocated to the tract.
302
+
303
+ ---
304
+
305
+ ### `client.texasWell(api)`
306
+
307
+ Per-well allocated production for a Texas well by API number (API-8 or
308
+ API-14) — summary scalars for every lease edge, the monthly series (when
309
+ provisioned), and an Arps decline fit.
310
+
311
+ ```typescript
312
+ const well = await client.texasWell("42-389-32345");
313
+ console.log(well.units[0]?.cum_boe);
314
+ if (well.decline.available) console.log(well.decline.value?.di);
315
+ ```
316
+
317
+ **Returns:** `TexasWell`. Volumes are allocated estimates — RRC reports
318
+ production by lease, never by well.
319
+
320
+ ---
321
+
190
322
  ## Error Handling
191
323
 
192
324
  All errors extend `TownshipError`:
@@ -217,7 +349,43 @@ try {
217
349
  }
218
350
  ```
219
351
 
220
- ## PLSS Format Examples
352
+ Errors from the Energy, Federal Land, and Texas APIs also carry a
353
+ machine-readable `code` (e.g. `invalid_parameter`, `plss_not_supported`,
354
+ `ambiguous_location`, `not_found`, `rate_limit_exceeded`); it is `null` for
355
+ endpoints that do not send one:
356
+
357
+ ```typescript
358
+ try {
359
+ await client.texasReport("NW 25 24N 1E 6th Meridian");
360
+ } catch (error) {
361
+ if (error instanceof ValidationError && error.code === "plss_not_supported") {
362
+ // Use federalLandReport or energyReport for PLSS descriptions
363
+ }
364
+ }
365
+ ```
366
+
367
+ ## What's new in v2.0.0
368
+
369
+ v2.0.0 adds the parcel-report APIs:
370
+
371
+ - `client.energyReport(legalLocation, { include? })` — Energy API report
372
+ - `client.federalLandReport(legalLocation, { include? })` — Federal Land API report
373
+ - `client.texasReport(legalLocation, { include? })` — Texas abstract report
374
+ - `client.texasProduction({ legalLocation } | { countyFips, abstractNo, blockNo? })` — RRC lease production
375
+ - `client.texasWell(api)` — per-well allocated production + Arps decline fit
376
+
377
+ Breaking changes:
378
+
379
+ - Error classes gained a third constructor parameter and a readonly `code`
380
+ property (`string | null`). If you subclass or construct SDK errors
381
+ directly, update the constructor calls; `instanceof` checks are unaffected.
382
+ - Error bodies of the form `{"error": {"code", "message"}}` (Energy, Federal
383
+ Land, and Texas APIs) are now parsed into `error.message`/`error.code`.
384
+ Legacy `{"error": "..."}` / `{"message": "..."}` bodies parse as before.
385
+
386
+ ## Format Examples
387
+
388
+ ### PLSS (30 states)
221
389
 
222
390
  ```
223
391
  NW 25 24N 1E 6th Meridian → Quarter Section (First Division)
@@ -227,6 +395,15 @@ NE 12 4N 5E Indian Meridian → Named meridian
227
395
  7 2N 3E Black Hills Meridian → Section with named meridian
228
396
  ```
229
397
 
398
+ ### Texas TXSS
399
+
400
+ ```
401
+ A-175 Reeves County
402
+ Abstract 175 Reeves County Texas
403
+ Block 25 Section 14 Pecos County
404
+ Survey H&TC, Travis County
405
+ ```
406
+
230
407
  ## License
231
408
 
232
409
  MIT — [Maps & Apps Inc.](https://townshipamerica.com)
package/dist/index.cjs CHANGED
@@ -32,39 +32,40 @@ module.exports = __toCommonJS(index_exports);
32
32
 
33
33
  // src/errors.ts
34
34
  var TownshipError = class extends Error {
35
- constructor(message, statusCode = null) {
35
+ constructor(message, statusCode = null, code = null) {
36
36
  super(message);
37
37
  this.statusCode = statusCode;
38
+ this.code = code;
38
39
  this.name = "TownshipError";
39
40
  }
40
41
  };
41
42
  var AuthenticationError = class extends TownshipError {
42
- constructor(message = "Invalid or missing API key") {
43
- super(message, 401);
43
+ constructor(message = "Invalid or missing API key", code = null) {
44
+ super(message, 401, code);
44
45
  this.name = "AuthenticationError";
45
46
  }
46
47
  };
47
48
  var NotFoundError = class extends TownshipError {
48
- constructor(message = "Location not found") {
49
- super(message, 404);
49
+ constructor(message = "Location not found", code = null) {
50
+ super(message, 404, code);
50
51
  this.name = "NotFoundError";
51
52
  }
52
53
  };
53
54
  var RateLimitError = class extends TownshipError {
54
- constructor(message = "Rate limit exceeded. Please slow down your requests.") {
55
- super(message, 429);
55
+ constructor(message = "Rate limit exceeded. Please slow down your requests.", code = null) {
56
+ super(message, 429, code);
56
57
  this.name = "RateLimitError";
57
58
  }
58
59
  };
59
60
  var ValidationError = class extends TownshipError {
60
- constructor(message = "Invalid request") {
61
- super(message, 400);
61
+ constructor(message = "Invalid request", code = null) {
62
+ super(message, 400, code);
62
63
  this.name = "ValidationError";
63
64
  }
64
65
  };
65
66
  var PayloadTooLargeError = class extends TownshipError {
66
- constructor(message = "Batch payload exceeds the maximum of 100 records per request") {
67
- super(message, 413);
67
+ constructor(message = "Batch payload exceeds the maximum of 100 records per request", code = null) {
68
+ super(message, 413, code);
68
69
  this.name = "PayloadTooLargeError";
69
70
  }
70
71
  };
@@ -116,7 +117,7 @@ var TownshipClient = class {
116
117
  ...init,
117
118
  headers: {
118
119
  "X-API-Key": this.apiKey,
119
- "User-Agent": "townshipamerica-js/1.0.0",
120
+ "User-Agent": "townshipamerica-js/2.0.0",
120
121
  ...init?.headers ?? {}
121
122
  },
122
123
  signal: controller.signal
@@ -137,25 +138,31 @@ var TownshipClient = class {
137
138
  }
138
139
  async handleError(response) {
139
140
  let message;
141
+ let code = null;
140
142
  try {
141
143
  const body = await response.json();
142
- message = body.error ?? body.message ?? response.statusText;
144
+ if (body.error && typeof body.error === "object") {
145
+ message = body.error.message ?? response.statusText;
146
+ code = body.error.code ?? null;
147
+ } else {
148
+ message = (typeof body.error === "string" ? body.error : void 0) ?? body.message ?? response.statusText;
149
+ }
143
150
  } catch {
144
151
  message = response.statusText;
145
152
  }
146
153
  const status = response.status;
147
- if (status === 400) throw new ValidationError(message);
148
- if (status === 401) throw new AuthenticationError(message);
149
- if (status === 404) throw new NotFoundError(message);
150
- if (status === 413) throw new PayloadTooLargeError(message);
151
- if (status === 429) throw new RateLimitError(message);
152
- throw new TownshipError(message, status);
154
+ if (status === 400) throw new ValidationError(message, code);
155
+ if (status === 401) throw new AuthenticationError(message, code);
156
+ if (status === 404) throw new NotFoundError(message, code);
157
+ if (status === 413) throw new PayloadTooLargeError(message, code);
158
+ if (status === 429) throw new RateLimitError(message, code);
159
+ throw new TownshipError(message, status, code);
153
160
  }
154
161
  // --- Search ---
155
162
  /**
156
- * Convert a PLSS legal land description to GPS coordinates.
163
+ * Convert a PLSS or Texas TXSS legal land description to GPS coordinates.
157
164
  *
158
- * @param legalLocation - e.g. "NW 25 24N 1E 6th Meridian"
165
+ * @param legalLocation - e.g. "NW 25 24N 1E 6th Meridian" or "A-175 Reeves County"
159
166
  * @returns A SearchResult with coordinates, boundary, and metadata.
160
167
  * @throws {ValidationError} If the location string is invalid.
161
168
  * @throws {NotFoundError} If no match is found.
@@ -171,11 +178,11 @@ var TownshipClient = class {
171
178
  return toSearchResult(data);
172
179
  }
173
180
  /**
174
- * Find the PLSS legal land description at the given GPS coordinates.
181
+ * Find the legal land description at the given GPS coordinates (PLSS or Texas TXSS).
175
182
  *
176
183
  * @param longitude - Longitude (x) coordinate.
177
184
  * @param latitude - Latitude (y) coordinate.
178
- * @param options - Optional unit filter.
185
+ * @param options - Optional PLSS unit filter (ignored for TXSS results).
179
186
  * @returns A SearchResult or array of SearchResults (when unit is 'all').
180
187
  */
181
188
  async reverse(longitude, latitude, options) {
@@ -207,7 +214,7 @@ var TownshipClient = class {
207
214
  }
208
215
  // --- Autocomplete ---
209
216
  /**
210
- * Get autocomplete suggestions for a partial PLSS description.
217
+ * Get autocomplete suggestions for a partial PLSS or Texas TXSS description.
211
218
  *
212
219
  * @param query - Partial search query (minimum 2 characters).
213
220
  * @param options - Optional limit (1–10, default 3) and proximity.
@@ -225,10 +232,10 @@ var TownshipClient = class {
225
232
  }
226
233
  // --- Batch ---
227
234
  /**
228
- * Convert multiple PLSS descriptions to GPS coordinates in one request.
229
- * Auto-chunks if more than 100 items.
235
+ * Convert multiple legal land descriptions to GPS coordinates in one request.
236
+ * Auto-chunks if more than 100 items. Mix PLSS and Texas TXSS inputs freely.
230
237
  *
231
- * @param locations - Array of PLSS legal land descriptions.
238
+ * @param locations - Array of legal land descriptions.
232
239
  * @param options - Optional chunk size.
233
240
  * @returns Array of SearchResult or null for each input.
234
241
  */
@@ -256,11 +263,11 @@ var TownshipClient = class {
256
263
  return results;
257
264
  }
258
265
  /**
259
- * Find PLSS descriptions for multiple coordinate pairs in one request.
266
+ * Find legal land descriptions for multiple coordinate pairs in one request.
260
267
  * Auto-chunks if more than 100 items.
261
268
  *
262
269
  * @param coordinates - Array of [longitude, latitude] pairs.
263
- * @param options - Optional unit filter and chunk size.
270
+ * @param options - Optional PLSS unit filter and chunk size.
264
271
  * @returns Array of SearchResult or null for each input.
265
272
  */
266
273
  async batchReverse(coordinates, options) {
@@ -326,6 +333,137 @@ var TownshipClient = class {
326
333
  }
327
334
  return data;
328
335
  }
336
+ // --- Energy API ---
337
+ /**
338
+ * Get the energy parcel report for a PLSS section. Covers state-regulator
339
+ * wells, operators, federal leases, county royalties, orphaned wells,
340
+ * pipelines, FracFocus disclosures, and development constraints.
341
+ *
342
+ * @param legalLocation - A PLSS legal description, e.g. "NW 25 24N 1E 6th Meridian"
343
+ * @param options - Optional section projection (`include`)
344
+ * @returns The energy report
345
+ *
346
+ * @example
347
+ * ```ts
348
+ * const report = await client.energyReport('25 24N 1E 6th Meridian')
349
+ * console.log(report.summary.wells_in_section)
350
+ * console.log(report.wells?.in_section.rows[0]?.api_number)
351
+ *
352
+ * // Only the sections you need — the rest are never queried
353
+ * const slim = await client.energyReport('25 24N 1E 6th Meridian', {
354
+ * include: ['wells', 'pipelines']
355
+ * })
356
+ * ```
357
+ */
358
+ async energyReport(legalLocation, options) {
359
+ const params = new URLSearchParams({ legal_location: legalLocation });
360
+ if (options?.include?.length) params.set("include", options.include.join(","));
361
+ return this.request(`/energy/report?${params}`);
362
+ }
363
+ // --- Federal Land API ---
364
+ /**
365
+ * Get the federal-land parcel report for a PLSS tract. Covers surface
366
+ * management, BLM leases and rights-of-way, flood zones, mining claims,
367
+ * wetlands, firesheds, soils, crop history, orphaned wells, critical
368
+ * habitat, public access, wildfire risk, and elevation.
369
+ *
370
+ * @param legalLocation - A PLSS legal description, e.g. "NW 25 24N 1E 6th Meridian"
371
+ * @param options - Optional section projection (`include`)
372
+ * @returns The federal-land report
373
+ *
374
+ * @example
375
+ * ```ts
376
+ * const report = await client.federalLandReport('NW 25 24N 1E 6th Meridian')
377
+ * console.log(report.surface_management?.rows[0]?.agency)
378
+ *
379
+ * // Only the sections you need — the pruned layers' queries never run
380
+ * const slim = await client.federalLandReport('NW 25 24N 1E 6th Meridian', {
381
+ * include: ['og_leases', 'flood_zones']
382
+ * })
383
+ * ```
384
+ */
385
+ async federalLandReport(legalLocation, options) {
386
+ const params = new URLSearchParams({ legal_location: legalLocation });
387
+ if (options?.include?.length) params.set("include", options.include.join(","));
388
+ return this.request(`/federal-land/report?${params}`);
389
+ }
390
+ // --- Texas API ---
391
+ /**
392
+ * Get the Texas abstract report for a TXSS legal description. Covers GLO
393
+ * state leases and units, PSF lands, RRC wells and pipelines, pending
394
+ * permits, coastal erosion, federal overlays, and RRC lease production.
395
+ *
396
+ * @param legalLocation - A Texas legal description, e.g. "A-175 Reeves County"
397
+ * @param options - Optional section projection (`include`)
398
+ * @returns The Texas report
399
+ *
400
+ * @example
401
+ * ```ts
402
+ * const report = await client.texasReport('A-175 Reeves County')
403
+ * console.log(report.active_wells?.rows[0]?.api_number)
404
+ * console.log(report.production?.summary.total_cum_boe)
405
+ *
406
+ * // Only the sections you need — the rest are never queried
407
+ * const slim = await client.texasReport('A-175 Reeves County', {
408
+ * include: ['state_leases', 'production']
409
+ * })
410
+ * ```
411
+ */
412
+ async texasReport(legalLocation, options) {
413
+ const params = new URLSearchParams({ legal_location: legalLocation });
414
+ if (options?.include?.length) params.set("include", options.include.join(","));
415
+ return this.request(`/texas/report?${params}`);
416
+ }
417
+ /**
418
+ * Get RRC lease production for a Texas abstract — per-lease lifetime
419
+ * totals, trailing-12-month volumes, and the 60-month monthly series.
420
+ * Production is reported by RRC at the LEASE level: rows are the leases
421
+ * whose wells fall on the abstract, never sub-allocated to the tract.
422
+ *
423
+ * @param options - Either `{legalLocation}` or `{countyFips, abstractNo, blockNo?}`
424
+ * @returns The abstract production rollup
425
+ *
426
+ * @example
427
+ * ```ts
428
+ * const byLocation = await client.texasProduction({ legalLocation: 'A-175 Reeves County' })
429
+ * const byKeys = await client.texasProduction({ countyFips: '48389', abstractNo: '175' })
430
+ * console.log(byKeys.summary.total_cum_boe)
431
+ * ```
432
+ */
433
+ async texasProduction(options) {
434
+ const params = new URLSearchParams();
435
+ if (options.legalLocation != null) {
436
+ params.set("legal_location", options.legalLocation);
437
+ } else if (options.countyFips != null && options.abstractNo != null) {
438
+ params.set("county_fips", options.countyFips);
439
+ params.set("abstract_no", options.abstractNo);
440
+ if (options.blockNo != null) params.set("block_no", options.blockNo);
441
+ } else {
442
+ throw new TownshipError(
443
+ "texasProduction requires either legalLocation or countyFips + abstractNo"
444
+ );
445
+ }
446
+ return this.request(`/texas/production?${params}`);
447
+ }
448
+ /**
449
+ * Get per-well allocated production for a Texas well by API number —
450
+ * summary scalars for every lease edge, the monthly series (when
451
+ * provisioned), and an Arps decline fit. Volumes are allocated estimates:
452
+ * RRC reports production by lease, never by well.
453
+ *
454
+ * @param api - API-8 or API-14 number (e.g. "42-389-32345" or "42389323450000")
455
+ * @returns The well's units, series, and decline analysis
456
+ *
457
+ * @example
458
+ * ```ts
459
+ * const well = await client.texasWell('42-389-32345')
460
+ * console.log(well.units[0]?.cum_boe)
461
+ * console.log(well.decline.available && well.decline.value?.di)
462
+ * ```
463
+ */
464
+ async texasWell(api) {
465
+ return this.request(`/texas/wells/${encodeURIComponent(api)}`);
466
+ }
329
467
  };
330
468
  // Annotate the CommonJS export names for ESM import in node:
331
469
  0 && (module.exports = {