Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ This project follows [Semantic Versioning](https://semver.org/).

### Added

- **`obligations_by_fiscal_year(fiscal_year, obligated)` shape expand on contracts, IDVs, OTAs and OT IDVs** (Tango API 5.11.0; parity with tango-python). Returns the award's obligations per federal fiscal year, oldest first, each rounded to cents. The new `FiscalYearObligation` model type and schema carry `fiscal_year` as an integer and `obligated` as a decimal, which the shaped response normalizes to a string like every money field. The API always sends `null` on IDVs and OT IDVs, whose transactions report a running lifetime total; the shaped contract and IDV methods read a `null` nested list as `[]`, as they do for every nested list.

- **`attachments(extraction_status)` shape field on opportunities and notices** (Tango API 5.11.0; parity with tango-python). Reports `pending`, `extracting`, `completed`, `failed` or `unsupported` for each attachment, so you can tell why `extracted_text` is missing. `OpportunityAttachment` gains the field, typed as an open string.

- **`commercial_item_acquisition_procedures` filter on `listContracts()` and `listIdvs()`** (Tango API 5.10.0; parity with tango-python), and on `listIdvAwards()` and `listIdvChildIdvs()`, which share those options. Filters by the FPDS commercial item acquisition procedures code: `A` (commercial products/services), `B` (products or services pursuant to FAR 12.102(f)), `C` (services pursuant to FAR 12.102(g)), `D` (commercial procedures not used) or `E` (DoD Section 803 Commercial Solutions Opening). Codes are case-insensitive and pipe-separated for OR, e.g. `"A|E"`; an unknown or multi-character code matches nothing. The API does not offer it on OTAs or OT IDVs, so `listOtas()` and `listOtidvs()` do not type it.

- **`PaginatedResponse.countType`** (parity with tango-python). `"exact"` or `"approximate"`, read from the API's `X-Results-CountType` header on every list method (`null` when the API doesn't send it). Past 1,000 matches the contract, IDV, opportunity and notice lists may return a query-planner estimate as `count`, which can be well off; this is how a caller tells the two apart. It is taken from each response itself, so concurrent calls on one client can't see each other's value the way `lastResponseHeaders` can.

- **Attachment file and link counts on opportunities and notices** (Tango API 5.9.0; parity with tango-python). Opportunities accept `meta(files_count,links_count)` beside `meta(attachments_count)`, and notices accept `file_count` and `link_count` beside `attachment_count`. An attachment's `type` is `file` (a document; only a file has extracted text) or `link` (a URL the notice lists). The new fields count each, and the existing total still counts every attachment, links included. An attachment of any other type counts only in the total, so files plus links need not equal it. The new fields are `null` until a record has been counted, so read `null` as unknown, not zero. `Opportunity` gains a typed `meta` (the new `OpportunityMeta`), `Notice` gains the three counts, and `docs/API_REFERENCE.md` documents the rules. The SDK's default shapes are unchanged, so name the fields in `shape`.

