deere-sdk 2.0.0 → 2.1.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.
- package/CHANGELOG.md +194 -0
- package/README.md +130 -20
- package/dist/api-servers.generated.d.ts +1 -1
- package/dist/api-servers.generated.js +1 -1
- package/dist/deere.d.ts +14 -0
- package/dist/deere.d.ts.map +1 -1
- package/dist/deere.js +20 -0
- package/dist/deere.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/safe/equipment.d.ts +92 -0
- package/dist/safe/equipment.d.ts.map +1 -0
- package/dist/safe/equipment.js +85 -0
- package/dist/safe/equipment.js.map +1 -0
- package/dist/safe/field-operations.d.ts +114 -0
- package/dist/safe/field-operations.d.ts.map +1 -0
- package/dist/safe/field-operations.js +112 -0
- package/dist/safe/field-operations.js.map +1 -0
- package/dist/safe/index.d.ts +52 -0
- package/dist/safe/index.d.ts.map +1 -0
- package/dist/safe/index.js +60 -0
- package/dist/safe/index.js.map +1 -0
- package/dist/safe/products.d.ts +53 -0
- package/dist/safe/products.d.ts.map +1 -0
- package/dist/safe/products.js +46 -0
- package/dist/safe/products.js.map +1 -0
- package/dist/types/generated/field-operations-api.d.ts +19 -0
- package/dist/types/generated/field-operations-api.d.ts.map +1 -1
- package/dist/types/generated/index.d.ts +1 -1
- package/dist/types/generated/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,200 @@ 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
|
+
## [2.1.1] - 2026-04-14
|
|
9
|
+
|
|
10
|
+
**Patch release completing 2.1.0's intended scope.** 2.1.0 shipped one safe
|
|
11
|
+
facade method — `deere.safe.fieldOperations.listAllWithMeasurements` — against
|
|
12
|
+
a plan that explicitly deferred `list`/`get` variants and silently omitted any
|
|
13
|
+
audit of the rest of the embed surface. A post-ship audit found that the same
|
|
14
|
+
silent-zero bug class was still loaded on TWO other field-operations methods,
|
|
15
|
+
plus the entire equipment and products families. 2.1.1 fixes that.
|
|
16
|
+
|
|
17
|
+
Framing as a patch is technically stretched (2.1.1 adds public API surface,
|
|
18
|
+
which semver-purists would call a minor), but the work here is completing
|
|
19
|
+
2.1.0's promise to kill the embed footgun in the `fieldOperations` family and
|
|
20
|
+
extending that guarantee to adjacent families where JD's spec documents narrow
|
|
21
|
+
embed enum values. Nothing in 2.1.0 is broken or removed.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **`deere.safe.fieldOperations.listWithMeasurements(orgId, fieldId, params?)`** —
|
|
26
|
+
paginated single-page variant. Returns `PaginatedResponse<FieldOperationWithMeasurements>`.
|
|
27
|
+
Forces `embed=measurementTypes`, runtime-verifies every operation on the
|
|
28
|
+
returned page carries the `measurementTypes` array, throws `DeereError` on
|
|
29
|
+
contract violation. Same guarantee contract as `listAllWithMeasurements`.
|
|
30
|
+
- **`deere.safe.fieldOperations.getWithMeasurements(operationId, params?)`** —
|
|
31
|
+
single-operation-by-id variant. Returns `FieldOperationIdWithMeasurements`.
|
|
32
|
+
JD treats the list-shape (`FieldOperation`) and get-shape (`FieldOperationId`)
|
|
33
|
+
as separate schemas; 2.1.0's spec patch only covered `FieldOperation`. 2.1.1
|
|
34
|
+
adds a matching patch for `FieldOperationId` so the narrowed return type on
|
|
35
|
+
the single-op path is honest.
|
|
36
|
+
- **`FieldOperationIdWithMeasurements`** — new exported type, the narrowed
|
|
37
|
+
variant of `FieldOperationId`.
|
|
38
|
+
- **`deere.safe.equipment`** (new facade, `SafeEquipmentApi`) — six methods
|
|
39
|
+
wrapping every embed-accepting raw method on `EquipmentApi`:
|
|
40
|
+
`getWithEmbed`, `getEquipmentWithEmbed`, `listEquipmentmodelsWithEmbed`,
|
|
41
|
+
`listEquipmentisgtypesWithEmbed`, `getEquipmentisgtypesWithEmbed`,
|
|
42
|
+
`getEquipmentisgtypes2WithEmbed`. Each method makes the `embed` parameter
|
|
43
|
+
**required at the type level** — TypeScript refuses to compile a call that
|
|
44
|
+
forgets it. Embed values follow JD's documented enums (`devices`, `equipment`,
|
|
45
|
+
`icon`, `pairingDetails`, `offsets`, `capabilities`, `make`, `type`, `isgType`,
|
|
46
|
+
`equipmentModels`, `recordMetadata`).
|
|
47
|
+
- **`deere.safe.products`** (new facade, `SafeProductsApi`) — three methods
|
|
48
|
+
wrapping every embed-accepting raw method on `ProductsApi`: `listWithEmbed`,
|
|
49
|
+
`listAllWithEmbed`, `getWithEmbed`. Embed values are JD's documented enum:
|
|
50
|
+
`documents`, `showMergedProducts`.
|
|
51
|
+
- **Spec patch: `FieldOperationId.measurementTypes`** — mirrors the 2.1.0
|
|
52
|
+
patch on `FieldOperation` so both the list-shape and get-shape carry the
|
|
53
|
+
optional array in the generated types. Added via one new `addProperty` entry
|
|
54
|
+
in `scripts/embed-contracts.yaml`.
|
|
55
|
+
|
|
56
|
+
### Important scope note — what 2.1.1 does NOT cover
|
|
57
|
+
|
|
58
|
+
Equipment and Products safe facades are **type-level forcing functions only**.
|
|
59
|
+
They require the caller to pass `embed`, but they do NOT narrow the return
|
|
60
|
+
type and do NOT runtime-verify that response fields are populated. The reason:
|
|
61
|
+
we don't yet have empirical wire traces confirming which response fields each
|
|
62
|
+
embed value populates on those endpoints. Without that evidence, any type
|
|
63
|
+
narrowing or runtime assertion would be guessing. 2.1.0's pattern of spec
|
|
64
|
+
patch + narrowed type + runtime verification is deferred for these families
|
|
65
|
+
until `field-mcp/scripts/jd-probe-shapes.ts` captures wire traces for
|
|
66
|
+
equipment and products. Once captured, a future release can tighten the
|
|
67
|
+
wrappers with the same registry-driven mechanism.
|
|
68
|
+
|
|
69
|
+
The following endpoints also take an `embed` parameter but **remain unwrapped
|
|
70
|
+
in 2.1.1** because JD's published OpenAPI spec documents the embed as a bare
|
|
71
|
+
`string` with no enum values — we literally cannot know what values the caller
|
|
72
|
+
should be forced to pass. These endpoints are still raw-only and still expose
|
|
73
|
+
the silent-zero footgun to callers who forget the embed: `boundaries.list`,
|
|
74
|
+
`boundaries.listAll`, `boundaries.listBoundaries`, `clients.list`,
|
|
75
|
+
`clients.listAll`, `clients.get`, `farms.list`, `farms.listAll`, `farms.get`,
|
|
76
|
+
`assets.list`, `assets.listAll`, `assets.get`, `guidance-lines.list`,
|
|
77
|
+
`guidance-lines.listAll`, `guidance-lines.get`, `harvest-id.list`,
|
|
78
|
+
`harvest-id.listAll`, `harvest-id.get`, `operators.list`, `operators.listAll`,
|
|
79
|
+
`operators.get`, `map-layers.list`, `map-layers.listAll`, `users.*`,
|
|
80
|
+
`flags.*`, `fields.*`. A proper audit of these requires both empirical wire
|
|
81
|
+
traces AND a fix-specs patch to tighten the `embed?: string` type to a
|
|
82
|
+
narrow enum, and is tracked as a future work item.
|
|
83
|
+
|
|
84
|
+
### Migration
|
|
85
|
+
|
|
86
|
+
If FieldMCP (or any other consumer) calls `fieldOperations.list` or
|
|
87
|
+
`fieldOperations.get` and reads measurement data from the response, migrate:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// Before — silent data loss if embed is forgotten
|
|
91
|
+
const page = await deere.fieldOperations.list(orgId, fieldId);
|
|
92
|
+
const op = await deere.fieldOperations.get(operationId);
|
|
93
|
+
|
|
94
|
+
// After — guaranteed measurementTypes, throws on contract drift
|
|
95
|
+
const page = await deere.safe.fieldOperations.listWithMeasurements(orgId, fieldId);
|
|
96
|
+
const op = await deere.safe.fieldOperations.getWithMeasurements(operationId);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
For equipment and products, the migration is the same pattern but the safe
|
|
100
|
+
wrapper just forces you to pick an embed at compile time:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
// Raw (compiles, will silently miss fields when you forget embed)
|
|
104
|
+
const equipmentList = await deere.equipment.get();
|
|
105
|
+
|
|
106
|
+
// Safe (refuses to compile unless you pass embed)
|
|
107
|
+
const equipmentList = await deere.safe.equipment.getWithEmbed({ embed: 'devices' });
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Unchanged
|
|
111
|
+
|
|
112
|
+
- Everything shipped in 2.1.0. `listAllWithMeasurements` is untouched, same
|
|
113
|
+
signature, same guarantee.
|
|
114
|
+
- Raw `FieldOperationsApi`, `EquipmentApi`, `ProductsApi` method signatures.
|
|
115
|
+
- Error hierarchy, URL resolution, HATEOAS mode.
|
|
116
|
+
- The contract registry mechanism and `applyEmbedContracts` patcher.
|
|
117
|
+
|
|
118
|
+
## [2.1.0] - 2026-04-14
|
|
119
|
+
|
|
120
|
+
**Minor, additive release.** Kills a footgun on `fieldOperations.listAll` by
|
|
121
|
+
introducing a "safe facade" layer (`deere.safe.*`) that forces query params
|
|
122
|
+
John Deere's API requires for a complete response but the raw SDK leaves
|
|
123
|
+
optional. Also adds a contract registry that lets future SDK patches encode
|
|
124
|
+
JD spec gaps in one place instead of across hand-written wrappers.
|
|
125
|
+
|
|
126
|
+
### Why
|
|
127
|
+
|
|
128
|
+
John Deere's API documents `embed` as an optional query param on
|
|
129
|
+
`GET /organizations/{orgId}/fields/{fieldId}/fieldOperations`, but silently
|
|
130
|
+
omits the `measurementTypes` array on every returned FieldOperation unless
|
|
131
|
+
the request passes `?embed=measurementTypes`. Downstream consumers that
|
|
132
|
+
forget the embed param get objects with zero values for yield, area,
|
|
133
|
+
moisture, application rate, and seeding population — and can't tell "missing
|
|
134
|
+
data" from "real zero" because JD's OpenAPI spec never documents the
|
|
135
|
+
invariant. FieldMCP shipped placeholder data to production three separate
|
|
136
|
+
times because of this exact bug. 2.1.0 makes "forget the embed param"
|
|
137
|
+
syntactically impossible.
|
|
138
|
+
|
|
139
|
+
### Added
|
|
140
|
+
|
|
141
|
+
- **`deere.safe.fieldOperations.listAllWithMeasurements(orgId, fieldId, params?)`**
|
|
142
|
+
— returns `FieldOperationWithMeasurements[]` (non-optional `measurementTypes`
|
|
143
|
+
array). Forces `embed=measurementTypes` on the outgoing request, and verifies
|
|
144
|
+
every returned operation actually carries the array, throwing `DeereError`
|
|
145
|
+
with the operation id on any contract violation. Empty `measurementTypes: []`
|
|
146
|
+
is valid (the operation has no recorded measurements yet); `undefined` is not
|
|
147
|
+
and fails loudly.
|
|
148
|
+
- **`SafeFacades` class** on `deere.safe` — composition root for safe facades.
|
|
149
|
+
Adding a new safe wrapper means writing a file under `src/safe/` and adding
|
|
150
|
+
one field + one constructor init to `SafeFacades`. The codegen at
|
|
151
|
+
`scripts/generate-sdk.ts` is deliberately kept dumb about what's inside
|
|
152
|
+
`SafeFacades` — it only emits the wire-up, never the contents.
|
|
153
|
+
- **`FieldOperationWithMeasurements`** type — re-exported from the main entry
|
|
154
|
+
for consumers who need to reference the narrowed shape directly.
|
|
155
|
+
- **`scripts/embed-contracts.yaml`** — new registry encoding JD's undocumented
|
|
156
|
+
invariants as a list of OpenAPI schema-patch operations. Consumed at codegen
|
|
157
|
+
time by `scripts/fix-specs.ts`'s `applyEmbedContracts()` transform before
|
|
158
|
+
`openapi-typescript` runs, so the generated types include the
|
|
159
|
+
previously-missing fields with JD's own declared schemas as `$ref` targets.
|
|
160
|
+
- **Generated type `ApplicationProductTotal`** and optional properties
|
|
161
|
+
`FieldOperation.measurementTypes: FieldOperationMeasurement[]` and
|
|
162
|
+
`FieldOperationMeasurementInFullRelease.applicationProductTotals:
|
|
163
|
+
ApplicationProductTotal[]` — produced by the registry patcher and visible to
|
|
164
|
+
both safe-path and raw-path callers.
|
|
165
|
+
|
|
166
|
+
### Migration
|
|
167
|
+
|
|
168
|
+
Replace raw `listAll` calls that read measurement data with the safe variant:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
// Before — silently returns FieldOperation objects without measurementTypes
|
|
172
|
+
// unless you remember to pass embed, and the type system doesn't warn you.
|
|
173
|
+
const ops = await deere.fieldOperations.listAll(orgId, fieldId);
|
|
174
|
+
const yield_ = ops[0].measurementTypes; // ← undefined, silent data loss
|
|
175
|
+
|
|
176
|
+
// After — always populated, type-guaranteed, throws clearly on drift
|
|
177
|
+
const ops = await deere.safe.fieldOperations.listAllWithMeasurements(
|
|
178
|
+
orgId,
|
|
179
|
+
fieldId
|
|
180
|
+
);
|
|
181
|
+
const yield_ = ops[0].measurementTypes[0]?.averageYield?.value; // typed, narrowed
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Raw `deere.fieldOperations.listAll` still exists and still works — it's the
|
|
185
|
+
right tool for metadata-only callers (calendar UIs, operation listings that
|
|
186
|
+
don't consume measurement data). The raw return type now carries
|
|
187
|
+
`measurementTypes?: FieldOperationMeasurement[]` as an optional field, so
|
|
188
|
+
raw-path consumers can read it when they pass the embed param themselves,
|
|
189
|
+
but with a compile-time nudge that it might be absent.
|
|
190
|
+
|
|
191
|
+
### Unchanged
|
|
192
|
+
|
|
193
|
+
- `FieldOperationsApi.listAll` signature, behavior, and existing query param
|
|
194
|
+
semantics. No breaking changes.
|
|
195
|
+
- All other generated API classes.
|
|
196
|
+
- Error hierarchy, HATEOAS mode, URL resolution, retry policy.
|
|
197
|
+
- `openapi-typescript` version, generator script structure (aside from the
|
|
198
|
+
three literal-string insertions in `generateMainClass()` that wire up
|
|
199
|
+
`SafeFacades` — see `scripts/generate-sdk.ts` and the `// DO NOT REORDER`
|
|
200
|
+
comment it emits into the generated `deere.ts`).
|
|
201
|
+
|
|
8
202
|
## [2.0.0] - 2026-04-13
|
|
9
203
|
|
|
10
204
|
**Major release.** URL resolution is now fully spec-driven. This release fixes
|
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/images/hero.png" alt="deere-sdk">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
<h1 align="center">deere-sdk</h1>
|
|
2
6
|
|
|
3
7
|
<p align="center">
|
|
@@ -59,7 +63,7 @@ import {Deere} from 'deere-sdk';
|
|
|
59
63
|
|
|
60
64
|
const deere = new Deere({
|
|
61
65
|
accessToken: 'your-oauth-access-token',
|
|
62
|
-
environment: '
|
|
66
|
+
environment: 'sandboxapi', // or 'api' for production
|
|
63
67
|
});
|
|
64
68
|
|
|
65
69
|
// List all organizations
|
|
@@ -98,13 +102,48 @@ This SDK requires an OAuth 2.0 access token from John Deere:
|
|
|
98
102
|
<details>
|
|
99
103
|
<summary><strong>Environments</strong></summary>
|
|
100
104
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
|
104
|
-
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
105
|
+
v2.0.0 uses raw John Deere subdomain names as environment values. Pass the subdomain (without `.deere.com`) as `environment`. Default: `sandboxapi`.
|
|
106
|
+
|
|
107
|
+
| Environment | URL | Use Case |
|
|
108
|
+
|------------------|----------------------------|----------------------------------|
|
|
109
|
+
| `api` | api.deere.com | Live production |
|
|
110
|
+
| `sandboxapi` | sandboxapi.deere.com | Development (default) |
|
|
111
|
+
| `partnerapi` | partnerapi.deere.com | Partner production |
|
|
112
|
+
| `apicert` | apicert.deere.com | Production certification |
|
|
113
|
+
| `partnerapicert` | partnerapicert.deere.com | Partner certification |
|
|
114
|
+
| `apiqa.tal` | apiqa.tal.deere.com | QA tier |
|
|
115
|
+
| `partnerapiqa` | partnerapiqa.deere.com | Partner QA |
|
|
116
|
+
| `sandboxapiqa` | sandboxapiqa.deere.com | Sandbox QA |
|
|
117
|
+
| `apidev.tal` | apidev.tal.deere.com | Internal dev tier (rarely used) |
|
|
118
|
+
|
|
119
|
+
Not every spec has servers for every environment. If you pick an environment a given spec doesn't ship (e.g., a production-only spec on `sandboxapi`), the constructor throws `UnsupportedEnvironmentError` with the valid values for that spec.
|
|
120
|
+
|
|
121
|
+
</details>
|
|
122
|
+
|
|
123
|
+
<details>
|
|
124
|
+
<summary><strong>Migrating from v1</strong></summary>
|
|
125
|
+
|
|
126
|
+
v1 accepted friendly environment names. v2.0.0 replaces them with the raw John Deere subdomain names so URL routing comes directly from each spec's OpenAPI `servers` block — no more hardcoded hostname maps.
|
|
127
|
+
|
|
128
|
+
Passing a v1 name to the v2 constructor throws immediately with a migration hint:
|
|
129
|
+
|
|
130
|
+
| v1 (pre-2.0.0) | v2.0.0+ |
|
|
131
|
+
|----------------|----------------|
|
|
132
|
+
| `production` | `api` |
|
|
133
|
+
| `sandbox` | `sandboxapi` |
|
|
134
|
+
| `partner` | `partnerapi` |
|
|
135
|
+
| `cert` | `apicert` |
|
|
136
|
+
| `qa` | `apiqa.tal` |
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// v1
|
|
140
|
+
const deere = new Deere({ accessToken, environment: 'sandbox' });
|
|
141
|
+
|
|
142
|
+
// v2.0.0
|
|
143
|
+
const deere = new Deere({ accessToken, environment: 'sandboxapi' });
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The SDK now uses separate host subdomains per spec family (e.g., `equipmentapi.deere.com` for machine telemetry, `api.deere.com` for organizations) on the production tier. v1 silently routed everything through `api.deere.com`, which worked for most flows but mis-routed some machine-data endpoints. v2 routes each call to the exact host the spec declares.
|
|
108
147
|
|
|
109
148
|
</details>
|
|
110
149
|
|
|
@@ -290,14 +329,26 @@ const models = await deere.equipment.listEquipmentmodels({equipmentModelName: '9
|
|
|
290
329
|
<summary><strong>Field Operations</strong></summary>
|
|
291
330
|
|
|
292
331
|
```typescript
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
//
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
332
|
+
// Prefer the safe facade when you need measurement data (yield, area,
|
|
333
|
+
// moisture, application rate, seeding population). It forces
|
|
334
|
+
// ?embed=measurementTypes on the request and guarantees the returned
|
|
335
|
+
// operations carry a measurementTypes array, throwing a clear error if
|
|
336
|
+
// JD's wire format ever drifts from the documented contract.
|
|
337
|
+
const ops = await deere.safe.fieldOperations.listAllWithMeasurements(
|
|
338
|
+
'org-id',
|
|
339
|
+
'field-id'
|
|
340
|
+
);
|
|
341
|
+
const yieldValue = ops[0].measurementTypes[0]?.averageYield?.value;
|
|
342
|
+
|
|
343
|
+
// Filter by type and season — filters forward through to the safe wrapper too.
|
|
344
|
+
const harvests = await deere.safe.fieldOperations.listAllWithMeasurements(
|
|
345
|
+
'org-id',
|
|
346
|
+
'field-id',
|
|
347
|
+
{ cropSeason: '2026', fieldOperationType: 'harvest' }
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
// Raw API (no forcing) — use when you only need metadata, not measurements.
|
|
351
|
+
const metaOnly = await deere.fieldOperations.list('org-id', 'field-id');
|
|
301
352
|
|
|
302
353
|
// Get operation details
|
|
303
354
|
const op = await deere.fieldOperations.get('operation-id');
|
|
@@ -309,6 +360,17 @@ const shapefile = await deere.fieldOperations.getFieldops('operation-id', {
|
|
|
309
360
|
});
|
|
310
361
|
```
|
|
311
362
|
|
|
363
|
+
**Why `deere.safe.*`?** John Deere's API silently omits the `measurementTypes`
|
|
364
|
+
array on `fieldOperations.listAll` responses unless the request passes
|
|
365
|
+
`?embed=measurementTypes`, and their OpenAPI spec doesn't document that
|
|
366
|
+
invariant. Consumers that forget the embed param get objects with zero values
|
|
367
|
+
for yield, area, moisture, and rate — and can't tell "missing data" from "real
|
|
368
|
+
zero." The safe facade makes that footgun syntactically impossible: you can't
|
|
369
|
+
call `listAllWithMeasurements` without the embed param because the wrapper
|
|
370
|
+
adds it for you, and the returned type guarantees `measurementTypes` is
|
|
371
|
+
present. See `src/safe/` and `scripts/embed-contracts.yaml` for the spec-patch
|
|
372
|
+
machinery that makes the narrowed type honest at the type level.
|
|
373
|
+
|
|
312
374
|
</details>
|
|
313
375
|
|
|
314
376
|
<details>
|
|
@@ -452,7 +514,7 @@ import {DeereClient} from 'deere-sdk';
|
|
|
452
514
|
|
|
453
515
|
const client = new DeereClient({
|
|
454
516
|
accessToken: 'your-token',
|
|
455
|
-
environment: '
|
|
517
|
+
environment: 'sandboxapi',
|
|
456
518
|
timeout: 30000, // Request timeout in ms (default: 30000)
|
|
457
519
|
maxRetries: 3, // Retry attempts (default: 3, set to 0 to disable)
|
|
458
520
|
});
|
|
@@ -470,6 +532,25 @@ for await (const items of client.paginate('/large/collection')) {
|
|
|
470
532
|
}
|
|
471
533
|
```
|
|
472
534
|
|
|
535
|
+
### fetchUrl — Bearer token hostname guard
|
|
536
|
+
|
|
537
|
+
`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.
|
|
538
|
+
|
|
539
|
+
```typescript
|
|
540
|
+
// Bearer token attached (trusted host)
|
|
541
|
+
await client.fetchUrl('GET', 'https://api.deere.com/platform/organizations');
|
|
542
|
+
|
|
543
|
+
// Bearer token SUPPRESSED (untrusted host) — request still goes out, just without Authorization
|
|
544
|
+
await client.fetchUrl('GET', 'https://example.com/some-webhook');
|
|
545
|
+
|
|
546
|
+
// You can opt in explicitly by passing your own Authorization header:
|
|
547
|
+
await client.fetchUrl('GET', 'https://example.com/api', undefined, {
|
|
548
|
+
headers: { Authorization: 'Bearer some-other-token' },
|
|
549
|
+
});
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Enable `hateoasDebug: true` to see a `console.warn` whenever a token is suppressed, so you can audit where your HATEOAS graph is pointing.
|
|
553
|
+
|
|
473
554
|
---
|
|
474
555
|
|
|
475
556
|
## HATEOAS Mode
|
|
@@ -479,7 +560,7 @@ John Deere requires applications to demonstrate [HATEOAS](https://en.wikipedia.o
|
|
|
479
560
|
```typescript
|
|
480
561
|
const deere = new Deere({
|
|
481
562
|
accessToken: 'your-token',
|
|
482
|
-
environment: '
|
|
563
|
+
environment: 'sandboxapi',
|
|
483
564
|
hateoas: true, // Enable HATEOAS link traversal
|
|
484
565
|
hateoasDebug: true, // Optional: log resolution details
|
|
485
566
|
});
|
|
@@ -499,7 +580,7 @@ import {Deere} from 'deere-sdk';
|
|
|
499
580
|
// 1. Create client with HATEOAS enabled
|
|
500
581
|
const deere = new Deere({
|
|
501
582
|
accessToken: 'your-oauth-token',
|
|
502
|
-
environment: '
|
|
583
|
+
environment: 'sandboxapi',
|
|
503
584
|
hateoas: true,
|
|
504
585
|
hateoasDebug: true, // See link resolution in console
|
|
505
586
|
});
|
|
@@ -573,8 +654,23 @@ const deere = new Deere({
|
|
|
573
654
|
|
|
574
655
|
### Error Types
|
|
575
656
|
|
|
657
|
+
| Error | When it's thrown | Retried? |
|
|
658
|
+
|-------------------------------|-------------------------------------------------------------------|----------|
|
|
659
|
+
| `DeereError` | Base class. Any HTTP error from John Deere (400/404/422/5xx). | Only 5xx |
|
|
660
|
+
| `RateLimitError` | HTTP 429. Only reaches your catch after all retries are exhausted. | Yes |
|
|
661
|
+
| `AuthError` | HTTP 401/403. Refresh your OAuth token. | No |
|
|
662
|
+
| `HateoasError` | HATEOAS link resolution fails (parent fetch errored or no matching link). | No |
|
|
663
|
+
| `UnsupportedEnvironmentError` | Constructor threw because `environment` doesn't match the spec's `servers` block. | N/A (thrown at construction) |
|
|
664
|
+
| `NoServerConfigError` | Constructor threw because a spec has no `servers` block at all. | N/A |
|
|
665
|
+
|
|
576
666
|
```typescript
|
|
577
|
-
import {
|
|
667
|
+
import {
|
|
668
|
+
DeereError,
|
|
669
|
+
RateLimitError,
|
|
670
|
+
AuthError,
|
|
671
|
+
HateoasError,
|
|
672
|
+
UnsupportedEnvironmentError,
|
|
673
|
+
} from 'deere-sdk';
|
|
578
674
|
|
|
579
675
|
try {
|
|
580
676
|
const fields = await deere.fields.listAll('org-id');
|
|
@@ -585,6 +681,12 @@ try {
|
|
|
585
681
|
} else if (error instanceof AuthError) {
|
|
586
682
|
// Never retried - refresh your token
|
|
587
683
|
console.log('Token expired - refresh required');
|
|
684
|
+
} else if (error instanceof HateoasError) {
|
|
685
|
+
// HATEOAS link resolution failed (only when hateoas: true)
|
|
686
|
+
console.log(`Link resolution failed on ${error.path}: ${error.message}`);
|
|
687
|
+
} else if (error instanceof UnsupportedEnvironmentError) {
|
|
688
|
+
// Spec doesn't ship this environment — try another from its valid list
|
|
689
|
+
console.log(error.message);
|
|
588
690
|
} else if (error instanceof DeereError) {
|
|
589
691
|
console.log(`API error: ${error.status} ${error.message}`);
|
|
590
692
|
}
|
|
@@ -691,6 +793,14 @@ git push --follow-tags
|
|
|
691
793
|
|
|
692
794
|
CI sees the tag → creates GitHub Release → publishes to npm.
|
|
693
795
|
|
|
796
|
+
**Gotcha:** GitHub sometimes does not fire the `push` event for a tag pushed via `git push --follow-tags`, so `release.yml` never auto-triggers. If you don't see a "Create Release" run within a minute of pushing the tag, dispatch it manually:
|
|
797
|
+
|
|
798
|
+
```bash
|
|
799
|
+
gh workflow run release.yml --ref vX.Y.Z
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
`release.yml` also accepts `workflow_dispatch`, so this produces an identical run against the tag's commit.
|
|
803
|
+
|
|
694
804
|
---
|
|
695
805
|
|
|
696
806
|
## Disclaimer
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* API server configuration per spec — single source of truth for URL resolution.
|
|
3
3
|
*
|
|
4
4
|
* @generated by scripts/generate-api-servers.ts — do not edit manually
|
|
5
|
-
* Last generated: 2026-04-
|
|
5
|
+
* Last generated: 2026-04-14T21:02:00.480Z
|
|
6
6
|
*
|
|
7
7
|
* Env coverage matrix (X = supported, - = throws UnsupportedEnvironmentError):
|
|
8
8
|
*
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* API server configuration per spec — single source of truth for URL resolution.
|
|
3
3
|
*
|
|
4
4
|
* @generated by scripts/generate-api-servers.ts — do not edit manually
|
|
5
|
-
* Last generated: 2026-04-
|
|
5
|
+
* Last generated: 2026-04-14T21:02:00.480Z
|
|
6
6
|
*
|
|
7
7
|
* Env coverage matrix (X = supported, - = throws UnsupportedEnvironmentError):
|
|
8
8
|
*
|
package/dist/deere.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { AempApi, AssetsApi, BoundariesApi, ClientsApi, ConnectionManagementApi, CropTypesApi, EquipmentApi, EquipmentMeasurementApi, FarmsApi, FieldOperationsApi, FieldsApi, FilesApi, FlagsApi, GuidanceLinesApi, HarvestIdApi, MachineAlertsApi, MachineDeviceStateReportsApi, MachineEngineHoursApi, MachineHoursOfOperationApi, MachineLocationsApi, MapLayersApi, NotificationsApi, OperatorsApi, OrganizationsApi, PartnershipsApi, ProductsApi, UsersApi, WebhookApi } from './api/index.js';
|
|
8
8
|
import { DeereClient, type DeereClientConfig } from './client.js';
|
|
9
|
+
import { SafeFacades } from './safe/index.js';
|
|
9
10
|
/**
|
|
10
11
|
* John Deere SDK
|
|
11
12
|
*
|
|
@@ -23,6 +24,14 @@ import { DeereClient, type DeereClientConfig } from './client.js';
|
|
|
23
24
|
* const orgs = await deere.organizations.listAll();
|
|
24
25
|
* const farms = await deere.farms.listAll(orgs[0].id);
|
|
25
26
|
* const fields = await deere.fields.listAll(orgs[0].id);
|
|
27
|
+
*
|
|
28
|
+
* // Safe facades force query params that JD's API requires for a complete
|
|
29
|
+
* // response but the raw SDK leaves optional. See src/safe/ and
|
|
30
|
+
* // scripts/embed-contracts.yaml for the contract invariants they enforce.
|
|
31
|
+
* const ops = await deere.safe.fieldOperations.listAllWithMeasurements(
|
|
32
|
+
* orgs[0].id,
|
|
33
|
+
* fields[0].id
|
|
34
|
+
* );
|
|
26
35
|
* ```
|
|
27
36
|
*/
|
|
28
37
|
export declare class Deere {
|
|
@@ -84,6 +93,11 @@ export declare class Deere {
|
|
|
84
93
|
readonly users: UsersApi;
|
|
85
94
|
/** webhook API */
|
|
86
95
|
readonly webhook: WebhookApi;
|
|
96
|
+
/**
|
|
97
|
+
* Safe facades that force query params the raw API leaves optional (e.g.
|
|
98
|
+
* `embed=measurementTypes`). See src/safe/ and scripts/embed-contracts.yaml.
|
|
99
|
+
*/
|
|
100
|
+
readonly safe: SafeFacades;
|
|
87
101
|
constructor(config: DeereClientConfig);
|
|
88
102
|
}
|
|
89
103
|
/**
|
package/dist/deere.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deere.d.ts","sourceRoot":"","sources":["../src/deere.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,OAAO,EACP,SAAS,EACT,aAAa,EACb,UAAU,EACV,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,uBAAuB,EACvB,QAAQ,EACR,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,4BAA4B,EAC5B,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,QAAQ,EACR,UAAU,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"deere.d.ts","sourceRoot":"","sources":["../src/deere.ts"],"names":[],"mappings":"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"}
|
package/dist/deere.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { AempApi, AssetsApi, BoundariesApi, ClientsApi, ConnectionManagementApi, CropTypesApi, EquipmentApi, EquipmentMeasurementApi, FarmsApi, FieldOperationsApi, FieldsApi, FilesApi, FlagsApi, GuidanceLinesApi, HarvestIdApi, MachineAlertsApi, MachineDeviceStateReportsApi, MachineEngineHoursApi, MachineHoursOfOperationApi, MachineLocationsApi, MapLayersApi, NotificationsApi, OperatorsApi, OrganizationsApi, PartnershipsApi, ProductsApi, UsersApi, WebhookApi, } from './api/index.js';
|
|
8
8
|
import { DeereClient } from './client.js';
|
|
9
|
+
import { SafeFacades } from './safe/index.js';
|
|
9
10
|
/**
|
|
10
11
|
* John Deere SDK
|
|
11
12
|
*
|
|
@@ -23,6 +24,14 @@ import { DeereClient } from './client.js';
|
|
|
23
24
|
* const orgs = await deere.organizations.listAll();
|
|
24
25
|
* const farms = await deere.farms.listAll(orgs[0].id);
|
|
25
26
|
* const fields = await deere.fields.listAll(orgs[0].id);
|
|
27
|
+
*
|
|
28
|
+
* // Safe facades force query params that JD's API requires for a complete
|
|
29
|
+
* // response but the raw SDK leaves optional. See src/safe/ and
|
|
30
|
+
* // scripts/embed-contracts.yaml for the contract invariants they enforce.
|
|
31
|
+
* const ops = await deere.safe.fieldOperations.listAllWithMeasurements(
|
|
32
|
+
* orgs[0].id,
|
|
33
|
+
* fields[0].id
|
|
34
|
+
* );
|
|
26
35
|
* ```
|
|
27
36
|
*/
|
|
28
37
|
export class Deere {
|
|
@@ -84,6 +93,11 @@ export class Deere {
|
|
|
84
93
|
users;
|
|
85
94
|
/** webhook API */
|
|
86
95
|
webhook;
|
|
96
|
+
/**
|
|
97
|
+
* Safe facades that force query params the raw API leaves optional (e.g.
|
|
98
|
+
* `embed=measurementTypes`). See src/safe/ and scripts/embed-contracts.yaml.
|
|
99
|
+
*/
|
|
100
|
+
safe;
|
|
87
101
|
constructor(config) {
|
|
88
102
|
this.client = new DeereClient(config);
|
|
89
103
|
this.aemp = new AempApi(this.client);
|
|
@@ -114,6 +128,12 @@ export class Deere {
|
|
|
114
128
|
this.products = new ProductsApi(this.client);
|
|
115
129
|
this.users = new UsersApi(this.client);
|
|
116
130
|
this.webhook = new WebhookApi(this.client);
|
|
131
|
+
// DO NOT REORDER: SafeFacades reads generated API fields (e.g.
|
|
132
|
+
// `this.fieldOperations`), so it MUST run AFTER every API field has
|
|
133
|
+
// been initialized above. The runtime guard in SafeFacades' constructor
|
|
134
|
+
// fires loudly if this line ever moves ahead of the generated field
|
|
135
|
+
// inits. See scripts/generate-sdk.ts generateMainClass() for the source.
|
|
136
|
+
this.safe = new SafeFacades(this);
|
|
117
137
|
}
|
|
118
138
|
}
|
|
119
139
|
/**
|
package/dist/deere.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deere.js","sourceRoot":"","sources":["../src/deere.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,OAAO,EACP,SAAS,EACT,aAAa,EACb,UAAU,EACV,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,uBAAuB,EACvB,QAAQ,EACR,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,4BAA4B,EAC5B,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,QAAQ,EACR,UAAU,GACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAA0B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"deere.js","sourceRoot":"","sources":["../src/deere.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -32,5 +32,6 @@ export * from './api/index.js';
|
|
|
32
32
|
export type { DeereClientConfig, Environment, Link, PaginatedResponse, RequestOptions, } from './client.js';
|
|
33
33
|
export { AuthError, createClient, DeereClient, DeereError, HateoasError, RateLimitError, } from './client.js';
|
|
34
34
|
export { createDeere, Deere } from './deere.js';
|
|
35
|
+
export { type FieldOperationIdWithMeasurements, type FieldOperationWithMeasurements, SafeEquipmentApi, SafeFacades, SafeFieldOperationsApi, SafeProductsApi, } from './safe/index.js';
|
|
35
36
|
export * as Types from './types/index.js';
|
|
36
37
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,IAAI,EACJ,iBAAiB,EACjB,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,IAAI,EACJ,iBAAiB,EACjB,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAIhD,OAAO,EACL,KAAK,gCAAgC,EACrC,KAAK,8BAA8B,EACnC,gBAAgB,EAChB,WAAW,EACX,sBAAsB,EACtB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,9 @@ export * from './api/index.js';
|
|
|
34
34
|
export { AuthError, createClient, DeereClient, DeereError, HateoasError, RateLimitError, } from './client.js';
|
|
35
35
|
// Main SDK class
|
|
36
36
|
export { createDeere, Deere } from './deere.js';
|
|
37
|
+
// Safe facades that force query params the raw API leaves optional.
|
|
38
|
+
// See scripts/embed-contracts.yaml and src/safe/ for context.
|
|
39
|
+
export { SafeEquipmentApi, SafeFacades, SafeFieldOperationsApi, SafeProductsApi, } from './safe/index.js';
|
|
37
40
|
// OpenAPI Types (for advanced usage)
|
|
38
41
|
export * as Types from './types/index.js';
|
|
39
42
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,cAAc;AACd,cAAc,gBAAgB,CAAC;AAQ/B,mBAAmB;AACnB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEhD,qCAAqC;AACrC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,cAAc;AACd,cAAc,gBAAgB,CAAC;AAQ/B,mBAAmB;AACnB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEhD,oEAAoE;AACpE,8DAA8D;AAC9D,OAAO,EAGL,gBAAgB,EAChB,WAAW,EACX,sBAAsB,EACtB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAEzB,qCAAqC;AACrC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC"}
|