townshipamerica 1.0.2 → 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
@@ -194,6 +194,131 @@ const fc = await client.raw("NW 25 24N 1E 6th Meridian");
194
194
 
195
195
  ---
196
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
+
197
322
  ## Error Handling
198
323
 
199
324
  All errors extend `TownshipError`:
@@ -224,6 +349,40 @@ try {
224
349
  }
225
350
  ```
226
351
 
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
+
227
386
  ## Format Examples
228
387
 
229
388
  ### PLSS (30 states)
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,19 +138,25 @@ 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
  /**
@@ -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 = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { TownshipClient } from \"./client.js\";\nexport {\n TownshipError,\n AuthenticationError,\n NotFoundError,\n RateLimitError,\n ValidationError,\n PayloadTooLargeError\n} from \"./errors.js\";\nexport type {\n TownshipClientOptions,\n GeoJSONPoint,\n GeoJSONPolygon,\n GeoJSONMultiPolygon,\n GeoJSONBoundary,\n GeoJSONFeature,\n GeoJSONFeatureCollection,\n FeatureProperties,\n Unit,\n SurveySystem,\n SearchResult,\n ReverseOptions,\n AutocompleteOptions,\n BatchSearchOptions,\n BatchReverseOptions\n} from \"./types.js\";\n","/**\n * Base error class for all Township SDK errors.\n */\nexport class TownshipError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number | null = null\n ) {\n super(message);\n this.name = \"TownshipError\";\n }\n}\n\n/**\n * Thrown when the API key is missing or invalid (HTTP 401).\n */\nexport class AuthenticationError extends TownshipError {\n constructor(message = \"Invalid or missing API key\") {\n super(message, 401);\n this.name = \"AuthenticationError\";\n }\n}\n\n/**\n * Thrown when no result is found for the given input.\n */\nexport class NotFoundError extends TownshipError {\n constructor(message = \"Location not found\") {\n super(message, 404);\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * Thrown when the API rate limit is exceeded (HTTP 429).\n */\nexport class RateLimitError extends TownshipError {\n constructor(message = \"Rate limit exceeded. Please slow down your requests.\") {\n super(message, 429);\n this.name = \"RateLimitError\";\n }\n}\n\n/**\n * Thrown when the request is malformed (HTTP 400).\n */\nexport class ValidationError extends TownshipError {\n constructor(message = \"Invalid request\") {\n super(message, 400);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Thrown when the batch payload exceeds the maximum size (HTTP 413).\n */\nexport class PayloadTooLargeError extends TownshipError {\n constructor(message = \"Batch payload exceeds the maximum of 100 records per request\") {\n super(message, 413);\n this.name = \"PayloadTooLargeError\";\n }\n}\n","import {\n AuthenticationError,\n NotFoundError,\n PayloadTooLargeError,\n RateLimitError,\n TownshipError,\n ValidationError\n} from \"./errors.js\";\nimport type {\n AutocompleteOptions,\n BatchReverseOptions,\n BatchSearchOptions,\n GeoJSONBoundary,\n GeoJSONFeatureCollection,\n ReverseOptions,\n SearchResult,\n TownshipClientOptions\n} from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://developer.townshipamerica.com\";\nconst DEFAULT_TIMEOUT = 30_000;\nconst MAX_BATCH_SIZE = 100;\n\nfunction toSearchResult(fc: GeoJSONFeatureCollection): SearchResult {\n const centroid = fc.features.find((f) => f.properties.shape === \"centroid\");\n const grid = fc.features.find((f) => f.properties.shape === \"grid\");\n\n const props = centroid?.properties ?? grid?.properties;\n if (!props) {\n throw new TownshipError(\"Unexpected API response: no features returned\");\n }\n\n const [lng, lat] = centroid ? (centroid.geometry.coordinates as [number, number]) : [0, 0];\n\n return {\n legalLocation: props.legal_location,\n latitude: lat,\n longitude: lng,\n state: props.state,\n county: props.county,\n unit: props.unit,\n surveySystem: props.survey_system,\n alternateLegalLocation: props.alternate_legal_location,\n boundary: grid ? (grid.geometry as GeoJSONBoundary) : null,\n raw: fc\n };\n}\n\nexport class TownshipClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n\n constructor(options: TownshipClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n\n if (!this.apiKey) {\n throw new TownshipError(\"apiKey is required\");\n }\n }\n\n // --- Internal ---\n\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n ...init,\n headers: {\n \"X-API-Key\": this.apiKey,\n \"User-Agent\": \"townshipamerica-js/1.0.0\",\n ...(init?.headers ?? {})\n },\n signal: controller.signal\n });\n\n if (!response.ok) {\n await this.handleError(response);\n }\n\n return (await response.json()) as T;\n } catch (error) {\n if (error instanceof TownshipError) throw error;\n if (error instanceof DOMException && error.name === \"AbortError\") {\n throw new TownshipError(\"Request timed out\");\n }\n throw new TownshipError(error instanceof Error ? error.message : \"Unknown error\");\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async handleError(response: Response): Promise<never> {\n let message: string;\n try {\n const body = (await response.json()) as Record<string, unknown>;\n message = (body.error ?? body.message ?? response.statusText) as string;\n } catch {\n message = response.statusText;\n }\n\n const status = response.status;\n if (status === 400) throw new ValidationError(message);\n if (status === 401) throw new AuthenticationError(message);\n if (status === 404) throw new NotFoundError(message);\n if (status === 413) throw new PayloadTooLargeError(message);\n if (status === 429) throw new RateLimitError(message);\n throw new TownshipError(message, status);\n }\n\n // --- Search ---\n\n /**\n * Convert a PLSS or Texas TXSS legal land description to GPS coordinates.\n *\n * @param legalLocation - e.g. \"NW 25 24N 1E 6th Meridian\" or \"A-175 Reeves County\"\n * @returns A SearchResult with coordinates, boundary, and metadata.\n * @throws {ValidationError} If the location string is invalid.\n * @throws {NotFoundError} If no match is found.\n */\n async search(legalLocation: string): Promise<SearchResult> {\n const params = new URLSearchParams({ location: legalLocation });\n const data = await this.request<GeoJSONFeatureCollection | Record<string, never>>(\n `/search/legal-location?${params}`\n );\n\n if (!(\"features\" in data) || !data.features?.length) {\n throw new NotFoundError(`No results found for \"${legalLocation}\"`);\n }\n\n return toSearchResult(data as GeoJSONFeatureCollection);\n }\n\n /**\n * Find the legal land description at the given GPS coordinates (PLSS or Texas TXSS).\n *\n * @param longitude - Longitude (x) coordinate.\n * @param latitude - Latitude (y) coordinate.\n * @param options - Optional PLSS unit filter (ignored for TXSS results).\n * @returns A SearchResult or array of SearchResults (when unit is 'all').\n */\n async reverse(\n longitude: number,\n latitude: number,\n options?: ReverseOptions\n ): Promise<SearchResult | SearchResult[]> {\n const params = new URLSearchParams({\n location: `${longitude},${latitude}`\n });\n if (options?.unit) {\n params.set(\"unit\", options.unit);\n }\n\n const data = await this.request<GeoJSONFeatureCollection | Record<string, never>>(\n `/search/coordinates?${params}`\n );\n\n if (!(\"features\" in data) || !data.features?.length) {\n throw new NotFoundError(`No results found for coordinates [${longitude}, ${latitude}]`);\n }\n\n const fc = data as GeoJSONFeatureCollection;\n\n if (options?.unit === \"all\") {\n const groups = new Map<string, typeof fc.features>();\n for (const feature of fc.features) {\n const key = feature.properties.legal_location;\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(feature);\n }\n\n return Array.from(groups.values()).map((features) => {\n return toSearchResult({ type: \"FeatureCollection\", features });\n });\n }\n\n return toSearchResult(fc);\n }\n\n // --- Autocomplete ---\n\n /**\n * Get autocomplete suggestions for a partial PLSS or Texas TXSS description.\n *\n * @param query - Partial search query (minimum 2 characters).\n * @param options - Optional limit (1–10, default 3) and proximity.\n * @returns Raw GeoJSON FeatureCollection with suggestion features.\n */\n async autocomplete(\n query: string,\n options?: AutocompleteOptions\n ): Promise<GeoJSONFeatureCollection> {\n const params = new URLSearchParams({ location: query });\n if (options?.limit != null) {\n params.set(\"limit\", String(options.limit));\n }\n if (options?.proximity) {\n params.set(\"proximity\", `${options.proximity[0]},${options.proximity[1]}`);\n }\n\n return this.request<GeoJSONFeatureCollection>(`/autocomplete/legal-location?${params}`);\n }\n\n // --- Batch ---\n\n /**\n * Convert multiple legal land descriptions to GPS coordinates in one request.\n * Auto-chunks if more than 100 items. Mix PLSS and Texas TXSS inputs freely.\n *\n * @param locations - Array of legal land descriptions.\n * @param options - Optional chunk size.\n * @returns Array of SearchResult or null for each input.\n */\n async batchSearch(\n locations: string[],\n options?: BatchSearchOptions\n ): Promise<(SearchResult | null)[]> {\n const chunkSize = Math.min(options?.chunkSize ?? MAX_BATCH_SIZE, MAX_BATCH_SIZE);\n const results: (SearchResult | null)[] = [];\n\n for (let i = 0; i < locations.length; i += chunkSize) {\n const chunk = locations.slice(i, i + chunkSize);\n const data = await this.request<(GeoJSONFeatureCollection | null)[]>(\n \"/batch/legal-location\",\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(chunk)\n }\n );\n\n for (const fc of data) {\n if (!fc || !fc.features?.length) {\n results.push(null);\n } else {\n results.push(toSearchResult(fc));\n }\n }\n }\n\n return results;\n }\n\n /**\n * Find legal land descriptions for multiple coordinate pairs in one request.\n * Auto-chunks if more than 100 items.\n *\n * @param coordinates - Array of [longitude, latitude] pairs.\n * @param options - Optional PLSS unit filter and chunk size.\n * @returns Array of SearchResult or null for each input.\n */\n async batchReverse(\n coordinates: [number, number][],\n options?: BatchReverseOptions\n ): Promise<(SearchResult | null)[]> {\n const chunkSize = Math.min(options?.chunkSize ?? MAX_BATCH_SIZE, MAX_BATCH_SIZE);\n const results: (SearchResult | null)[] = [];\n\n for (let i = 0; i < coordinates.length; i += chunkSize) {\n const chunk = coordinates.slice(i, i + chunkSize);\n const body: Record<string, unknown> = { coordinates: chunk };\n if (options?.unit) {\n body.unit = options.unit;\n }\n\n const data = await this.request<\n (GeoJSONFeatureCollection | null)[] | GeoJSONFeatureCollection\n >(\"/batch/coordinates\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body)\n });\n\n if (Array.isArray(data)) {\n for (const fc of data) {\n if (!fc || !fc.features?.length) {\n results.push(null);\n } else {\n results.push(toSearchResult(fc));\n }\n }\n } else if (data && \"features\" in data) {\n // unit=all returns a single FeatureCollection — split by legal_location\n const groups = new Map<string, typeof data.features>();\n for (const feature of data.features) {\n const key = JSON.stringify(feature.properties.search_term);\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(feature);\n }\n for (const features of groups.values()) {\n results.push(toSearchResult({ type: \"FeatureCollection\", features }));\n }\n }\n }\n\n return results;\n }\n\n // --- Convenience ---\n\n /**\n * Get the boundary polygon for a legal land description.\n *\n * @param legalLocation - e.g. \"NW 25 24N 1E 6th Meridian\"\n * @returns The boundary GeoJSON Polygon, or null if not found.\n */\n async boundary(legalLocation: string): Promise<GeoJSONBoundary | null> {\n const result = await this.search(legalLocation);\n return result.boundary;\n }\n\n /**\n * Get the raw GeoJSON FeatureCollection for a legal land description.\n *\n * @param legalLocation - e.g. \"NW 25 24N 1E 6th Meridian\"\n * @returns The raw GeoJSON FeatureCollection from the API.\n */\n async raw(legalLocation: string): Promise<GeoJSONFeatureCollection> {\n const params = new URLSearchParams({ location: legalLocation });\n const data = await this.request<GeoJSONFeatureCollection | Record<string, never>>(\n `/search/legal-location?${params}`\n );\n\n if (!(\"features\" in data)) {\n return { type: \"FeatureCollection\", features: [] };\n }\n\n return data as GeoJSONFeatureCollection;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { TownshipClient } from \"./client.js\";\nexport {\n TownshipError,\n AuthenticationError,\n NotFoundError,\n RateLimitError,\n ValidationError,\n PayloadTooLargeError\n} from \"./errors.js\";\nexport type {\n TownshipClientOptions,\n GeoJSONPoint,\n GeoJSONPolygon,\n GeoJSONMultiPolygon,\n GeoJSONBoundary,\n GeoJSONFeature,\n GeoJSONFeatureCollection,\n FeatureProperties,\n Unit,\n SurveySystem,\n SearchResult,\n ReverseOptions,\n AutocompleteOptions,\n BatchSearchOptions,\n BatchReverseOptions,\n // Shared report types\n LatLng,\n EntityRef,\n SectionEnvelope,\n UnavailableSection,\n SectionSource,\n ReportMeta,\n ReportParcel,\n // Energy API\n EnergyReportSection,\n EnergyReportOptions,\n EnergyWellRow,\n EnergyOrphanedWellRow,\n EnergyLeaseRow,\n EnergyOperatorRow,\n EnergyRoyaltyItem,\n EnergyRoyalties,\n EnergyPipelineRow,\n FracFocusRow,\n EnergySplitEstateSide,\n EnergySplitEstate,\n EnergySageGrouseHabitat,\n EnergySageGrouse,\n EnergyRenewableSiting,\n EnergyConstraints,\n EnergySummary,\n EnergyWells,\n EnergyReport,\n // Federal Land API\n FederalLandReportSection,\n FederalLandReportOptions,\n SurfaceManagementRow,\n FederalLeaseRow,\n RightOfWayRow,\n FloodZoneRow,\n MiningClaimRow,\n WetlandRow,\n FireshedRow,\n SoilRow,\n OrphanedWellRow,\n CriticalHabitatRow,\n PublicAccessRow,\n WildfireRiskRow,\n CropHistory,\n Elevation,\n FederalLandReport,\n // Texas API\n TexasReportSection,\n TexasReportOptions,\n TexasStateLeaseRow,\n TexasStateUnitRow,\n TexasPsfLandRow,\n TexasStateAgencyLandRow,\n TexasUplandLeaseRow,\n TexasActiveWellRow,\n TexasPipelineRow,\n TexasPendingPermitRow,\n TexasCoastalErosionRow,\n TexasMonthlyVolume,\n TexasProductionLease,\n TexasAbstractRef,\n TexasProductionSummary,\n TexasProductionBlock,\n TexasProduction,\n TexasReport,\n TexasProductionOptions,\n TexasWellLocation,\n TexasWellUnit,\n TexasWellSeriesPoint,\n TexasDeclineFit,\n TexasDecline,\n TexasDeclineCurvePoint,\n TexasWellSeriesUnit,\n TexasWell\n} from \"./types.js\";\n","/**\n * Base error class for all Township SDK errors.\n *\n * `code` carries the machine-readable error code the Energy, Federal Land,\n * and Texas APIs return in v1 error bodies (`{\"error\": {\"code\", \"message\"}}`),\n * e.g. `invalid_parameter`, `missing_parameter`, `plss_not_supported`,\n * `ambiguous_location`, `not_found`, `rate_limit_exceeded`. It is null for\n * endpoints that do not send one.\n */\nexport class TownshipError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number | null = null,\n public readonly code: string | null = null\n ) {\n super(message);\n this.name = \"TownshipError\";\n }\n}\n\n/**\n * Thrown when the API key is missing or invalid (HTTP 401).\n */\nexport class AuthenticationError extends TownshipError {\n constructor(message = \"Invalid or missing API key\", code: string | null = null) {\n super(message, 401, code);\n this.name = \"AuthenticationError\";\n }\n}\n\n/**\n * Thrown when no result is found for the given input.\n */\nexport class NotFoundError extends TownshipError {\n constructor(message = \"Location not found\", code: string | null = null) {\n super(message, 404, code);\n this.name = \"NotFoundError\";\n }\n}\n\n/**\n * Thrown when the API rate limit is exceeded (HTTP 429).\n */\nexport class RateLimitError extends TownshipError {\n constructor(\n message = \"Rate limit exceeded. Please slow down your requests.\",\n code: string | null = null\n ) {\n super(message, 429, code);\n this.name = \"RateLimitError\";\n }\n}\n\n/**\n * Thrown when the request is malformed (HTTP 400).\n */\nexport class ValidationError extends TownshipError {\n constructor(message = \"Invalid request\", code: string | null = null) {\n super(message, 400, code);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Thrown when the batch payload exceeds the maximum size (HTTP 413).\n */\nexport class PayloadTooLargeError extends TownshipError {\n constructor(\n message = \"Batch payload exceeds the maximum of 100 records per request\",\n code: string | null = null\n ) {\n super(message, 413, code);\n this.name = \"PayloadTooLargeError\";\n }\n}\n","import {\n AuthenticationError,\n NotFoundError,\n PayloadTooLargeError,\n RateLimitError,\n TownshipError,\n ValidationError\n} from \"./errors.js\";\nimport type {\n AutocompleteOptions,\n BatchReverseOptions,\n BatchSearchOptions,\n EnergyReport,\n EnergyReportOptions,\n FederalLandReport,\n FederalLandReportOptions,\n GeoJSONBoundary,\n GeoJSONFeatureCollection,\n ReverseOptions,\n SearchResult,\n TexasProduction,\n TexasProductionOptions,\n TexasReport,\n TexasReportOptions,\n TexasWell,\n TownshipClientOptions\n} from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://developer.townshipamerica.com\";\nconst DEFAULT_TIMEOUT = 30_000;\nconst MAX_BATCH_SIZE = 100;\n\nfunction toSearchResult(fc: GeoJSONFeatureCollection): SearchResult {\n const centroid = fc.features.find((f) => f.properties.shape === \"centroid\");\n const grid = fc.features.find((f) => f.properties.shape === \"grid\");\n\n const props = centroid?.properties ?? grid?.properties;\n if (!props) {\n throw new TownshipError(\"Unexpected API response: no features returned\");\n }\n\n const [lng, lat] = centroid ? (centroid.geometry.coordinates as [number, number]) : [0, 0];\n\n return {\n legalLocation: props.legal_location,\n latitude: lat,\n longitude: lng,\n state: props.state,\n county: props.county,\n unit: props.unit,\n surveySystem: props.survey_system,\n alternateLegalLocation: props.alternate_legal_location,\n boundary: grid ? (grid.geometry as GeoJSONBoundary) : null,\n raw: fc\n };\n}\n\nexport class TownshipClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly timeout: number;\n\n constructor(options: TownshipClientOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n\n if (!this.apiKey) {\n throw new TownshipError(\"apiKey is required\");\n }\n }\n\n // --- Internal ---\n\n private async request<T>(path: string, init?: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n ...init,\n headers: {\n \"X-API-Key\": this.apiKey,\n \"User-Agent\": \"townshipamerica-js/2.0.0\",\n ...(init?.headers ?? {})\n },\n signal: controller.signal\n });\n\n if (!response.ok) {\n await this.handleError(response);\n }\n\n return (await response.json()) as T;\n } catch (error) {\n if (error instanceof TownshipError) throw error;\n if (error instanceof DOMException && error.name === \"AbortError\") {\n throw new TownshipError(\"Request timed out\");\n }\n throw new TownshipError(error instanceof Error ? error.message : \"Unknown error\");\n } finally {\n clearTimeout(timer);\n }\n }\n\n private async handleError(response: Response): Promise<never> {\n let message: string;\n let code: string | null = null;\n try {\n const body = (await response.json()) as {\n error?: { code?: string; message?: string } | string;\n message?: string;\n };\n // Energy/Federal Land/Texas v1 error bodies are {\"error\": {\"code\", \"message\"}}\n if (body.error && typeof body.error === \"object\") {\n message = body.error.message ?? response.statusText;\n code = body.error.code ?? null;\n } else {\n message =\n (typeof body.error === \"string\" ? body.error : undefined) ??\n body.message ??\n response.statusText;\n }\n } catch {\n message = response.statusText;\n }\n\n const status = response.status;\n if (status === 400) throw new ValidationError(message, code);\n if (status === 401) throw new AuthenticationError(message, code);\n if (status === 404) throw new NotFoundError(message, code);\n if (status === 413) throw new PayloadTooLargeError(message, code);\n if (status === 429) throw new RateLimitError(message, code);\n throw new TownshipError(message, status, code);\n }\n\n // --- Search ---\n\n /**\n * Convert a PLSS or Texas TXSS legal land description to GPS coordinates.\n *\n * @param legalLocation - e.g. \"NW 25 24N 1E 6th Meridian\" or \"A-175 Reeves County\"\n * @returns A SearchResult with coordinates, boundary, and metadata.\n * @throws {ValidationError} If the location string is invalid.\n * @throws {NotFoundError} If no match is found.\n */\n async search(legalLocation: string): Promise<SearchResult> {\n const params = new URLSearchParams({ location: legalLocation });\n const data = await this.request<GeoJSONFeatureCollection | Record<string, never>>(\n `/search/legal-location?${params}`\n );\n\n if (!(\"features\" in data) || !data.features?.length) {\n throw new NotFoundError(`No results found for \"${legalLocation}\"`);\n }\n\n return toSearchResult(data as GeoJSONFeatureCollection);\n }\n\n /**\n * Find the legal land description at the given GPS coordinates (PLSS or Texas TXSS).\n *\n * @param longitude - Longitude (x) coordinate.\n * @param latitude - Latitude (y) coordinate.\n * @param options - Optional PLSS unit filter (ignored for TXSS results).\n * @returns A SearchResult or array of SearchResults (when unit is 'all').\n */\n async reverse(\n longitude: number,\n latitude: number,\n options?: ReverseOptions\n ): Promise<SearchResult | SearchResult[]> {\n const params = new URLSearchParams({\n location: `${longitude},${latitude}`\n });\n if (options?.unit) {\n params.set(\"unit\", options.unit);\n }\n\n const data = await this.request<GeoJSONFeatureCollection | Record<string, never>>(\n `/search/coordinates?${params}`\n );\n\n if (!(\"features\" in data) || !data.features?.length) {\n throw new NotFoundError(`No results found for coordinates [${longitude}, ${latitude}]`);\n }\n\n const fc = data as GeoJSONFeatureCollection;\n\n if (options?.unit === \"all\") {\n const groups = new Map<string, typeof fc.features>();\n for (const feature of fc.features) {\n const key = feature.properties.legal_location;\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(feature);\n }\n\n return Array.from(groups.values()).map((features) => {\n return toSearchResult({ type: \"FeatureCollection\", features });\n });\n }\n\n return toSearchResult(fc);\n }\n\n // --- Autocomplete ---\n\n /**\n * Get autocomplete suggestions for a partial PLSS or Texas TXSS description.\n *\n * @param query - Partial search query (minimum 2 characters).\n * @param options - Optional limit (1–10, default 3) and proximity.\n * @returns Raw GeoJSON FeatureCollection with suggestion features.\n */\n async autocomplete(\n query: string,\n options?: AutocompleteOptions\n ): Promise<GeoJSONFeatureCollection> {\n const params = new URLSearchParams({ location: query });\n if (options?.limit != null) {\n params.set(\"limit\", String(options.limit));\n }\n if (options?.proximity) {\n params.set(\"proximity\", `${options.proximity[0]},${options.proximity[1]}`);\n }\n\n return this.request<GeoJSONFeatureCollection>(`/autocomplete/legal-location?${params}`);\n }\n\n // --- Batch ---\n\n /**\n * Convert multiple legal land descriptions to GPS coordinates in one request.\n * Auto-chunks if more than 100 items. Mix PLSS and Texas TXSS inputs freely.\n *\n * @param locations - Array of legal land descriptions.\n * @param options - Optional chunk size.\n * @returns Array of SearchResult or null for each input.\n */\n async batchSearch(\n locations: string[],\n options?: BatchSearchOptions\n ): Promise<(SearchResult | null)[]> {\n const chunkSize = Math.min(options?.chunkSize ?? MAX_BATCH_SIZE, MAX_BATCH_SIZE);\n const results: (SearchResult | null)[] = [];\n\n for (let i = 0; i < locations.length; i += chunkSize) {\n const chunk = locations.slice(i, i + chunkSize);\n const data = await this.request<(GeoJSONFeatureCollection | null)[]>(\n \"/batch/legal-location\",\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(chunk)\n }\n );\n\n for (const fc of data) {\n if (!fc || !fc.features?.length) {\n results.push(null);\n } else {\n results.push(toSearchResult(fc));\n }\n }\n }\n\n return results;\n }\n\n /**\n * Find legal land descriptions for multiple coordinate pairs in one request.\n * Auto-chunks if more than 100 items.\n *\n * @param coordinates - Array of [longitude, latitude] pairs.\n * @param options - Optional PLSS unit filter and chunk size.\n * @returns Array of SearchResult or null for each input.\n */\n async batchReverse(\n coordinates: [number, number][],\n options?: BatchReverseOptions\n ): Promise<(SearchResult | null)[]> {\n const chunkSize = Math.min(options?.chunkSize ?? MAX_BATCH_SIZE, MAX_BATCH_SIZE);\n const results: (SearchResult | null)[] = [];\n\n for (let i = 0; i < coordinates.length; i += chunkSize) {\n const chunk = coordinates.slice(i, i + chunkSize);\n const body: Record<string, unknown> = { coordinates: chunk };\n if (options?.unit) {\n body.unit = options.unit;\n }\n\n const data = await this.request<\n (GeoJSONFeatureCollection | null)[] | GeoJSONFeatureCollection\n >(\"/batch/coordinates\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body)\n });\n\n if (Array.isArray(data)) {\n for (const fc of data) {\n if (!fc || !fc.features?.length) {\n results.push(null);\n } else {\n results.push(toSearchResult(fc));\n }\n }\n } else if (data && \"features\" in data) {\n // unit=all returns a single FeatureCollection — split by legal_location\n const groups = new Map<string, typeof data.features>();\n for (const feature of data.features) {\n const key = JSON.stringify(feature.properties.search_term);\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(feature);\n }\n for (const features of groups.values()) {\n results.push(toSearchResult({ type: \"FeatureCollection\", features }));\n }\n }\n }\n\n return results;\n }\n\n // --- Convenience ---\n\n /**\n * Get the boundary polygon for a legal land description.\n *\n * @param legalLocation - e.g. \"NW 25 24N 1E 6th Meridian\"\n * @returns The boundary GeoJSON Polygon, or null if not found.\n */\n async boundary(legalLocation: string): Promise<GeoJSONBoundary | null> {\n const result = await this.search(legalLocation);\n return result.boundary;\n }\n\n /**\n * Get the raw GeoJSON FeatureCollection for a legal land description.\n *\n * @param legalLocation - e.g. \"NW 25 24N 1E 6th Meridian\"\n * @returns The raw GeoJSON FeatureCollection from the API.\n */\n async raw(legalLocation: string): Promise<GeoJSONFeatureCollection> {\n const params = new URLSearchParams({ location: legalLocation });\n const data = await this.request<GeoJSONFeatureCollection | Record<string, never>>(\n `/search/legal-location?${params}`\n );\n\n if (!(\"features\" in data)) {\n return { type: \"FeatureCollection\", features: [] };\n }\n\n return data as GeoJSONFeatureCollection;\n }\n\n // --- Energy API ---\n\n /**\n * Get the energy parcel report for a PLSS section. Covers state-regulator\n * wells, operators, federal leases, county royalties, orphaned wells,\n * pipelines, FracFocus disclosures, and development constraints.\n *\n * @param legalLocation - A PLSS legal description, e.g. \"NW 25 24N 1E 6th Meridian\"\n * @param options - Optional section projection (`include`)\n * @returns The energy report\n *\n * @example\n * ```ts\n * const report = await client.energyReport('25 24N 1E 6th Meridian')\n * console.log(report.summary.wells_in_section)\n * console.log(report.wells?.in_section.rows[0]?.api_number)\n *\n * // Only the sections you need — the rest are never queried\n * const slim = await client.energyReport('25 24N 1E 6th Meridian', {\n * include: ['wells', 'pipelines']\n * })\n * ```\n */\n async energyReport(legalLocation: string, options?: EnergyReportOptions): Promise<EnergyReport> {\n const params = new URLSearchParams({ legal_location: legalLocation });\n if (options?.include?.length) params.set(\"include\", options.include.join(\",\"));\n return this.request<EnergyReport>(`/energy/report?${params}`);\n }\n\n // --- Federal Land API ---\n\n /**\n * Get the federal-land parcel report for a PLSS tract. Covers surface\n * management, BLM leases and rights-of-way, flood zones, mining claims,\n * wetlands, firesheds, soils, crop history, orphaned wells, critical\n * habitat, public access, wildfire risk, and elevation.\n *\n * @param legalLocation - A PLSS legal description, e.g. \"NW 25 24N 1E 6th Meridian\"\n * @param options - Optional section projection (`include`)\n * @returns The federal-land report\n *\n * @example\n * ```ts\n * const report = await client.federalLandReport('NW 25 24N 1E 6th Meridian')\n * console.log(report.surface_management?.rows[0]?.agency)\n *\n * // Only the sections you need — the pruned layers' queries never run\n * const slim = await client.federalLandReport('NW 25 24N 1E 6th Meridian', {\n * include: ['og_leases', 'flood_zones']\n * })\n * ```\n */\n async federalLandReport(\n legalLocation: string,\n options?: FederalLandReportOptions\n ): Promise<FederalLandReport> {\n const params = new URLSearchParams({ legal_location: legalLocation });\n if (options?.include?.length) params.set(\"include\", options.include.join(\",\"));\n return this.request<FederalLandReport>(`/federal-land/report?${params}`);\n }\n\n // --- Texas API ---\n\n /**\n * Get the Texas abstract report for a TXSS legal description. Covers GLO\n * state leases and units, PSF lands, RRC wells and pipelines, pending\n * permits, coastal erosion, federal overlays, and RRC lease production.\n *\n * @param legalLocation - A Texas legal description, e.g. \"A-175 Reeves County\"\n * @param options - Optional section projection (`include`)\n * @returns The Texas report\n *\n * @example\n * ```ts\n * const report = await client.texasReport('A-175 Reeves County')\n * console.log(report.active_wells?.rows[0]?.api_number)\n * console.log(report.production?.summary.total_cum_boe)\n *\n * // Only the sections you need — the rest are never queried\n * const slim = await client.texasReport('A-175 Reeves County', {\n * include: ['state_leases', 'production']\n * })\n * ```\n */\n async texasReport(legalLocation: string, options?: TexasReportOptions): Promise<TexasReport> {\n const params = new URLSearchParams({ legal_location: legalLocation });\n if (options?.include?.length) params.set(\"include\", options.include.join(\",\"));\n return this.request<TexasReport>(`/texas/report?${params}`);\n }\n\n /**\n * Get RRC lease production for a Texas abstract — per-lease lifetime\n * totals, trailing-12-month volumes, and the 60-month monthly series.\n * Production is reported by RRC at the LEASE level: rows are the leases\n * whose wells fall on the abstract, never sub-allocated to the tract.\n *\n * @param options - Either `{legalLocation}` or `{countyFips, abstractNo, blockNo?}`\n * @returns The abstract production rollup\n *\n * @example\n * ```ts\n * const byLocation = await client.texasProduction({ legalLocation: 'A-175 Reeves County' })\n * const byKeys = await client.texasProduction({ countyFips: '48389', abstractNo: '175' })\n * console.log(byKeys.summary.total_cum_boe)\n * ```\n */\n async texasProduction(options: TexasProductionOptions): Promise<TexasProduction> {\n const params = new URLSearchParams();\n if (options.legalLocation != null) {\n params.set(\"legal_location\", options.legalLocation);\n } else if (options.countyFips != null && options.abstractNo != null) {\n params.set(\"county_fips\", options.countyFips);\n params.set(\"abstract_no\", options.abstractNo);\n if (options.blockNo != null) params.set(\"block_no\", options.blockNo);\n } else {\n throw new TownshipError(\n \"texasProduction requires either legalLocation or countyFips + abstractNo\"\n );\n }\n return this.request<TexasProduction>(`/texas/production?${params}`);\n }\n\n /**\n * Get per-well allocated production for a Texas well by API number —\n * summary scalars for every lease edge, the monthly series (when\n * provisioned), and an Arps decline fit. Volumes are allocated estimates:\n * RRC reports production by lease, never by well.\n *\n * @param api - API-8 or API-14 number (e.g. \"42-389-32345\" or \"42389323450000\")\n * @returns The well's units, series, and decline analysis\n *\n * @example\n * ```ts\n * const well = await client.texasWell('42-389-32345')\n * console.log(well.units[0]?.cum_boe)\n * console.log(well.decline.available && well.decline.value?.di)\n * ```\n */\n async texasWell(api: string): Promise<TexasWell> {\n return this.request<TexasWell>(`/texas/wells/${encodeURIComponent(api)}`);\n }\n}\n"],"mappings":"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","names":[]}