- **Federal Register documents** (Tango API 5.3.0; parity with tango-python). `listFederalRegisterDocuments(options)` and `getFederalRegisterDocument(uuid, options)` over `/api/federal_register/`, plus a `FederalRegisterDocument` model interface, a registered shape schema, and the `FEDERAL_REGISTER_MINIMAL` / `FEDERAL_REGISTER_COMPREHENSIVE` defaults. These are the rules, proposed rules, notices and presidential documents published in the Federal Register since 1994. All seventeen of the API's filters are typed options on `ListFederalRegisterDocumentsOptions`, including `comments_open`, `cfr_title` / `cfr_part`, `rin`, and both `agency` (a Tango organization, including its sub-agencies) and `fr_agency` (the Federal Register's own agency slug).
Expand Down Expand Up @@ -58,6 +66,8 @@ This project follows [Semantic Versioning](https://semver.org/).

### Changed

- Re-vendored `contracts/filter_shape_contract.json` for Tango API 5.11.0 and regenerated the overlay.
- Documented that `recipient_uei` on `listContracts()` (and `uei` on `listIdvs()`, `listOtas()` and `listOtidvs()`) accepts several UEIs joined by `|`, up to 500 (Tango API 5.11.0); the SDK already passed the value through unchanged.
- Re-vendored the contract for Tango API 5.9.0 (51 resources) and regenerated the overlay: 385 fields across 28 containers, 76 nested schemas. `contracts/observed_shape_types.json` is re-vendored from tango-python as well, so the new fields carry the types the API returns (`awards` is a list, `awarded` a boolean, `data_through_period` an integer) instead of types guessed from their names.
- Re-vendored `contracts/filter_shape_contract.json` (schema_version 2, 48 resources) and regenerated `src/shapes/generatedOverlay.ts` from it — 359 fields across 25 containers, 73 nested schemas.
- Re-vendored the contract for Tango API 5.1.0 and regenerated the overlay, which now merges a model's expand when two resources embed it instead of letting the narrower copy win.
Expand All @@ -70,13 +80,15 @@ This project follows [Semantic Versioning](https://semver.org/).

### Fixed

- **API errors now carry the server's reason** (parity with tango-python). A 403 or other non-2xx response the SDK had no dedicated error class for threw `TangoAPIError("API request failed with status 403")`, so a caller refused for a G2X-only shape field or a plan-gated filter couldn't tell why without digging into `responseData`. The message now ends with the API's own explanation (`API request failed with status 403: G2X shape fields are not allowed for your account.`), and the parsed body stays on `responseData`. Non-JSON bodies, such as a proxy's 502 page, keep the old message.
- **`attachments(name,doc_role,doc_role_alt)` no longer throws `ShapeValidationError`** on `getOpportunity`, `listOpportunities`, `getNotice` and `listNotices`; the API serves both fields on the Pro plan and above when they are named. New `OpportunityAttachment` and `AttachmentDocRole` types cover the six roles and are used on `Opportunity` and `Notice`.
- **SLED solicitations accept `delisted_at` and `meta(jurisdiction_declared)`**, which were rejected client-side. `SledOpportunity` and `SledMetaPayload` carry the new fields, and `status_reason` now documents `delisted`.
- **`ProtestRecord` types `agency` and `protester` as the strings the API returns**, and gains `title`, `docket_url`, `decision_url`, `organization`, `dockets` and `decisions`. The never-served `docket` property is deprecated in favor of `dockets`.
- **`getProtest` takes the case's `case_id` UUID**, which is all the route accepts; a case number returns 404. The parameter is renamed `caseId` and the docs say how to look a case up by number, and `listProtests` is documented as covering GAO, COFC and SBA OHA.

### Documentation

- `docs/API_REFERENCE.md` covers `obligations_by_fiscal_year`, `commercial_item_acquisition_procedures`, pipe-joined UEIs, `attachments(extraction_status)` and `countType`. `docs/WEBHOOKS.md` notes that `alerts.federal_register.match` and `alerts.ebuy_request.match` are alertable, with `query_type: "federal_register"` and `"ebuy_request"`.
- New **Federal Register** section in `docs/API_REFERENCE.md` with both methods and the full filter table, and both new constants in the `docs/SHAPES.md` preset table. `README.md`'s method list gained both methods.
- New **GSA eBuy** section in `docs/API_REFERENCE.md` covering all four methods, the full filter table, and the data caveats (the frozen `status`, the empty-list-not-error scoping, the short-lived attachment URL, the named-only `attachments(extracted_text)`). `README.md`'s method and error lists gained the new methods and error.
- New **Contract Appeals** section in `docs/API_REFERENCE.md` covering both methods, the full filter table, and the two properties that catch people out (the core-subset default and the tier-gated, absent-rather-than-null `decision_text`). `README.md`'s method list gained both methods.
Expand Down
Loading
Loading