deere-sdk 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +47 -22
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.0.1] - 2026-09-07
9
+
10
+ ### Changed
11
+ - Synced with latest John Deere API specifications
12
+
8
13
  ## [3.0.0] - 2026-08-13
9
14
 
10
15
  Two published methods were resolving to URLs that do not exist, and a third was
package/README.md CHANGED
@@ -31,12 +31,12 @@
31
31
 
32
32
  ## Highlights
33
33
 
34
- - **28 APIs** with **146 operations** — Full coverage of John Deere agricultural APIs
34
+ - **28 APIs** with **201 methods** — Full coverage of John Deere agricultural APIs
35
35
  - **Fully typed** — Auto-generated TypeScript types from OpenAPI specs
36
36
  - **Auto-pagination** — `listAll()` methods handle pagination automatically
37
37
  - **HAL support** — Built-in link following for John Deere's HAL-style responses
38
38
  - **Automatic retries** — Exponential backoff with jitter for transient failures
39
- - **Daily health checks** — Automated monitoring of API availability
39
+ - **Daily health checks** — Automated monitoring of spec availability and live route reachability
40
40
 
41
41
  ---
42
42
 
@@ -117,7 +117,7 @@ Authoritative list of scopes supported by the authorization server: [`https://si
117
117
  <details>
118
118
  <summary><strong>Environments</strong></summary>
119
119
 
120
- v2.0.0 uses raw John Deere subdomain names as environment values. Pass the subdomain (without `.deere.com`) as `environment`. Default: `sandboxapi`.
120
+ The SDK uses raw John Deere subdomain names as environment values. Pass the subdomain (without `.deere.com`) as `environment`. Default: `sandboxapi`.
121
121
 
122
122
  | Environment | URL | Use Case |
123
123
  |------------------|----------------------------|----------------------------------|
@@ -162,6 +162,23 @@ The SDK now uses separate host subdomains per spec family (e.g., `equipmentapi.d
162
162
 
163
163
  </details>
164
164
 
165
+ <details>
166
+ <summary><strong>Migrating from v2</strong></summary>
167
+
168
+ One method was removed. Everything else is source-compatible.
169
+
170
+ | Removed | Replacement |
171
+ |--------------------------------|-------------|
172
+ | `deere.organizations.listUsers` | None |
173
+
174
+ `GET /organizations/{orgId}/users` returns 404 in every environment and appears in none of the 85 APIs John Deere publishes. It had reached the SDK through a hand-written spec injection rather than from a published spec, so it shipped as a typed method that could never succeed. Any call to it was already failing.
175
+
176
+ There is no replacement. `GET /organizations/{orgId}/staff` exists but returned 403 to an application holding full scopes, and no response body has been captured, so shipping a method for it would mean inventing its types. See `CHANGELOG.md` for the measurements.
177
+
178
+ Two methods that previously returned 404 now work, with no signature change: `deere.notifications.get` and `deere.products.listActiveIngredients`. Both were building `/platform` URLs for routes John Deere serves from `/isg`.
179
+
180
+ </details>
181
+
165
182
  ---
166
183
 
167
184
  ## API Reference
@@ -170,30 +187,30 @@ The SDK now uses separate host subdomains per spec family (e.g., `equipmentapi.d
170
187
 
171
188
  | API | Property | Methods | Description |
172
189
  |---------------------------------------------------------------------------|------------------------------|---------|-----------------------------------|
173
- | [Organizations](https://developer.deere.com/dev-docs/organizations) | `deere.organizations` | 5 | Organization management |
190
+ | [Organizations](https://developer.deere.com/dev-docs/organizations) | `deere.organizations` | 4 | Organization management |
174
191
  | [Fields](https://developer.deere.com/dev-docs/fields) | `deere.fields` | 8 | Field CRUD and boundaries |
175
192
  | [Farms](https://developer.deere.com/dev-docs/farms) | `deere.farms` | 8 | Farm management |
176
193
  | [Boundaries](https://developer.deere.com/dev-docs/boundaries) | `deere.boundaries` | 8 | Field boundary management |
177
194
  | [Clients](https://developer.deere.com/dev-docs/clients) | `deere.clients` | 8 | Customer management |
178
195
  | [Equipment](https://developer.deere.com/dev-docs/equipment) | `deere.equipment` | 16 | Machines and implements |
179
- | [Field Operations](https://developer.deere.com/dev-docs/field-operations) | `deere.fieldOperations` | 4 | Harvests, plantings, applications |
196
+ | [Field Operations](https://developer.deere.com/dev-docs/field-operations) | `deere.fieldOperations` | 6 | Harvests, plantings, applications |
180
197
  | [Crop Types](https://developer.deere.com/dev-docs/crop-types) | `deere.cropTypes` | 5 | Crop type catalog |
181
- | [Products](https://developer.deere.com/dev-docs/products) | `deere.products` | 10 | Seeds and chemicals catalog |
182
- | [Map Layers](https://developer.deere.com/dev-docs/map-layers) | `deere.mapLayers` | 5 | Map layer management |
183
- | [Files](https://developer.deere.com/dev-docs/files) | `deere.files` | 6 | File management |
184
- | [Flags](https://developer.deere.com/dev-docs/flags) | `deere.flags` | 7 | Field flags/markers |
198
+ | [Products](https://developer.deere.com/dev-docs/products) | `deere.products` | 39 | Seeds and chemicals catalog |
199
+ | [Map Layers](https://developer.deere.com/dev-docs/map-layers) | `deere.mapLayers` | 15 | Map layer management |
200
+ | [Files](https://developer.deere.com/dev-docs/files) | `deere.files` | 10 | File management |
201
+ | [Flags](https://developer.deere.com/dev-docs/flags) | `deere.flags` | 15 | Field flags/markers |
185
202
  | [Guidance Lines](https://developer.deere.com/dev-docs/guidance-lines) | `deere.guidanceLines` | 5 | GPS guidance lines |
186
203
  | [Operators](https://developer.deere.com/dev-docs/operators) | `deere.operators` | 7 | Machine operator management |
187
204
  | [Users](https://developer.deere.com/dev-docs/users) | `deere.users` | 1 | User information |
188
205
  | [Assets](https://developer.deere.com/dev-docs/assets) | `deere.assets` | 9 | Asset tracking |
189
- | [Webhooks](https://developer.deere.com/dev-docs/webhook) | `deere.webhook` | 5 | Event subscriptions |
206
+ | [Webhooks](https://developer.deere.com/dev-docs/webhook) | `deere.webhook` | 7 | Event subscriptions |
190
207
  | [Connections](https://developer.deere.com/dev-docs/connection-management) | `deere.connectionManagement` | 4 | OAuth connections |
191
208
 
192
209
  ### Machine Data APIs
193
210
 
194
211
  | API | Property | Methods | Description |
195
212
  |---------------------------------------------------------------------------------------|-----------------------------------|---------|---------------------------|
196
- | [Machine Locations](https://developer.deere.com/dev-docs/machine-locations) | `deere.machineLocations` | 1 | GPS location history |
213
+ | [Machine Locations](https://developer.deere.com/dev-docs/machine-locations) | `deere.machineLocations` | 2 | GPS location history |
197
214
  | [Machine Alerts](https://developer.deere.com/dev-docs/machine-alerts) | `deere.machineAlerts` | 2 | DTC alerts |
198
215
  | [Engine Hours](https://developer.deere.com/dev-docs/machine-engine-hours) | `deere.machineEngineHours` | 2 | Engine hours tracking |
199
216
  | [Hours of Operation](https://developer.deere.com/dev-docs/machine-hours-of-operation) | `deere.machineHoursOfOperation` | 2 | On/off duration |
@@ -531,19 +548,25 @@ const client = new DeereClient({
531
548
  maxRetries: 3, // Retry attempts (default: 3, set to 0 to disable)
532
549
  });
533
550
 
534
- // Raw requests
535
- const response = await client.get<CustomType>('/some/endpoint');
536
- const created = await client.post('/some/endpoint', {data: 'value'});
551
+ // Raw requests. The first argument is the spec name; it selects the host,
552
+ // since different John Deere APIs live on different subdomains and paths.
553
+ const response = await client.get<CustomType>('organizations', '/organizations');
554
+ const created = await client.post('fields', '/organizations/123/fields', {name: 'North'});
537
555
 
538
556
  // Follow HAL links
539
557
  const nextPage = await client.followLink(response.links[0]);
540
558
 
541
559
  // Automatic pagination
542
- for await (const items of client.paginate('/large/collection')) {
560
+ for await (const items of client.paginate('fields', '/organizations/123/fields')) {
543
561
  console.log(items);
544
562
  }
563
+
564
+ // Or collect every page at once
565
+ const all = await client.getAll('fields', '/organizations/123/fields');
545
566
  ```
546
567
 
568
+ There is no `baseUrl` option. Each spec declares its own host, so the URL is resolved per call from the spec name and the environment. Passing a spec name that does not ship your chosen environment throws `UnsupportedEnvironmentError` before any request goes out.
569
+
547
570
  ### fetchUrl — Bearer token hostname guard
548
571
 
549
572
  `DeereClient` exposes `fetchUrl(method, url, body?, options?)` and `followLink(url)` for calling absolute URLs (e.g., HAL `next` page links, externally-discovered URLs). Both **suppress the OAuth Bearer token** on any URL whose hostname is not a trusted `*.deere.com` origin. This prevents accidental token leakage if a HATEOAS response, user-supplied URL, or link cache ever includes a third-party host.
@@ -598,7 +621,7 @@ const deere = new Deere({
598
621
  });
599
622
 
600
623
  // 2. Warm the cache (optional — reduces cold-start latency)
601
- await deere.client.warmLinkCache(['/organizations']);
624
+ await deere.client.warmLinkCache('organizations', ['/organizations']);
602
625
 
603
626
  // 3. Use the SDK normally — HATEOAS happens transparently
604
627
  const orgs = await deere.organizations.listAll();
@@ -723,13 +746,15 @@ type Equipment = Types.Equipment.components['schemas']['equipment-model'];
723
746
 
724
747
  ## API Status
725
748
 
726
- This SDK includes automated daily health checks to monitor John Deere API availability.
749
+ This SDK includes automated daily checks against John Deere's live infrastructure. One asks whether every spec is still published and consumable; the other asks whether every URL the SDK builds still corresponds to a route that exists.
750
+
751
+ | Status | Meaning |
752
+ |--------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
753
+ | ![passing](https://img.shields.io/badge/API%20Health-28%2F28-brightgreen?style=flat-square) | Every spec is fresh from John Deere's portal and validates |
754
+ | ![degraded](https://img.shields.io/badge/API%20Health-27%2F28,%201%20frozen-yellow?style=flat-square) | The only shortfall is specs deliberately frozen with a recorded reason and date |
755
+ | ![failing](https://img.shields.io/badge/API%20Health-25%2F28-red?style=flat-square) | An active spec cannot be fetched or validated, so the pipeline is blind to it |
727
756
 
728
- | Status | Meaning |
729
- |---------------------------------------------------------------------------------------------|------------------------------------------------|
730
- | ![passing](https://img.shields.io/badge/API%20Health-28%2F28-brightgreen?style=flat-square) | All APIs responding with valid specs |
731
- | ![degraded](https://img.shields.io/badge/API%20Health-25%2F28-yellow?style=flat-square) | Some APIs unavailable or returning empty specs |
732
- | ![failing](https://img.shields.io/badge/API%20Health-10%2F28-red?style=flat-square) | Major API outage detected |
757
+ Yellow is not a partial outage. A frozen spec is one this repo deliberately pins to a committed copy rather than the portal's current document, usually because adopting the current one would drop a method that still works. `scripts/spec-registry.yaml` records which specs are frozen, why, and since when. Green means nothing is pinned.
733
758
 
734
759
  <details>
735
760
  <summary><strong>APIs Without Public Specs</strong></summary>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deere-sdk",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Unofficial TypeScript SDK for John Deere Operations Center API",
5
5
  "author": "ProductOfAmerica",
6
6
  "license": "MIT",