From d89fe54529884b6eb82c256c68f055c3e66466d9 Mon Sep 17 00:00:00 2001 From: "V. David Zvenyach" Date: Fri, 14 Aug 2026 11:33:05 -0500 Subject: [PATCH 1/7] feat(conformance): vendor API contract 4.22.0; offline filter + reverse shape-coverage gates Ports tango-python's contract-vendoring architecture: conformance now runs offline against contracts/filter_shape_contract.json as a hard CI gate, with a token-gated warn-only staleness diff. Adds scripts/check-shape-coverage.ts (reverse gate), conformance + shape-coverage baselines capturing the current parity backlog, and gate tests. Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 68 +- CHANGELOG.md | 11 + contracts/conformance_baseline.json | 14 + contracts/filter_shape_contract.json | 9240 +++++++++++++++++ contracts/shape_coverage_baseline.json | 428 + package.json | 1 + scripts/check-filter-shape-conformance.ts | 123 +- scripts/check-shape-coverage.ts | 435 + tests/scripts/conformance.test.ts | 95 +- .../scripts/fixtures/mini-baseline-stale.json | 7 + tests/scripts/fixtures/mini-baseline.json | 7 + tests/scripts/shape-coverage.test.ts | 111 + 12 files changed, 10463 insertions(+), 77 deletions(-) create mode 100644 contracts/conformance_baseline.json create mode 100644 contracts/filter_shape_contract.json create mode 100644 contracts/shape_coverage_baseline.json create mode 100644 scripts/check-shape-coverage.ts create mode 100644 tests/scripts/fixtures/mini-baseline-stale.json create mode 100644 tests/scripts/fixtures/mini-baseline.json create mode 100644 tests/scripts/shape-coverage.test.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7463743..ce49bbc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,12 +2,14 @@ name: CI # Lint + typecheck + test gate runs on every PR and push to main. # -# The SDK filter/shape conformance check needs the canonical manifest from the -# private makegov/tango repo, which requires a TANGO_API_REPO_ACCESS_TOKEN secret -# the public CI does not have. The conformance job SKIPS cleanly when the token -# is absent (rather than failing on an empty token) and becomes a hard gate the -# moment the secret is configured. The lint + test gate below is self-contained -# and blocks the PR on failure. +# The SDK filter/shape conformance check and the reverse shape-coverage check +# are HARD gates that run offline against the vendored contract at +# contracts/filter_shape_contract.json — no secrets needed, so forks and +# tokenless runs get the full check instead of a silent skip. A second, +# token-gated step compares the vendored contract against the tango repo's +# HEAD and emits a staleness notice (never a failure — tango HEAD may carry +# unreleased changes). Refresh the vendored contract by copying +# contracts/filter_shape_contract.json from makegov/tango. on: push: branches: [ main ] @@ -52,13 +54,33 @@ jobs: run: npx vitest run conformance: - # Requires the canonical filter_shape manifest from the private makegov/tango - # repo. When TANGO_API_REPO_ACCESS_TOKEN is not configured, every real step - # is skipped and the job passes (rather than failing on an empty token). - # Configure the secret to turn this into a hard gate automatically. + # Hard gate against the vendored contract (contracts/filter_shape_contract.json). + # Runs unconditionally — no secrets required, so forks and tokenless runs + # get the full check instead of a silent skip. runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install dependencies + run: npm install --ignore-scripts --no-audit --no-fund + + - name: Check SDK filter/shape conformance (vendored contract) + run: npx tsx scripts/check-filter-shape-conformance.ts + + - name: Check reverse shape coverage (Tango exposes -> SDK captures) + # Complements the conformance check with the OTHER direction: fails when + # Tango's shape trees expose a field/expand the SDK schema doesn't capture + # and it isn't in contracts/shape_coverage_baseline.json. Also offline + # against the vendored contract — no secrets, works on forks. + run: npx tsx scripts/check-shape-coverage.ts + + # --- Staleness notice (best-effort, never fails the job) --------------- - name: Determine token availability id: gate env: @@ -68,13 +90,10 @@ jobs: echo "ready=true" >> "$GITHUB_OUTPUT" else echo "ready=false" >> "$GITHUB_OUTPUT" - echo "::notice::Skipping SDK conformance check — TANGO_API_REPO_ACCESS_TOKEN not configured." + echo "::notice::Contract staleness check skipped — TANGO_API_REPO_ACCESS_TOKEN not configured." fi - - uses: actions/checkout@v4 - if: steps.gate.outputs.ready == 'true' - - - name: Checkout tango API repo (manifest source) + - name: Checkout tango API repo (contract source) if: steps.gate.outputs.ready == 'true' uses: actions/checkout@v4 with: @@ -82,16 +101,11 @@ jobs: path: tango-api token: ${{ secrets.TANGO_API_REPO_ACCESS_TOKEN }} - - name: Set up Node.js - if: steps.gate.outputs.ready == 'true' - uses: actions/setup-node@v4 - with: - node-version: "20" - - - name: Install dependencies - if: steps.gate.outputs.ready == 'true' - run: npm install --ignore-scripts --no-audit --no-fund - - - name: Check SDK filter/shape conformance + - name: Compare vendored contract against tango HEAD if: steps.gate.outputs.ready == 'true' - run: npx tsx scripts/check-filter-shape-conformance.ts --manifest tango-api/contracts/filter_shape_contract.json + run: | + if ! diff -q contracts/filter_shape_contract.json tango-api/contracts/filter_shape_contract.json >/dev/null; then + echo "::warning::Vendored contract differs from makegov/tango HEAD. Refresh contracts/filter_shape_contract.json and re-run the conformance gates." + else + echo "Vendored contract matches makegov/tango HEAD." + fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 6aa88da..952ebb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ This project follows [Semantic Versioning](https://semver.org/). ## [Unreleased] +### Added +- Vendored the canonical API filter/shape contract at `contracts/filter_shape_contract.json` (API 4.22.0), so conformance checking is fully offline — no token, no sibling checkout. +- New reverse shape-coverage gate `scripts/check-shape-coverage.ts` (npm script `check-shape-coverage`): walks every resource's shape tree in the vendored contract against the SDK's explicit schema registry and fails on any field or expand the SDK does not capture, unless recorded in `contracts/shape_coverage_baseline.json` as tracked backlog. +- Accepted-gaps baselines: `contracts/conformance_baseline.json` (missing filters + unimplemented resources) and `contracts/shape_coverage_baseline.json` (known shape-coverage gaps). Baselined gaps report as warnings; anything new is an error. + +### Changed +- `scripts/check-filter-shape-conformance.ts` now defaults to the vendored contract instead of a sibling `../tango` checkout (`TANGO_CONTRACT_PATH` or `--manifest` still point it at a live checkout), covers every resource in the 4.22.0 contract in its resource map, and treats an unimplemented resource as an error unless baselined. + +### CI +- The `conformance` job is now a hard gate that runs both conformance directions offline against the vendored contract on every PR — it no longer needs `TANGO_API_REPO_ACCESS_TOKEN` and no longer skips silently without it. A separate token-gated step diffs the vendored contract against makegov/tango HEAD and emits a staleness warning (never a failure). + ## [1.1.0] - 2026-05-29 ### Changed (breaking) diff --git a/contracts/conformance_baseline.json b/contracts/conformance_baseline.json new file mode 100644 index 0000000..ebd6e17 --- /dev/null +++ b/contracts/conformance_baseline.json @@ -0,0 +1,14 @@ +{ + "_comment": "Accepted SDK coverage gaps vs the API contract. Gaps listed here downgrade from error to warning in scripts/check-filter-shape-conformance.ts. Each entry is tracked backlog: remove it in the same PR that closes the gap in the SDK. `missing_filters` maps a resource to filter params the mapped method does not expose; `unimplemented_resources` lists contract resources with no SDK method at all. dibbs/*, exclusions, and sbir/* are pending implementation; events and news are content endpoints with no list method and stay baselined permanently (tango-python does the same).", + "missing_filters": {}, + "unimplemented_resources": [ + "dibbs/awards", + "dibbs/rfps", + "dibbs/rfqs", + "events", + "exclusions", + "news", + "sbir/solicitations", + "sbir/topics" + ] +} diff --git a/contracts/filter_shape_contract.json b/contracts/filter_shape_contract.json new file mode 100644 index 0000000..d68bd21 --- /dev/null +++ b/contracts/filter_shape_contract.json @@ -0,0 +1,9240 @@ +{ + "meta": { + "api_version": "4.22.0", + "description": "Canonical API filter/shape contract. Downstream consumers (SDK, MCP) should validate their conformance against this manifest.", + "generated_from": "scripts/filter_shape_conformance.py", + "schema_version": 2 + }, + "policy": { + "critical_runtime_swagger_resources": [] + }, + "resources": { + "agencies": { + "basename": "agency", + "docs_file": null, + "docs_params": [], + "prefix": "agencies", + "resource_key": "agencies", + "runtime": { + "filter_params": [ + "search" + ], + "filter_params_detail": { + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "department": { + "expands": {}, + "fields": [ + "abbreviation", + "cgac", + "code", + "congressional_justification", + "description", + "name", + "website" + ] + } + }, + "fields": [ + "abbreviation", + "code", + "name" + ] + }, + "shape_flat_paths": [ + "abbreviation", + "code", + "department", + "department.abbreviation", + "department.cgac", + "department.code", + "department.congressional_justification", + "department.description", + "department.name", + "department.website", + "name" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "agencies.views.AgencyViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "search", + "shape", + "show_shapes" + ] + }, + "assistance_listings": { + "basename": "assistancelisting", + "docs_file": null, + "docs_params": [], + "prefix": "assistance_listings", + "resource_key": "assistance_listings", + "runtime": { + "filter_params": [], + "filter_params_detail": {}, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "StaticModelCachedPagination", + "max_page_size": 10000 + }, + "shape": { + "expands": {}, + "fields": [ + "applicant_eligibility", + "archived_date", + "benefit_eligibility", + "number", + "objectives", + "popular_name", + "published_date", + "title" + ] + }, + "shape_flat_paths": [ + "applicant_eligibility", + "archived_date", + "benefit_eligibility", + "number", + "objectives", + "popular_name", + "published_date", + "title" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "shared.views.AssistanceListingViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "shape", + "show_shapes" + ] + }, + "budget/accounts": { + "basename": "budget-account", + "docs_file": null, + "docs_params": [], + "prefix": "budget/accounts", + "resource_key": "budget/accounts", + "runtime": { + "filter_params": [ + "account_title__icontains", + "actual_vs_requested_contract", + "actual_vs_requested_contract__gte", + "actual_vs_requested_contract__lte", + "actual_vs_requested_contract_capped", + "actual_vs_requested_contract_capped__gte", + "actual_vs_requested_contract_capped__lte", + "agency_code", + "agency_code__in", + "apportioned", + "apportioned__gte", + "apportioned__lte", + "apportioned_to_enacted_pct", + "apportioned_to_enacted_pct__gte", + "apportioned_to_enacted_pct__lte", + "apportioned_to_enacted_pct_capped", + "apportioned_to_enacted_pct_capped__gte", + "apportioned_to_enacted_pct_capped__lte", + "assistance_obligated", + "assistance_obligated__gte", + "assistance_obligated__lte", + "assistance_outlayed", + "assistance_outlayed__gte", + "assistance_outlayed__lte", + "ba_growth_next_year_pct", + "ba_growth_next_year_pct__gte", + "ba_growth_next_year_pct__lte", + "bea_category", + "bea_category__in", + "bureau_name", + "bureau_name__icontains", + "bureau_name__in", + "contract_obligated", + "contract_obligated__gte", + "contract_obligated__lte", + "contract_outlayed", + "contract_outlayed__gte", + "contract_outlayed__lte", + "contract_share_of_obligated_capped", + "contract_share_of_obligated_capped__gte", + "contract_share_of_obligated_capped__lte", + "enacted_ba", + "enacted_ba_5yr_cagr", + "enacted_ba_5yr_cagr__gte", + "enacted_ba_5yr_cagr__lte", + "enacted_ba__gte", + "enacted_ba__lte", + "enacted_ba_yoy_pct", + "enacted_ba_yoy_pct__gte", + "enacted_ba_yoy_pct__lte", + "federal_account_symbol", + "federal_account_symbol__in", + "fiscal_year", + "fiscal_year__gte", + "fiscal_year__in", + "fiscal_year__lte", + "obligated_to_apportioned_pct", + "obligated_to_apportioned_pct__gte", + "obligated_to_apportioned_pct__lte", + "obligated_to_apportioned_pct_capped", + "obligated_to_apportioned_pct_capped__gte", + "obligated_to_apportioned_pct_capped__lte", + "obligated_to_enacted_pct", + "obligated_to_enacted_pct__gte", + "obligated_to_enacted_pct__lte", + "obligated_to_enacted_pct_capped", + "obligated_to_enacted_pct_capped__gte", + "obligated_to_enacted_pct_capped__lte", + "obligated_total", + "obligated_total__gte", + "obligated_total__lte", + "obligated_yoy_pct", + "obligated_yoy_pct__gte", + "obligated_yoy_pct__lte", + "on_off_budget", + "outlayed_to_obligated_pct", + "outlayed_to_obligated_pct__gte", + "outlayed_to_obligated_pct__lte", + "outlayed_to_obligated_pct_capped", + "outlayed_to_obligated_pct_capped__gte", + "outlayed_to_obligated_pct_capped__lte", + "outlayed_total", + "outlayed_total__gte", + "outlayed_total__lte", + "requested_ba", + "requested_ba__gte", + "requested_ba__lte", + "search", + "subfunction_code", + "subfunction_code__in", + "unobligated_balance", + "unobligated_balance__gte", + "unobligated_balance__lte", + "unobligated_pct", + "unobligated_pct__gte", + "unobligated_pct__lte" + ], + "filter_params_detail": { + "account_title__icontains": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "actual_vs_requested_contract": { + "filter_class": "NumberFilter", + "type": "number" + }, + "actual_vs_requested_contract__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "actual_vs_requested_contract__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "actual_vs_requested_contract_capped": { + "filter_class": "NumberFilter", + "type": "number" + }, + "actual_vs_requested_contract_capped__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "actual_vs_requested_contract_capped__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "agency_code": { + "filter_class": "CharFilter", + "type": "string" + }, + "agency_code__in": { + "filter_class": "CharInFilter", + "lookup": "in", + "type": "string" + }, + "apportioned": { + "filter_class": "NumberFilter", + "type": "number" + }, + "apportioned__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "apportioned__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "apportioned_to_enacted_pct": { + "filter_class": "NumberFilter", + "type": "number" + }, + "apportioned_to_enacted_pct__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "apportioned_to_enacted_pct__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "apportioned_to_enacted_pct_capped": { + "filter_class": "NumberFilter", + "type": "number" + }, + "apportioned_to_enacted_pct_capped__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "apportioned_to_enacted_pct_capped__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "assistance_obligated": { + "filter_class": "NumberFilter", + "type": "number" + }, + "assistance_obligated__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "assistance_obligated__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "assistance_outlayed": { + "filter_class": "NumberFilter", + "type": "number" + }, + "assistance_outlayed__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "assistance_outlayed__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "ba_growth_next_year_pct": { + "filter_class": "NumberFilter", + "type": "number" + }, + "ba_growth_next_year_pct__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "ba_growth_next_year_pct__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "bea_category": { + "filter_class": "CharFilter", + "type": "string" + }, + "bea_category__in": { + "filter_class": "CharInFilter", + "lookup": "in", + "type": "string" + }, + "bureau_name": { + "filter_class": "CharFilter", + "type": "string" + }, + "bureau_name__icontains": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "bureau_name__in": { + "filter_class": "CharInFilter", + "lookup": "in", + "type": "string" + }, + "contract_obligated": { + "filter_class": "NumberFilter", + "type": "number" + }, + "contract_obligated__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "contract_obligated__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "contract_outlayed": { + "filter_class": "NumberFilter", + "type": "number" + }, + "contract_outlayed__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "contract_outlayed__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "contract_share_of_obligated_capped": { + "filter_class": "NumberFilter", + "type": "number" + }, + "contract_share_of_obligated_capped__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "contract_share_of_obligated_capped__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "enacted_ba": { + "filter_class": "NumberFilter", + "type": "number" + }, + "enacted_ba_5yr_cagr": { + "filter_class": "NumberFilter", + "type": "number" + }, + "enacted_ba_5yr_cagr__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "enacted_ba_5yr_cagr__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "enacted_ba__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "enacted_ba__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "enacted_ba_yoy_pct": { + "filter_class": "NumberFilter", + "type": "number" + }, + "enacted_ba_yoy_pct__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "enacted_ba_yoy_pct__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "federal_account_symbol": { + "filter_class": "CharFilter", + "type": "string" + }, + "federal_account_symbol__in": { + "filter_class": "CharInFilter", + "lookup": "in", + "type": "string" + }, + "fiscal_year": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "fiscal_year__in": { + "filter_class": "NumberInFilter", + "lookup": "in", + "type": "number" + }, + "fiscal_year__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "obligated_to_apportioned_pct": { + "filter_class": "NumberFilter", + "type": "number" + }, + "obligated_to_apportioned_pct__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "obligated_to_apportioned_pct__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "obligated_to_apportioned_pct_capped": { + "filter_class": "NumberFilter", + "type": "number" + }, + "obligated_to_apportioned_pct_capped__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "obligated_to_apportioned_pct_capped__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "obligated_to_enacted_pct": { + "filter_class": "NumberFilter", + "type": "number" + }, + "obligated_to_enacted_pct__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "obligated_to_enacted_pct__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "obligated_to_enacted_pct_capped": { + "filter_class": "NumberFilter", + "type": "number" + }, + "obligated_to_enacted_pct_capped__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "obligated_to_enacted_pct_capped__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "obligated_total": { + "filter_class": "NumberFilter", + "type": "number" + }, + "obligated_total__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "obligated_total__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "obligated_yoy_pct": { + "filter_class": "NumberFilter", + "type": "number" + }, + "obligated_yoy_pct__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "obligated_yoy_pct__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "on_off_budget": { + "filter_class": "CharFilter", + "type": "string" + }, + "outlayed_to_obligated_pct": { + "filter_class": "NumberFilter", + "type": "number" + }, + "outlayed_to_obligated_pct__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "outlayed_to_obligated_pct__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "outlayed_to_obligated_pct_capped": { + "filter_class": "NumberFilter", + "type": "number" + }, + "outlayed_to_obligated_pct_capped__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "outlayed_to_obligated_pct_capped__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "outlayed_total": { + "filter_class": "NumberFilter", + "type": "number" + }, + "outlayed_total__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "outlayed_total__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "requested_ba": { + "filter_class": "NumberFilter", + "type": "number" + }, + "requested_ba__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "requested_ba__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "search": { + "filter_class": "DRFSearchFilter", + "type": "string" + }, + "subfunction_code": { + "filter_class": "CharFilter", + "type": "string" + }, + "subfunction_code__in": { + "filter_class": "CharInFilter", + "lookup": "in", + "type": "string" + }, + "unobligated_balance": { + "filter_class": "NumberFilter", + "type": "number" + }, + "unobligated_balance__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "unobligated_balance__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "unobligated_pct": { + "filter_class": "NumberFilter", + "type": "number" + }, + "unobligated_pct__gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "unobligated_pct__lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "actual_vs_requested_contract_capped", + "agency_code", + "ba_growth_next_year_pct", + "contract_obligated", + "contract_share_of_obligated_capped", + "enacted_ba", + "enacted_ba_5yr_cagr", + "enacted_ba_yoy_pct", + "federal_account_symbol", + "fiscal_year", + "modified", + "obligated_to_apportioned_pct_capped", + "obligated_to_enacted_pct_capped", + "obligated_total", + "outlayed_total" + ], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "appendix": { + "expands": {}, + "fields": [ + "agency_code", + "appendix_granule_id", + "appendix_pdf_url", + "federal_account_symbol", + "fiscal_year", + "has_object_classification", + "has_program_financing", + "n_program_activities", + "narrative_length", + "on_off_budget", + "request", + "subfunction_code" + ] + }, + "narratives": { + "expands": {}, + "fields": [ + "account_code", + "account_heading", + "agency_code", + "agency_title", + "appropriations_length", + "appropriations_text", + "budget_year", + "bureau_title", + "date_issued", + "federal_account_symbol", + "fiscal_year", + "fund_type", + "granule_id", + "granule_title", + "narrative_id", + "narrative_length", + "narrative_text", + "notes", + "on_off_budget", + "source_url", + "subaccount_code", + "subfunction_code" + ] + } + }, + "fields": [ + "account_narrative_excerpt", + "account_title", + "actual_vs_requested_contract", + "actual_vs_requested_contract_capped", + "actual_vs_requested_contract_capped_flag", + "agency_code", + "agency_name", + "appendix_pdf_url", + "apportioned", + "apportioned_to_enacted_pct", + "apportioned_to_enacted_pct_capped", + "apportioned_to_enacted_pct_capped_flag", + "assistance_obligated", + "assistance_outlayed", + "assistance_share_capped_flag", + "assistance_share_of_obligated", + "assistance_share_of_obligated_capped", + "attribution_confidence", + "attribution_status", + "ba_growth_next_year", + "ba_growth_next_year_pct", + "bea_category", + "bureau_name", + "contract_obligated", + "contract_obligated_5yr_cagr", + "contract_obligated_estimated", + "contract_obligated_yoy_pct", + "contract_outlayed", + "contract_share_capped_flag", + "contract_share_of_obligated", + "contract_share_of_obligated_capped", + "created", + "enacted_ba", + "enacted_ba_5yr_cagr", + "enacted_ba_yoy_pct", + "enacted_to_requested_pct", + "enacted_to_requested_pct_capped", + "enacted_to_requested_pct_capped_flag", + "federal_account_symbol", + "fiscal_year", + "id", + "modified", + "n_contracts", + "n_grants", + "n_unique_contract_recipients", + "n_unique_grant_recipients", + "next_year_requested_ba", + "obligated_to_apportioned_pct", + "obligated_to_apportioned_pct_capped", + "obligated_to_apportioned_pct_capped_flag", + "obligated_to_enacted_pct", + "obligated_to_enacted_pct_capped", + "obligated_to_enacted_pct_capped_flag", + "obligated_total", + "obligated_yoy_pct", + "on_off_budget", + "outlayed_to_obligated_pct", + "outlayed_to_obligated_pct_capped", + "outlayed_to_obligated_pct_capped_flag", + "outlayed_total", + "requested_ba", + "requested_contractual_services", + "requested_personnel_share", + "subfunction_code", + "top_contract_recipients", + "top_grant_recipients", + "unlinked_obligated", + "unobligated_balance", + "unobligated_pct" + ] + }, + "shape_flat_paths": [ + "account_narrative_excerpt", + "account_title", + "actual_vs_requested_contract", + "actual_vs_requested_contract_capped", + "actual_vs_requested_contract_capped_flag", + "agency_code", + "agency_name", + "appendix", + "appendix.agency_code", + "appendix.appendix_granule_id", + "appendix.appendix_pdf_url", + "appendix.federal_account_symbol", + "appendix.fiscal_year", + "appendix.has_object_classification", + "appendix.has_program_financing", + "appendix.n_program_activities", + "appendix.narrative_length", + "appendix.on_off_budget", + "appendix.request", + "appendix.subfunction_code", + "appendix_pdf_url", + "apportioned", + "apportioned_to_enacted_pct", + "apportioned_to_enacted_pct_capped", + "apportioned_to_enacted_pct_capped_flag", + "assistance_obligated", + "assistance_outlayed", + "assistance_share_capped_flag", + "assistance_share_of_obligated", + "assistance_share_of_obligated_capped", + "attribution_confidence", + "attribution_status", + "ba_growth_next_year", + "ba_growth_next_year_pct", + "bea_category", + "bureau_name", + "contract_obligated", + "contract_obligated_5yr_cagr", + "contract_obligated_estimated", + "contract_obligated_yoy_pct", + "contract_outlayed", + "contract_share_capped_flag", + "contract_share_of_obligated", + "contract_share_of_obligated_capped", + "created", + "enacted_ba", + "enacted_ba_5yr_cagr", + "enacted_ba_yoy_pct", + "enacted_to_requested_pct", + "enacted_to_requested_pct_capped", + "enacted_to_requested_pct_capped_flag", + "federal_account_symbol", + "fiscal_year", + "id", + "modified", + "n_contracts", + "n_grants", + "n_unique_contract_recipients", + "n_unique_grant_recipients", + "narratives", + "narratives.account_code", + "narratives.account_heading", + "narratives.agency_code", + "narratives.agency_title", + "narratives.appropriations_length", + "narratives.appropriations_text", + "narratives.budget_year", + "narratives.bureau_title", + "narratives.date_issued", + "narratives.federal_account_symbol", + "narratives.fiscal_year", + "narratives.fund_type", + "narratives.granule_id", + "narratives.granule_title", + "narratives.narrative_id", + "narratives.narrative_length", + "narratives.narrative_text", + "narratives.notes", + "narratives.on_off_budget", + "narratives.source_url", + "narratives.subaccount_code", + "narratives.subfunction_code", + "next_year_requested_ba", + "obligated_to_apportioned_pct", + "obligated_to_apportioned_pct_capped", + "obligated_to_apportioned_pct_capped_flag", + "obligated_to_enacted_pct", + "obligated_to_enacted_pct_capped", + "obligated_to_enacted_pct_capped_flag", + "obligated_total", + "obligated_yoy_pct", + "on_off_budget", + "outlayed_to_obligated_pct", + "outlayed_to_obligated_pct_capped", + "outlayed_to_obligated_pct_capped_flag", + "outlayed_total", + "requested_ba", + "requested_contractual_services", + "requested_personnel_share", + "subfunction_code", + "top_contract_recipients", + "top_grant_recipients", + "unlinked_obligated", + "unobligated_balance", + "unobligated_pct" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "budget.views.BudgetAccountViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "business_types": { + "basename": "businesstype", + "docs_file": null, + "docs_params": [], + "prefix": "business_types", + "resource_key": "business_types", + "runtime": { + "filter_params": [], + "filter_params_detail": {}, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "StaticModelCachedPagination", + "max_page_size": 10000 + }, + "shape": { + "expands": {}, + "fields": [ + "code", + "name" + ] + }, + "shape_flat_paths": [ + "code", + "name" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "shared.views.BusinessTypesViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "shape", + "show_shapes" + ] + }, + "contracts": { + "basename": "contract", + "docs_file": null, + "docs_params": [], + "prefix": "contracts", + "resource_key": "contracts", + "runtime": { + "filter_params": [ + "award_date", + "award_date_gte", + "award_date_lte", + "award_type", + "awarding_agency", + "expiring_gte", + "expiring_lte", + "fiscal_year", + "fiscal_year_gte", + "fiscal_year_lte", + "funding_agency", + "key", + "naics", + "obligated_gte", + "obligated_lte", + "ordering", + "piid", + "pop_end_date_gte", + "pop_end_date_lte", + "pop_start_date_gte", + "pop_start_date_lte", + "psc", + "recipient", + "search", + "set_aside", + "solicitation_identifier", + "uei" + ], + "filter_params_detail": { + "award_date": { + "filter_class": "DateFilter", + "type": "date" + }, + "award_date_gte": { + "filter_class": "DateFilter", + "type": "date" + }, + "award_date_lte": { + "filter_class": "DateFilter", + "type": "date" + }, + "award_type": { + "choices": [ + "A", + "B", + "C", + "D", + "a", + "b", + "c", + "d" + ], + "choices_count": 8, + "filter_class": "UppercaseCodeChoiceFilter", + "type": "choice" + }, + "awarding_agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "expiring_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "expiring_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "fiscal_year": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_gte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_lte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "funding_agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "key": { + "filter_class": "IdListFilter", + "type": "string" + }, + "naics": { + "filter_class": "CustomNAICSFilter", + "type": "string" + }, + "obligated_gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "obligated_lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "ordering": { + "choices": [ + "-award_date", + "-obligated", + "-total_contract_value", + "award_date", + "obligated", + "total_contract_value" + ], + "choices_count": 6, + "filter_class": "OrderingFilter", + "type": "ordering" + }, + "piid": { + "filter_class": "UppercaseCharFilter", + "type": "string" + }, + "pop_end_date_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "pop_end_date_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "pop_start_date_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "pop_start_date_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "psc": { + "filter_class": "CustomPSCFilter", + "type": "string" + }, + "recipient": { + "filter_class": "CharFilter", + "type": "string" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "set_aside": { + "filter_class": "CustomSetAsideFilter", + "type": "string" + }, + "solicitation_identifier": { + "filter_class": "UppercaseCharFilter", + "type": "string" + }, + "uei": { + "filter_class": "UppercaseCharFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "award_date", + "obligated", + "total_contract_value" + ], + "pagination": { + "class": "KeysetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "award_type": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "awarding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "commercial_item_acquisition_procedures": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "competition": { + "expands": {}, + "fields": [ + "contract_type", + "extent_competed", + "number_of_offers_received", + "other_than_full_and_open_competition", + "solicitation_date", + "solicitation_identifier", + "solicitation_procedures" + ] + }, + "consolidated_contract": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "contingency_humanitarian_or_peacekeeping_operation": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "contract_bundling": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "cost_accounting_standards_clause": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "cost_or_pricing_data": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "domestic_or_foreign_entity": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "epa_designated_product": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "evaluated_preference": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "fair_opportunity_limited_sources": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "fed_biz_opps": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "foreign_funding": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "funding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "information_technology_commercial_item_category": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "inherently_governmental_functions": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "legislative_mandates": { + "expands": {}, + "fields": [ + "clinger_cohen_act_planning", + "construction_wage_rate_requirements", + "employment_eligibility_verification", + "interagency_contracting_authority", + "labor_standards", + "materials_supplies_articles_equipment", + "other_statutory_authority", + "service_contract_inventory" + ] + }, + "naics": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "officers": { + "expands": {}, + "fields": [ + "highly_compensated_officer_1_amount", + "highly_compensated_officer_1_name", + "highly_compensated_officer_2_amount", + "highly_compensated_officer_2_name", + "highly_compensated_officer_3_amount", + "highly_compensated_officer_3_name", + "highly_compensated_officer_4_amount", + "highly_compensated_officer_4_name", + "highly_compensated_officer_5_amount", + "highly_compensated_officer_5_name" + ] + }, + "parent_award": { + "expands": {}, + "fields": [ + "key", + "piid" + ] + }, + "performance_based_service_acquisition": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "period_of_performance": { + "expands": {}, + "fields": [ + "current_end_date", + "start_date", + "ultimate_completion_date" + ] + }, + "place_of_manufacture": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city_name", + "country_code", + "country_name", + "state_code", + "state_name", + "zip_code" + ] + }, + "psc": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "recipient": { + "expands": {}, + "fields": [ + "cage", + "cage_code", + "display_name", + "legal_business_name", + "uei" + ] + }, + "recovered_materials_sustainability": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "research": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "sam_exception": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "set_aside": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "subawards_summary": { + "expands": {}, + "fields": [ + "count", + "total_amount" + ] + }, + "subcontracting_plan": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "tradeoff_process": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "transactions": { + "expands": {}, + "fields": [ + "action_type", + "description", + "modification_number", + "obligated", + "transaction_date" + ] + }, + "undefinitized_action": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "vehicle": { + "expands": {}, + "fields": [ + "agency_id", + "award_date", + "contract_type", + "description", + "fiscal_year", + "last_date_to_order", + "naics_code", + "psc_code", + "set_aside", + "solicitation_date", + "solicitation_description", + "solicitation_identifier", + "solicitation_title", + "type_of_idc", + "uuid", + "vehicle_type", + "who_can_use" + ] + } + }, + "fields": [ + "award_date", + "award_type", + "base_and_exercised_options_value", + "contract_financing", + "description", + "dod_acquisition_program", + "dod_transaction_number", + "fiscal_year", + "government_furnished_property", + "key", + "local_area_set_aside", + "major_program", + "naics_code", + "number_of_actions", + "number_of_offers_source", + "obligated", + "piid", + "price_evaluation_percent_difference", + "psc_code", + "purchase_card_as_payment_method", + "set_aside", + "simplified_procedures_for_certain_commercial_items", + "small_business_competitiveness_demonstration_program", + "solicitation_identifier", + "subawards_summary", + "total_contract_value", + "transactions", + "type_of_set_aside_source" + ] + }, + "shape_flat_paths": [ + "award_date", + "award_type", + "award_type.code", + "award_type.description", + "awarding_office", + "awarding_office.agency_code", + "awarding_office.agency_name", + "awarding_office.department_code", + "awarding_office.department_name", + "awarding_office.office_code", + "awarding_office.office_name", + "awarding_office.organization_id", + "base_and_exercised_options_value", + "commercial_item_acquisition_procedures", + "commercial_item_acquisition_procedures.code", + "commercial_item_acquisition_procedures.description", + "competition", + "competition.contract_type", + "competition.extent_competed", + "competition.number_of_offers_received", + "competition.other_than_full_and_open_competition", + "competition.solicitation_date", + "competition.solicitation_identifier", + "competition.solicitation_procedures", + "consolidated_contract", + "consolidated_contract.code", + "consolidated_contract.description", + "contingency_humanitarian_or_peacekeeping_operation", + "contingency_humanitarian_or_peacekeeping_operation.code", + "contingency_humanitarian_or_peacekeeping_operation.description", + "contract_bundling", + "contract_bundling.code", + "contract_bundling.description", + "contract_financing", + "cost_accounting_standards_clause", + "cost_accounting_standards_clause.code", + "cost_accounting_standards_clause.description", + "cost_or_pricing_data", + "cost_or_pricing_data.code", + "cost_or_pricing_data.description", + "description", + "dod_acquisition_program", + "dod_transaction_number", + "domestic_or_foreign_entity", + "domestic_or_foreign_entity.code", + "domestic_or_foreign_entity.description", + "epa_designated_product", + "epa_designated_product.code", + "epa_designated_product.description", + "evaluated_preference", + "evaluated_preference.code", + "evaluated_preference.description", + "fair_opportunity_limited_sources", + "fair_opportunity_limited_sources.code", + "fair_opportunity_limited_sources.description", + "fed_biz_opps", + "fed_biz_opps.code", + "fed_biz_opps.description", + "fiscal_year", + "foreign_funding", + "foreign_funding.code", + "foreign_funding.description", + "funding_office", + "funding_office.agency_code", + "funding_office.agency_name", + "funding_office.department_code", + "funding_office.department_name", + "funding_office.office_code", + "funding_office.office_name", + "funding_office.organization_id", + "government_furnished_property", + "information_technology_commercial_item_category", + "information_technology_commercial_item_category.code", + "information_technology_commercial_item_category.description", + "inherently_governmental_functions", + "inherently_governmental_functions.code", + "inherently_governmental_functions.description", + "key", + "legislative_mandates", + "legislative_mandates.clinger_cohen_act_planning", + "legislative_mandates.construction_wage_rate_requirements", + "legislative_mandates.employment_eligibility_verification", + "legislative_mandates.interagency_contracting_authority", + "legislative_mandates.labor_standards", + "legislative_mandates.materials_supplies_articles_equipment", + "legislative_mandates.other_statutory_authority", + "legislative_mandates.service_contract_inventory", + "local_area_set_aside", + "major_program", + "naics", + "naics.code", + "naics.description", + "naics_code", + "number_of_actions", + "number_of_offers_source", + "obligated", + "officers", + "officers.highly_compensated_officer_1_amount", + "officers.highly_compensated_officer_1_name", + "officers.highly_compensated_officer_2_amount", + "officers.highly_compensated_officer_2_name", + "officers.highly_compensated_officer_3_amount", + "officers.highly_compensated_officer_3_name", + "officers.highly_compensated_officer_4_amount", + "officers.highly_compensated_officer_4_name", + "officers.highly_compensated_officer_5_amount", + "officers.highly_compensated_officer_5_name", + "parent_award", + "parent_award.key", + "parent_award.piid", + "performance_based_service_acquisition", + "performance_based_service_acquisition.code", + "performance_based_service_acquisition.description", + "period_of_performance", + "period_of_performance.current_end_date", + "period_of_performance.start_date", + "period_of_performance.ultimate_completion_date", + "piid", + "place_of_manufacture", + "place_of_manufacture.code", + "place_of_manufacture.description", + "place_of_performance", + "place_of_performance.city_name", + "place_of_performance.country_code", + "place_of_performance.country_name", + "place_of_performance.state_code", + "place_of_performance.state_name", + "place_of_performance.zip_code", + "price_evaluation_percent_difference", + "psc", + "psc.code", + "psc.description", + "psc_code", + "purchase_card_as_payment_method", + "recipient", + "recipient.cage", + "recipient.cage_code", + "recipient.display_name", + "recipient.legal_business_name", + "recipient.uei", + "recovered_materials_sustainability", + "recovered_materials_sustainability.code", + "recovered_materials_sustainability.description", + "research", + "research.code", + "research.description", + "sam_exception", + "sam_exception.code", + "sam_exception.description", + "set_aside", + "set_aside.code", + "set_aside.description", + "simplified_procedures_for_certain_commercial_items", + "small_business_competitiveness_demonstration_program", + "solicitation_identifier", + "subawards_summary", + "subawards_summary.count", + "subawards_summary.total_amount", + "subcontracting_plan", + "subcontracting_plan.code", + "subcontracting_plan.description", + "total_contract_value", + "tradeoff_process", + "tradeoff_process.code", + "tradeoff_process.description", + "transactions", + "transactions.action_type", + "transactions.description", + "transactions.modification_number", + "transactions.obligated", + "transactions.transaction_date", + "type_of_set_aside_source", + "undefinitized_action", + "undefinitized_action.code", + "undefinitized_action.description", + "vehicle", + "vehicle.agency_id", + "vehicle.award_date", + "vehicle.contract_type", + "vehicle.description", + "vehicle.fiscal_year", + "vehicle.last_date_to_order", + "vehicle.naics_code", + "vehicle.psc_code", + "vehicle.set_aside", + "vehicle.solicitation_date", + "vehicle.solicitation_description", + "vehicle.solicitation_identifier", + "vehicle.solicitation_title", + "vehicle.type_of_idc", + "vehicle.uuid", + "vehicle.vehicle_type", + "vehicle.who_can_use" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "awards.views.contracts.ContractViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "award_date", + "award_date_gte", + "award_date_lte", + "award_type", + "awarding_agency", + "cursor", + "expiring_gte", + "expiring_lte", + "fiscal_year", + "fiscal_year_gte", + "fiscal_year_lte", + "flat", + "flat_lists", + "funding_agency", + "joiner", + "limit", + "naics", + "obligated_gte", + "obligated_lte", + "ordering", + "piid", + "pop_end_date_gte", + "pop_end_date_lte", + "pop_start_date_gte", + "pop_start_date_lte", + "psc", + "recipient", + "set_aside", + "shape", + "uei" + ] + }, + "departments": { + "basename": "department", + "docs_file": null, + "docs_params": [], + "prefix": "departments", + "resource_key": "departments", + "runtime": { + "filter_params": [], + "filter_params_detail": {}, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": {}, + "fields": [ + "abbreviation", + "cgac", + "code", + "congressional_justification", + "description", + "name", + "website" + ] + }, + "shape_flat_paths": [ + "abbreviation", + "cgac", + "code", + "congressional_justification", + "description", + "name", + "website" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "agencies.views.DepartmentViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "shape", + "show_shapes" + ] + }, + "dibbs/awards": { + "basename": "dibbs-award", + "docs_file": null, + "docs_params": [], + "prefix": "dibbs/awards", + "resource_key": "dibbs/awards", + "runtime": { + "filter_params": [ + "award_date_after", + "award_date_before", + "award_number", + "awardee_cage", + "delivery_order_number", + "entity", + "nsn", + "organization", + "part_number", + "posted_date_after", + "posted_date_before", + "purchase_request", + "search", + "solicitation", + "total_contract_price_max", + "total_contract_price_min" + ], + "filter_params_detail": { + "award_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "award_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "award_number": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "awardee_cage": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "delivery_order_number": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "entity": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "nsn": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "organization": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "part_number": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "posted_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "posted_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "purchase_request": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "solicitation": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "total_contract_price_max": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "total_contract_price_min": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "award_date", + "modified", + "posted_date", + "rank", + "total_contract_price" + ], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "awardee": { + "expands": {}, + "fields": [ + "cage_code", + "legal_business_name", + "uei" + ] + }, + "organization": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + } + }, + "fields": [ + "award_date", + "award_number", + "awardee_cage", + "delivery_order_counter", + "delivery_order_number", + "last_mod_posting_date", + "nomenclature", + "nsn", + "part_number", + "posted_date", + "purchase_request", + "solicitation", + "total_contract_price", + "total_contract_price_text", + "uuid" + ] + }, + "shape_flat_paths": [ + "award_date", + "award_number", + "awardee", + "awardee.cage_code", + "awardee.legal_business_name", + "awardee.uei", + "awardee_cage", + "delivery_order_counter", + "delivery_order_number", + "last_mod_posting_date", + "nomenclature", + "nsn", + "organization", + "organization.agency_code", + "organization.agency_name", + "organization.department_code", + "organization.department_name", + "organization.office_code", + "organization.office_name", + "organization.organization_id", + "part_number", + "posted_date", + "purchase_request", + "solicitation", + "total_contract_price", + "total_contract_price_text", + "uuid" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "dibbs.views.DibbsAwardViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "dibbs/rfps": { + "basename": "dibbs-rfp", + "docs_file": null, + "docs_params": [], + "prefix": "dibbs/rfps", + "resource_key": "dibbs/rfps", + "runtime": { + "filter_params": [ + "buyer_code", + "closes_date_after", + "closes_date_before", + "issued_date_after", + "issued_date_before", + "nsn", + "open", + "organization", + "part_number", + "search", + "solicitation" + ], + "filter_params_detail": { + "buyer_code": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "closes_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "closes_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "issued_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "issued_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "nsn": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "open": { + "filter_class": "BooleanFilter", + "type": "boolean" + }, + "organization": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "part_number": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "solicitation": { + "filter_class": "BaseSmartFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "closes_date", + "issued_date", + "modified", + "rank" + ], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "organization": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + } + }, + "fields": [ + "buyer_code", + "closes_date", + "document_url", + "is_open", + "issued_date", + "nomenclature", + "nsn", + "part_number", + "solicitation", + "tech_docs_url", + "uuid" + ] + }, + "shape_flat_paths": [ + "buyer_code", + "closes_date", + "document_url", + "is_open", + "issued_date", + "nomenclature", + "nsn", + "organization", + "organization.agency_code", + "organization.agency_name", + "organization.department_code", + "organization.department_name", + "organization.office_code", + "organization.office_name", + "organization.organization_id", + "part_number", + "solicitation", + "tech_docs_url", + "uuid" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "dibbs.views.DibbsRfpViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "dibbs/rfqs": { + "basename": "dibbs-rfq", + "docs_file": null, + "docs_params": [], + "prefix": "dibbs/rfqs", + "resource_key": "dibbs/rfqs", + "runtime": { + "filter_params": [ + "issue_date_after", + "issue_date_before", + "nsn", + "open", + "organization", + "part_number", + "purchase_request", + "quantity_max", + "quantity_min", + "return_by_date_after", + "return_by_date_before", + "search", + "set_aside", + "solicitation", + "status_code" + ], + "filter_params_detail": { + "issue_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "issue_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "nsn": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "open": { + "filter_class": "BooleanFilter", + "type": "boolean" + }, + "organization": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "part_number": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "purchase_request": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "quantity_max": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "quantity_min": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "return_by_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "return_by_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "set_aside": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "solicitation": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "status_code": { + "filter_class": "BaseSmartFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "issue_date", + "modified", + "quantity", + "rank", + "return_by_date" + ], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "organization": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + } + }, + "fields": [ + "document_url", + "is_open", + "issue_date", + "nomenclature", + "nsn", + "part_number", + "purchase_request", + "quantity", + "return_by_date", + "set_aside", + "solicitation", + "solicitation_formatted", + "status_code", + "unit_of_issue", + "uuid" + ] + }, + "shape_flat_paths": [ + "document_url", + "is_open", + "issue_date", + "nomenclature", + "nsn", + "organization", + "organization.agency_code", + "organization.agency_name", + "organization.department_code", + "organization.department_name", + "organization.office_code", + "organization.office_name", + "organization.organization_id", + "part_number", + "purchase_request", + "quantity", + "return_by_date", + "set_aside", + "solicitation", + "solicitation_formatted", + "status_code", + "unit_of_issue", + "uuid" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "dibbs.views.DibbsRfqViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "entities": { + "basename": "entity", + "docs_file": null, + "docs_params": [], + "prefix": "entities", + "resource_key": "entities", + "runtime": { + "filter_params": [ + "cage", + "cage_code", + "naics", + "name", + "psc", + "purpose_of_registration_code", + "search", + "socioeconomic", + "state", + "total_awards_obligated_gte", + "total_awards_obligated_lte", + "uei", + "zip_code" + ], + "filter_params_detail": { + "cage": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "cage_code": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "naics": { + "filter_class": "EntityNAICSFilter", + "type": "string" + }, + "name": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "psc": { + "filter_class": "CustomPSCFilter", + "type": "string" + }, + "purpose_of_registration_code": { + "filter_class": "CharFilter", + "type": "string" + }, + "search": { + "filter_class": "CustomEntityFilter", + "type": "string" + }, + "socioeconomic": { + "filter_class": "CustomBusinessTypeFilter", + "type": "string" + }, + "state": { + "filter_class": "CharFilter", + "lookup": "state_or_province_code__contains", + "type": "string" + }, + "total_awards_obligated_gte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "total_awards_obligated_lte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "uei": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "zip_code": { + "filter_class": "CharFilter", + "lookup": "zip_code__exact", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "business_types": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "country_of_incorporation": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "entity_structure": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "entity_type": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "federal_obligations": { + "expands": {}, + "fields": [ + "active", + "total" + ] + }, + "highest_owner": { + "expands": {}, + "fields": [ + "cage_code", + "legal_business_name", + "uei" + ] + }, + "immediate_owner": { + "expands": {}, + "fields": [ + "cage_code", + "legal_business_name", + "uei" + ] + }, + "mailing_address": { + "expands": {}, + "fields": [ + "address_line1", + "address_line2", + "city", + "country_code", + "country_name", + "county", + "county_code", + "fips_code", + "state_or_province_code", + "zip_code", + "zip_code_plus4" + ] + }, + "naics_codes": { + "expands": {}, + "fields": [ + "code", + "sba_small_business" + ] + }, + "organization_structure": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "past_performance": { + "expands": {}, + "fields": [ + "summary", + "top_agencies" + ] + }, + "physical_address": { + "expands": {}, + "fields": [ + "address_line1", + "address_line2", + "city", + "country_code", + "country_name", + "county", + "county_code", + "fips_code", + "state_or_province_code", + "zip_code", + "zip_code_plus4" + ] + }, + "profit_structure": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "purpose_of_registration": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "relationships": { + "expands": {}, + "fields": [ + "confidence", + "display_name", + "relation", + "source", + "type", + "uei", + "verification_method" + ] + }, + "sba_business_types": { + "expands": {}, + "fields": [ + "code", + "description", + "entry_date", + "exit_date" + ] + }, + "state_of_incorporation": { + "expands": {}, + "fields": [ + "code", + "description" + ] + } + }, + "fields": [ + "additional_website", + "business_types", + "cage_code", + "capabilities", + "capabilities_link", + "congressional_district", + "county", + "current_principals", + "dba_name", + "description", + "display_name", + "dodaac", + "email_address", + "entity_division_name", + "entity_division_number", + "entity_start_date", + "entity_url", + "evs_source", + "exclusion_status_flag", + "exclusion_url", + "fiscal_year_end_close_date", + "g2x_about", + "g2x_ai_summary", + "g2x_employee_count", + "highest_owner", + "immediate_owner", + "keywords", + "last_update_date", + "legal_business_name", + "mailing_address", + "naics_codes", + "naics_small_codes", + "non_fed_govt_certifications", + "past_performance", + "physical_address", + "primary_naics", + "psc_codes", + "public_display_flag", + "registered", + "registration_status", + "relationships", + "sam_activation_date", + "sam_expiration_date", + "sam_registration_date", + "sba_business_types", + "special_equip_material", + "submission_date", + "uei", + "uei_creation_date", + "uei_expiration_date", + "uei_status", + "uuid" + ] + }, + "shape_flat_paths": [ + "additional_website", + "business_types", + "business_types.code", + "business_types.description", + "cage_code", + "capabilities", + "capabilities_link", + "congressional_district", + "country_of_incorporation", + "country_of_incorporation.code", + "country_of_incorporation.description", + "county", + "current_principals", + "dba_name", + "description", + "display_name", + "dodaac", + "email_address", + "entity_division_name", + "entity_division_number", + "entity_start_date", + "entity_structure", + "entity_structure.code", + "entity_structure.description", + "entity_type", + "entity_type.code", + "entity_type.description", + "entity_url", + "evs_source", + "exclusion_status_flag", + "exclusion_url", + "federal_obligations", + "federal_obligations.active", + "federal_obligations.total", + "fiscal_year_end_close_date", + "g2x_about", + "g2x_ai_summary", + "g2x_employee_count", + "highest_owner", + "highest_owner.cage_code", + "highest_owner.legal_business_name", + "highest_owner.uei", + "immediate_owner", + "immediate_owner.cage_code", + "immediate_owner.legal_business_name", + "immediate_owner.uei", + "keywords", + "last_update_date", + "legal_business_name", + "mailing_address", + "mailing_address.address_line1", + "mailing_address.address_line2", + "mailing_address.city", + "mailing_address.country_code", + "mailing_address.country_name", + "mailing_address.county", + "mailing_address.county_code", + "mailing_address.fips_code", + "mailing_address.state_or_province_code", + "mailing_address.zip_code", + "mailing_address.zip_code_plus4", + "naics_codes", + "naics_codes.code", + "naics_codes.sba_small_business", + "naics_small_codes", + "non_fed_govt_certifications", + "organization_structure", + "organization_structure.code", + "organization_structure.description", + "past_performance", + "past_performance.summary", + "past_performance.top_agencies", + "physical_address", + "physical_address.address_line1", + "physical_address.address_line2", + "physical_address.city", + "physical_address.country_code", + "physical_address.country_name", + "physical_address.county", + "physical_address.county_code", + "physical_address.fips_code", + "physical_address.state_or_province_code", + "physical_address.zip_code", + "physical_address.zip_code_plus4", + "primary_naics", + "profit_structure", + "profit_structure.code", + "profit_structure.description", + "psc_codes", + "public_display_flag", + "purpose_of_registration", + "purpose_of_registration.code", + "purpose_of_registration.description", + "registered", + "registration_status", + "relationships", + "relationships.confidence", + "relationships.display_name", + "relationships.relation", + "relationships.source", + "relationships.type", + "relationships.uei", + "relationships.verification_method", + "sam_activation_date", + "sam_expiration_date", + "sam_registration_date", + "sba_business_types", + "sba_business_types.code", + "sba_business_types.description", + "sba_business_types.entry_date", + "sba_business_types.exit_date", + "special_equip_material", + "state_of_incorporation", + "state_of_incorporation.code", + "state_of_incorporation.description", + "submission_date", + "uei", + "uei_creation_date", + "uei_expiration_date", + "uei_status", + "uuid" + ], + "shape_supported": true, + "shape_tier_required": "pro", + "viewset": "entities.views.EntityViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "shape", + "show_shapes" + ] + }, + "events": { + "basename": "g2x-events", + "docs_file": null, + "docs_params": [], + "prefix": "events", + "resource_key": "events", + "runtime": { + "filter_params": [ + "is_free", + "is_virtual", + "organizer", + "search", + "source", + "start_date_after", + "start_date_before", + "state" + ], + "filter_params_detail": { + "is_free": { + "filter_class": "BooleanFilter", + "type": "boolean" + }, + "is_virtual": { + "filter_class": "BooleanFilter", + "type": "boolean" + }, + "organizer": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "source": { + "filter_class": "CharFilter", + "type": "string" + }, + "start_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "start_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "state": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": null, + "shape_flat_paths": [], + "shape_supported": false, + "shape_tier_required": null, + "viewset": "g2x.views.content.EventsViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "exclusions": { + "basename": "exclusion", + "docs_file": null, + "docs_params": [], + "prefix": "exclusions", + "resource_key": "exclusions", + "runtime": { + "filter_params": [ + "activate_date_after", + "activate_date_before", + "active", + "cage_code", + "classification_type", + "delisted", + "entity_uei", + "excluding_agency_code", + "excluding_agency_name", + "exclusion_program", + "exclusion_type", + "npi", + "search", + "termination_date_after", + "termination_date_before", + "uei", + "update_date_after", + "update_date_before" + ], + "filter_params_detail": { + "activate_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "activate_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "active": { + "filter_class": "BooleanFilter", + "type": "boolean" + }, + "cage_code": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "classification_type": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "delisted": { + "filter_class": "BooleanFilter", + "lookup": "isnull", + "type": "boolean" + }, + "entity_uei": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "excluding_agency_code": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "excluding_agency_name": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "exclusion_program": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "exclusion_type": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "npi": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "termination_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "termination_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "uei": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "update_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "update_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "activate_date", + "create_date", + "modified", + "rank", + "termination_date", + "update_date" + ], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": {}, + "fields": [ + "activate_date", + "additional_comments", + "cage_code", + "classification_type", + "create_date", + "ct_code", + "delisted_at", + "display_name", + "dnb_open_data", + "entity_name", + "entity_uei", + "evs_investigation_status", + "excluding_agency_code", + "excluding_agency_name", + "exclusion_key", + "exclusion_program", + "exclusion_type", + "first_name", + "is_currently_excluded", + "is_fascsa_order", + "last_name", + "middle_name", + "more_locations", + "npi", + "prefix", + "primary_address", + "references", + "secondary_address", + "suffix", + "termination_date", + "termination_type", + "uei", + "update_date", + "vessel_call_sign", + "vessel_flag", + "vessel_grt", + "vessel_owner", + "vessel_tonnage", + "vessel_type" + ] + }, + "shape_flat_paths": [ + "activate_date", + "additional_comments", + "cage_code", + "classification_type", + "create_date", + "ct_code", + "delisted_at", + "display_name", + "dnb_open_data", + "entity_name", + "entity_uei", + "evs_investigation_status", + "excluding_agency_code", + "excluding_agency_name", + "exclusion_key", + "exclusion_program", + "exclusion_type", + "first_name", + "is_currently_excluded", + "is_fascsa_order", + "last_name", + "middle_name", + "more_locations", + "npi", + "prefix", + "primary_address", + "references", + "secondary_address", + "suffix", + "termination_date", + "termination_type", + "uei", + "update_date", + "vessel_call_sign", + "vessel_flag", + "vessel_grt", + "vessel_owner", + "vessel_tonnage", + "vessel_type" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "exclusions.views.ExclusionViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "ordering", + "page", + "shape", + "show_shapes" + ] + }, + "forecasts": { + "basename": "forecast", + "docs_file": null, + "docs_params": [], + "prefix": "forecasts", + "resource_key": "forecasts", + "runtime": { + "filter_params": [ + "agency", + "award_date_after", + "award_date_before", + "fiscal_year", + "fiscal_year_gte", + "fiscal_year_lte", + "id", + "modified_after", + "modified_before", + "naics_code", + "naics_starts_with", + "search", + "source_system", + "status" + ], + "filter_params_detail": { + "agency": { + "filter_class": "OrganizationScopeAgencyFilter", + "type": "string" + }, + "award_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "award_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "fiscal_year": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "fiscal_year_lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "id": { + "filter_class": "IdListFilter", + "type": "string" + }, + "modified_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "modified_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "naics_code": { + "filter_class": "CustomNAICSFilter", + "type": "string" + }, + "naics_starts_with": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "source_system": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "status": { + "filter_class": "BaseSmartFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "anticipated_award_date", + "fiscal_year", + "title" + ], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "display": { + "expands": {}, + "fields": [ + "agency", + "anticipated_award_date", + "contract_vehicle", + "description", + "estimated_period", + "fiscal_year", + "naics_code", + "place_of_performance", + "primary_contact", + "set_aside", + "status", + "title" + ] + }, + "organization": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "raw_data": { + "expands": {}, + "fields": [ + "*" + ] + } + }, + "fields": [ + "agency", + "anticipated_award_date", + "contract_vehicle", + "created", + "description", + "estimated_period", + "external_id", + "fiscal_year", + "id", + "is_active", + "modified", + "naics_code", + "organization_id", + "place_of_performance", + "primary_contact", + "raw_data", + "set_aside", + "source_system", + "status", + "title" + ] + }, + "shape_flat_paths": [ + "agency", + "anticipated_award_date", + "contract_vehicle", + "created", + "description", + "display", + "display.agency", + "display.anticipated_award_date", + "display.contract_vehicle", + "display.description", + "display.estimated_period", + "display.fiscal_year", + "display.naics_code", + "display.place_of_performance", + "display.primary_contact", + "display.set_aside", + "display.status", + "display.title", + "estimated_period", + "external_id", + "fiscal_year", + "id", + "is_active", + "modified", + "naics_code", + "organization", + "organization.agency_code", + "organization.agency_name", + "organization.department_code", + "organization.department_name", + "organization.office_code", + "organization.office_name", + "organization.organization_id", + "organization_id", + "place_of_performance", + "primary_contact", + "raw_data", + "raw_data.*", + "set_aside", + "source_system", + "status", + "title" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "forecasts.views.ForecastViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "ordering", + "page", + "shape" + ] + }, + "grants": { + "basename": "grantopportunity", + "docs_file": null, + "docs_params": [], + "prefix": "grants", + "resource_key": "grants", + "runtime": { + "filter_params": [ + "agency", + "applicant_types", + "cfda_number", + "funding_categories", + "funding_instruments", + "grant_id", + "opportunity_number", + "posted_date_after", + "posted_date_before", + "response_date_after", + "response_date_before", + "search", + "status" + ], + "filter_params_detail": { + "agency": { + "filter_class": "OrganizationScopeAgencyFilter", + "type": "string" + }, + "applicant_types": { + "choices": [ + "00", + "01", + "02", + "04", + "05", + "06", + "07", + "08", + "11", + "12", + "13", + "20", + "21", + "22", + "23", + "25", + "99", + "DESCRIPTION" + ], + "choices_count": 18, + "filter_class": "CaseInsensitiveChoiceFilter", + "lookup": "icontains", + "type": "choice" + }, + "cfda_number": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "funding_categories": { + "choices": [ + "AG", + "AR", + "BC", + "CD", + "CP", + "DESCRIPTION", + "DPR", + "ED", + "EL", + "ELT", + "EN", + "ENV", + "FN", + "HE", + "HL", + "HO", + "HU", + "IE", + "IIJ", + "IS", + "ISS", + "LJ", + "LJL", + "MH", + "NR", + "O", + "OZ", + "RA", + "RD", + "ST", + "T", + "TR" + ], + "choices_count": 32, + "filter_class": "CaseInsensitiveChoiceFilter", + "lookup": "icontains", + "type": "choice" + }, + "funding_instruments": { + "choices": [ + "CA", + "D", + "DESCRIPTION", + "G", + "L", + "O", + "PC", + "S", + "U", + "V" + ], + "choices_count": 10, + "filter_class": "CaseInsensitiveChoiceFilter", + "lookup": "icontains", + "type": "choice" + }, + "grant_id": { + "filter_class": "IdListFilter", + "type": "string" + }, + "opportunity_number": { + "filter_class": "CharFilter", + "type": "string" + }, + "posted_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "posted_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "response_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "response_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "status": { + "choices": [ + "F", + "P" + ], + "choices_count": 2, + "filter_class": "CaseInsensitiveChoiceFilter", + "type": "choice" + } + }, + "ordering_aliases": [ + "last_updated" + ], + "ordering_fields": [ + "deadline_current", + "posted_date", + "rank" + ], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "additional_info": { + "expands": {}, + "fields": [ + "description", + "link" + ] + }, + "applicant_types": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "attachments": { + "expands": {}, + "fields": [ + "mime_type", + "name", + "posted_date", + "resource_id", + "type", + "url" + ] + }, + "category": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "cfda_numbers": { + "expands": {}, + "fields": [ + "number", + "title" + ] + }, + "funding_categories": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "funding_details": { + "expands": {}, + "fields": [ + "award_ceiling", + "award_floor", + "estimated_total_funding", + "expected_number_of_awards" + ] + }, + "funding_instruments": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "grantor_contact": { + "expands": {}, + "fields": [ + "email", + "name", + "phone" + ] + }, + "important_dates": { + "expands": {}, + "fields": [ + "estimated_application_response_date", + "estimated_application_response_date_description", + "estimated_project_start_date", + "estimated_synopsis_post_date", + "posted_date", + "response_date", + "response_date_description" + ] + }, + "organization": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "status": { + "expands": {}, + "fields": [ + "code", + "description" + ] + } + }, + "fields": [ + "agency_code", + "applicant_eligibility_description", + "description", + "forecast", + "funding_activity_category_description", + "grant_id", + "grantor_contact", + "last_updated", + "opportunity_history", + "opportunity_number", + "organization_id", + "status", + "synopsis", + "title" + ] + }, + "shape_flat_paths": [ + "additional_info", + "additional_info.description", + "additional_info.link", + "agency_code", + "applicant_eligibility_description", + "applicant_types", + "applicant_types.code", + "applicant_types.description", + "attachments", + "attachments.mime_type", + "attachments.name", + "attachments.posted_date", + "attachments.resource_id", + "attachments.type", + "attachments.url", + "category", + "category.code", + "category.description", + "cfda_numbers", + "cfda_numbers.number", + "cfda_numbers.title", + "description", + "forecast", + "funding_activity_category_description", + "funding_categories", + "funding_categories.code", + "funding_categories.description", + "funding_details", + "funding_details.award_ceiling", + "funding_details.award_floor", + "funding_details.estimated_total_funding", + "funding_details.expected_number_of_awards", + "funding_instruments", + "funding_instruments.code", + "funding_instruments.description", + "grant_id", + "grantor_contact", + "grantor_contact.email", + "grantor_contact.name", + "grantor_contact.phone", + "important_dates", + "important_dates.estimated_application_response_date", + "important_dates.estimated_application_response_date_description", + "important_dates.estimated_project_start_date", + "important_dates.estimated_synopsis_post_date", + "important_dates.posted_date", + "important_dates.response_date", + "important_dates.response_date_description", + "last_updated", + "opportunity_history", + "opportunity_number", + "organization", + "organization.agency_code", + "organization.agency_name", + "organization.department_code", + "organization.department_name", + "organization.office_code", + "organization.office_name", + "organization.organization_id", + "organization_id", + "status", + "status.code", + "status.description", + "synopsis", + "title" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "grants.views.GrantOpportunityViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "shape", + "show_shapes" + ] + }, + "gsa_elibrary_contracts": { + "basename": "gsa-elibrary-contract", + "docs_file": null, + "docs_params": [], + "prefix": "gsa_elibrary_contracts", + "resource_key": "gsa_elibrary_contracts", + "runtime": { + "filter_params": [ + "contract_number", + "key", + "piid", + "schedule", + "search", + "sin", + "uei" + ], + "filter_params_detail": { + "contract_number": { + "filter_class": "UppercaseCharFilter", + "type": "string" + }, + "key": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "piid": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "schedule": { + "filter_class": "UppercaseCharFilter", + "type": "string" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "sin": { + "filter_class": "CharFilter", + "type": "string" + }, + "uei": { + "filter_class": "CharFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "contract_number", + "last_updated", + "schedule" + ], + "pagination": { + "class": "ExactCountPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "idv": { + "expands": {}, + "fields": [ + "award_date", + "key" + ] + }, + "recipient": { + "expands": {}, + "fields": [ + "display_name", + "uei" + ] + } + }, + "fields": [ + "contract_number", + "cooperative_purchasing", + "disaster_recovery_purchasing", + "file_urls", + "schedule", + "sins", + "uei", + "uuid" + ] + }, + "shape_flat_paths": [ + "contract_number", + "cooperative_purchasing", + "disaster_recovery_purchasing", + "file_urls", + "idv", + "idv.award_date", + "idv.key", + "recipient", + "recipient.display_name", + "recipient.uei", + "schedule", + "sins", + "uei", + "uuid" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "awards.views.gsa_elibrary.GsaELibraryContractViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "contract_number", + "flat", + "flat_lists", + "joiner", + "key", + "limit", + "ordering", + "page", + "piid", + "schedule", + "search", + "shape", + "show_shapes", + "sin", + "uei" + ] + }, + "idvs": { + "basename": "idv", + "docs_file": null, + "docs_params": [], + "prefix": "idvs", + "resource_key": "idvs", + "runtime": { + "filter_params": [ + "award_date", + "award_date_gte", + "award_date_lte", + "awarding_agency", + "expiring_gte", + "expiring_lte", + "fiscal_year", + "fiscal_year_gte", + "fiscal_year_lte", + "funding_agency", + "idv_type", + "key", + "last_date_to_order_gte", + "last_date_to_order_lte", + "naics", + "ordering", + "piid", + "pop_start_date_gte", + "pop_start_date_lte", + "psc", + "recipient", + "search", + "set_aside", + "solicitation_identifier", + "uei" + ], + "filter_params_detail": { + "award_date": { + "filter_class": "DateFilter", + "type": "date" + }, + "award_date_gte": { + "filter_class": "DateFilter", + "type": "date" + }, + "award_date_lte": { + "filter_class": "DateFilter", + "type": "date" + }, + "awarding_agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "expiring_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "expiring_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "fiscal_year": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_gte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_lte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "funding_agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "idv_type": { + "choices": [ + "A", + "B", + "C", + "D", + "E", + "a", + "b", + "c", + "d", + "e" + ], + "choices_count": 10, + "filter_class": "UppercaseCodeChoiceFilter", + "type": "choice" + }, + "key": { + "filter_class": "IdListFilter", + "type": "string" + }, + "last_date_to_order_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "last_date_to_order_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "naics": { + "filter_class": "CustomNAICSFilter", + "type": "string" + }, + "ordering": { + "choices": [ + "-award_date", + "-obligated", + "-total_contract_value", + "award_date", + "obligated", + "total_contract_value" + ], + "choices_count": 6, + "filter_class": "OrderingFilter", + "type": "ordering" + }, + "piid": { + "filter_class": "UppercaseCharFilter", + "type": "string" + }, + "pop_start_date_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "pop_start_date_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "psc": { + "filter_class": "CustomPSCFilter", + "type": "string" + }, + "recipient": { + "filter_class": "CharFilter", + "type": "string" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "set_aside": { + "filter_class": "CustomSetAsideFilter", + "type": "string" + }, + "solicitation_identifier": { + "filter_class": "UppercaseCharFilter", + "type": "string" + }, + "uei": { + "filter_class": "UppercaseCharFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "award_date", + "obligated", + "total_contract_value" + ], + "pagination": { + "class": "KeysetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "awarding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "awards": { + "expands": {}, + "fields": [ + "award_date", + "base_and_exercised_options_value", + "description", + "fiscal_year", + "key", + "naics_code", + "obligated", + "piid", + "psc_code", + "total_contract_value", + "transactions" + ] + }, + "competition": { + "expands": {}, + "fields": [ + "contract_type", + "extent_competed", + "number_of_offers_received", + "other_than_full_and_open_competition", + "solicitation_date", + "solicitation_identifier", + "solicitation_procedures" + ] + }, + "funding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "gsa_elibrary": { + "expands": {}, + "fields": [ + "contract_number", + "cooperative_purchasing", + "disaster_recovery_purchasing", + "external_id", + "extracted_text", + "file_urls", + "schedule", + "sins", + "source_data", + "uei" + ] + }, + "idv_type": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "legislative_mandates": { + "expands": {}, + "fields": [ + "clinger_cohen_act_planning", + "construction_wage_rate_requirements", + "employment_eligibility_verification", + "interagency_contracting_authority", + "labor_standards", + "materials_supplies_articles_equipment", + "other_statutory_authority", + "service_contract_inventory" + ] + }, + "multiple_or_single_award_idv": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "naics": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "officers": { + "expands": {}, + "fields": [ + "highly_compensated_officer_1_amount", + "highly_compensated_officer_1_name", + "highly_compensated_officer_2_amount", + "highly_compensated_officer_2_name", + "highly_compensated_officer_3_amount", + "highly_compensated_officer_3_name", + "highly_compensated_officer_4_amount", + "highly_compensated_officer_4_name", + "highly_compensated_officer_5_amount", + "highly_compensated_officer_5_name" + ] + }, + "parent_award": { + "expands": {}, + "fields": [ + "key", + "piid" + ] + }, + "period_of_performance": { + "expands": {}, + "fields": [ + "last_date_to_order", + "start_date" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city_name", + "country_code", + "country_name", + "state_code", + "state_name", + "zip_code" + ] + }, + "psc": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "recipient": { + "expands": {}, + "fields": [ + "cage", + "cage_code", + "display_name", + "legal_business_name", + "uei" + ] + }, + "set_aside": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "subawards_summary": { + "expands": {}, + "fields": [ + "count", + "total_amount" + ] + }, + "transactions": { + "expands": {}, + "fields": [ + "action_type", + "description", + "modification_number", + "obligated", + "transaction_date" + ] + }, + "type_of_idc": { + "expands": {}, + "fields": [ + "code", + "description" + ] + } + }, + "fields": [ + "award_date", + "commercial_item_acquisition_procedures", + "consolidated_contract", + "contingency_humanitarian_or_peacekeeping_operation", + "contract_bundling", + "contract_financing", + "cost_accounting_standards_clause", + "cost_or_pricing_data", + "description", + "dod_acquisition_program", + "dod_transaction_number", + "domestic_or_foreign_entity", + "email_address", + "epa_designated_product", + "evaluated_preference", + "fair_opportunity_limited_sources", + "fed_biz_opps", + "fee_range_lower_value", + "fee_range_upper_value", + "fiscal_year", + "fixed_fee_value", + "foreign_funding", + "government_furnished_property", + "idv_type", + "idv_website", + "inherently_governmental_functions", + "key", + "local_area_set_aside", + "major_program", + "multiple_or_single_award_idv", + "naics_code", + "number_of_actions", + "number_of_offers_source", + "obligated", + "ordering_procedure", + "performance_based_service_acquisition", + "piid", + "program_acronym", + "psc_code", + "recovered_materials_sustainability", + "research", + "sam_exception", + "set_aside", + "simplified_procedures_for_certain_commercial_items", + "small_business_competitiveness_demonstration_program", + "solicitation_identifier", + "subawards_summary", + "subcontracting_plan", + "total_contract_value", + "total_estimated_order_value", + "tradeoff_process", + "transactions", + "type_of_fee_for_use_of_service", + "type_of_idc", + "undefinitized_action", + "vehicle_uuid", + "who_can_use" + ] + }, + "shape_flat_paths": [ + "award_date", + "awarding_office", + "awarding_office.agency_code", + "awarding_office.agency_name", + "awarding_office.department_code", + "awarding_office.department_name", + "awarding_office.office_code", + "awarding_office.office_name", + "awarding_office.organization_id", + "awards", + "awards.award_date", + "awards.base_and_exercised_options_value", + "awards.description", + "awards.fiscal_year", + "awards.key", + "awards.naics_code", + "awards.obligated", + "awards.piid", + "awards.psc_code", + "awards.total_contract_value", + "awards.transactions", + "commercial_item_acquisition_procedures", + "competition", + "competition.contract_type", + "competition.extent_competed", + "competition.number_of_offers_received", + "competition.other_than_full_and_open_competition", + "competition.solicitation_date", + "competition.solicitation_identifier", + "competition.solicitation_procedures", + "consolidated_contract", + "contingency_humanitarian_or_peacekeeping_operation", + "contract_bundling", + "contract_financing", + "cost_accounting_standards_clause", + "cost_or_pricing_data", + "description", + "dod_acquisition_program", + "dod_transaction_number", + "domestic_or_foreign_entity", + "email_address", + "epa_designated_product", + "evaluated_preference", + "fair_opportunity_limited_sources", + "fed_biz_opps", + "fee_range_lower_value", + "fee_range_upper_value", + "fiscal_year", + "fixed_fee_value", + "foreign_funding", + "funding_office", + "funding_office.agency_code", + "funding_office.agency_name", + "funding_office.department_code", + "funding_office.department_name", + "funding_office.office_code", + "funding_office.office_name", + "funding_office.organization_id", + "government_furnished_property", + "gsa_elibrary", + "gsa_elibrary.contract_number", + "gsa_elibrary.cooperative_purchasing", + "gsa_elibrary.disaster_recovery_purchasing", + "gsa_elibrary.external_id", + "gsa_elibrary.extracted_text", + "gsa_elibrary.file_urls", + "gsa_elibrary.schedule", + "gsa_elibrary.sins", + "gsa_elibrary.source_data", + "gsa_elibrary.uei", + "idv_type", + "idv_type.code", + "idv_type.description", + "idv_website", + "inherently_governmental_functions", + "key", + "legislative_mandates", + "legislative_mandates.clinger_cohen_act_planning", + "legislative_mandates.construction_wage_rate_requirements", + "legislative_mandates.employment_eligibility_verification", + "legislative_mandates.interagency_contracting_authority", + "legislative_mandates.labor_standards", + "legislative_mandates.materials_supplies_articles_equipment", + "legislative_mandates.other_statutory_authority", + "legislative_mandates.service_contract_inventory", + "local_area_set_aside", + "major_program", + "multiple_or_single_award_idv", + "multiple_or_single_award_idv.code", + "multiple_or_single_award_idv.description", + "naics", + "naics.code", + "naics.description", + "naics_code", + "number_of_actions", + "number_of_offers_source", + "obligated", + "officers", + "officers.highly_compensated_officer_1_amount", + "officers.highly_compensated_officer_1_name", + "officers.highly_compensated_officer_2_amount", + "officers.highly_compensated_officer_2_name", + "officers.highly_compensated_officer_3_amount", + "officers.highly_compensated_officer_3_name", + "officers.highly_compensated_officer_4_amount", + "officers.highly_compensated_officer_4_name", + "officers.highly_compensated_officer_5_amount", + "officers.highly_compensated_officer_5_name", + "ordering_procedure", + "parent_award", + "parent_award.key", + "parent_award.piid", + "performance_based_service_acquisition", + "period_of_performance", + "period_of_performance.last_date_to_order", + "period_of_performance.start_date", + "piid", + "place_of_performance", + "place_of_performance.city_name", + "place_of_performance.country_code", + "place_of_performance.country_name", + "place_of_performance.state_code", + "place_of_performance.state_name", + "place_of_performance.zip_code", + "program_acronym", + "psc", + "psc.code", + "psc.description", + "psc_code", + "recipient", + "recipient.cage", + "recipient.cage_code", + "recipient.display_name", + "recipient.legal_business_name", + "recipient.uei", + "recovered_materials_sustainability", + "research", + "sam_exception", + "set_aside", + "set_aside.code", + "set_aside.description", + "simplified_procedures_for_certain_commercial_items", + "small_business_competitiveness_demonstration_program", + "solicitation_identifier", + "subawards_summary", + "subawards_summary.count", + "subawards_summary.total_amount", + "subcontracting_plan", + "total_contract_value", + "total_estimated_order_value", + "tradeoff_process", + "transactions", + "transactions.action_type", + "transactions.description", + "transactions.modification_number", + "transactions.obligated", + "transactions.transaction_date", + "type_of_fee_for_use_of_service", + "type_of_idc", + "type_of_idc.code", + "type_of_idc.description", + "undefinitized_action", + "vehicle_uuid", + "who_can_use" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "awards.views.idvs.IDVViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "award_date", + "award_date_gte", + "award_date_lte", + "awarding_agency", + "cursor", + "expiring_gte", + "expiring_lte", + "fiscal_year", + "fiscal_year_gte", + "fiscal_year_lte", + "flat", + "flat_lists", + "funding_agency", + "idv_type", + "joiner", + "last_date_to_order_gte", + "last_date_to_order_lte", + "limit", + "naics", + "ordering", + "piid", + "pop_start_date_gte", + "pop_start_date_lte", + "psc", + "recipient", + "set_aside", + "shape", + "show_shapes", + "uei" + ] + }, + "itdashboard": { + "basename": "itdashboardinvestment", + "docs_file": null, + "docs_params": [], + "prefix": "itdashboard", + "resource_key": "itdashboard", + "runtime": { + "filter_params": [ + "agency_code", + "agency_name", + "cio_rating", + "cio_rating_max", + "performance_risk", + "previous_uii", + "search", + "type_of_investment", + "updated_time_after", + "updated_time_before" + ], + "filter_params_detail": { + "agency_code": { + "filter_class": "NumberFilter", + "type": "number" + }, + "agency_name": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "cio_rating": { + "filter_class": "CIORatingFilter", + "type": "number" + }, + "cio_rating_max": { + "filter_class": "CIORatingMaxFilter", + "type": "number" + }, + "performance_risk": { + "filter_class": "PerformanceRiskFilter", + "type": "boolean" + }, + "previous_uii": { + "filter_class": "CharFilter", + "type": "string" + }, + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "type_of_investment": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "updated_time_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "updated_time_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "cio_evaluation": { + "expands": {}, + "fields": [ + "*" + ] + }, + "contracts": { + "expands": {}, + "fields": [ + "*" + ] + }, + "cost_pools_towers": { + "expands": {}, + "fields": [ + "*" + ] + }, + "details": { + "expands": {}, + "fields": [ + "business_case_url", + "change_in_status", + "current_uii", + "investment_description", + "it_infrastructure_and_management_type", + "last_updated", + "mission_delivery_and_management_support_area", + "mission_support_investment_categories", + "national_security_system_identifier", + "previous_uii", + "public_urls", + "shared_services_category", + "shared_services_identifier" + ] + }, + "funding": { + "expands": {}, + "fields": [ + "fy2020_contribution", + "fy2020_internal_funding", + "fy2021_contribution", + "fy2021_internal_funding", + "fy2022_contribution", + "fy2022_internal_funding", + "fy2023_contribution", + "fy2023_internal_funding", + "fy2024_contribution", + "fy2024_internal_funding", + "fy2025_contribution", + "fy2025_internal_funding" + ] + }, + "funding_sources": { + "expands": {}, + "fields": [ + "*" + ] + }, + "operational_analysis": { + "expands": {}, + "fields": [ + "*" + ] + }, + "organization": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "performance_actual": { + "expands": {}, + "fields": [ + "*" + ] + }, + "performance_metrics": { + "expands": {}, + "fields": [ + "*" + ] + }, + "projects": { + "expands": {}, + "fields": [ + "*" + ] + } + }, + "fields": [ + "agency_code", + "agency_name", + "bureau_code", + "bureau_name", + "business_case_html", + "investment_title", + "organization_id", + "part_of_it_portfolio", + "type_of_investment", + "uii", + "updated_time", + "url" + ] + }, + "shape_flat_paths": [ + "agency_code", + "agency_name", + "bureau_code", + "bureau_name", + "business_case_html", + "cio_evaluation", + "cio_evaluation.*", + "contracts", + "contracts.*", + "cost_pools_towers", + "cost_pools_towers.*", + "details", + "details.business_case_url", + "details.change_in_status", + "details.current_uii", + "details.investment_description", + "details.it_infrastructure_and_management_type", + "details.last_updated", + "details.mission_delivery_and_management_support_area", + "details.mission_support_investment_categories", + "details.national_security_system_identifier", + "details.previous_uii", + "details.public_urls", + "details.shared_services_category", + "details.shared_services_identifier", + "funding", + "funding.fy2020_contribution", + "funding.fy2020_internal_funding", + "funding.fy2021_contribution", + "funding.fy2021_internal_funding", + "funding.fy2022_contribution", + "funding.fy2022_internal_funding", + "funding.fy2023_contribution", + "funding.fy2023_internal_funding", + "funding.fy2024_contribution", + "funding.fy2024_internal_funding", + "funding.fy2025_contribution", + "funding.fy2025_internal_funding", + "funding_sources", + "funding_sources.*", + "investment_title", + "operational_analysis", + "operational_analysis.*", + "organization", + "organization.agency_code", + "organization.agency_name", + "organization.department_code", + "organization.department_name", + "organization.office_code", + "organization.office_name", + "organization.organization_id", + "organization_id", + "part_of_it_portfolio", + "performance_actual", + "performance_actual.*", + "performance_metrics", + "performance_metrics.*", + "projects", + "projects.*", + "type_of_investment", + "uii", + "updated_time", + "url" + ], + "shape_supported": true, + "shape_tier_required": "business", + "viewset": "itdashboard.views.ITDashboardInvestmentViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "mas_sins": { + "basename": "massin", + "docs_file": null, + "docs_params": [], + "prefix": "mas_sins", + "resource_key": "mas_sins", + "runtime": { + "filter_params": [ + "search" + ], + "filter_params_detail": { + "search": { + "filter_class": "ViewHandledParam", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "StaticModelCachedPagination", + "max_page_size": 10000 + }, + "shape": { + "expands": {}, + "fields": [ + "description", + "expiration_date", + "large_category_code", + "large_category_name", + "naics_codes", + "olm", + "psc_code", + "service_comm_code", + "set_aside_code", + "sin", + "state_local", + "sub_category_code", + "sub_category_name", + "tdr", + "title" + ] + }, + "shape_flat_paths": [ + "description", + "expiration_date", + "large_category_code", + "large_category_name", + "naics_codes", + "olm", + "psc_code", + "service_comm_code", + "set_aside_code", + "sin", + "state_local", + "sub_category_code", + "sub_category_name", + "tdr", + "title" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "shared.views.MasSinsViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "search", + "shape", + "show_shapes" + ] + }, + "naics": { + "basename": "naicscode", + "docs_file": null, + "docs_params": [], + "prefix": "naics", + "resource_key": "naics", + "runtime": { + "filter_params": [ + "employee_limit", + "employee_limit_gte", + "employee_limit_lte", + "revenue_limit", + "revenue_limit_gte", + "revenue_limit_lte", + "search" + ], + "filter_params_detail": { + "employee_limit": { + "filter_class": "SizeLimitFilter", + "type": "string" + }, + "employee_limit_gte": { + "filter_class": "SizeLimitFilter", + "lookup": "gte", + "type": "string" + }, + "employee_limit_lte": { + "filter_class": "SizeLimitFilter", + "lookup": "lte", + "type": "string" + }, + "revenue_limit": { + "filter_class": "SizeLimitFilter", + "type": "string" + }, + "revenue_limit_gte": { + "filter_class": "SizeLimitFilter", + "lookup": "gte", + "type": "string" + }, + "revenue_limit_lte": { + "filter_class": "SizeLimitFilter", + "lookup": "lte", + "type": "string" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "StaticModelCachedPagination", + "max_page_size": 10000 + }, + "shape": { + "expands": { + "federal_obligations": { + "expands": {}, + "fields": [ + "active", + "total" + ] + }, + "size_standards": { + "expands": {}, + "fields": [ + "employee_limit", + "revenue_limit" + ] + } + }, + "fields": [ + "code", + "description" + ] + }, + "shape_flat_paths": [ + "code", + "description", + "federal_obligations", + "federal_obligations.active", + "federal_obligations.total", + "size_standards", + "size_standards.employee_limit", + "size_standards.revenue_limit" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "shared.views.NaicsCodeViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "employee_limit", + "employee_limit_gte", + "employee_limit_lte", + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "revenue_limit", + "revenue_limit_gte", + "revenue_limit_lte", + "search", + "shape", + "show_shapes" + ] + }, + "news": { + "basename": "g2x-news", + "docs_file": null, + "docs_params": [], + "prefix": "news", + "resource_key": "news", + "runtime": { + "filter_params": [ + "published_after", + "published_before", + "search", + "source", + "tag", + "vertical" + ], + "filter_params_detail": { + "published_after": { + "filter_class": "DateTimeFilter", + "lookup": "gte", + "type": "datetime" + }, + "published_before": { + "filter_class": "DateTimeFilter", + "lookup": "lte", + "type": "datetime" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "source": { + "filter_class": "CharFilter", + "type": "string" + }, + "tag": { + "filter_class": "CharFilter", + "type": "string" + }, + "vertical": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": null, + "shape_flat_paths": [], + "shape_supported": false, + "shape_tier_required": null, + "viewset": "g2x.views.content.NewsViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "notices": { + "basename": "notice", + "docs_file": null, + "docs_params": [], + "prefix": "notices", + "resource_key": "notices", + "runtime": { + "filter_params": [ + "active", + "agency", + "naics", + "notice_type", + "posted_date_after", + "posted_date_before", + "psc", + "response_deadline_after", + "response_deadline_before", + "search", + "set_aside", + "solicitation_number" + ], + "filter_params_detail": { + "active": { + "filter_class": "BooleanFilter", + "type": "boolean" + }, + "agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "naics": { + "filter_class": "CustomNAICSFilter", + "type": "string" + }, + "notice_type": { + "filter_class": "NoticeTypeFilter", + "type": "string" + }, + "posted_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "posted_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "psc": { + "filter_class": "CustomPSCFilter", + "type": "string" + }, + "response_deadline_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "response_deadline_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "search": { + "filter_class": "NoticeSearchFilter", + "type": "string" + }, + "set_aside": { + "filter_class": "CustomSetAsideFilter", + "type": "string" + }, + "solicitation_number": { + "filter_class": "CharFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "address": { + "expands": {}, + "fields": [ + "city", + "country", + "state", + "zip" + ] + }, + "archive": { + "expands": {}, + "fields": [ + "date", + "type" + ] + }, + "attachments": { + "expands": {}, + "fields": [ + "attachment_id", + "extracted_text", + "file_size", + "mime_type", + "name", + "posted_date", + "resource_id", + "type", + "url" + ] + }, + "meta": { + "expands": { + "notice_type": { + "expands": {}, + "fields": [ + "code", + "type" + ] + } + }, + "fields": [ + "link", + "notice_type", + "parent_notice_id", + "related_notice_id" + ] + }, + "office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "opportunity": { + "expands": {}, + "fields": [ + "link", + "opportunity_id" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city", + "country", + "state", + "street_address", + "zip" + ] + }, + "primary_contact": { + "expands": {}, + "fields": [ + "email", + "fax", + "full_name", + "phone", + "title" + ] + }, + "secondary_contact": { + "expands": {}, + "fields": [ + "email", + "fax", + "full_name", + "phone", + "title" + ] + }, + "set_aside": { + "expands": {}, + "fields": [ + "code", + "description" + ] + } + }, + "fields": [ + "active", + "address", + "archive", + "attachment_count", + "attachments", + "award_number", + "description", + "last_updated", + "meta", + "naics_code", + "notice_id", + "office", + "opportunity", + "opportunity_id", + "place_of_performance", + "posted_date", + "psc_code", + "response_deadline", + "sam_url", + "set_aside", + "solicitation_number", + "title" + ] + }, + "shape_flat_paths": [ + "active", + "address", + "address.city", + "address.country", + "address.state", + "address.zip", + "archive", + "archive.date", + "archive.type", + "attachment_count", + "attachments", + "attachments.attachment_id", + "attachments.extracted_text", + "attachments.file_size", + "attachments.mime_type", + "attachments.name", + "attachments.posted_date", + "attachments.resource_id", + "attachments.type", + "attachments.url", + "award_number", + "description", + "last_updated", + "meta", + "meta.link", + "meta.notice_type", + "meta.notice_type.code", + "meta.notice_type.type", + "meta.parent_notice_id", + "meta.related_notice_id", + "naics_code", + "notice_id", + "office", + "office.agency_code", + "office.agency_name", + "office.department_code", + "office.department_name", + "office.office_code", + "office.office_name", + "office.organization_id", + "opportunity", + "opportunity.link", + "opportunity.opportunity_id", + "opportunity_id", + "place_of_performance", + "place_of_performance.city", + "place_of_performance.country", + "place_of_performance.state", + "place_of_performance.street_address", + "place_of_performance.zip", + "posted_date", + "primary_contact", + "primary_contact.email", + "primary_contact.fax", + "primary_contact.full_name", + "primary_contact.phone", + "primary_contact.title", + "psc_code", + "response_deadline", + "sam_url", + "secondary_contact", + "secondary_contact.email", + "secondary_contact.fax", + "secondary_contact.full_name", + "secondary_contact.phone", + "secondary_contact.title", + "set_aside", + "set_aside.code", + "set_aside.description", + "solicitation_number", + "title" + ], + "shape_supported": true, + "shape_tier_required": "pro", + "viewset": "opportunities.views.NoticeViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "agency", + "department", + "flat", + "flat_lists", + "joiner", + "limit", + "notice_id", + "notice_type", + "office", + "ordering", + "page", + "posted_date_after", + "posted_date_before", + "response_deadline_after", + "response_deadline_before", + "search", + "shape", + "show_shapes", + "solicitation_number" + ] + }, + "offices": { + "basename": "office", + "docs_file": null, + "docs_params": [], + "prefix": "offices", + "resource_key": "offices", + "runtime": { + "filter_params": [ + "search" + ], + "filter_params_detail": { + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "agency": { + "expands": {}, + "fields": [ + "abbreviation", + "code", + "name" + ] + }, + "department": { + "expands": {}, + "fields": [ + "abbreviation", + "cgac", + "code", + "congressional_justification", + "description", + "name", + "website" + ] + } + }, + "fields": [ + "agency_code", + "agency_name", + "code", + "department_code", + "department_name", + "name", + "office_code", + "office_name" + ] + }, + "shape_flat_paths": [ + "agency", + "agency.abbreviation", + "agency.code", + "agency.name", + "agency_code", + "agency_name", + "code", + "department", + "department.abbreviation", + "department.cgac", + "department.code", + "department.congressional_justification", + "department.description", + "department.name", + "department.website", + "department_code", + "department_name", + "name", + "office_code", + "office_name" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "agencies.views.OfficeViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "shape", + "show_shapes" + ] + }, + "opportunities": { + "basename": "opportunity", + "docs_file": null, + "docs_params": [], + "prefix": "opportunities", + "resource_key": "opportunities", + "runtime": { + "filter_params": [ + "active", + "agency", + "first_notice_date_after", + "first_notice_date_before", + "last_notice_date_after", + "last_notice_date_before", + "naics", + "notice_type", + "opportunity_id", + "place_of_performance", + "psc", + "response_deadline_after", + "response_deadline_before", + "search", + "set_aside", + "solicitation_number" + ], + "filter_params_detail": { + "active": { + "filter_class": "BooleanFilter", + "type": "boolean" + }, + "agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "first_notice_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "first_notice_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "last_notice_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "last_notice_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "naics": { + "filter_class": "CustomNAICSFilter", + "type": "string" + }, + "notice_type": { + "filter_class": "NoticeTypeFilter", + "type": "string" + }, + "opportunity_id": { + "filter_class": "IdListFilter", + "type": "string" + }, + "place_of_performance": { + "filter_class": "OpportunityPlaceOfPerformanceFilter", + "type": "string" + }, + "psc": { + "filter_class": "CustomPSCFilter", + "type": "string" + }, + "response_deadline_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "response_deadline_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "search": { + "filter_class": "OpportunitySearchFilter", + "type": "string" + }, + "set_aside": { + "filter_class": "CustomSetAsideFilter", + "type": "string" + }, + "solicitation_number": { + "filter_class": "BaseSmartFilter", + "type": "string" + } + }, + "ordering_aliases": [ + "posted_date" + ], + "ordering_fields": [ + "first_notice_date", + "last_notice_date", + "response_deadline" + ], + "pagination": { + "class": "OpportunityPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "agency": { + "expands": {}, + "fields": [ + "abbreviation", + "code", + "name" + ] + }, + "attachments": { + "expands": {}, + "fields": [ + "attachment_id", + "extracted_text", + "file_size", + "mime_type", + "name", + "posted_date", + "resource_id", + "type", + "url" + ] + }, + "department": { + "expands": {}, + "fields": [ + "abbreviation", + "cgac", + "code", + "congressional_justification", + "description", + "name", + "website" + ] + }, + "latest_notice": { + "expands": {}, + "fields": [ + "link", + "notice_id" + ] + }, + "meta": { + "expands": { + "notice_type": { + "expands": {}, + "fields": [ + "code", + "type" + ] + } + }, + "fields": [ + "attachments_count", + "notice_type", + "notices_count" + ] + }, + "notice_history": { + "expands": {}, + "fields": [ + "deleted", + "index", + "latest", + "notice_id", + "notice_type_code", + "parent_notice_id", + "posted_date", + "related_notice_id", + "solicitation_number", + "title" + ] + }, + "office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city", + "country", + "state", + "street_address", + "zip" + ] + }, + "primary_contact": { + "expands": {}, + "fields": [ + "email", + "fax", + "full_name", + "phone", + "title" + ] + }, + "secondary_contact": { + "expands": {}, + "fields": [ + "email", + "fax", + "full_name", + "phone", + "title" + ] + }, + "set_aside": { + "expands": {}, + "fields": [ + "code", + "description" + ] + } + }, + "fields": [ + "active", + "agency", + "agency_id", + "archive_date", + "attachments", + "award_number", + "department", + "department_id", + "description", + "first_notice_date", + "last_notice_date", + "latest_notice", + "latest_notice_id", + "meta", + "naics_code", + "office", + "office_id", + "opportunity_id", + "place_of_performance", + "primary_contact", + "psc_code", + "response_deadline", + "sam_url", + "secondary_contact", + "set_aside", + "snippet", + "solicitation_number", + "title" + ] + }, + "shape_flat_paths": [ + "active", + "agency", + "agency.abbreviation", + "agency.code", + "agency.name", + "agency_id", + "archive_date", + "attachments", + "attachments.attachment_id", + "attachments.extracted_text", + "attachments.file_size", + "attachments.mime_type", + "attachments.name", + "attachments.posted_date", + "attachments.resource_id", + "attachments.type", + "attachments.url", + "award_number", + "department", + "department.abbreviation", + "department.cgac", + "department.code", + "department.congressional_justification", + "department.description", + "department.name", + "department.website", + "department_id", + "description", + "first_notice_date", + "last_notice_date", + "latest_notice", + "latest_notice.link", + "latest_notice.notice_id", + "latest_notice_id", + "meta", + "meta.attachments_count", + "meta.notice_type", + "meta.notice_type.code", + "meta.notice_type.type", + "meta.notices_count", + "naics_code", + "notice_history", + "notice_history.deleted", + "notice_history.index", + "notice_history.latest", + "notice_history.notice_id", + "notice_history.notice_type_code", + "notice_history.parent_notice_id", + "notice_history.posted_date", + "notice_history.related_notice_id", + "notice_history.solicitation_number", + "notice_history.title", + "office", + "office.agency_code", + "office.agency_name", + "office.department_code", + "office.department_name", + "office.office_code", + "office.office_name", + "office.organization_id", + "office_id", + "opportunity_id", + "place_of_performance", + "place_of_performance.city", + "place_of_performance.country", + "place_of_performance.state", + "place_of_performance.street_address", + "place_of_performance.zip", + "primary_contact", + "primary_contact.email", + "primary_contact.fax", + "primary_contact.full_name", + "primary_contact.phone", + "primary_contact.title", + "psc_code", + "response_deadline", + "sam_url", + "secondary_contact", + "secondary_contact.email", + "secondary_contact.fax", + "secondary_contact.full_name", + "secondary_contact.phone", + "secondary_contact.title", + "set_aside", + "set_aside.code", + "set_aside.description", + "snippet", + "solicitation_number", + "title" + ], + "shape_supported": true, + "shape_tier_required": "pro", + "viewset": "opportunities.views.OpportunityViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "active", + "agency", + "first_notice_date_after", + "first_notice_date_before", + "flat", + "flat_lists", + "joiner", + "last_notice_date_after", + "last_notice_date_before", + "limit", + "naics", + "notice_type", + "ordering", + "page", + "place_of_performance", + "psc", + "response_deadline_after", + "response_deadline_before", + "search", + "set_aside", + "shape", + "show_shapes", + "solicitation_number" + ] + }, + "organizations": { + "basename": "organization", + "docs_file": null, + "docs_params": [], + "prefix": "organizations", + "resource_key": "organizations", + "runtime": { + "filter_params": [ + "cgac", + "include_inactive", + "level", + "parent", + "search", + "type" + ], + "filter_params_detail": { + "cgac": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "include_inactive": { + "filter_class": "CharFilter", + "type": "string" + }, + "level": { + "filter_class": "NumberFilter", + "type": "number" + }, + "parent": { + "filter_class": "CharFilter", + "type": "string" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "type": { + "choices": [ + "AGENCY", + "DEPARTMENT", + "MAJOR COMMAND", + "OFFICE", + "SUB COMMAND" + ], + "choices_count": 5, + "filter_class": "LenientMultipleChoiceFilter", + "type": "choice" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "agency": { + "expands": {}, + "fields": [ + "abbreviation", + "code", + "name" + ] + }, + "ancestors": { + "expands": {}, + "fields": [ + "fh_key", + "level", + "name", + "short_name" + ] + }, + "budget_appropriation": { + "expands": {}, + "fields": [ + "cgac", + "fiscal_year", + "n_accounts", + "scope", + "summary", + "top_accounts" + ] + }, + "budget_spending": { + "expands": {}, + "fields": [ + "fiscal_year", + "n_orgs_in_rollup", + "organization_id", + "summary", + "top_accounts" + ] + }, + "children": { + "expands": {}, + "fields": [ + "cgac", + "code", + "fh_key", + "is_active", + "key", + "level", + "name", + "short_name", + "type" + ] + }, + "department": { + "expands": {}, + "fields": [ + "abbreviation", + "code", + "name" + ] + }, + "parent": { + "expands": {}, + "fields": [ + "cgac", + "code", + "fh_key", + "is_active", + "key", + "level", + "name", + "short_name", + "type" + ] + } + }, + "fields": [ + "aac_code", + "canonical_code", + "cgac", + "code", + "description", + "end_date", + "fh_key", + "fpds_code", + "fpds_org_id", + "full_parent_path_name", + "is_active", + "key", + "l1_fh_key", + "l2_fh_key", + "l3_fh_key", + "l4_fh_key", + "l5_fh_key", + "l6_fh_key", + "l7_fh_key", + "l8_fh_key", + "level", + "logo", + "mod_status", + "name", + "obligation_rank", + "obligations", + "parent_fh_key", + "short_name", + "start_date", + "summary", + "total_obligations", + "tree_obligations", + "type" + ] + }, + "shape_flat_paths": [ + "aac_code", + "agency", + "agency.abbreviation", + "agency.code", + "agency.name", + "ancestors", + "ancestors.fh_key", + "ancestors.level", + "ancestors.name", + "ancestors.short_name", + "budget_appropriation", + "budget_appropriation.cgac", + "budget_appropriation.fiscal_year", + "budget_appropriation.n_accounts", + "budget_appropriation.scope", + "budget_appropriation.summary", + "budget_appropriation.top_accounts", + "budget_spending", + "budget_spending.fiscal_year", + "budget_spending.n_orgs_in_rollup", + "budget_spending.organization_id", + "budget_spending.summary", + "budget_spending.top_accounts", + "canonical_code", + "cgac", + "children", + "children.cgac", + "children.code", + "children.fh_key", + "children.is_active", + "children.key", + "children.level", + "children.name", + "children.short_name", + "children.type", + "code", + "department", + "department.abbreviation", + "department.code", + "department.name", + "description", + "end_date", + "fh_key", + "fpds_code", + "fpds_org_id", + "full_parent_path_name", + "is_active", + "key", + "l1_fh_key", + "l2_fh_key", + "l3_fh_key", + "l4_fh_key", + "l5_fh_key", + "l6_fh_key", + "l7_fh_key", + "l8_fh_key", + "level", + "logo", + "mod_status", + "name", + "obligation_rank", + "obligations", + "parent", + "parent.cgac", + "parent.code", + "parent.fh_key", + "parent.is_active", + "parent.key", + "parent.level", + "parent.name", + "parent.short_name", + "parent.type", + "parent_fh_key", + "short_name", + "start_date", + "summary", + "total_obligations", + "tree_obligations", + "type" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "agencies.views.OrganizationViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "cgac", + "flat", + "flat_lists", + "include_inactive", + "joiner", + "level", + "limit", + "page", + "parent", + "search", + "shape", + "show_shapes", + "type" + ] + }, + "otas": { + "basename": "ota", + "docs_file": null, + "docs_params": [], + "prefix": "otas", + "resource_key": "otas", + "runtime": { + "filter_params": [ + "award_date", + "award_date_gte", + "award_date_lte", + "awarding_agency", + "expiring_gte", + "expiring_lte", + "fiscal_year", + "fiscal_year_gte", + "fiscal_year_lte", + "funding_agency", + "key", + "ordering", + "piid", + "pop_end_date_gte", + "pop_end_date_lte", + "pop_start_date_gte", + "pop_start_date_lte", + "psc", + "recipient", + "search", + "uei" + ], + "filter_params_detail": { + "award_date": { + "filter_class": "DateFilter", + "type": "date" + }, + "award_date_gte": { + "filter_class": "DateFilter", + "type": "date" + }, + "award_date_lte": { + "filter_class": "DateFilter", + "type": "date" + }, + "awarding_agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "expiring_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "expiring_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "fiscal_year": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_gte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_lte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "funding_agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "key": { + "filter_class": "IdListFilter", + "type": "string" + }, + "ordering": { + "choices": [ + "-award_date", + "-obligated", + "-total_contract_value", + "award_date", + "obligated", + "total_contract_value" + ], + "choices_count": 6, + "filter_class": "OrderingFilter", + "type": "ordering" + }, + "piid": { + "filter_class": "UppercaseCharFilter", + "type": "string" + }, + "pop_end_date_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "pop_end_date_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "pop_start_date_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "pop_start_date_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "psc": { + "filter_class": "CustomPSCFilter", + "type": "string" + }, + "recipient": { + "filter_class": "CharFilter", + "type": "string" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "uei": { + "filter_class": "UppercaseCharFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "award_date", + "obligated", + "total_contract_value" + ], + "pagination": { + "class": "KeysetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "award_type": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "awarding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "extent_competed": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "funding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "parent_award": { + "expands": {}, + "fields": [ + "key", + "piid" + ] + }, + "period_of_performance": { + "expands": {}, + "fields": [ + "current_end_date", + "start_date", + "ultimate_completion_date" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city_name", + "country_code", + "country_name", + "state_code", + "state_name", + "zip_code" + ] + }, + "psc": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "recipient": { + "expands": {}, + "fields": [ + "cage", + "cage_code", + "display_name", + "legal_business_name", + "uei" + ] + }, + "transactions": { + "expands": {}, + "fields": [ + "action_type", + "description", + "modification_number", + "obligated", + "transaction_date" + ] + }, + "type_of_ot_agreement": { + "expands": {}, + "fields": [ + "code", + "description" + ] + } + }, + "fields": [ + "award_date", + "award_type", + "base_and_exercised_options_value", + "consortia", + "consortia_uei", + "description", + "dod_acquisition_program", + "extent_competed", + "fiscal_year", + "key", + "non_governmental_dollars", + "non_traditional_government_contractor_participation", + "obligated", + "parent_award_modification_number", + "piid", + "psc_code", + "total_contract_value", + "transactions", + "type_of_ot_agreement" + ] + }, + "shape_flat_paths": [ + "award_date", + "award_type", + "award_type.code", + "award_type.description", + "awarding_office", + "awarding_office.agency_code", + "awarding_office.agency_name", + "awarding_office.department_code", + "awarding_office.department_name", + "awarding_office.office_code", + "awarding_office.office_name", + "awarding_office.organization_id", + "base_and_exercised_options_value", + "consortia", + "consortia_uei", + "description", + "dod_acquisition_program", + "extent_competed", + "extent_competed.code", + "extent_competed.description", + "fiscal_year", + "funding_office", + "funding_office.agency_code", + "funding_office.agency_name", + "funding_office.department_code", + "funding_office.department_name", + "funding_office.office_code", + "funding_office.office_name", + "funding_office.organization_id", + "key", + "non_governmental_dollars", + "non_traditional_government_contractor_participation", + "obligated", + "parent_award", + "parent_award.key", + "parent_award.piid", + "parent_award_modification_number", + "period_of_performance", + "period_of_performance.current_end_date", + "period_of_performance.start_date", + "period_of_performance.ultimate_completion_date", + "piid", + "place_of_performance", + "place_of_performance.city_name", + "place_of_performance.country_code", + "place_of_performance.country_name", + "place_of_performance.state_code", + "place_of_performance.state_name", + "place_of_performance.zip_code", + "psc", + "psc.code", + "psc.description", + "psc_code", + "recipient", + "recipient.cage", + "recipient.cage_code", + "recipient.display_name", + "recipient.legal_business_name", + "recipient.uei", + "total_contract_value", + "transactions", + "transactions.action_type", + "transactions.description", + "transactions.modification_number", + "transactions.obligated", + "transactions.transaction_date", + "type_of_ot_agreement", + "type_of_ot_agreement.code", + "type_of_ot_agreement.description" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "awards.views.otas.OTAViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "cursor", + "flat", + "flat_lists", + "joiner", + "limit", + "shape", + "show_shapes" + ] + }, + "otidvs": { + "basename": "otidv", + "docs_file": null, + "docs_params": [], + "prefix": "otidvs", + "resource_key": "otidvs", + "runtime": { + "filter_params": [ + "award_date", + "award_date_gte", + "award_date_lte", + "awarding_agency", + "expiring_gte", + "expiring_lte", + "fiscal_year", + "fiscal_year_gte", + "fiscal_year_lte", + "funding_agency", + "key", + "ordering", + "piid", + "pop_end_date_gte", + "pop_end_date_lte", + "pop_start_date_gte", + "pop_start_date_lte", + "psc", + "recipient", + "search", + "uei" + ], + "filter_params_detail": { + "award_date": { + "filter_class": "DateFilter", + "type": "date" + }, + "award_date_gte": { + "filter_class": "DateFilter", + "type": "date" + }, + "award_date_lte": { + "filter_class": "DateFilter", + "type": "date" + }, + "awarding_agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "expiring_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "expiring_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "fiscal_year": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_gte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_lte": { + "filter_class": "NumberFilter", + "type": "number" + }, + "funding_agency": { + "filter_class": "PerformantAgencyFilter", + "type": "string" + }, + "key": { + "filter_class": "IdListFilter", + "type": "string" + }, + "ordering": { + "choices": [ + "-award_date", + "-obligated", + "-total_contract_value", + "award_date", + "obligated", + "total_contract_value" + ], + "choices_count": 6, + "filter_class": "OrderingFilter", + "type": "ordering" + }, + "piid": { + "filter_class": "UppercaseCharFilter", + "type": "string" + }, + "pop_end_date_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "pop_end_date_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "pop_start_date_gte": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "pop_start_date_lte": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "psc": { + "filter_class": "CustomPSCFilter", + "type": "string" + }, + "recipient": { + "filter_class": "CharFilter", + "type": "string" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "uei": { + "filter_class": "UppercaseCharFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "award_date", + "obligated", + "total_contract_value" + ], + "pagination": { + "class": "KeysetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "awarding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "extent_competed": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "funding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "period_of_performance": { + "expands": {}, + "fields": [ + "current_end_date", + "start_date", + "ultimate_completion_date" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city_name", + "country_code", + "country_name", + "state_code", + "state_name", + "zip_code" + ] + }, + "psc": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "recipient": { + "expands": {}, + "fields": [ + "cage", + "cage_code", + "display_name", + "legal_business_name", + "uei" + ] + }, + "transactions": { + "expands": {}, + "fields": [ + "action_type", + "description", + "modification_number", + "obligated", + "transaction_date" + ] + }, + "type_of_ot_agreement": { + "expands": {}, + "fields": [ + "code", + "description" + ] + } + }, + "fields": [ + "award_date", + "base_and_exercised_options_value", + "consortia", + "consortia_uei", + "description", + "dod_acquisition_program", + "extent_competed", + "fiscal_year", + "idv_type", + "key", + "non_governmental_dollars", + "non_traditional_government_contractor_participation", + "obligated", + "piid", + "psc_code", + "total_contract_value", + "transactions", + "type_of_ot_agreement" + ] + }, + "shape_flat_paths": [ + "award_date", + "awarding_office", + "awarding_office.agency_code", + "awarding_office.agency_name", + "awarding_office.department_code", + "awarding_office.department_name", + "awarding_office.office_code", + "awarding_office.office_name", + "awarding_office.organization_id", + "base_and_exercised_options_value", + "consortia", + "consortia_uei", + "description", + "dod_acquisition_program", + "extent_competed", + "extent_competed.code", + "extent_competed.description", + "fiscal_year", + "funding_office", + "funding_office.agency_code", + "funding_office.agency_name", + "funding_office.department_code", + "funding_office.department_name", + "funding_office.office_code", + "funding_office.office_name", + "funding_office.organization_id", + "idv_type", + "key", + "non_governmental_dollars", + "non_traditional_government_contractor_participation", + "obligated", + "period_of_performance", + "period_of_performance.current_end_date", + "period_of_performance.start_date", + "period_of_performance.ultimate_completion_date", + "piid", + "place_of_performance", + "place_of_performance.city_name", + "place_of_performance.country_code", + "place_of_performance.country_name", + "place_of_performance.state_code", + "place_of_performance.state_name", + "place_of_performance.zip_code", + "psc", + "psc.code", + "psc.description", + "psc_code", + "recipient", + "recipient.cage", + "recipient.cage_code", + "recipient.display_name", + "recipient.legal_business_name", + "recipient.uei", + "total_contract_value", + "transactions", + "transactions.action_type", + "transactions.description", + "transactions.modification_number", + "transactions.obligated", + "transactions.transaction_date", + "type_of_ot_agreement", + "type_of_ot_agreement.code", + "type_of_ot_agreement.description" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "awards.views.otidvs.OTIDVViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "cursor", + "flat", + "flat_lists", + "joiner", + "limit", + "shape", + "show_shapes" + ] + }, + "protests": { + "basename": "bidprotest", + "docs_file": null, + "docs_params": [], + "prefix": "protests", + "resource_key": "protests", + "runtime": { + "filter_params": [ + "agency", + "case_number", + "case_type", + "decision_date_after", + "decision_date_before", + "filed_date_after", + "filed_date_before", + "naics_code", + "outcome", + "protester", + "search", + "solicitation_number", + "source_system" + ], + "filter_params_detail": { + "agency": { + "filter_class": "OrganizationScopeAgencyFilter", + "type": "string" + }, + "case_number": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "case_type": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "decision_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "decision_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "filed_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "filed_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "naics_code": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "outcome": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "protester": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "search": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "solicitation_number": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "source_system": { + "filter_class": "BaseSmartFilter", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "BidProtestPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "decisions": { + "expands": {}, + "fields": [ + "courtlistener_url", + "decision_date", + "document_type", + "document_url", + "judges", + "outcome", + "title" + ] + }, + "dockets": { + "expands": { + "organization": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + } + }, + "fields": [ + "agency", + "case_number", + "case_type", + "challenged_party", + "decision_date", + "decision_text", + "decision_url", + "digest", + "docket_number", + "docket_url", + "due_date", + "filed_date", + "judge", + "naics_code", + "outcome", + "outcome_reason", + "posted_date", + "protester", + "size_standard", + "solicitation_number", + "source_system", + "title" + ] + }, + "organization": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "resolved_agency": { + "expands": {}, + "fields": [ + "key", + "match_confidence", + "name", + "rationale" + ] + }, + "resolved_protester": { + "expands": {}, + "fields": [ + "match_confidence", + "name", + "rationale", + "uei" + ] + } + }, + "fields": [ + "agency", + "case_id", + "case_number", + "case_type", + "challenged_party", + "decision_date", + "decision_text", + "decision_url", + "decisions", + "digest", + "docket_url", + "dockets", + "due_date", + "filed_date", + "judge", + "naics_code", + "organization", + "outcome", + "outcome_reason", + "posted_date", + "protester", + "resolved_agency", + "resolved_protester", + "size_standard", + "solicitation_number", + "source_system", + "title" + ] + }, + "shape_flat_paths": [ + "agency", + "case_id", + "case_number", + "case_type", + "challenged_party", + "decision_date", + "decision_text", + "decision_url", + "decisions", + "decisions.courtlistener_url", + "decisions.decision_date", + "decisions.document_type", + "decisions.document_url", + "decisions.judges", + "decisions.outcome", + "decisions.title", + "digest", + "docket_url", + "dockets", + "dockets.agency", + "dockets.case_number", + "dockets.case_type", + "dockets.challenged_party", + "dockets.decision_date", + "dockets.decision_text", + "dockets.decision_url", + "dockets.digest", + "dockets.docket_number", + "dockets.docket_url", + "dockets.due_date", + "dockets.filed_date", + "dockets.judge", + "dockets.naics_code", + "dockets.organization", + "dockets.organization.agency_code", + "dockets.organization.agency_name", + "dockets.organization.department_code", + "dockets.organization.department_name", + "dockets.organization.office_code", + "dockets.organization.office_name", + "dockets.organization.organization_id", + "dockets.outcome", + "dockets.outcome_reason", + "dockets.posted_date", + "dockets.protester", + "dockets.size_standard", + "dockets.solicitation_number", + "dockets.source_system", + "dockets.title", + "due_date", + "filed_date", + "judge", + "naics_code", + "organization", + "organization.agency_code", + "organization.agency_name", + "organization.department_code", + "organization.department_name", + "organization.office_code", + "organization.office_name", + "organization.organization_id", + "outcome", + "outcome_reason", + "posted_date", + "protester", + "resolved_agency", + "resolved_agency.key", + "resolved_agency.match_confidence", + "resolved_agency.name", + "resolved_agency.rationale", + "resolved_protester", + "resolved_protester.match_confidence", + "resolved_protester.name", + "resolved_protester.rationale", + "resolved_protester.uei", + "size_standard", + "solicitation_number", + "source_system", + "title" + ], + "shape_supported": true, + "shape_tier_required": "enterprise_a", + "viewset": "protests.views.BidProtestViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "psc": { + "basename": "productservicecode", + "docs_file": null, + "docs_params": [], + "prefix": "psc", + "resource_key": "psc", + "runtime": { + "filter_params": [ + "has_awards" + ], + "filter_params_detail": { + "has_awards": { + "filter_class": "ViewHandledParam", + "type": "boolean" + } + }, + "ordering_aliases": [], + "ordering_fields": [], + "pagination": { + "class": "StaticModelCachedPagination", + "max_page_size": 10000 + }, + "shape": { + "expands": { + "current": { + "expands": {}, + "fields": [ + "active", + "description", + "end_date", + "excludes", + "includes", + "name", + "start_date" + ] + }, + "historical": { + "expands": {}, + "fields": [ + "active", + "description", + "end_date", + "excludes", + "includes", + "name", + "start_date" + ] + } + }, + "fields": [ + "category", + "code", + "level_1_category", + "level_1_category_code", + "level_2_category", + "level_2_category_code", + "parent" + ] + }, + "shape_flat_paths": [ + "category", + "code", + "current", + "current.active", + "current.description", + "current.end_date", + "current.excludes", + "current.includes", + "current.name", + "current.start_date", + "historical", + "historical.active", + "historical.description", + "historical.end_date", + "historical.excludes", + "historical.includes", + "historical.name", + "historical.start_date", + "level_1_category", + "level_1_category_code", + "level_2_category", + "level_2_category_code", + "parent" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "shared.views.ProductServiceCodeViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "page", + "shape", + "show_shapes" + ] + }, + "sbir/solicitations": { + "basename": "sbir-solicitation", + "docs_file": null, + "docs_params": [], + "prefix": "sbir/solicitations", + "resource_key": "sbir/solicitations", + "runtime": { + "filter_params": [ + "activity", + "cycle_name", + "end_date_after", + "end_date_before", + "out_of_cycle", + "program", + "search", + "solicitation_number", + "solicitation_status", + "start_date_after", + "start_date_before", + "year" + ], + "filter_params_detail": { + "activity": { + "choices": [ + "closed", + "open" + ], + "choices_count": 2, + "filter_class": "ChoiceFilter", + "type": "choice" + }, + "cycle_name": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "end_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "end_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "out_of_cycle": { + "filter_class": "BooleanFilter", + "type": "boolean" + }, + "program": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "solicitation_number": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "solicitation_status": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "start_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "start_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "year": { + "filter_class": "NumberFilter", + "type": "number" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "activity", + "end_date", + "modified", + "start_date", + "year" + ], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "documents": { + "expands": {}, + "fields": [ + "cycle_name", + "document_id", + "extraction_status", + "file_size", + "filename", + "n_chars", + "n_pages", + "s3_key" + ] + }, + "topics": { + "expands": {}, + "fields": [ + "agency", + "close_date", + "title", + "topic_id", + "topic_number", + "topic_url" + ] + } + }, + "fields": [ + "activity", + "cycle", + "cycle_name", + "end_date", + "out_of_cycle", + "program", + "sol_download_url", + "solicitation_cycle_id", + "solicitation_id", + "solicitation_number", + "solicitation_status", + "source_last_updated", + "start_date", + "title", + "year" + ] + }, + "shape_flat_paths": [ + "activity", + "cycle", + "cycle_name", + "documents", + "documents.cycle_name", + "documents.document_id", + "documents.extraction_status", + "documents.file_size", + "documents.filename", + "documents.n_chars", + "documents.n_pages", + "documents.s3_key", + "end_date", + "out_of_cycle", + "program", + "sol_download_url", + "solicitation_cycle_id", + "solicitation_id", + "solicitation_number", + "solicitation_status", + "source_last_updated", + "start_date", + "title", + "topics", + "topics.agency", + "topics.close_date", + "topics.title", + "topics.topic_id", + "topics.topic_number", + "topics.topic_url", + "year" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "sbir.views.SbirDsipSolicitationViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "sbir/topics": { + "basename": "sbir-topic", + "docs_file": null, + "docs_params": [], + "prefix": "sbir/topics", + "resource_key": "sbir/topics", + "runtime": { + "filter_params": [ + "activity", + "agency", + "close_date_after", + "close_date_before", + "doc_source", + "open_date_after", + "open_date_before", + "release_date_after", + "release_date_before", + "search", + "solicitation_number", + "topic_number", + "year" + ], + "filter_params_detail": { + "activity": { + "choices": [ + "closed", + "open", + "unknown" + ], + "choices_count": 3, + "filter_class": "ChoiceFilter", + "type": "choice" + }, + "agency": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "close_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "close_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "doc_source": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "open_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "open_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "release_date_after": { + "filter_class": "DateFromToRangeFilter", + "lookup": "gte", + "type": "date" + }, + "release_date_before": { + "filter_class": "DateFromToRangeFilter", + "lookup": "lte", + "type": "date" + }, + "search": { + "filter_class": "CharFilter", + "type": "string" + }, + "solicitation_number": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "topic_number": { + "filter_class": "CharFilter", + "lookup": "icontains", + "type": "string" + }, + "year": { + "filter_class": "NumberFilter", + "type": "number" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "activity", + "close_date", + "modified", + "open_date", + "release_date", + "year" + ], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "grant": { + "expands": {}, + "fields": [ + "grant_id", + "opportunity_number", + "response_date", + "title" + ] + }, + "opportunity": { + "expands": {}, + "fields": [ + "opportunity_id", + "response_deadline", + "solicitation_number", + "title" + ] + }, + "solicitation": { + "expands": {}, + "fields": [ + "cycle_name", + "end_date", + "out_of_cycle", + "program", + "solicitation_id", + "solicitation_number", + "solicitation_status", + "start_date", + "title", + "year" + ] + } + }, + "fields": [ + "activity", + "agency", + "close_date", + "description", + "doc_source", + "due_dates_text", + "listed_open", + "official_solicitation_url", + "open_date", + "release_date", + "solicitation_number", + "solicitation_status", + "source_last_updated", + "title", + "topic_id", + "topic_node_id", + "topic_number", + "topic_url", + "year" + ] + }, + "shape_flat_paths": [ + "activity", + "agency", + "close_date", + "description", + "doc_source", + "due_dates_text", + "grant", + "grant.grant_id", + "grant.opportunity_number", + "grant.response_date", + "grant.title", + "listed_open", + "official_solicitation_url", + "open_date", + "opportunity", + "opportunity.opportunity_id", + "opportunity.response_deadline", + "opportunity.solicitation_number", + "opportunity.title", + "release_date", + "solicitation", + "solicitation.cycle_name", + "solicitation.end_date", + "solicitation.out_of_cycle", + "solicitation.program", + "solicitation.solicitation_id", + "solicitation.solicitation_number", + "solicitation.solicitation_status", + "solicitation.start_date", + "solicitation.title", + "solicitation.year", + "solicitation_number", + "solicitation_status", + "source_last_updated", + "title", + "topic_id", + "topic_node_id", + "topic_number", + "topic_url", + "year" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "sbir.views.SbirTopicViewSet" + }, + "swagger_has_key": false, + "swagger_params": [] + }, + "subawards": { + "basename": "subaward", + "docs_file": null, + "docs_params": [], + "prefix": "subawards", + "resource_key": "subawards", + "runtime": { + "filter_params": [ + "award_key", + "awarding_agency", + "fiscal_year", + "fiscal_year_gte", + "fiscal_year_lte", + "funding_agency", + "prime_uei", + "recipient", + "sub_uei" + ], + "filter_params_detail": { + "award_key": { + "filter_class": "CharFilter", + "type": "string" + }, + "awarding_agency": { + "filter_class": "SubawardAgencyFilter", + "type": "string" + }, + "fiscal_year": { + "filter_class": "NumberFilter", + "type": "number" + }, + "fiscal_year_gte": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "fiscal_year_lte": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "funding_agency": { + "filter_class": "SubawardAgencyFilter", + "type": "string" + }, + "prime_uei": { + "filter_class": "CharFilter", + "type": "string" + }, + "recipient": { + "filter_class": "CharFilter", + "type": "string" + }, + "sub_uei": { + "filter_class": "CharFilter", + "type": "string" + } + }, + "ordering_aliases": [ + "last_modified_date" + ], + "ordering_fields": [], + "pagination": { + "class": "CachedPageNumberPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "awarding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name" + ] + }, + "fsrs_details": { + "expands": {}, + "fields": [ + "id", + "last_modified_date", + "month", + "year" + ] + }, + "funding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name" + ] + }, + "highly_compensated_officers": { + "expands": {}, + "fields": [ + "amount", + "name" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city", + "country_code", + "state", + "zip" + ] + }, + "prime_recipient": { + "expands": {}, + "fields": [ + "display_name", + "uei" + ] + }, + "subaward_details": { + "expands": {}, + "fields": [ + "action_date", + "amount", + "description", + "fiscal_year", + "number", + "type" + ] + }, + "subaward_recipient": { + "expands": {}, + "fields": [ + "display_name", + "duns", + "uei" + ] + } + }, + "fields": [ + "award_key", + "key", + "piid", + "prime_awardee_name", + "prime_awardee_uei", + "recipient_business_types", + "recipient_dba_name", + "recipient_duns", + "recipient_name", + "recipient_parent_duns", + "recipient_parent_name", + "recipient_parent_uei", + "recipient_uei", + "usaspending_permalink" + ] + }, + "shape_flat_paths": [ + "award_key", + "awarding_office", + "awarding_office.agency_code", + "awarding_office.agency_name", + "awarding_office.department_code", + "awarding_office.department_name", + "awarding_office.office_code", + "awarding_office.office_name", + "fsrs_details", + "fsrs_details.id", + "fsrs_details.last_modified_date", + "fsrs_details.month", + "fsrs_details.year", + "funding_office", + "funding_office.agency_code", + "funding_office.agency_name", + "funding_office.department_code", + "funding_office.department_name", + "funding_office.office_code", + "funding_office.office_name", + "highly_compensated_officers", + "highly_compensated_officers.amount", + "highly_compensated_officers.name", + "key", + "piid", + "place_of_performance", + "place_of_performance.city", + "place_of_performance.country_code", + "place_of_performance.state", + "place_of_performance.zip", + "prime_awardee_name", + "prime_awardee_uei", + "prime_recipient", + "prime_recipient.display_name", + "prime_recipient.uei", + "recipient_business_types", + "recipient_dba_name", + "recipient_duns", + "recipient_name", + "recipient_parent_duns", + "recipient_parent_name", + "recipient_parent_uei", + "recipient_uei", + "subaward_details", + "subaward_details.action_date", + "subaward_details.amount", + "subaward_details.description", + "subaward_details.fiscal_year", + "subaward_details.number", + "subaward_details.type", + "subaward_recipient", + "subaward_recipient.display_name", + "subaward_recipient.duns", + "subaward_recipient.uei", + "usaspending_permalink" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "awards.views.subawards.SubawardViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "flat", + "flat_lists", + "joiner", + "limit", + "ordering", + "page", + "shape", + "show_shapes" + ] + }, + "vehicles": { + "basename": "vehicle", + "docs_file": null, + "docs_params": [], + "prefix": "vehicles", + "resource_key": "vehicles", + "runtime": { + "filter_params": [ + "agency", + "award_date_after", + "award_date_before", + "contract_type", + "fiscal_year", + "idv_count_max", + "idv_count_min", + "last_date_to_order_after", + "last_date_to_order_before", + "naics_code", + "order_count_max", + "order_count_min", + "organization_id", + "program_acronym", + "psc_code", + "search", + "set_aside", + "total_obligated_max", + "total_obligated_min", + "type_of_idc", + "vehicle_type", + "who_can_use" + ], + "filter_params_detail": { + "agency": { + "filter_class": "VehiclePerformantAgencyFilter", + "type": "string" + }, + "award_date_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "award_date_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "contract_type": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "fiscal_year": { + "filter_class": "NumberFilter", + "type": "number" + }, + "idv_count_max": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "idv_count_min": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "last_date_to_order_after": { + "filter_class": "DateFilter", + "lookup": "gte", + "type": "date" + }, + "last_date_to_order_before": { + "filter_class": "DateFilter", + "lookup": "lte", + "type": "date" + }, + "naics_code": { + "filter_class": "NumberFilter", + "type": "number" + }, + "order_count_max": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "order_count_min": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "organization_id": { + "filter_class": "UUIDFilter", + "type": "string" + }, + "program_acronym": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "psc_code": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + }, + "search": { + "filter_class": "ViewHandledSearch", + "type": "string" + }, + "set_aside": { + "filter_class": "CustomSetAsideFilter", + "type": "string" + }, + "total_obligated_max": { + "filter_class": "NumberFilter", + "lookup": "lte", + "type": "number" + }, + "total_obligated_min": { + "filter_class": "NumberFilter", + "lookup": "gte", + "type": "number" + }, + "type_of_idc": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "vehicle_type": { + "filter_class": "BaseSmartFilter", + "type": "string" + }, + "who_can_use": { + "filter_class": "CharFilter", + "lookup": "iexact", + "type": "string" + } + }, + "ordering_aliases": [], + "ordering_fields": [ + "award_date", + "fiscal_year", + "idv_count", + "last_date_to_order", + "latest_award_date", + "order_count", + "total_obligated", + "vehicle_obligations" + ], + "pagination": { + "class": "StandardResultsSetPagination", + "max_page_size": 100 + }, + "shape": { + "expands": { + "agency_details": { + "expands": {}, + "fields": [ + "*", + "awarding_office", + "funding_office" + ] + }, + "awardees": { + "expands": { + "awarding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "awards": { + "expands": {}, + "fields": [ + "award_date", + "base_and_exercised_options_value", + "description", + "fiscal_year", + "key", + "naics_code", + "obligated", + "piid", + "psc_code", + "total_contract_value", + "transactions" + ] + }, + "competition": { + "expands": {}, + "fields": [ + "contract_type", + "extent_competed", + "number_of_offers_received", + "other_than_full_and_open_competition", + "solicitation_date", + "solicitation_identifier", + "solicitation_procedures" + ] + }, + "funding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "gsa_elibrary": { + "expands": {}, + "fields": [ + "contract_number", + "cooperative_purchasing", + "disaster_recovery_purchasing", + "external_id", + "extracted_text", + "file_urls", + "schedule", + "sins", + "source_data", + "uei" + ] + }, + "idv_type": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "legislative_mandates": { + "expands": {}, + "fields": [ + "clinger_cohen_act_planning", + "construction_wage_rate_requirements", + "employment_eligibility_verification", + "interagency_contracting_authority", + "labor_standards", + "materials_supplies_articles_equipment", + "other_statutory_authority", + "service_contract_inventory" + ] + }, + "multiple_or_single_award_idv": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "naics": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "officers": { + "expands": {}, + "fields": [ + "highly_compensated_officer_1_amount", + "highly_compensated_officer_1_name", + "highly_compensated_officer_2_amount", + "highly_compensated_officer_2_name", + "highly_compensated_officer_3_amount", + "highly_compensated_officer_3_name", + "highly_compensated_officer_4_amount", + "highly_compensated_officer_4_name", + "highly_compensated_officer_5_amount", + "highly_compensated_officer_5_name" + ] + }, + "orders": { + "expands": { + "award_type": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "awarding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "commercial_item_acquisition_procedures": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "competition": { + "expands": {}, + "fields": [ + "contract_type", + "extent_competed", + "number_of_offers_received", + "other_than_full_and_open_competition", + "solicitation_date", + "solicitation_identifier", + "solicitation_procedures" + ] + }, + "consolidated_contract": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "contingency_humanitarian_or_peacekeeping_operation": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "contract_bundling": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "cost_accounting_standards_clause": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "cost_or_pricing_data": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "domestic_or_foreign_entity": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "epa_designated_product": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "evaluated_preference": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "fair_opportunity_limited_sources": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "fed_biz_opps": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "foreign_funding": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "funding_office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "information_technology_commercial_item_category": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "inherently_governmental_functions": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "legislative_mandates": { + "expands": {}, + "fields": [ + "clinger_cohen_act_planning", + "construction_wage_rate_requirements", + "employment_eligibility_verification", + "interagency_contracting_authority", + "labor_standards", + "materials_supplies_articles_equipment", + "other_statutory_authority", + "service_contract_inventory" + ] + }, + "naics": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "officers": { + "expands": {}, + "fields": [ + "highly_compensated_officer_1_amount", + "highly_compensated_officer_1_name", + "highly_compensated_officer_2_amount", + "highly_compensated_officer_2_name", + "highly_compensated_officer_3_amount", + "highly_compensated_officer_3_name", + "highly_compensated_officer_4_amount", + "highly_compensated_officer_4_name", + "highly_compensated_officer_5_amount", + "highly_compensated_officer_5_name" + ] + }, + "parent_award": { + "expands": {}, + "fields": [ + "key", + "piid" + ] + }, + "performance_based_service_acquisition": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "period_of_performance": { + "expands": {}, + "fields": [ + "current_end_date", + "start_date", + "ultimate_completion_date" + ] + }, + "place_of_manufacture": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city_name", + "country_code", + "country_name", + "state_code", + "state_name", + "zip_code" + ] + }, + "psc": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "recipient": { + "expands": {}, + "fields": [ + "cage", + "cage_code", + "display_name", + "legal_business_name", + "uei" + ] + }, + "recovered_materials_sustainability": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "research": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "sam_exception": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "set_aside": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "subawards_summary": { + "expands": {}, + "fields": [ + "count", + "total_amount" + ] + }, + "subcontracting_plan": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "tradeoff_process": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "transactions": { + "expands": {}, + "fields": [ + "action_type", + "description", + "modification_number", + "obligated", + "transaction_date" + ] + }, + "undefinitized_action": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "vehicle": { + "expands": {}, + "fields": [ + "agency_id", + "award_date", + "contract_type", + "description", + "fiscal_year", + "last_date_to_order", + "naics_code", + "psc_code", + "set_aside", + "solicitation_date", + "solicitation_description", + "solicitation_identifier", + "solicitation_title", + "type_of_idc", + "uuid", + "vehicle_type", + "who_can_use" + ] + } + }, + "fields": [ + "award_date", + "award_type", + "base_and_exercised_options_value", + "contract_financing", + "description", + "dod_acquisition_program", + "dod_transaction_number", + "fiscal_year", + "government_furnished_property", + "key", + "local_area_set_aside", + "major_program", + "naics_code", + "number_of_actions", + "number_of_offers_source", + "obligated", + "piid", + "price_evaluation_percent_difference", + "psc_code", + "purchase_card_as_payment_method", + "set_aside", + "simplified_procedures_for_certain_commercial_items", + "small_business_competitiveness_demonstration_program", + "solicitation_identifier", + "subawards_summary", + "total_contract_value", + "transactions", + "type_of_set_aside_source" + ] + }, + "parent_award": { + "expands": {}, + "fields": [ + "key", + "piid" + ] + }, + "period_of_performance": { + "expands": {}, + "fields": [ + "last_date_to_order", + "start_date" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city_name", + "country_code", + "country_name", + "state_code", + "state_name", + "zip_code" + ] + }, + "psc": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "recipient": { + "expands": {}, + "fields": [ + "cage", + "cage_code", + "display_name", + "legal_business_name", + "uei" + ] + }, + "set_aside": { + "expands": {}, + "fields": [ + "code", + "description" + ] + }, + "subawards_summary": { + "expands": {}, + "fields": [ + "count", + "total_amount" + ] + }, + "transactions": { + "expands": {}, + "fields": [ + "action_type", + "description", + "modification_number", + "obligated", + "transaction_date" + ] + }, + "type_of_idc": { + "expands": {}, + "fields": [ + "code", + "description" + ] + } + }, + "fields": [ + "award_date", + "commercial_item_acquisition_procedures", + "consolidated_contract", + "contingency_humanitarian_or_peacekeeping_operation", + "contract_bundling", + "contract_financing", + "cost_accounting_standards_clause", + "cost_or_pricing_data", + "description", + "dod_acquisition_program", + "dod_transaction_number", + "domestic_or_foreign_entity", + "email_address", + "epa_designated_product", + "evaluated_preference", + "fair_opportunity_limited_sources", + "fed_biz_opps", + "fee_range_lower_value", + "fee_range_upper_value", + "fiscal_year", + "fixed_fee_value", + "foreign_funding", + "government_furnished_property", + "idv_type", + "idv_website", + "inherently_governmental_functions", + "key", + "local_area_set_aside", + "major_program", + "multiple_or_single_award_idv", + "naics_code", + "number_of_actions", + "number_of_offers_source", + "obligated", + "ordering_procedure", + "performance_based_service_acquisition", + "piid", + "program_acronym", + "psc_code", + "recovered_materials_sustainability", + "research", + "sam_exception", + "set_aside", + "simplified_procedures_for_certain_commercial_items", + "small_business_competitiveness_demonstration_program", + "solicitation_identifier", + "subawards_summary", + "subcontracting_plan", + "title", + "total_contract_value", + "total_estimated_order_value", + "tradeoff_process", + "transactions", + "type_of_fee_for_use_of_service", + "type_of_idc", + "undefinitized_action", + "uuid", + "vehicle_uuid", + "who_can_use" + ] + }, + "competition_details": { + "expands": {}, + "fields": [ + "*", + "commercial_item_acquisition_procedures", + "evaluated_preference", + "extent_competed", + "most_recent_solicitation_date", + "number_of_offers_received", + "original_solicitation_date", + "other_than_full_and_open_competition", + "set_aside", + "simplified_procedures_for_certain_commercial_items", + "small_business_competitiveness_demonstration_program", + "solicitation_identifier", + "solicitation_procedures" + ] + }, + "metrics": { + "expands": {}, + "fields": [ + "*", + "avg_offers_received", + "avg_order_value", + "award_concentration_hhi", + "competed_rate", + "days_since_last_order", + "max_order_value", + "obligation_to_ceiling_ratio", + "order_concentration_hhi", + "recent_obligations_24mo", + "recent_orders_24mo", + "top_recipient_share", + "using_agency_count" + ] + }, + "opportunity": { + "expands": { + "agency": { + "expands": {}, + "fields": [ + "abbreviation", + "code", + "name" + ] + }, + "attachments": { + "expands": {}, + "fields": [ + "attachment_id", + "extracted_text", + "file_size", + "mime_type", + "name", + "posted_date", + "resource_id", + "type", + "url" + ] + }, + "department": { + "expands": {}, + "fields": [ + "abbreviation", + "cgac", + "code", + "congressional_justification", + "description", + "name", + "website" + ] + }, + "latest_notice": { + "expands": {}, + "fields": [ + "link", + "notice_id" + ] + }, + "meta": { + "expands": { + "notice_type": { + "expands": {}, + "fields": [ + "code", + "type" + ] + } + }, + "fields": [ + "attachments_count", + "notice_type", + "notices_count" + ] + }, + "notice_history": { + "expands": {}, + "fields": [ + "deleted", + "index", + "latest", + "notice_id", + "notice_type_code", + "parent_notice_id", + "posted_date", + "related_notice_id", + "solicitation_number", + "title" + ] + }, + "office": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + }, + "place_of_performance": { + "expands": {}, + "fields": [ + "city", + "country", + "state", + "street_address", + "zip" + ] + }, + "primary_contact": { + "expands": {}, + "fields": [ + "email", + "fax", + "full_name", + "phone", + "title" + ] + }, + "secondary_contact": { + "expands": {}, + "fields": [ + "email", + "fax", + "full_name", + "phone", + "title" + ] + }, + "set_aside": { + "expands": {}, + "fields": [ + "code", + "description" + ] + } + }, + "fields": [ + "active", + "agency", + "agency_id", + "archive_date", + "attachments", + "award_number", + "department", + "department_id", + "description", + "first_notice_date", + "last_notice_date", + "latest_notice", + "latest_notice_id", + "meta", + "naics_code", + "office", + "office_id", + "opportunity_id", + "place_of_performance", + "primary_contact", + "psc_code", + "response_deadline", + "sam_url", + "secondary_contact", + "set_aside", + "snippet", + "solicitation_number", + "title" + ] + }, + "organization": { + "expands": {}, + "fields": [ + "agency_code", + "agency_name", + "department_code", + "department_name", + "office_code", + "office_name", + "organization_id" + ] + } + }, + "fields": [ + "agency_details", + "agency_id", + "award_date", + "awardee_count", + "contract_type", + "description", + "descriptions", + "fiscal_year", + "idv_count", + "is_synthetic_solicitation", + "last_date_to_order", + "latest_award_date", + "naics_code", + "name", + "opportunity_id", + "order_count", + "organization", + "organization_id", + "program_acronym", + "psc_code", + "set_aside", + "solicitation_date", + "solicitation_description", + "solicitation_identifier", + "solicitation_title", + "total_obligated", + "type_of_idc", + "uuid", + "vehicle_contracts_value", + "vehicle_obligations", + "vehicle_type", + "who_can_use" + ] + }, + "shape_flat_paths": [ + "agency_details", + "agency_details.*", + "agency_details.awarding_office", + "agency_details.funding_office", + "agency_id", + "award_date", + "awardee_count", + "awardees", + "awardees.award_date", + "awardees.awarding_office", + "awardees.awarding_office.agency_code", + "awardees.awarding_office.agency_name", + "awardees.awarding_office.department_code", + "awardees.awarding_office.department_name", + "awardees.awarding_office.office_code", + "awardees.awarding_office.office_name", + "awardees.awarding_office.organization_id", + "awardees.awards", + "awardees.awards.award_date", + "awardees.awards.base_and_exercised_options_value", + "awardees.awards.description", + "awardees.awards.fiscal_year", + "awardees.awards.key", + "awardees.awards.naics_code", + "awardees.awards.obligated", + "awardees.awards.piid", + "awardees.awards.psc_code", + "awardees.awards.total_contract_value", + "awardees.awards.transactions", + "awardees.commercial_item_acquisition_procedures", + "awardees.competition", + "awardees.competition.contract_type", + "awardees.competition.extent_competed", + "awardees.competition.number_of_offers_received", + "awardees.competition.other_than_full_and_open_competition", + "awardees.competition.solicitation_date", + "awardees.competition.solicitation_identifier", + "awardees.competition.solicitation_procedures", + "awardees.consolidated_contract", + "awardees.contingency_humanitarian_or_peacekeeping_operation", + "awardees.contract_bundling", + "awardees.contract_financing", + "awardees.cost_accounting_standards_clause", + "awardees.cost_or_pricing_data", + "awardees.description", + "awardees.dod_acquisition_program", + "awardees.dod_transaction_number", + "awardees.domestic_or_foreign_entity", + "awardees.email_address", + "awardees.epa_designated_product", + "awardees.evaluated_preference", + "awardees.fair_opportunity_limited_sources", + "awardees.fed_biz_opps", + "awardees.fee_range_lower_value", + "awardees.fee_range_upper_value", + "awardees.fiscal_year", + "awardees.fixed_fee_value", + "awardees.foreign_funding", + "awardees.funding_office", + "awardees.funding_office.agency_code", + "awardees.funding_office.agency_name", + "awardees.funding_office.department_code", + "awardees.funding_office.department_name", + "awardees.funding_office.office_code", + "awardees.funding_office.office_name", + "awardees.funding_office.organization_id", + "awardees.government_furnished_property", + "awardees.gsa_elibrary", + "awardees.gsa_elibrary.contract_number", + "awardees.gsa_elibrary.cooperative_purchasing", + "awardees.gsa_elibrary.disaster_recovery_purchasing", + "awardees.gsa_elibrary.external_id", + "awardees.gsa_elibrary.extracted_text", + "awardees.gsa_elibrary.file_urls", + "awardees.gsa_elibrary.schedule", + "awardees.gsa_elibrary.sins", + "awardees.gsa_elibrary.source_data", + "awardees.gsa_elibrary.uei", + "awardees.idv_type", + "awardees.idv_type.code", + "awardees.idv_type.description", + "awardees.idv_website", + "awardees.inherently_governmental_functions", + "awardees.key", + "awardees.legislative_mandates", + "awardees.legislative_mandates.clinger_cohen_act_planning", + "awardees.legislative_mandates.construction_wage_rate_requirements", + "awardees.legislative_mandates.employment_eligibility_verification", + "awardees.legislative_mandates.interagency_contracting_authority", + "awardees.legislative_mandates.labor_standards", + "awardees.legislative_mandates.materials_supplies_articles_equipment", + "awardees.legislative_mandates.other_statutory_authority", + "awardees.legislative_mandates.service_contract_inventory", + "awardees.local_area_set_aside", + "awardees.major_program", + "awardees.multiple_or_single_award_idv", + "awardees.multiple_or_single_award_idv.code", + "awardees.multiple_or_single_award_idv.description", + "awardees.naics", + "awardees.naics.code", + "awardees.naics.description", + "awardees.naics_code", + "awardees.number_of_actions", + "awardees.number_of_offers_source", + "awardees.obligated", + "awardees.officers", + "awardees.officers.highly_compensated_officer_1_amount", + "awardees.officers.highly_compensated_officer_1_name", + "awardees.officers.highly_compensated_officer_2_amount", + "awardees.officers.highly_compensated_officer_2_name", + "awardees.officers.highly_compensated_officer_3_amount", + "awardees.officers.highly_compensated_officer_3_name", + "awardees.officers.highly_compensated_officer_4_amount", + "awardees.officers.highly_compensated_officer_4_name", + "awardees.officers.highly_compensated_officer_5_amount", + "awardees.officers.highly_compensated_officer_5_name", + "awardees.ordering_procedure", + "awardees.orders", + "awardees.orders.award_date", + "awardees.orders.award_type", + "awardees.orders.award_type.code", + "awardees.orders.award_type.description", + "awardees.orders.awarding_office", + "awardees.orders.awarding_office.agency_code", + "awardees.orders.awarding_office.agency_name", + "awardees.orders.awarding_office.department_code", + "awardees.orders.awarding_office.department_name", + "awardees.orders.awarding_office.office_code", + "awardees.orders.awarding_office.office_name", + "awardees.orders.awarding_office.organization_id", + "awardees.orders.base_and_exercised_options_value", + "awardees.orders.commercial_item_acquisition_procedures", + "awardees.orders.commercial_item_acquisition_procedures.code", + "awardees.orders.commercial_item_acquisition_procedures.description", + "awardees.orders.competition", + "awardees.orders.competition.contract_type", + "awardees.orders.competition.extent_competed", + "awardees.orders.competition.number_of_offers_received", + "awardees.orders.competition.other_than_full_and_open_competition", + "awardees.orders.competition.solicitation_date", + "awardees.orders.competition.solicitation_identifier", + "awardees.orders.competition.solicitation_procedures", + "awardees.orders.consolidated_contract", + "awardees.orders.consolidated_contract.code", + "awardees.orders.consolidated_contract.description", + "awardees.orders.contingency_humanitarian_or_peacekeeping_operation", + "awardees.orders.contingency_humanitarian_or_peacekeeping_operation.code", + "awardees.orders.contingency_humanitarian_or_peacekeeping_operation.description", + "awardees.orders.contract_bundling", + "awardees.orders.contract_bundling.code", + "awardees.orders.contract_bundling.description", + "awardees.orders.contract_financing", + "awardees.orders.cost_accounting_standards_clause", + "awardees.orders.cost_accounting_standards_clause.code", + "awardees.orders.cost_accounting_standards_clause.description", + "awardees.orders.cost_or_pricing_data", + "awardees.orders.cost_or_pricing_data.code", + "awardees.orders.cost_or_pricing_data.description", + "awardees.orders.description", + "awardees.orders.dod_acquisition_program", + "awardees.orders.dod_transaction_number", + "awardees.orders.domestic_or_foreign_entity", + "awardees.orders.domestic_or_foreign_entity.code", + "awardees.orders.domestic_or_foreign_entity.description", + "awardees.orders.epa_designated_product", + "awardees.orders.epa_designated_product.code", + "awardees.orders.epa_designated_product.description", + "awardees.orders.evaluated_preference", + "awardees.orders.evaluated_preference.code", + "awardees.orders.evaluated_preference.description", + "awardees.orders.fair_opportunity_limited_sources", + "awardees.orders.fair_opportunity_limited_sources.code", + "awardees.orders.fair_opportunity_limited_sources.description", + "awardees.orders.fed_biz_opps", + "awardees.orders.fed_biz_opps.code", + "awardees.orders.fed_biz_opps.description", + "awardees.orders.fiscal_year", + "awardees.orders.foreign_funding", + "awardees.orders.foreign_funding.code", + "awardees.orders.foreign_funding.description", + "awardees.orders.funding_office", + "awardees.orders.funding_office.agency_code", + "awardees.orders.funding_office.agency_name", + "awardees.orders.funding_office.department_code", + "awardees.orders.funding_office.department_name", + "awardees.orders.funding_office.office_code", + "awardees.orders.funding_office.office_name", + "awardees.orders.funding_office.organization_id", + "awardees.orders.government_furnished_property", + "awardees.orders.information_technology_commercial_item_category", + "awardees.orders.information_technology_commercial_item_category.code", + "awardees.orders.information_technology_commercial_item_category.description", + "awardees.orders.inherently_governmental_functions", + "awardees.orders.inherently_governmental_functions.code", + "awardees.orders.inherently_governmental_functions.description", + "awardees.orders.key", + "awardees.orders.legislative_mandates", + "awardees.orders.legislative_mandates.clinger_cohen_act_planning", + "awardees.orders.legislative_mandates.construction_wage_rate_requirements", + "awardees.orders.legislative_mandates.employment_eligibility_verification", + "awardees.orders.legislative_mandates.interagency_contracting_authority", + "awardees.orders.legislative_mandates.labor_standards", + "awardees.orders.legislative_mandates.materials_supplies_articles_equipment", + "awardees.orders.legislative_mandates.other_statutory_authority", + "awardees.orders.legislative_mandates.service_contract_inventory", + "awardees.orders.local_area_set_aside", + "awardees.orders.major_program", + "awardees.orders.naics", + "awardees.orders.naics.code", + "awardees.orders.naics.description", + "awardees.orders.naics_code", + "awardees.orders.number_of_actions", + "awardees.orders.number_of_offers_source", + "awardees.orders.obligated", + "awardees.orders.officers", + "awardees.orders.officers.highly_compensated_officer_1_amount", + "awardees.orders.officers.highly_compensated_officer_1_name", + "awardees.orders.officers.highly_compensated_officer_2_amount", + "awardees.orders.officers.highly_compensated_officer_2_name", + "awardees.orders.officers.highly_compensated_officer_3_amount", + "awardees.orders.officers.highly_compensated_officer_3_name", + "awardees.orders.officers.highly_compensated_officer_4_amount", + "awardees.orders.officers.highly_compensated_officer_4_name", + "awardees.orders.officers.highly_compensated_officer_5_amount", + "awardees.orders.officers.highly_compensated_officer_5_name", + "awardees.orders.parent_award", + "awardees.orders.parent_award.key", + "awardees.orders.parent_award.piid", + "awardees.orders.performance_based_service_acquisition", + "awardees.orders.performance_based_service_acquisition.code", + "awardees.orders.performance_based_service_acquisition.description", + "awardees.orders.period_of_performance", + "awardees.orders.period_of_performance.current_end_date", + "awardees.orders.period_of_performance.start_date", + "awardees.orders.period_of_performance.ultimate_completion_date", + "awardees.orders.piid", + "awardees.orders.place_of_manufacture", + "awardees.orders.place_of_manufacture.code", + "awardees.orders.place_of_manufacture.description", + "awardees.orders.place_of_performance", + "awardees.orders.place_of_performance.city_name", + "awardees.orders.place_of_performance.country_code", + "awardees.orders.place_of_performance.country_name", + "awardees.orders.place_of_performance.state_code", + "awardees.orders.place_of_performance.state_name", + "awardees.orders.place_of_performance.zip_code", + "awardees.orders.price_evaluation_percent_difference", + "awardees.orders.psc", + "awardees.orders.psc.code", + "awardees.orders.psc.description", + "awardees.orders.psc_code", + "awardees.orders.purchase_card_as_payment_method", + "awardees.orders.recipient", + "awardees.orders.recipient.cage", + "awardees.orders.recipient.cage_code", + "awardees.orders.recipient.display_name", + "awardees.orders.recipient.legal_business_name", + "awardees.orders.recipient.uei", + "awardees.orders.recovered_materials_sustainability", + "awardees.orders.recovered_materials_sustainability.code", + "awardees.orders.recovered_materials_sustainability.description", + "awardees.orders.research", + "awardees.orders.research.code", + "awardees.orders.research.description", + "awardees.orders.sam_exception", + "awardees.orders.sam_exception.code", + "awardees.orders.sam_exception.description", + "awardees.orders.set_aside", + "awardees.orders.set_aside.code", + "awardees.orders.set_aside.description", + "awardees.orders.simplified_procedures_for_certain_commercial_items", + "awardees.orders.small_business_competitiveness_demonstration_program", + "awardees.orders.solicitation_identifier", + "awardees.orders.subawards_summary", + "awardees.orders.subawards_summary.count", + "awardees.orders.subawards_summary.total_amount", + "awardees.orders.subcontracting_plan", + "awardees.orders.subcontracting_plan.code", + "awardees.orders.subcontracting_plan.description", + "awardees.orders.total_contract_value", + "awardees.orders.tradeoff_process", + "awardees.orders.tradeoff_process.code", + "awardees.orders.tradeoff_process.description", + "awardees.orders.transactions", + "awardees.orders.transactions.action_type", + "awardees.orders.transactions.description", + "awardees.orders.transactions.modification_number", + "awardees.orders.transactions.obligated", + "awardees.orders.transactions.transaction_date", + "awardees.orders.type_of_set_aside_source", + "awardees.orders.undefinitized_action", + "awardees.orders.undefinitized_action.code", + "awardees.orders.undefinitized_action.description", + "awardees.orders.vehicle", + "awardees.orders.vehicle.agency_id", + "awardees.orders.vehicle.award_date", + "awardees.orders.vehicle.contract_type", + "awardees.orders.vehicle.description", + "awardees.orders.vehicle.fiscal_year", + "awardees.orders.vehicle.last_date_to_order", + "awardees.orders.vehicle.naics_code", + "awardees.orders.vehicle.psc_code", + "awardees.orders.vehicle.set_aside", + "awardees.orders.vehicle.solicitation_date", + "awardees.orders.vehicle.solicitation_description", + "awardees.orders.vehicle.solicitation_identifier", + "awardees.orders.vehicle.solicitation_title", + "awardees.orders.vehicle.type_of_idc", + "awardees.orders.vehicle.uuid", + "awardees.orders.vehicle.vehicle_type", + "awardees.orders.vehicle.who_can_use", + "awardees.parent_award", + "awardees.parent_award.key", + "awardees.parent_award.piid", + "awardees.performance_based_service_acquisition", + "awardees.period_of_performance", + "awardees.period_of_performance.last_date_to_order", + "awardees.period_of_performance.start_date", + "awardees.piid", + "awardees.place_of_performance", + "awardees.place_of_performance.city_name", + "awardees.place_of_performance.country_code", + "awardees.place_of_performance.country_name", + "awardees.place_of_performance.state_code", + "awardees.place_of_performance.state_name", + "awardees.place_of_performance.zip_code", + "awardees.program_acronym", + "awardees.psc", + "awardees.psc.code", + "awardees.psc.description", + "awardees.psc_code", + "awardees.recipient", + "awardees.recipient.cage", + "awardees.recipient.cage_code", + "awardees.recipient.display_name", + "awardees.recipient.legal_business_name", + "awardees.recipient.uei", + "awardees.recovered_materials_sustainability", + "awardees.research", + "awardees.sam_exception", + "awardees.set_aside", + "awardees.set_aside.code", + "awardees.set_aside.description", + "awardees.simplified_procedures_for_certain_commercial_items", + "awardees.small_business_competitiveness_demonstration_program", + "awardees.solicitation_identifier", + "awardees.subawards_summary", + "awardees.subawards_summary.count", + "awardees.subawards_summary.total_amount", + "awardees.subcontracting_plan", + "awardees.title", + "awardees.total_contract_value", + "awardees.total_estimated_order_value", + "awardees.tradeoff_process", + "awardees.transactions", + "awardees.transactions.action_type", + "awardees.transactions.description", + "awardees.transactions.modification_number", + "awardees.transactions.obligated", + "awardees.transactions.transaction_date", + "awardees.type_of_fee_for_use_of_service", + "awardees.type_of_idc", + "awardees.type_of_idc.code", + "awardees.type_of_idc.description", + "awardees.undefinitized_action", + "awardees.uuid", + "awardees.vehicle_uuid", + "awardees.who_can_use", + "competition_details", + "competition_details.*", + "competition_details.commercial_item_acquisition_procedures", + "competition_details.evaluated_preference", + "competition_details.extent_competed", + "competition_details.most_recent_solicitation_date", + "competition_details.number_of_offers_received", + "competition_details.original_solicitation_date", + "competition_details.other_than_full_and_open_competition", + "competition_details.set_aside", + "competition_details.simplified_procedures_for_certain_commercial_items", + "competition_details.small_business_competitiveness_demonstration_program", + "competition_details.solicitation_identifier", + "competition_details.solicitation_procedures", + "contract_type", + "description", + "descriptions", + "fiscal_year", + "idv_count", + "is_synthetic_solicitation", + "last_date_to_order", + "latest_award_date", + "metrics", + "metrics.*", + "metrics.avg_offers_received", + "metrics.avg_order_value", + "metrics.award_concentration_hhi", + "metrics.competed_rate", + "metrics.days_since_last_order", + "metrics.max_order_value", + "metrics.obligation_to_ceiling_ratio", + "metrics.order_concentration_hhi", + "metrics.recent_obligations_24mo", + "metrics.recent_orders_24mo", + "metrics.top_recipient_share", + "metrics.using_agency_count", + "naics_code", + "name", + "opportunity", + "opportunity.active", + "opportunity.agency", + "opportunity.agency.abbreviation", + "opportunity.agency.code", + "opportunity.agency.name", + "opportunity.agency_id", + "opportunity.archive_date", + "opportunity.attachments", + "opportunity.attachments.attachment_id", + "opportunity.attachments.extracted_text", + "opportunity.attachments.file_size", + "opportunity.attachments.mime_type", + "opportunity.attachments.name", + "opportunity.attachments.posted_date", + "opportunity.attachments.resource_id", + "opportunity.attachments.type", + "opportunity.attachments.url", + "opportunity.award_number", + "opportunity.department", + "opportunity.department.abbreviation", + "opportunity.department.cgac", + "opportunity.department.code", + "opportunity.department.congressional_justification", + "opportunity.department.description", + "opportunity.department.name", + "opportunity.department.website", + "opportunity.department_id", + "opportunity.description", + "opportunity.first_notice_date", + "opportunity.last_notice_date", + "opportunity.latest_notice", + "opportunity.latest_notice.link", + "opportunity.latest_notice.notice_id", + "opportunity.latest_notice_id", + "opportunity.meta", + "opportunity.meta.attachments_count", + "opportunity.meta.notice_type", + "opportunity.meta.notice_type.code", + "opportunity.meta.notice_type.type", + "opportunity.meta.notices_count", + "opportunity.naics_code", + "opportunity.notice_history", + "opportunity.notice_history.deleted", + "opportunity.notice_history.index", + "opportunity.notice_history.latest", + "opportunity.notice_history.notice_id", + "opportunity.notice_history.notice_type_code", + "opportunity.notice_history.parent_notice_id", + "opportunity.notice_history.posted_date", + "opportunity.notice_history.related_notice_id", + "opportunity.notice_history.solicitation_number", + "opportunity.notice_history.title", + "opportunity.office", + "opportunity.office.agency_code", + "opportunity.office.agency_name", + "opportunity.office.department_code", + "opportunity.office.department_name", + "opportunity.office.office_code", + "opportunity.office.office_name", + "opportunity.office.organization_id", + "opportunity.office_id", + "opportunity.opportunity_id", + "opportunity.place_of_performance", + "opportunity.place_of_performance.city", + "opportunity.place_of_performance.country", + "opportunity.place_of_performance.state", + "opportunity.place_of_performance.street_address", + "opportunity.place_of_performance.zip", + "opportunity.primary_contact", + "opportunity.primary_contact.email", + "opportunity.primary_contact.fax", + "opportunity.primary_contact.full_name", + "opportunity.primary_contact.phone", + "opportunity.primary_contact.title", + "opportunity.psc_code", + "opportunity.response_deadline", + "opportunity.sam_url", + "opportunity.secondary_contact", + "opportunity.secondary_contact.email", + "opportunity.secondary_contact.fax", + "opportunity.secondary_contact.full_name", + "opportunity.secondary_contact.phone", + "opportunity.secondary_contact.title", + "opportunity.set_aside", + "opportunity.set_aside.code", + "opportunity.set_aside.description", + "opportunity.snippet", + "opportunity.solicitation_number", + "opportunity.title", + "opportunity_id", + "order_count", + "organization", + "organization.agency_code", + "organization.agency_name", + "organization.department_code", + "organization.department_name", + "organization.office_code", + "organization.office_name", + "organization.organization_id", + "organization_id", + "program_acronym", + "psc_code", + "set_aside", + "solicitation_date", + "solicitation_description", + "solicitation_identifier", + "solicitation_title", + "total_obligated", + "type_of_idc", + "uuid", + "vehicle_contracts_value", + "vehicle_obligations", + "vehicle_type", + "who_can_use" + ], + "shape_supported": true, + "shape_tier_required": null, + "viewset": "awards.views.vehicles.VehicleViewSet" + }, + "swagger_has_key": true, + "swagger_params": [ + "agency", + "award_date_after", + "award_date_before", + "contract_type", + "fiscal_year", + "flat", + "flat_lists", + "idv_count_max", + "idv_count_min", + "joiner", + "last_date_to_order_after", + "last_date_to_order_before", + "limit", + "naics_code", + "order_count_max", + "order_count_min", + "ordering", + "organization_id", + "page", + "program_acronym", + "psc_code", + "search", + "set_aside", + "shape", + "show_shapes", + "total_obligated_max", + "total_obligated_min", + "type_of_idc", + "vehicle_type", + "who_can_use" + ] + } + }, + "unmapped_resources": { + "no_docs_page": [ + "agencies", + "assistance_listings", + "budget/accounts", + "business_types", + "contracts", + "departments", + "dibbs/awards", + "dibbs/rfps", + "dibbs/rfqs", + "entities", + "events", + "exclusions", + "forecasts", + "grants", + "gsa_elibrary_contracts", + "idvs", + "itdashboard", + "mas_sins", + "naics", + "news", + "notices", + "offices", + "opportunities", + "organizations", + "otas", + "otidvs", + "protests", + "psc", + "sbir/solicitations", + "sbir/topics", + "subawards", + "vehicles" + ], + "no_swagger": [ + "budget/accounts", + "dibbs/awards", + "dibbs/rfps", + "dibbs/rfqs", + "events", + "itdashboard", + "news", + "protests", + "sbir/solicitations", + "sbir/topics" + ] + } +} diff --git a/contracts/shape_coverage_baseline.json b/contracts/shape_coverage_baseline.json new file mode 100644 index 0000000..e0baad7 --- /dev/null +++ b/contracts/shape_coverage_baseline.json @@ -0,0 +1,428 @@ +{ + "description": "Known reverse shape-coverage gaps (Tango exposes, SDK schema lacks), accepted as a tracked backlog. check-shape-coverage.ts fails only on gaps NOT listed here. Burn down and regenerate with --update-baseline.", + "count": 422, + "known_gaps": [ + "expand_flat|agencies|(root)|department", + "expand_flat|contracts|(root)|commercial_item_acquisition_procedures", + "expand_flat|contracts|(root)|consolidated_contract", + "expand_flat|contracts|(root)|contingency_humanitarian_or_peacekeeping_operation", + "expand_flat|contracts|(root)|contract_bundling", + "expand_flat|contracts|(root)|cost_accounting_standards_clause", + "expand_flat|contracts|(root)|cost_or_pricing_data", + "expand_flat|contracts|(root)|domestic_or_foreign_entity", + "expand_flat|contracts|(root)|epa_designated_product", + "expand_flat|contracts|(root)|evaluated_preference", + "expand_flat|contracts|(root)|fair_opportunity_limited_sources", + "expand_flat|contracts|(root)|fed_biz_opps", + "expand_flat|contracts|(root)|foreign_funding", + "expand_flat|contracts|(root)|information_technology_commercial_item_category", + "expand_flat|contracts|(root)|inherently_governmental_functions", + "expand_flat|contracts|(root)|performance_based_service_acquisition", + "expand_flat|contracts|(root)|place_of_manufacture", + "expand_flat|contracts|(root)|recovered_materials_sustainability", + "expand_flat|contracts|(root)|research", + "expand_flat|contracts|(root)|sam_exception", + "expand_flat|contracts|(root)|set_aside", + "expand_flat|contracts|(root)|subcontracting_plan", + "expand_flat|contracts|(root)|tradeoff_process", + "expand_flat|contracts|(root)|transactions", + "expand_flat|contracts|(root)|undefinitized_action", + "expand_flat|entities|(root)|business_types", + "expand_flat|entities|(root)|federal_obligations", + "expand_flat|entities|(root)|highest_owner", + "expand_flat|entities|(root)|immediate_owner", + "expand_flat|entities|(root)|mailing_address", + "expand_flat|entities|(root)|naics_codes", + "expand_flat|entities|(root)|physical_address", + "expand_flat|entities|(root)|relationships", + "expand_flat|entities|(root)|sba_business_types", + "expand_flat|grants|(root)|funding_details", + "expand_flat|grants|(root)|grantor_contact", + "expand_flat|grants|(root)|important_dates", + "expand_flat|idvs|(root)|idv_type", + "expand_flat|idvs|(root)|multiple_or_single_award_idv", + "expand_flat|idvs|(root)|type_of_idc", + "expand_flat|itdashboard|(root)|details", + "expand_flat|itdashboard|(root)|funding", + "expand_flat|notices|(root)|opportunity", + "expand_flat|notices|(root)|set_aside", + "expand_flat|offices|(root)|agency", + "expand_flat|opportunities|(root)|attachments", + "expand_flat|opportunities|(root)|meta", + "expand_flat|opportunities|(root)|notice_history", + "expand_flat|opportunities|(root)|place_of_performance", + "expand_flat|opportunities|(root)|set_aside", + "expand_flat|vehicles|awardees.orders|commercial_item_acquisition_procedures", + "expand_flat|vehicles|awardees.orders|consolidated_contract", + "expand_flat|vehicles|awardees.orders|contingency_humanitarian_or_peacekeeping_operation", + "expand_flat|vehicles|awardees.orders|contract_bundling", + "expand_flat|vehicles|awardees.orders|cost_accounting_standards_clause", + "expand_flat|vehicles|awardees.orders|cost_or_pricing_data", + "expand_flat|vehicles|awardees.orders|domestic_or_foreign_entity", + "expand_flat|vehicles|awardees.orders|epa_designated_product", + "expand_flat|vehicles|awardees.orders|evaluated_preference", + "expand_flat|vehicles|awardees.orders|fair_opportunity_limited_sources", + "expand_flat|vehicles|awardees.orders|fed_biz_opps", + "expand_flat|vehicles|awardees.orders|foreign_funding", + "expand_flat|vehicles|awardees.orders|information_technology_commercial_item_category", + "expand_flat|vehicles|awardees.orders|inherently_governmental_functions", + "expand_flat|vehicles|awardees.orders|performance_based_service_acquisition", + "expand_flat|vehicles|awardees.orders|place_of_manufacture", + "expand_flat|vehicles|awardees.orders|recovered_materials_sustainability", + "expand_flat|vehicles|awardees.orders|research", + "expand_flat|vehicles|awardees.orders|sam_exception", + "expand_flat|vehicles|awardees.orders|set_aside", + "expand_flat|vehicles|awardees.orders|subcontracting_plan", + "expand_flat|vehicles|awardees.orders|tradeoff_process", + "expand_flat|vehicles|awardees.orders|transactions", + "expand_flat|vehicles|awardees.orders|undefinitized_action", + "expand_flat|vehicles|awardees|idv_type", + "expand_flat|vehicles|awardees|multiple_or_single_award_idv", + "expand_flat|vehicles|awardees|type_of_idc", + "expand_flat|vehicles|opportunity|attachments", + "expand_flat|vehicles|opportunity|meta", + "expand_flat|vehicles|opportunity|notice_history", + "expand_flat|vehicles|opportunity|place_of_performance", + "expand_flat|vehicles|opportunity|set_aside", + "missing_expand|contracts|(root)|award_type", + "missing_expand|contracts|(root)|officers", + "missing_expand|contracts|(root)|period_of_performance", + "missing_expand|contracts|(root)|vehicle", + "missing_expand|entities|(root)|country_of_incorporation", + "missing_expand|entities|(root)|entity_structure", + "missing_expand|entities|(root)|entity_type", + "missing_expand|entities|(root)|organization_structure", + "missing_expand|entities|(root)|past_performance", + "missing_expand|entities|(root)|profit_structure", + "missing_expand|entities|(root)|purpose_of_registration", + "missing_expand|entities|(root)|state_of_incorporation", + "missing_expand|forecasts|(root)|display", + "missing_expand|forecasts|(root)|organization", + "missing_expand|forecasts|(root)|raw_data", + "missing_expand|grants|(root)|additional_info", + "missing_expand|grants|(root)|organization", + "missing_expand|idvs|(root)|gsa_elibrary", + "missing_expand|notices|(root)|address", + "missing_expand|notices|(root)|archive", + "missing_expand|notices|(root)|attachments", + "missing_expand|notices|(root)|meta", + "missing_expand|notices|(root)|office", + "missing_expand|notices|(root)|place_of_performance", + "missing_expand|notices|(root)|primary_contact", + "missing_expand|notices|(root)|secondary_contact", + "missing_expand|offices|(root)|department", + "missing_expand|opportunities|(root)|agency", + "missing_expand|opportunities|(root)|department", + "missing_expand|opportunities|(root)|latest_notice", + "missing_expand|opportunities|(root)|secondary_contact", + "missing_expand|organizations|(root)|agency", + "missing_expand|organizations|(root)|ancestors", + "missing_expand|organizations|(root)|budget_appropriation", + "missing_expand|organizations|(root)|budget_spending", + "missing_expand|organizations|(root)|children", + "missing_expand|organizations|(root)|department", + "missing_expand|organizations|(root)|parent", + "missing_expand|otas|(root)|award_type", + "missing_expand|otas|(root)|awarding_office", + "missing_expand|otas|(root)|extent_competed", + "missing_expand|otas|(root)|funding_office", + "missing_expand|otas|(root)|parent_award", + "missing_expand|otas|(root)|period_of_performance", + "missing_expand|otas|(root)|place_of_performance", + "missing_expand|otas|(root)|psc", + "missing_expand|otas|(root)|transactions", + "missing_expand|otas|(root)|type_of_ot_agreement", + "missing_expand|otidvs|(root)|awarding_office", + "missing_expand|otidvs|(root)|extent_competed", + "missing_expand|otidvs|(root)|funding_office", + "missing_expand|otidvs|(root)|period_of_performance", + "missing_expand|otidvs|(root)|place_of_performance", + "missing_expand|otidvs|(root)|psc", + "missing_expand|otidvs|(root)|transactions", + "missing_expand|otidvs|(root)|type_of_ot_agreement", + "missing_expand|protests|(root)|decisions", + "missing_expand|protests|(root)|resolved_agency", + "missing_expand|protests|(root)|resolved_protester", + "missing_expand|protests|dockets|organization", + "missing_expand|vehicles|awardees.orders|award_type", + "missing_expand|vehicles|awardees.orders|officers", + "missing_expand|vehicles|awardees.orders|period_of_performance", + "missing_expand|vehicles|awardees.orders|vehicle", + "missing_expand|vehicles|awardees|gsa_elibrary", + "missing_expand|vehicles|opportunity|agency", + "missing_expand|vehicles|opportunity|department", + "missing_expand|vehicles|opportunity|latest_notice", + "missing_expand|vehicles|opportunity|secondary_contact", + "missing_field|contracts|(root)|award_type", + "missing_field|contracts|awarding_office|agency_code", + "missing_field|contracts|awarding_office|agency_name", + "missing_field|contracts|awarding_office|department_code", + "missing_field|contracts|awarding_office|department_name", + "missing_field|contracts|awarding_office|office_code", + "missing_field|contracts|awarding_office|office_name", + "missing_field|contracts|awarding_office|organization_id", + "missing_field|contracts|funding_office|agency_code", + "missing_field|contracts|funding_office|agency_name", + "missing_field|contracts|funding_office|department_code", + "missing_field|contracts|funding_office|department_name", + "missing_field|contracts|funding_office|office_code", + "missing_field|contracts|funding_office|office_name", + "missing_field|contracts|funding_office|organization_id", + "missing_field|departments|(root)|cgac", + "missing_field|departments|(root)|congressional_justification", + "missing_field|departments|(root)|description", + "missing_field|departments|(root)|website", + "missing_field|entities|(root)|additional_website", + "missing_field|entities|(root)|capabilities_link", + "missing_field|entities|(root)|county", + "missing_field|entities|(root)|current_principals", + "missing_field|entities|(root)|display_name", + "missing_field|entities|(root)|g2x_about", + "missing_field|entities|(root)|g2x_ai_summary", + "missing_field|entities|(root)|g2x_employee_count", + "missing_field|entities|(root)|naics_small_codes", + "missing_field|entities|(root)|non_fed_govt_certifications", + "missing_field|entities|(root)|past_performance", + "missing_field|entities|(root)|special_equip_material", + "missing_field|entities|(root)|uuid", + "missing_field|forecasts|(root)|created", + "missing_field|forecasts|(root)|modified", + "missing_field|forecasts|(root)|organization_id", + "missing_field|forecasts|(root)|raw_data", + "missing_field|grants|(root)|forecast", + "missing_field|grants|(root)|opportunity_history", + "missing_field|grants|(root)|organization_id", + "missing_field|grants|(root)|synopsis", + "missing_field|gsa_elibrary_contracts|(root)|uei", + "missing_field|idvs|(root)|commercial_item_acquisition_procedures", + "missing_field|idvs|(root)|consolidated_contract", + "missing_field|idvs|(root)|contingency_humanitarian_or_peacekeeping_operation", + "missing_field|idvs|(root)|contract_bundling", + "missing_field|idvs|(root)|contract_financing", + "missing_field|idvs|(root)|cost_accounting_standards_clause", + "missing_field|idvs|(root)|cost_or_pricing_data", + "missing_field|idvs|(root)|dod_acquisition_program", + "missing_field|idvs|(root)|dod_transaction_number", + "missing_field|idvs|(root)|domestic_or_foreign_entity", + "missing_field|idvs|(root)|email_address", + "missing_field|idvs|(root)|epa_designated_product", + "missing_field|idvs|(root)|evaluated_preference", + "missing_field|idvs|(root)|fair_opportunity_limited_sources", + "missing_field|idvs|(root)|fed_biz_opps", + "missing_field|idvs|(root)|fee_range_lower_value", + "missing_field|idvs|(root)|fee_range_upper_value", + "missing_field|idvs|(root)|fixed_fee_value", + "missing_field|idvs|(root)|foreign_funding", + "missing_field|idvs|(root)|government_furnished_property", + "missing_field|idvs|(root)|idv_website", + "missing_field|idvs|(root)|inherently_governmental_functions", + "missing_field|idvs|(root)|local_area_set_aside", + "missing_field|idvs|(root)|major_program", + "missing_field|idvs|(root)|number_of_actions", + "missing_field|idvs|(root)|number_of_offers_source", + "missing_field|idvs|(root)|ordering_procedure", + "missing_field|idvs|(root)|performance_based_service_acquisition", + "missing_field|idvs|(root)|program_acronym", + "missing_field|idvs|(root)|recovered_materials_sustainability", + "missing_field|idvs|(root)|research", + "missing_field|idvs|(root)|sam_exception", + "missing_field|idvs|(root)|simplified_procedures_for_certain_commercial_items", + "missing_field|idvs|(root)|small_business_competitiveness_demonstration_program", + "missing_field|idvs|(root)|solicitation_identifier", + "missing_field|idvs|(root)|subcontracting_plan", + "missing_field|idvs|(root)|total_estimated_order_value", + "missing_field|idvs|(root)|tradeoff_process", + "missing_field|idvs|(root)|type_of_fee_for_use_of_service", + "missing_field|idvs|(root)|undefinitized_action", + "missing_field|idvs|(root)|vehicle_uuid", + "missing_field|idvs|(root)|who_can_use", + "missing_field|idvs|awarding_office|organization_id", + "missing_field|idvs|funding_office|organization_id", + "missing_field|itdashboard|(root)|organization_id", + "missing_field|notices|(root)|address", + "missing_field|notices|(root)|archive", + "missing_field|notices|(root)|attachments", + "missing_field|notices|(root)|meta", + "missing_field|notices|(root)|office", + "missing_field|notices|(root)|opportunity_id", + "missing_field|notices|(root)|place_of_performance", + "missing_field|offices|(root)|agency_code", + "missing_field|offices|(root)|agency_name", + "missing_field|offices|(root)|department_code", + "missing_field|offices|(root)|department_name", + "missing_field|offices|(root)|office_code", + "missing_field|offices|(root)|office_name", + "missing_field|opportunities|(root)|agency", + "missing_field|opportunities|(root)|agency_id", + "missing_field|opportunities|(root)|archive_date", + "missing_field|opportunities|(root)|department", + "missing_field|opportunities|(root)|department_id", + "missing_field|opportunities|(root)|latest_notice", + "missing_field|opportunities|(root)|latest_notice_id", + "missing_field|opportunities|(root)|office_id", + "missing_field|opportunities|(root)|secondary_contact", + "missing_field|opportunities|(root)|snippet", + "missing_field|opportunities|office|agency_code", + "missing_field|opportunities|office|agency_name", + "missing_field|opportunities|office|department_code", + "missing_field|opportunities|office|department_name", + "missing_field|opportunities|office|office_code", + "missing_field|opportunities|office|office_name", + "missing_field|opportunities|office|organization_id", + "missing_field|organizations|(root)|aac_code", + "missing_field|organizations|(root)|canonical_code", + "missing_field|organizations|(root)|cgac", + "missing_field|organizations|(root)|code", + "missing_field|organizations|(root)|description", + "missing_field|organizations|(root)|end_date", + "missing_field|organizations|(root)|fpds_code", + "missing_field|organizations|(root)|fpds_org_id", + "missing_field|organizations|(root)|full_parent_path_name", + "missing_field|organizations|(root)|is_active", + "missing_field|organizations|(root)|l1_fh_key", + "missing_field|organizations|(root)|l2_fh_key", + "missing_field|organizations|(root)|l3_fh_key", + "missing_field|organizations|(root)|l4_fh_key", + "missing_field|organizations|(root)|l5_fh_key", + "missing_field|organizations|(root)|l6_fh_key", + "missing_field|organizations|(root)|l7_fh_key", + "missing_field|organizations|(root)|l8_fh_key", + "missing_field|organizations|(root)|logo", + "missing_field|organizations|(root)|mod_status", + "missing_field|organizations|(root)|obligation_rank", + "missing_field|organizations|(root)|obligations", + "missing_field|organizations|(root)|parent_fh_key", + "missing_field|organizations|(root)|start_date", + "missing_field|organizations|(root)|summary", + "missing_field|organizations|(root)|total_obligations", + "missing_field|organizations|(root)|tree_obligations", + "missing_field|otas|(root)|award_type", + "missing_field|otas|(root)|base_and_exercised_options_value", + "missing_field|otas|(root)|consortia", + "missing_field|otas|(root)|consortia_uei", + "missing_field|otas|(root)|dod_acquisition_program", + "missing_field|otas|(root)|extent_competed", + "missing_field|otas|(root)|fiscal_year", + "missing_field|otas|(root)|non_governmental_dollars", + "missing_field|otas|(root)|non_traditional_government_contractor_participation", + "missing_field|otas|(root)|parent_award_modification_number", + "missing_field|otas|(root)|psc_code", + "missing_field|otas|(root)|transactions", + "missing_field|otas|(root)|type_of_ot_agreement", + "missing_field|otidvs|(root)|base_and_exercised_options_value", + "missing_field|otidvs|(root)|consortia", + "missing_field|otidvs|(root)|consortia_uei", + "missing_field|otidvs|(root)|dod_acquisition_program", + "missing_field|otidvs|(root)|extent_competed", + "missing_field|otidvs|(root)|fiscal_year", + "missing_field|otidvs|(root)|non_governmental_dollars", + "missing_field|otidvs|(root)|non_traditional_government_contractor_participation", + "missing_field|otidvs|(root)|psc_code", + "missing_field|otidvs|(root)|transactions", + "missing_field|otidvs|(root)|type_of_ot_agreement", + "missing_field|protests|(root)|challenged_party", + "missing_field|protests|(root)|decision_text", + "missing_field|protests|(root)|decisions", + "missing_field|protests|(root)|judge", + "missing_field|protests|(root)|naics_code", + "missing_field|protests|(root)|outcome_reason", + "missing_field|protests|(root)|resolved_agency", + "missing_field|protests|(root)|resolved_protester", + "missing_field|protests|(root)|size_standard", + "missing_field|protests|dockets|challenged_party", + "missing_field|protests|dockets|decision_text", + "missing_field|protests|dockets|judge", + "missing_field|protests|dockets|naics_code", + "missing_field|protests|dockets|outcome_reason", + "missing_field|protests|dockets|size_standard", + "missing_field|vehicles|(root)|name", + "missing_field|vehicles|awardees.awarding_office|organization_id", + "missing_field|vehicles|awardees.funding_office|organization_id", + "missing_field|vehicles|awardees.orders.awarding_office|agency_code", + "missing_field|vehicles|awardees.orders.awarding_office|agency_name", + "missing_field|vehicles|awardees.orders.awarding_office|department_code", + "missing_field|vehicles|awardees.orders.awarding_office|department_name", + "missing_field|vehicles|awardees.orders.awarding_office|office_code", + "missing_field|vehicles|awardees.orders.awarding_office|office_name", + "missing_field|vehicles|awardees.orders.awarding_office|organization_id", + "missing_field|vehicles|awardees.orders.funding_office|agency_code", + "missing_field|vehicles|awardees.orders.funding_office|agency_name", + "missing_field|vehicles|awardees.orders.funding_office|department_code", + "missing_field|vehicles|awardees.orders.funding_office|department_name", + "missing_field|vehicles|awardees.orders.funding_office|office_code", + "missing_field|vehicles|awardees.orders.funding_office|office_name", + "missing_field|vehicles|awardees.orders.funding_office|organization_id", + "missing_field|vehicles|awardees.orders|award_type", + "missing_field|vehicles|awardees|commercial_item_acquisition_procedures", + "missing_field|vehicles|awardees|consolidated_contract", + "missing_field|vehicles|awardees|contingency_humanitarian_or_peacekeeping_operation", + "missing_field|vehicles|awardees|contract_bundling", + "missing_field|vehicles|awardees|contract_financing", + "missing_field|vehicles|awardees|cost_accounting_standards_clause", + "missing_field|vehicles|awardees|cost_or_pricing_data", + "missing_field|vehicles|awardees|dod_acquisition_program", + "missing_field|vehicles|awardees|dod_transaction_number", + "missing_field|vehicles|awardees|domestic_or_foreign_entity", + "missing_field|vehicles|awardees|email_address", + "missing_field|vehicles|awardees|epa_designated_product", + "missing_field|vehicles|awardees|evaluated_preference", + "missing_field|vehicles|awardees|fair_opportunity_limited_sources", + "missing_field|vehicles|awardees|fed_biz_opps", + "missing_field|vehicles|awardees|fee_range_lower_value", + "missing_field|vehicles|awardees|fee_range_upper_value", + "missing_field|vehicles|awardees|fixed_fee_value", + "missing_field|vehicles|awardees|foreign_funding", + "missing_field|vehicles|awardees|government_furnished_property", + "missing_field|vehicles|awardees|idv_website", + "missing_field|vehicles|awardees|inherently_governmental_functions", + "missing_field|vehicles|awardees|local_area_set_aside", + "missing_field|vehicles|awardees|major_program", + "missing_field|vehicles|awardees|number_of_actions", + "missing_field|vehicles|awardees|number_of_offers_source", + "missing_field|vehicles|awardees|ordering_procedure", + "missing_field|vehicles|awardees|performance_based_service_acquisition", + "missing_field|vehicles|awardees|program_acronym", + "missing_field|vehicles|awardees|recovered_materials_sustainability", + "missing_field|vehicles|awardees|research", + "missing_field|vehicles|awardees|sam_exception", + "missing_field|vehicles|awardees|simplified_procedures_for_certain_commercial_items", + "missing_field|vehicles|awardees|small_business_competitiveness_demonstration_program", + "missing_field|vehicles|awardees|solicitation_identifier", + "missing_field|vehicles|awardees|subcontracting_plan", + "missing_field|vehicles|awardees|total_estimated_order_value", + "missing_field|vehicles|awardees|tradeoff_process", + "missing_field|vehicles|awardees|type_of_fee_for_use_of_service", + "missing_field|vehicles|awardees|undefinitized_action", + "missing_field|vehicles|awardees|vehicle_uuid", + "missing_field|vehicles|awardees|who_can_use", + "missing_field|vehicles|opportunity.office|agency_code", + "missing_field|vehicles|opportunity.office|agency_name", + "missing_field|vehicles|opportunity.office|department_code", + "missing_field|vehicles|opportunity.office|department_name", + "missing_field|vehicles|opportunity.office|office_code", + "missing_field|vehicles|opportunity.office|office_name", + "missing_field|vehicles|opportunity.office|organization_id", + "missing_field|vehicles|opportunity|agency", + "missing_field|vehicles|opportunity|agency_id", + "missing_field|vehicles|opportunity|archive_date", + "missing_field|vehicles|opportunity|department", + "missing_field|vehicles|opportunity|department_id", + "missing_field|vehicles|opportunity|latest_notice", + "missing_field|vehicles|opportunity|latest_notice_id", + "missing_field|vehicles|opportunity|office_id", + "missing_field|vehicles|opportunity|secondary_contact", + "missing_field|vehicles|opportunity|snippet", + "unmapped_resource|assistance_listings|(root)|AssistanceListing", + "unmapped_resource|budget/accounts|(root)|BudgetAccount", + "unmapped_resource|business_types|(root)|BusinessType", + "unmapped_resource|dibbs/awards|(root)|DibbsAward", + "unmapped_resource|dibbs/rfps|(root)|DibbsRfp", + "unmapped_resource|dibbs/rfqs|(root)|DibbsRfq", + "unmapped_resource|exclusions|(root)|Exclusion", + "unmapped_resource|mas_sins|(root)|MasSin", + "unmapped_resource|naics|(root)|Naics", + "unmapped_resource|psc|(root)|PSC", + "unmapped_resource|sbir/solicitations|(root)|SbirSolicitation", + "unmapped_resource|sbir/topics|(root)|SbirTopic" + ] +} diff --git a/package.json b/package.json index 65cc3a3..161a4c2 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "test": "vitest", "coverage": "vitest run --coverage", "check-conformance": "tsx scripts/check-filter-shape-conformance.ts", + "check-shape-coverage": "tsx scripts/check-shape-coverage.ts", "prepare": "npm run build", "prepublishOnly": "npm run lint && npm run test && npm run build" }, diff --git a/scripts/check-filter-shape-conformance.ts b/scripts/check-filter-shape-conformance.ts index 7d50f47..d9d0372 100644 --- a/scripts/check-filter-shape-conformance.ts +++ b/scripts/check-filter-shape-conformance.ts @@ -3,21 +3,19 @@ * * Port of `scripts/check_filter_shape_conformance.py` from tango-python. * - * Reads the manifest (generated by tango) and checks that the SDK exposes the - * appropriate filter params on every list_/get_ method, and that every - * `ShapeConfig` default parses + validates against an explicit schema. + * Reads the contract (generated by tango, vendored at contracts/filter_shape_contract.json) and checks that the SDK exposes the appropriate filter params on every list/get method, and that every `ShapeConfig` default parses + validates against an explicit schema. + * Missing filters and unimplemented resources are errors unless accepted in contracts/conformance_baseline.json (then warnings — a tracked backlog, not silent drift). * - * Uses the TypeScript Compiler API to introspect `src/client.ts` — interfaces - * are types, not values, so a pure runtime probe wouldn't catch type-only - * filter declarations. + * Uses the TypeScript Compiler API to introspect `src/client.ts` — interfaces are types, not values, so a pure runtime probe wouldn't catch type-only filter declarations. * * Usage: - * npx tsx scripts/check-filter-shape-conformance.ts \ - * --manifest ../tango/contracts/filter_shape_contract.json + * npx tsx scripts/check-filter-shape-conformance.ts + * npx tsx scripts/check-filter-shape-conformance.ts --manifest ../tango/contracts/filter_shape_contract.json + * TANGO_CONTRACT_PATH=../tango/contracts/filter_shape_contract.json npx tsx scripts/check-filter-shape-conformance.ts * * Or programmatically: * import { runConformance } from "./check-filter-shape-conformance.ts"; - * const { errors, warnings } = await runConformance({ manifestPath, clientPath, configPath }); + * const { errors, warnings } = runConformance({ manifestPath, clientPath, configPath }); */ import * as fs from "node:fs"; @@ -34,13 +32,13 @@ const __dirname = path.dirname(__filename); const REPO_ROOT = path.resolve(__dirname, ".."); const DEFAULT_CLIENT_PATH = path.join(REPO_ROOT, "src", "client.ts"); const DEFAULT_CONFIG_PATH = path.join(REPO_ROOT, "src", "config.ts"); -const DEFAULT_MANIFEST_PATH = path.resolve( - REPO_ROOT, - "..", - "tango", - "contracts", - "filter_shape_contract.json", -); +// Offline by default: the vendored contract ships with the repo, so the gate runs with no token and no sibling checkout. +// TANGO_CONTRACT_PATH points the check at a live/local tango checkout's contract instead (e.g. ../tango/contracts/filter_shape_contract.json). +const VENDORED_MANIFEST_PATH = path.join(REPO_ROOT, "contracts", "filter_shape_contract.json"); +const DEFAULT_MANIFEST_PATH = process.env.TANGO_CONTRACT_PATH + ? path.resolve(process.env.TANGO_CONTRACT_PATH) + : VENDORED_MANIFEST_PATH; +const DEFAULT_BASELINE_PATH = path.join(REPO_ROOT, "contracts", "conformance_baseline.json"); // --------------------------------------------------------------------------- // Resource → SDK method mapping @@ -64,8 +62,27 @@ export const RESOURCE_TO_METHOD: Record = { naics: "listNaics", gsa_elibrary_contracts: "listGsaElibraryContracts", itdashboard: "listItDashboard", + // Nested routes are keyed with a slash in the contract ("budget/accounts"). + // The pre-slash key is kept so an older vendored contract still maps. + "budget/accounts": "listBudgetAccounts", budget_accounts: "listBudgetAccounts", offices: "listOffices", + protests: "listProtests", + psc: "listPsc", + mas_sins: "listMasSins", + departments: "listDepartments", + business_types: "listBusinessTypes", + assistance_listings: "listAssistanceListings", + // Pending: not implemented in the SDK yet — baselined in contracts/conformance_baseline.json until the methods land. + "dibbs/rfqs": null, + "dibbs/rfps": null, + "dibbs/awards": null, + exclusions: null, + "sbir/topics": null, + "sbir/solicitations": null, + // Genuinely absent from the SDK: content endpoints with no shaping and no list method — permanently baselined. + events: null, + news: null, }; // --------------------------------------------------------------------------- @@ -301,6 +318,25 @@ export interface ConformanceResult { warnings: string[]; } +export interface ConformanceBaseline { + missing_filters?: Record; + unimplemented_resources?: string[]; +} + +/** + * Load the accepted-gaps baseline. Gaps listed there warn instead of error. + */ +export function loadBaseline(baselinePath: string): ConformanceBaseline { + if (!fs.existsSync(baselinePath)) { + return { missing_filters: {}, unimplemented_resources: [] }; + } + const raw = JSON.parse(fs.readFileSync(baselinePath, "utf8")) as ConformanceBaseline; + return { + missing_filters: raw.missing_filters ?? {}, + unimplemented_resources: raw.unimplemented_resources ?? [], + }; +} + export interface RunConformanceOptions { manifestPath: string; clientPath?: string; @@ -309,6 +345,8 @@ export interface RunConformanceOptions { skipShapes?: boolean; /** Override resource → method mapping (used by tests). */ resourceMap?: Record; + /** Override the accepted-gaps baseline path; null disables the baseline entirely (used by tests). */ + baselinePath?: string | null; } /** @@ -319,6 +357,11 @@ export function runConformance(opts: RunConformanceOptions): ConformanceResult { const clientPath = opts.clientPath ?? DEFAULT_CLIENT_PATH; const configPath = opts.configPath ?? DEFAULT_CONFIG_PATH; const resourceMap = opts.resourceMap ?? RESOURCE_TO_METHOD; + const baseline = + opts.baselinePath === null + ? { missing_filters: {}, unimplemented_resources: [] } + : loadBaseline(opts.baselinePath ?? DEFAULT_BASELINE_PATH); + const baselineUnimplemented = new Set(baseline.unimplemented_resources ?? []); const errors: string[] = []; const warnings: string[] = []; @@ -342,19 +385,22 @@ export function runConformance(opts: RunConformanceOptions): ConformanceResult { const runtimeFilters = payload?.runtime?.filter_params ?? []; if (sdkMethod === null) { - if (runtimeFilters.length > 0) { - warnings.push(`${resourceName}: no SDK method implemented for this resource`); + // Unimplemented is an error unless the baseline accepts it as tracked backlog. + if (baselineUnimplemented.has(resourceName)) { + warnings.push(`${resourceName}: no SDK method implemented (baselined as accepted gap)`); + } else { + errors.push( + `${resourceName}: no SDK method implemented for this resource (add to contracts/conformance_baseline.json unimplemented_resources if accepted)`, + ); } continue; } if (sdkMethod === undefined) { // Resource appears in the manifest but is not in our explicit map. - if (runtimeFilters.length > 0) { - warnings.push( - `${resourceName}: no SDK method mapped in conformance script (add to RESOURCE_TO_METHOD)`, - ); - } + errors.push( + `${resourceName}: no SDK method mapped in conformance script (add to RESOURCE_TO_METHOD)`, + ); continue; } @@ -389,6 +435,14 @@ export function runConformance(opts: RunConformanceOptions): ConformanceResult { if (!isExposed) missing.push(filter); } + const acceptedMissing = new Set(baseline.missing_filters?.[resourceName] ?? []); + const staleBaseline = [...acceptedMissing].filter((p) => !missing.includes(p)).sort(); + if (staleBaseline.length > 0) { + warnings.push( + `${resourceName}: baseline entries no longer needed: ${staleBaseline.join(", ")}`, + ); + } + if (missing.length === 0) continue; if (resolved.hasIndexSignature) { @@ -397,9 +451,28 @@ export function runConformance(opts: RunConformanceOptions): ConformanceResult { warnings.push( `${resourceName}: \`${sdkMethod}\` relies on index signature for filters: ${missing.join(", ")}`, ); - } else { + continue; + } + + const hardMissing = missing.filter((p) => !acceptedMissing.has(p)); + const knownMissing = missing.filter((p) => acceptedMissing.has(p)); + if (hardMissing.length > 0) { errors.push( - `${resourceName}: \`${sdkMethod}\` missing runtime filters: ${missing.join(", ")}`, + `${resourceName}: \`${sdkMethod}\` missing runtime filters: ${hardMissing.join(", ")}`, + ); + } + if (knownMissing.length > 0) { + warnings.push( + `${resourceName}: \`${sdkMethod}\` known gaps (baselined): ${knownMissing.join(", ")}`, + ); + } + } + + // A baselined-unimplemented resource that gained a real mapping means the baseline entry should be retired. + for (const resourceName of baselineUnimplemented) { + if (typeof resourceMap[resourceName] === "string") { + warnings.push( + `${resourceName}: unimplemented_resources baseline entry no longer needed (resource is mapped)`, ); } } diff --git a/scripts/check-shape-coverage.ts b/scripts/check-shape-coverage.ts new file mode 100644 index 0000000..c26def3 --- /dev/null +++ b/scripts/check-shape-coverage.ts @@ -0,0 +1,435 @@ +/** + * Reverse shape-coverage gate: Tango's shape trees -> SDK schemas. + * + * Port of `scripts/check_shape_coverage.py` from tango-python. + * + * The conformance check (check-filter-shape-conformance.ts) validates one direction only: that the SDK's ShapeConfig constants reference allowed fields. + * This checks the reverse — that the SDK actually captures every field and expand Tango exposes. + * A field Tango returns that the SDK schema lacks can't be requested through the typed shape API at all, so that reverse gap is where the SDK silently under-serves users. + * + * It walks each resource's real shape tree from the vendored contract (contracts/filter_shape_contract.json — Tango's own generated truth) against the SDK's explicit schema registry (src/shapes/explicitSchemas.ts) and reports what Tango exposes that the SDK does not capture: + * + * missing_field Tango exposes a leaf field; SDK schema has no such key. + * missing_expand Tango exposes a whole nested expand; SDK schema lacks it. + * expand_flat SDK carries the expand as a scalar with no nested schema, so its sub-fields are unreachable. + * unmapped_resource A resource has a contract shape tree but no SDK schema. + * contract_missing_shape A shaping resource publishes no shape tree (upstream contract defect). + * + * Fully local: no network, no API key, no tango checkout — it reads the vendored contract, so it runs on forks and in tokenless CI. + * TANGO_CONTRACT_PATH points it at a live/local tango checkout's contract instead. + * + * Baseline: contracts/shape_coverage_baseline.json records the currently-known gaps. + * The gate fails only on findings NOT in the baseline — new drift fails immediately while the known backlog is burned down separately. + * Refresh with --update-baseline after intentionally changing coverage. + * + * Exit codes: 0 = no new gaps, 1 = new gaps beyond the baseline, 2 = setup error. + * Run: npx tsx scripts/check-shape-coverage.ts [--update-baseline] [--json] + */ + +import * as fs from "node:fs"; +import * as path from "node:path"; +import { fileURLToPath } from "node:url"; + +import { SchemaRegistry } from "../src/shapes/schema.js"; +import type { FieldSchemaMap } from "../src/shapes/schemaTypes.js"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const REPO_ROOT = path.resolve(__dirname, ".."); +const VENDORED_CONTRACT_PATH = path.join(REPO_ROOT, "contracts", "filter_shape_contract.json"); +const DEFAULT_CONTRACT_PATH = process.env.TANGO_CONTRACT_PATH + ? path.resolve(process.env.TANGO_CONTRACT_PATH) + : VENDORED_CONTRACT_PATH; +const DEFAULT_BASELINE_PATH = path.join(REPO_ROOT, "contracts", "shape_coverage_baseline.json"); + +// Contract resource key -> SDK model name in the explicit schema registry. +// A resource whose model is not registered is reported as unmapped_resource. +export const RESOURCE_TO_MODEL: Record = { + contracts: "Contract", + idvs: "IDV", + vehicles: "Vehicle", + otas: "OTA", + otidvs: "OTIDV", + subawards: "Subaward", + organizations: "Organization", + opportunities: "Opportunity", + notices: "Notice", + forecasts: "Forecast", + grants: "Grant", + entities: "Entity", + agencies: "Agency", + naics: "Naics", + gsa_elibrary_contracts: "GsaElibraryContract", + itdashboard: "ITDashboardInvestment", + // Nested routes are keyed with a slash in the contract ("budget/accounts"). + // The pre-slash key is kept so an older vendored contract still maps. + "budget/accounts": "BudgetAccount", + budget_accounts: "BudgetAccount", + protests: "Protest", + offices: "Office", + assistance_listings: "AssistanceListing", + business_types: "BusinessType", + departments: "Department", + psc: "PSC", + mas_sins: "MasSin", + "dibbs/rfqs": "DibbsRfq", + "dibbs/rfps": "DibbsRfp", + "dibbs/awards": "DibbsAward", + exclusions: "Exclusion", + "sbir/topics": "SbirTopic", + "sbir/solicitations": "SbirSolicitation", + events: "Event", + news: "News", +}; + +// --------------------------------------------------------------------------- +// Contract types +// --------------------------------------------------------------------------- + +export interface ShapeNode { + fields?: string[] | null; + expands?: Record | null; +} + +interface ResourceRuntime { + shape?: ShapeNode | null; + shape_supported?: boolean; + shape_error?: string | null; +} + +export interface Contract { + resources?: Record; +} + +export interface Finding { + kind: + | "missing_field" + | "missing_expand" + | "expand_flat" + | "unresolved_node" + | "unmapped_resource" + | "contract_missing_shape"; + resource: string; + path: string; + name?: string; + sub_nodes?: number; +} + +// --------------------------------------------------------------------------- +// Gap collection +// --------------------------------------------------------------------------- + +function tryGetSchema(registry: SchemaRegistry, modelName: string | undefined): FieldSchemaMap | null { + if (!modelName) return null; + try { + return registry.getSchema(modelName).fields; + } catch { + return null; + } +} + +/** + * Walk every resource's contract shape tree against the SDK schema registry. + * Returns a flat list of finding records keyed for baseline diffing. + */ +export function collectGaps(contract: Contract, registry: SchemaRegistry | null): Finding[] { + const findings: Finding[] = []; + + const walk = ( + resource: string, + nodePath: string, + node: ShapeNode, + schema: FieldSchemaMap | null, + ): void => { + // A node the SDK can't resolve to a schema — its whole subtree is uncheckable. + if (schema === null) { + findings.push({ kind: "unresolved_node", resource, path: nodePath || "(root)" }); + return; + } + const fields = node.fields ?? []; + // A wildcard node ("*") permits any key, so leaf coverage is vacuously satisfied. + const wildcard = fields.includes("*"); + if (!wildcard) { + for (const f of fields) { + if (f === "*") continue; + if (!(f in schema)) { + findings.push({ + kind: "missing_field", + resource, + path: nodePath || "(root)", + name: f, + }); + } + } + } + for (const [ename, enode] of Object.entries(node.expands ?? {})) { + const fs_ = schema[ename]; + const childPath = nodePath ? `${nodePath}.${ename}` : ename; + // A wildcard expand ("*") is freeform (any key permitted) — the SDK + // carrying it as a plain dict is full coverage, not a flattened gap. + if (fs_ !== undefined && (enode.fields ?? []).includes("*")) { + continue; + } + if (fs_ === undefined) { + const sub = (enode.fields ?? []).length + Object.keys(enode.expands ?? {}).length; + findings.push({ + kind: "missing_expand", + resource, + path: nodePath || "(root)", + name: ename, + sub_nodes: sub, + }); + continue; + } + const childSchema = fs_.nestedModel ? tryGetSchema(registry!, fs_.nestedModel) : null; + if (childSchema === null) { + // SDK has the key but as a scalar (no nested schema) — Tango models + // it as an object, so its sub-fields are unreachable through shapes. + findings.push({ kind: "expand_flat", resource, path: nodePath || "(root)", name: ename }); + continue; + } + walk(resource, childPath, enode, childSchema); + } + }; + + for (const [rkey, r] of Object.entries(contract.resources ?? {})) { + const runtime = r.runtime ?? {}; + const shape = runtime.shape; + if (!shape) { + // Contracts at schema_version >= 2 declare shape_supported, so a null + // tree on a shaping resource is a hard finding (the contract understates + // the API). Older contracts omit the key; there null is genuinely + // ambiguous and skipping stays the only safe read. + if (runtime.shape_supported) { + findings.push({ + kind: "contract_missing_shape", + resource: rkey, + path: "(root)", + name: runtime.shape_error ?? "no shape tree published", + }); + } + continue; + } + const modelName = RESOURCE_TO_MODEL[rkey]; + const schema = registry ? tryGetSchema(registry, modelName) : null; + if (schema === null) { + findings.push({ + kind: "unmapped_resource", + resource: rkey, + path: "(root)", + name: modelName ?? "(no model mapped)", + }); + continue; + } + walk(rkey, "", shape, schema); + } + + return findings; +} + +/** + * Stable identity for baseline diffing — ignores volatile counts like sub_nodes. + */ +export function findingKey(f: Finding): string { + return [f.kind, f.resource, f.path ?? "", String(f.name ?? "")].join("|"); +} + +// --------------------------------------------------------------------------- +// Baseline +// --------------------------------------------------------------------------- + +export function loadBaseline(baselinePath: string): Set { + if (!fs.existsSync(baselinePath)) return new Set(); + const data = JSON.parse(fs.readFileSync(baselinePath, "utf8")) as { known_gaps?: string[] }; + return new Set(data.known_gaps ?? []); +} + +function writeBaseline(baselinePath: string, findings: Finding[]): void { + const keys = findings.map(findingKey).sort(); + fs.mkdirSync(path.dirname(baselinePath), { recursive: true }); + fs.writeFileSync( + baselinePath, + JSON.stringify( + { + description: + "Known reverse shape-coverage gaps (Tango exposes, SDK schema lacks), accepted as a tracked backlog. check-shape-coverage.ts fails only on gaps NOT listed here. Burn down and regenerate with --update-baseline.", + count: keys.length, + known_gaps: keys, + }, + null, + 2, + ) + "\n", + "utf8", + ); +} + +// --------------------------------------------------------------------------- +// Reporting +// --------------------------------------------------------------------------- + +function printGrouped(title: string, findings: Finding[]): void { + if (findings.length === 0) return; + process.stdout.write(`\n${title} (${findings.length}):\n`); + const byRes = new Map(); + for (const f of findings) { + const rows = byRes.get(f.resource) ?? []; + rows.push(f); + byRes.set(f.resource, rows); + } + for (const res of [...byRes.keys()].sort()) { + const rows = byRes.get(res)!; + process.stdout.write(` ${res} (${rows.length}):\n`); + const sorted = [...rows].sort((a, b) => + `${a.path}|${a.name ?? ""}`.localeCompare(`${b.path}|${b.name ?? ""}`), + ); + for (const f of sorted) { + const extra = f.sub_nodes ? ` (+${f.sub_nodes} sub-nodes)` : ""; + process.stdout.write( + f.name ? ` ${f.path} -> ${f.name}${extra}\n` : ` ${f.path}\n`, + ); + } + } +} + +// --------------------------------------------------------------------------- +// CLI +// --------------------------------------------------------------------------- + +export interface RunShapeCoverageOptions { + contractPath?: string; + baselinePath?: string; + updateBaseline?: boolean; + json?: boolean; +} + +export function runShapeCoverage(opts: RunShapeCoverageOptions = {}): number { + const contractPath = opts.contractPath ?? DEFAULT_CONTRACT_PATH; + const baselinePath = opts.baselinePath ?? DEFAULT_BASELINE_PATH; + + if (!fs.existsSync(contractPath)) { + process.stderr.write(`error: vendored contract not found at ${contractPath}\n`); + return 2; + } + + const contract = JSON.parse(fs.readFileSync(contractPath, "utf8")) as Contract; + const registry = new SchemaRegistry(); + const findings = collectGaps(contract, registry); + + if (opts.updateBaseline) { + writeBaseline(baselinePath, findings); + process.stdout.write( + `Wrote ${path.relative(REPO_ROOT, baselinePath)} with ${findings.length} known gaps.\n`, + ); + return 0; + } + + const baseline = loadBaseline(baselinePath); + const currentKeys = new Set(findings.map(findingKey)); + const newFindings = findings.filter((f) => !baseline.has(findingKey(f))); + const fixed = [...baseline].filter((k) => !currentKeys.has(k)).sort(); + + if (opts.json) { + process.stdout.write( + JSON.stringify( + { new: newFindings, total: findings.length, baseline: baseline.size, fixed }, + null, + 2, + ) + "\n", + ); + return newFindings.length > 0 ? 1 : 0; + } + + process.stdout.write( + `Shape coverage: ${findings.length} total gaps, ${baseline.size} baselined, ${newFindings.length} NEW, ${fixed.length} fixed since baseline.\n`, + ); + if (fixed.length > 0) { + process.stdout.write( + `\n${fixed.length} baselined gap(s) now fixed — run --update-baseline to shrink the baseline:\n`, + ); + for (const k of fixed) process.stdout.write(` ${k}\n`); + } + if (newFindings.length === 0) { + process.stdout.write("\nNo new shape-coverage drift.\n"); + return 0; + } + + const contractGaps = newFindings.filter((f) => f.kind === "contract_missing_shape"); + if (contractGaps.length > 0) { + process.stdout.write( + "\n*** CONTRACT DEFECT — these resources support shaping but publish no shape tree ***\n", + ); + printGrouped("RESOURCES WITH NO SHAPE TREE", contractGaps); + process.stdout.write( + "\n This is an upstream problem, not an SDK one: the vendored contract understates\n" + + " the API, so coverage cannot be checked for these resources at all. Refresh the\n" + + " vendored contract from makegov/tango; if it persists, the generator is failing\n" + + " to extract them.\n", + ); + } + + process.stdout.write( + "\n*** NEW shape-coverage drift (Tango exposes these; the SDK schema does not) ***\n", + ); + printGrouped( + "MISSING FIELDS", + newFindings.filter((f) => f.kind === "missing_field"), + ); + printGrouped( + "MISSING EXPANDS", + newFindings.filter((f) => f.kind === "missing_expand"), + ); + printGrouped( + "EXPANDS FLATTENED (no nested schema)", + newFindings.filter((f) => f.kind === "expand_flat"), + ); + printGrouped( + "UNRESOLVED NODES", + newFindings.filter((f) => f.kind === "unresolved_node"), + ); + printGrouped( + "UNMAPPED RESOURCES", + newFindings.filter((f) => f.kind === "unmapped_resource"), + ); + process.stdout.write( + "\nFix the SDK schema (src/shapes/explicitSchemas.ts), or if intentional, run --update-baseline.\n", + ); + return 1; +} + +function main(): number { + const argv = process.argv.slice(2); + const opts: RunShapeCoverageOptions = {}; + for (let i = 0; i < argv.length; i += 1) { + const arg = argv[i]; + if (arg === "--update-baseline") { + opts.updateBaseline = true; + } else if (arg === "--json") { + opts.json = true; + } else if (arg === "--contract") { + opts.contractPath = path.resolve(argv[i + 1]); + i += 1; + } else if (arg.startsWith("--contract=")) { + opts.contractPath = path.resolve(arg.slice("--contract=".length)); + } else if (arg === "-h" || arg === "--help") { + process.stdout.write( + "Usage: tsx scripts/check-shape-coverage.ts [--update-baseline] [--json] [--contract PATH]\n", + ); + return 0; + } + } + return runShapeCoverage(opts); +} + +// Run main only when invoked directly (not when imported by tests). +const isDirectRun = (() => { + try { + const invoked = process.argv[1] ? path.resolve(process.argv[1]) : ""; + return invoked === __filename; + } catch { + return false; + } +})(); + +if (isDirectRun) { + process.exit(main()); +} diff --git a/tests/scripts/conformance.test.ts b/tests/scripts/conformance.test.ts index ceee59d..4344e4c 100644 --- a/tests/scripts/conformance.test.ts +++ b/tests/scripts/conformance.test.ts @@ -1,4 +1,3 @@ -import * as fs from "node:fs"; import * as path from "node:path"; import { fileURLToPath } from "node:url"; import { describe, it, expect } from "vitest"; @@ -10,12 +9,10 @@ const __dirname = path.dirname(__filename); const FIXTURES_DIR = path.join(__dirname, "fixtures"); const MINI_CLIENT = path.join(FIXTURES_DIR, "mini-client.ts"); -const REAL_MANIFEST = path.resolve( +const VENDORED_CONTRACT = path.resolve( __dirname, "..", "..", - "..", - "tango", "contracts", "filter_shape_contract.json", ); @@ -27,6 +24,7 @@ describe("check-filter-shape-conformance script", () => { clientPath: MINI_CLIENT, skipShapes: true, resourceMap: { foos: "listFoos" }, + baselinePath: null, }); expect(result.errors).toEqual([]); // The fixture's interface has no index signature → no kwargs-style warning. @@ -39,6 +37,7 @@ describe("check-filter-shape-conformance script", () => { clientPath: MINI_CLIENT, skipShapes: true, resourceMap: { bars: "listBars" }, + baselinePath: null, }); expect(result.errors.length).toBe(1); expect(result.errors[0]).toMatch(/bars/); @@ -47,12 +46,66 @@ describe("check-filter-shape-conformance script", () => { expect(result.errors[0]).not.toMatch(/fiscal_year/); }); + it("downgrades a baselined missing filter to a warning", () => { + const result = runConformance({ + manifestPath: path.join(FIXTURES_DIR, "mini-manifest-missing.json"), + clientPath: MINI_CLIENT, + skipShapes: true, + resourceMap: { bars: "listBars" }, + baselinePath: path.join(FIXTURES_DIR, "mini-baseline.json"), + }); + expect(result.errors).toEqual([]); + expect(result.warnings.length).toBe(1); + expect(result.warnings[0]).toMatch(/known gaps \(baselined\)/); + expect(result.warnings[0]).toMatch(/awarding_agency/); + }); + + it("treats a null-mapped resource as an error unless baselined", () => { + const hard = runConformance({ + manifestPath: path.join(FIXTURES_DIR, "mini-manifest-ok.json"), + clientPath: MINI_CLIENT, + skipShapes: true, + resourceMap: { foos: null }, + baselinePath: null, + }); + expect(hard.errors.length).toBe(1); + expect(hard.errors[0]).toMatch(/foos: no SDK method implemented/); + + const accepted = runConformance({ + manifestPath: path.join(FIXTURES_DIR, "mini-manifest-ok.json"), + clientPath: MINI_CLIENT, + skipShapes: true, + resourceMap: { foos: null }, + baselinePath: path.join(FIXTURES_DIR, "mini-baseline.json"), + }); + expect(accepted.errors).toEqual([]); + expect(accepted.warnings.some((w) => /foos.*baselined as accepted gap/.test(w))).toBe(true); + }); + + it("warns about baseline entries no longer needed", () => { + const result = runConformance({ + manifestPath: path.join(FIXTURES_DIR, "mini-manifest-ok.json"), + clientPath: MINI_CLIENT, + skipShapes: true, + resourceMap: { foos: "listFoos" }, + baselinePath: path.join(FIXTURES_DIR, "mini-baseline-stale.json"), + }); + expect(result.errors).toEqual([]); + expect(result.warnings.some((w) => /foos: baseline entries no longer needed/.test(w))).toBe( + true, + ); + expect( + result.warnings.some((w) => /unimplemented_resources baseline entry no longer needed/.test(w)), + ).toBe(true); + }); + it("downgrades missing filters to warnings when the Options interface has an index signature", () => { const result = runConformance({ manifestPath: path.join(FIXTURES_DIR, "mini-manifest-indexsig.json"), clientPath: MINI_CLIENT, skipShapes: true, resourceMap: { baz: "listBaz" }, + baselinePath: null, }); expect(result.errors).toEqual([]); expect(result.warnings.length).toBe(1); @@ -67,35 +120,27 @@ describe("check-filter-shape-conformance script", () => { clientPath: MINI_CLIENT, skipShapes: true, resourceMap: { foos: "listNonExistent" }, + baselinePath: null, }); expect(result.errors.length).toBe(1); expect(result.errors[0]).toMatch(/listNonExistent/); expect(result.errors[0]).toMatch(/not found/); }); - it("runs against the real manifest and produces well-formed JSON", () => { - // The real manifest path is optional — skip if a sibling tango checkout - // doesn't exist on this machine. - if (!fs.existsSync(REAL_MANIFEST)) { - console.warn(`Skipping: real manifest not found at ${REAL_MANIFEST}`); - return; - } - - const result = runConformance({ manifestPath: REAL_MANIFEST }); - - expect(typeof result).toBe("object"); - expect(result.manifest).toBe(path.resolve(REAL_MANIFEST)); - expect(Array.isArray(result.errors)).toBe(true); - expect(Array.isArray(result.warnings)).toBe(true); + it("passes against the vendored contract with the committed baseline (the CI gate)", () => { + const result = runConformance({ manifestPath: VENDORED_CONTRACT }); - // Every entry should be a string. - for (const e of result.errors) expect(typeof e).toBe("string"); + expect(result.manifest).toBe(VENDORED_CONTRACT); + expect(result.errors).toEqual([]); for (const w of result.warnings) expect(typeof w).toBe("string"); + }); - // Surface the current state for transparency. - // eslint-disable-next-line no-console - console.log( - `[conformance] real manifest: errors=${result.errors.length}, warnings=${result.warnings.length}`, - ); + it("fails against the vendored contract when the baseline is withheld", () => { + // Proves the gate has teeth: the pending resources (dibbs/*, exclusions, + // sbir/*) error without their baseline entries. + const result = runConformance({ manifestPath: VENDORED_CONTRACT, baselinePath: null }); + + expect(result.errors.length).toBeGreaterThan(0); + expect(result.errors.some((e) => /dibbs/.test(e))).toBe(true); }); }); diff --git a/tests/scripts/fixtures/mini-baseline-stale.json b/tests/scripts/fixtures/mini-baseline-stale.json new file mode 100644 index 0000000..90bb9b5 --- /dev/null +++ b/tests/scripts/fixtures/mini-baseline-stale.json @@ -0,0 +1,7 @@ +{ + "_comment": "Fixture baseline: every entry is stale — foos exposes all filters and is mapped to a real method.", + "missing_filters": { + "foos": ["awarding_agency"] + }, + "unimplemented_resources": ["foos"] +} diff --git a/tests/scripts/fixtures/mini-baseline.json b/tests/scripts/fixtures/mini-baseline.json new file mode 100644 index 0000000..3c3d4a8 --- /dev/null +++ b/tests/scripts/fixtures/mini-baseline.json @@ -0,0 +1,7 @@ +{ + "_comment": "Fixture baseline: accepts bars' missing awarding_agency filter and the unimplemented foos resource.", + "missing_filters": { + "bars": ["awarding_agency"] + }, + "unimplemented_resources": ["foos"] +} diff --git a/tests/scripts/shape-coverage.test.ts b/tests/scripts/shape-coverage.test.ts new file mode 100644 index 0000000..71d5893 --- /dev/null +++ b/tests/scripts/shape-coverage.test.ts @@ -0,0 +1,111 @@ +import * as fs from "node:fs"; +import * as path from "node:path"; +import { fileURLToPath } from "node:url"; +import { describe, it, expect } from "vitest"; + +import { + collectGaps, + findingKey, + loadBaseline, + type Contract, +} from "../../scripts/check-shape-coverage.js"; +import { SchemaRegistry } from "../../src/shapes/schema.js"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const CONTRACTS_DIR = path.resolve(__dirname, "..", "..", "contracts"); +const VENDORED_CONTRACT = path.join(CONTRACTS_DIR, "filter_shape_contract.json"); +const BASELINE = path.join(CONTRACTS_DIR, "shape_coverage_baseline.json"); + +function contractFor(runtime: Record): Contract { + return { resources: { widgets: { runtime } } } as Contract; +} + +describe("check-shape-coverage script", () => { + it("flags a null shape tree on a shaping resource as a contract defect", () => { + const findings = collectGaps( + contractFor({ shape: null, shape_supported: true, shape_error: "AttributeError: boom" }), + null, + ); + expect(findings.length).toBe(1); + expect(findings[0].kind).toBe("contract_missing_shape"); + expect(findings[0].resource).toBe("widgets"); + expect(findings[0].name).toContain("AttributeError"); + }); + + it("still flags it without a recorded error", () => { + const findings = collectGaps(contractFor({ shape: null, shape_supported: true }), null); + expect(findings.map((f) => f.kind)).toEqual(["contract_missing_shape"]); + expect(findings[0].name).toBe("no shape tree published"); + }); + + it("does not flag a resource that genuinely has no shaping (news/events)", () => { + const findings = collectGaps(contractFor({ shape: null, shape_supported: false }), null); + expect(findings).toEqual([]); + }); + + it("skips a null tree on an older contract without shape_supported", () => { + const findings = collectGaps(contractFor({ shape: null }), null); + expect(findings).toEqual([]); + }); + + it("produces a stable finding key for baselining", () => { + const key = findingKey({ + kind: "contract_missing_shape", + resource: "widgets", + path: "(root)", + name: "no shape tree published", + }); + expect(key).toBe("contract_missing_shape|widgets|(root)|no shape tree published"); + }); + + it("reports a fabricated unknown field as a missing_field gap", () => { + const contract: Contract = { + resources: { + contracts: { + runtime: { + shape_supported: true, + shape: { fields: ["piid", "definitely_not_a_real_field"], expands: {} }, + }, + }, + }, + }; + const findings = collectGaps(contract, new SchemaRegistry()); + expect(findings.length).toBe(1); + expect(findings[0].kind).toBe("missing_field"); + expect(findings[0].name).toBe("definitely_not_a_real_field"); + // ...and that gap is not hidden by the committed baseline. + expect(loadBaseline(BASELINE).has(findingKey(findings[0]))).toBe(false); + }); + + it("accepts a wildcard node without checking leaves", () => { + const contract: Contract = { + resources: { + contracts: { + runtime: { + shape_supported: true, + shape: { fields: ["*", "definitely_not_a_real_field"], expands: {} }, + }, + }, + }, + }; + expect(collectGaps(contract, new SchemaRegistry())).toEqual([]); + }); + + it("passes against the vendored contract with the committed baseline (the CI gate)", () => { + const contract = JSON.parse(fs.readFileSync(VENDORED_CONTRACT, "utf8")) as Contract; + const findings = collectGaps(contract, new SchemaRegistry()); + const baseline = loadBaseline(BASELINE); + const fresh = findings.filter((f) => !baseline.has(findingKey(f))); + expect(fresh).toEqual([]); + }); + + it("vendored contract publishes a shape tree for every shaping resource", () => { + const contract = JSON.parse(fs.readFileSync(VENDORED_CONTRACT, "utf8")) as Contract; + const blind = Object.entries(contract.resources ?? {}) + .filter(([, r]) => r.runtime?.shape_supported && !r.runtime?.shape) + .map(([name]) => name); + expect(blind).toEqual([]); + }); +}); From 3794e2a5ed9558f4fc4e51dd9ddc3190543e134c Mon Sep 17 00:00:00 2001 From: "V. David Zvenyach" Date: Fri, 14 Aug 2026 11:46:51 -0500 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20exclusions,=20SBIR,=20and=20DIBBS?= =?UTF-8?q?=20resources=20=E2=80=94=2012=20methods,=206=20iterators,=20ful?= =?UTF-8?q?l=20shape=20schemas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors tango-python v1.3.0: listExclusions/getExclusion, listSbirTopics/getSbirTopic, listSbirSolicitations/getSbirSolicitation, listDibbsRfqs/getDibbsRfq, listDibbsRfps/getDibbsRfp, listDibbsAwards/getDibbsAward, each with every contract filter as an explicit typed option, ShapeConfig presets, registered schemas (13 incl. nested refs), models, and iterate wrappers. Conformance baseline shrinks to events/news only; shape-coverage gaps 422 → 416. Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 5 + contracts/conformance_baseline.json | 10 +- contracts/shape_coverage_baseline.json | 10 +- scripts/check-filter-shape-conformance.ts | 19 +- src/client.ts | 521 ++++++- src/config.ts | 29 + src/index.ts | 6 + src/models/Dibbs.ts | 97 ++ src/models/Exclusion.ts | 50 + src/models/Sbir.ts | 57 + src/models/index.ts | 9 + src/shapes/explicitSchemas.ts | 1219 +++++++++++++++++ tests/scripts/conformance.test.ts | 7 +- .../unit/client.dibbs-exclusions-sbir.test.ts | 297 ++++ tests/unit/client.iterate.test.ts | 36 + tests/unit/config.shapes.parity.test.ts | 64 + tests/unit/shapes.schema.parity.test.ts | 78 ++ 17 files changed, 2487 insertions(+), 27 deletions(-) create mode 100644 src/models/Dibbs.ts create mode 100644 src/models/Exclusion.ts create mode 100644 src/models/Sbir.ts create mode 100644 tests/unit/client.dibbs-exclusions-sbir.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 952ebb1..b2c0b1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,16 @@ This project follows [Semantic Versioning](https://semver.org/). ## [Unreleased] ### Added +- **DIBBS, exclusions, and SBIR/STTR endpoint support** (parity with tango-python v1.3.0). Six endpoint families had no SDK support at all — no models, no methods. Added `listDibbsRfqs`/`getDibbsRfq`, `listDibbsRfps`/`getDibbsRfp`, `listDibbsAwards`/`getDibbsAward`, `listExclusions`/`getExclusion`, `listSbirTopics`/`getSbirTopic`, and `listSbirSolicitations`/`getSbirSolicitation`, with every filter param in the API contract exposed as a typed option, explicit shape schemas (including the nested organization/awardee/topic/document expands), and `ShapeConfig` defaults. New model interfaces: `DibbsRfq`, `DibbsRfp`, `DibbsAward`, `Exclusion`, `SbirTopic`, `SbirSolicitation`. + + Two API behaviors are worth knowing. `is_open` (DIBBS) and `is_currently_excluded` (exclusions) are derived at query time, so filter with the `open` / `active` options rather than shaping on those fields. And DIBBS `total_contract_price` is the *order* total repeated on every line item — never sum it across rows; deduplicate on award + delivery-order number first. +- Async iteration for the six new resources: `iterateDibbsRfqs`, `iterateDibbsRfps`, `iterateDibbsAwards`, `iterateExclusions`, `iterateSbirTopics`, and `iterateSbirSolicitations` (plus the matching `IterableListMethod` entries for the generic `iterate()`). - Vendored the canonical API filter/shape contract at `contracts/filter_shape_contract.json` (API 4.22.0), so conformance checking is fully offline — no token, no sibling checkout. - New reverse shape-coverage gate `scripts/check-shape-coverage.ts` (npm script `check-shape-coverage`): walks every resource's shape tree in the vendored contract against the SDK's explicit schema registry and fails on any field or expand the SDK does not capture, unless recorded in `contracts/shape_coverage_baseline.json` as tracked backlog. - Accepted-gaps baselines: `contracts/conformance_baseline.json` (missing filters + unimplemented resources) and `contracts/shape_coverage_baseline.json` (known shape-coverage gaps). Baselined gaps report as warnings; anything new is an error. ### Changed +- Both conformance baselines shrank with the new resources: `dibbs/*`, `exclusions`, and `sbir/*` left `unimplemented_resources` in `contracts/conformance_baseline.json`, and their `unmapped_resource` entries left `contracts/shape_coverage_baseline.json` (422 → 416 known gaps). - `scripts/check-filter-shape-conformance.ts` now defaults to the vendored contract instead of a sibling `../tango` checkout (`TANGO_CONTRACT_PATH` or `--manifest` still point it at a live checkout), covers every resource in the 4.22.0 contract in its resource map, and treats an unimplemented resource as an error unless baselined. ### CI diff --git a/contracts/conformance_baseline.json b/contracts/conformance_baseline.json index ebd6e17..c036c0f 100644 --- a/contracts/conformance_baseline.json +++ b/contracts/conformance_baseline.json @@ -1,14 +1,8 @@ { - "_comment": "Accepted SDK coverage gaps vs the API contract. Gaps listed here downgrade from error to warning in scripts/check-filter-shape-conformance.ts. Each entry is tracked backlog: remove it in the same PR that closes the gap in the SDK. `missing_filters` maps a resource to filter params the mapped method does not expose; `unimplemented_resources` lists contract resources with no SDK method at all. dibbs/*, exclusions, and sbir/* are pending implementation; events and news are content endpoints with no list method and stay baselined permanently (tango-python does the same).", + "_comment": "Accepted SDK coverage gaps vs the API contract. Gaps listed here downgrade from error to warning in scripts/check-filter-shape-conformance.ts. Each entry is tracked backlog: remove it in the same PR that closes the gap in the SDK. `missing_filters` maps a resource to filter params the mapped method does not expose; `unimplemented_resources` lists contract resources with no SDK method at all. events and news are content endpoints with no list method and stay baselined permanently (tango-python does the same).", "missing_filters": {}, "unimplemented_resources": [ - "dibbs/awards", - "dibbs/rfps", - "dibbs/rfqs", "events", - "exclusions", - "news", - "sbir/solicitations", - "sbir/topics" + "news" ] } diff --git a/contracts/shape_coverage_baseline.json b/contracts/shape_coverage_baseline.json index e0baad7..ea74e16 100644 --- a/contracts/shape_coverage_baseline.json +++ b/contracts/shape_coverage_baseline.json @@ -1,6 +1,6 @@ { "description": "Known reverse shape-coverage gaps (Tango exposes, SDK schema lacks), accepted as a tracked backlog. check-shape-coverage.ts fails only on gaps NOT listed here. Burn down and regenerate with --update-baseline.", - "count": 422, + "count": 416, "known_gaps": [ "expand_flat|agencies|(root)|department", "expand_flat|contracts|(root)|commercial_item_acquisition_procedures", @@ -415,14 +415,8 @@ "unmapped_resource|assistance_listings|(root)|AssistanceListing", "unmapped_resource|budget/accounts|(root)|BudgetAccount", "unmapped_resource|business_types|(root)|BusinessType", - "unmapped_resource|dibbs/awards|(root)|DibbsAward", - "unmapped_resource|dibbs/rfps|(root)|DibbsRfp", - "unmapped_resource|dibbs/rfqs|(root)|DibbsRfq", - "unmapped_resource|exclusions|(root)|Exclusion", "unmapped_resource|mas_sins|(root)|MasSin", "unmapped_resource|naics|(root)|Naics", - "unmapped_resource|psc|(root)|PSC", - "unmapped_resource|sbir/solicitations|(root)|SbirSolicitation", - "unmapped_resource|sbir/topics|(root)|SbirTopic" + "unmapped_resource|psc|(root)|PSC" ] } diff --git a/scripts/check-filter-shape-conformance.ts b/scripts/check-filter-shape-conformance.ts index d9d0372..0d68561 100644 --- a/scripts/check-filter-shape-conformance.ts +++ b/scripts/check-filter-shape-conformance.ts @@ -73,13 +73,12 @@ export const RESOURCE_TO_METHOD: Record = { departments: "listDepartments", business_types: "listBusinessTypes", assistance_listings: "listAssistanceListings", - // Pending: not implemented in the SDK yet — baselined in contracts/conformance_baseline.json until the methods land. - "dibbs/rfqs": null, - "dibbs/rfps": null, - "dibbs/awards": null, - exclusions: null, - "sbir/topics": null, - "sbir/solicitations": null, + "dibbs/rfqs": "listDibbsRfqs", + "dibbs/rfps": "listDibbsRfps", + "dibbs/awards": "listDibbsAwards", + exclusions: "listExclusions", + "sbir/topics": "listSbirTopics", + "sbir/solicitations": "listSbirSolicitations", // Genuinely absent from the SDK: content endpoints with no shaping and no list method — permanently baselined. events: null, news: null, @@ -118,6 +117,12 @@ const SHAPE_CONFIG_ENTRIES: ShapeEntry[] = [ { shapeName: "ITDASHBOARD_INVESTMENTS_COMPREHENSIVE", modelName: "ITDashboardInvestment" }, { shapeName: "VEHICLE_ORDERS_MINIMAL", modelName: "Contract" }, { shapeName: "PROTESTS_MINIMAL", modelName: "Protest" }, + { shapeName: "DIBBS_RFQS_MINIMAL", modelName: "DibbsRfq" }, + { shapeName: "DIBBS_RFPS_MINIMAL", modelName: "DibbsRfp" }, + { shapeName: "DIBBS_AWARDS_MINIMAL", modelName: "DibbsAward" }, + { shapeName: "EXCLUSIONS_MINIMAL", modelName: "Exclusion" }, + { shapeName: "SBIR_TOPICS_MINIMAL", modelName: "SbirTopic" }, + { shapeName: "SBIR_SOLICITATIONS_MINIMAL", modelName: "SbirSolicitation" }, ]; // --------------------------------------------------------------------------- diff --git a/src/client.ts b/src/client.ts index 6a2d5ca..1452d67 100644 --- a/src/client.ts +++ b/src/client.ts @@ -380,6 +380,148 @@ export interface ListBudgetAccountsOptions extends ListOptionsBase { [key: string]: unknown; } +/** + * DIBBS RFQ list options — matches `tango_python.TangoClient.list_dibbs_rfqs`. + */ +export interface ListDibbsRfqsOptions extends ListOptionsBase { + nsn?: string; + part_number?: string; + solicitation?: string; + purchase_request?: string; + organization?: string; + status_code?: string; + set_aside?: string; + /** True returns only RFQs whose return_by_date has not passed. `is_open` is derived at query time, so filter with this rather than shaping on `is_open`. */ + open?: boolean; + quantity_min?: number; + quantity_max?: number; + issue_date_after?: string; + issue_date_before?: string; + return_by_date_after?: string; + return_by_date_before?: string; + search?: string; + /** Sort field (issue_date, return_by_date, quantity, rank, modified). */ + ordering?: string; + [key: string]: unknown; +} + +/** + * DIBBS RFP list options — matches `tango_python.TangoClient.list_dibbs_rfps`. + */ +export interface ListDibbsRfpsOptions extends ListOptionsBase { + nsn?: string; + part_number?: string; + solicitation?: string; + organization?: string; + buyer_code?: string; + /** True returns only RFPs whose closes_date has not passed. `is_open` is derived at query time, so filter with this rather than shaping on `is_open`. */ + open?: boolean; + issued_date_after?: string; + issued_date_before?: string; + closes_date_after?: string; + closes_date_before?: string; + search?: string; + /** Sort field (issued_date, closes_date, rank, modified). */ + ordering?: string; + [key: string]: unknown; +} + +/** + * DIBBS award list options — matches `tango_python.TangoClient.list_dibbs_awards`. + */ +export interface ListDibbsAwardsOptions extends ListOptionsBase { + award_number?: string; + delivery_order_number?: string; + solicitation?: string; + purchase_request?: string; + nsn?: string; + part_number?: string; + awardee_cage?: string; + entity?: string; + organization?: string; + total_contract_price_min?: number; + total_contract_price_max?: number; + award_date_after?: string; + award_date_before?: string; + posted_date_after?: string; + posted_date_before?: string; + search?: string; + /** Sort field (award_date, posted_date, total_contract_price, rank, modified). */ + ordering?: string; + [key: string]: unknown; +} + +/** + * Exclusions list options — matches `tango_python.TangoClient.list_exclusions`. + */ +export interface ListExclusionsOptions extends ListOptionsBase { + uei?: string; + entity_uei?: string; + cage_code?: string; + npi?: string; + classification_type?: string; + exclusion_type?: string; + exclusion_program?: string; + excluding_agency_code?: string; + excluding_agency_name?: string; + /** True returns only records currently in effect. `is_currently_excluded` is derived at query time, so filter with this rather than shaping on it. */ + active?: boolean; + delisted?: boolean; + activate_date_after?: string; + activate_date_before?: string; + termination_date_after?: string; + termination_date_before?: string; + update_date_after?: string; + update_date_before?: string; + search?: string; + /** Sort field (activate_date, termination_date, create_date, update_date, rank, modified). */ + ordering?: string; + [key: string]: unknown; +} + +/** + * SBIR topic list options — matches `tango_python.TangoClient.list_sbir_topics`. + */ +export interface ListSbirTopicsOptions extends ListOptionsBase { + topic_number?: string; + solicitation_number?: string; + agency?: string; + activity?: string; + year?: number; + doc_source?: string; + open_date_after?: string; + open_date_before?: string; + close_date_after?: string; + close_date_before?: string; + release_date_after?: string; + release_date_before?: string; + search?: string; + /** Sort field (open_date, close_date, release_date, year, activity, modified). */ + ordering?: string; + [key: string]: unknown; +} + +/** + * SBIR solicitation list options — matches `tango_python.TangoClient.list_sbir_solicitations`. + */ +export interface ListSbirSolicitationsOptions extends ListOptionsBase { + solicitation_number?: string; + solicitation_status?: string; + program?: string; + activity?: string; + cycle_name?: string; + out_of_cycle?: boolean; + year?: number; + start_date_after?: string; + start_date_before?: string; + end_date_after?: string; + end_date_before?: string; + search?: string; + /** Sort field (start_date, end_date, year, activity, modified). */ + ordering?: string; + [key: string]: unknown; +} + /** * List methods on `TangoClient` that `iterate()` knows how to drive. Every * entry must accept an options object and return a `PaginatedResponse` @@ -393,7 +535,13 @@ export type IterableListMethod = | "listGrants" | "listForecasts" | "listIdvs" - | "listVehicles"; + | "listVehicles" + | "listDibbsRfqs" + | "listDibbsRfps" + | "listDibbsAwards" + | "listExclusions" + | "listSbirTopics" + | "listSbirSolicitations"; // --------------------------------------------------------------------------- // Read-method option interfaces (lookups + awards completeness + other) @@ -1675,6 +1823,30 @@ export class TangoClient { return this.iterate>("listVehicles", options); } + iterateDibbsRfqs(options: ListDibbsRfqsOptions = {}): AsyncIterableIterator> { + return this.iterate>("listDibbsRfqs", options); + } + + iterateDibbsRfps(options: ListDibbsRfpsOptions = {}): AsyncIterableIterator> { + return this.iterate>("listDibbsRfps", options); + } + + iterateDibbsAwards(options: ListDibbsAwardsOptions = {}): AsyncIterableIterator> { + return this.iterate>("listDibbsAwards", options); + } + + iterateExclusions(options: ListExclusionsOptions = {}): AsyncIterableIterator> { + return this.iterate>("listExclusions", options); + } + + iterateSbirTopics(options: ListSbirTopicsOptions = {}): AsyncIterableIterator> { + return this.iterate>("listSbirTopics", options); + } + + iterateSbirSolicitations(options: ListSbirSolicitationsOptions = {}): AsyncIterableIterator> { + return this.iterate>("listSbirSolicitations", options); + } + // --------------------------------------------------------------------------- // Lookups // --------------------------------------------------------------------------- @@ -1905,6 +2077,353 @@ export class TangoClient { return buildPaginatedResponse(data); } + // --------------------------------------------------------------------------- + // DLA DIBBS (RFQs, RFPs, awards) + // --------------------------------------------------------------------------- + + /** + * List DLA DIBBS request-for-quote solicitations (`/api/dibbs/rfqs/`). + * + * `is_open` is derived at query time from `return_by_date`, so filter with + * the `open` option rather than shaping on `is_open`. + */ + async listDibbsRfqs(options: ListDibbsRfqsOptions = {}): Promise>> { + const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; + + const params: AnyRecord = { + page, + limit: Math.min(limit, 100), + }; + + const shapeToUse = shape ?? ShapeConfig.DIBBS_RFQS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) params.flat = "true"; + if (flatLists) params.flat_lists = "true"; + } + + Object.assign(params, filters); + + const data = await this.http.get("/api/dibbs/rfqs/", params); + const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; + + const results = this.materializeList("DibbsRfq", shapeSpec, rawResults, flat); + + return buildPaginatedResponse({ ...data, results }); + } + + /** Get a single DIBBS RFQ by uuid (`/api/dibbs/rfqs/{uuid}/`). */ + async getDibbsRfq( + uuid: string, + options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, + ): Promise> { + if (!uuid) throw new TangoValidationError("DIBBS RFQ uuid is required"); + + const { shape, flat = false, flatLists = false, joiner = "." } = options; + const params: AnyRecord = {}; + + const shapeToUse = shape ?? ShapeConfig.DIBBS_RFQS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) { + params.flat = "true"; + if (joiner) params.joiner = joiner; + } + if (flatLists) params.flat_lists = "true"; + } + + const data = await this.http.get(`/api/dibbs/rfqs/${encodeURIComponent(uuid)}/`, params); + return this.materializeOne("DibbsRfq", shapeSpec, data, flat, joiner); + } + + /** + * List DLA DIBBS request-for-proposal solicitations (`/api/dibbs/rfps/`). + * + * `is_open` is derived at query time from `closes_date`, so filter with the + * `open` option rather than shaping on `is_open`. + */ + async listDibbsRfps(options: ListDibbsRfpsOptions = {}): Promise>> { + const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; + + const params: AnyRecord = { + page, + limit: Math.min(limit, 100), + }; + + const shapeToUse = shape ?? ShapeConfig.DIBBS_RFPS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) params.flat = "true"; + if (flatLists) params.flat_lists = "true"; + } + + Object.assign(params, filters); + + const data = await this.http.get("/api/dibbs/rfps/", params); + const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; + + const results = this.materializeList("DibbsRfp", shapeSpec, rawResults, flat); + + return buildPaginatedResponse({ ...data, results }); + } + + /** Get a single DIBBS RFP by uuid (`/api/dibbs/rfps/{uuid}/`). */ + async getDibbsRfp( + uuid: string, + options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, + ): Promise> { + if (!uuid) throw new TangoValidationError("DIBBS RFP uuid is required"); + + const { shape, flat = false, flatLists = false, joiner = "." } = options; + const params: AnyRecord = {}; + + const shapeToUse = shape ?? ShapeConfig.DIBBS_RFPS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) { + params.flat = "true"; + if (joiner) params.joiner = joiner; + } + if (flatLists) params.flat_lists = "true"; + } + + const data = await this.http.get(`/api/dibbs/rfps/${encodeURIComponent(uuid)}/`, params); + return this.materializeOne("DibbsRfp", shapeSpec, data, flat, joiner); + } + + /** + * List DLA DIBBS awards (`/api/dibbs/awards/`). + * + * WARNING: `total_contract_price` is the *order* total repeated on every + * line item of the award. Never sum it across rows — doing so multiplies + * the value by the line-item count. Deduplicate on `award_number` + + * `delivery_order_number` first. + */ + async listDibbsAwards(options: ListDibbsAwardsOptions = {}): Promise>> { + const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; + + const params: AnyRecord = { + page, + limit: Math.min(limit, 100), + }; + + const shapeToUse = shape ?? ShapeConfig.DIBBS_AWARDS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) params.flat = "true"; + if (flatLists) params.flat_lists = "true"; + } + + Object.assign(params, filters); + + const data = await this.http.get("/api/dibbs/awards/", params); + const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; + + const results = this.materializeList("DibbsAward", shapeSpec, rawResults, flat); + + return buildPaginatedResponse({ ...data, results }); + } + + /** Get a single DIBBS award by uuid (`/api/dibbs/awards/{uuid}/`). */ + async getDibbsAward( + uuid: string, + options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, + ): Promise> { + if (!uuid) throw new TangoValidationError("DIBBS award uuid is required"); + + const { shape, flat = false, flatLists = false, joiner = "." } = options; + const params: AnyRecord = {}; + + const shapeToUse = shape ?? ShapeConfig.DIBBS_AWARDS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) { + params.flat = "true"; + if (joiner) params.joiner = joiner; + } + if (flatLists) params.flat_lists = "true"; + } + + const data = await this.http.get(`/api/dibbs/awards/${encodeURIComponent(uuid)}/`, params); + return this.materializeOne("DibbsAward", shapeSpec, data, flat, joiner); + } + + // --------------------------------------------------------------------------- + // Exclusions (SAM.gov debarments) + // --------------------------------------------------------------------------- + + /** + * List SAM.gov exclusion (debarment) records (`/api/exclusions/`). + * + * `is_currently_excluded` is derived at query time from the + * activate/termination dates, so filter with the `active` option rather + * than shaping on `is_currently_excluded`. + */ + async listExclusions(options: ListExclusionsOptions = {}): Promise>> { + const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; + + const params: AnyRecord = { + page, + limit: Math.min(limit, 100), + }; + + const shapeToUse = shape ?? ShapeConfig.EXCLUSIONS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) params.flat = "true"; + if (flatLists) params.flat_lists = "true"; + } + + Object.assign(params, filters); + + const data = await this.http.get("/api/exclusions/", params); + const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; + + const results = this.materializeList("Exclusion", shapeSpec, rawResults, flat); + + return buildPaginatedResponse({ ...data, results }); + } + + /** Get a single exclusion by its deterministic exclusion_key (`/api/exclusions/{exclusion_key}/`). */ + async getExclusion( + exclusionKey: string, + options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, + ): Promise> { + if (!exclusionKey) throw new TangoValidationError("exclusion_key is required"); + + const { shape, flat = false, flatLists = false, joiner = "." } = options; + const params: AnyRecord = {}; + + const shapeToUse = shape ?? ShapeConfig.EXCLUSIONS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) { + params.flat = "true"; + if (joiner) params.joiner = joiner; + } + if (flatLists) params.flat_lists = "true"; + } + + const data = await this.http.get(`/api/exclusions/${encodeURIComponent(exclusionKey)}/`, params); + return this.materializeOne("Exclusion", shapeSpec, data, flat, joiner); + } + + // --------------------------------------------------------------------------- + // SBIR/STTR (topics, DoD DSIP solicitations) + // --------------------------------------------------------------------------- + + /** List SBIR/STTR topics (`/api/sbir/topics/`). */ + async listSbirTopics(options: ListSbirTopicsOptions = {}): Promise>> { + const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; + + const params: AnyRecord = { + page, + limit: Math.min(limit, 100), + }; + + const shapeToUse = shape ?? ShapeConfig.SBIR_TOPICS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) params.flat = "true"; + if (flatLists) params.flat_lists = "true"; + } + + Object.assign(params, filters); + + const data = await this.http.get("/api/sbir/topics/", params); + const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; + + const results = this.materializeList("SbirTopic", shapeSpec, rawResults, flat); + + return buildPaginatedResponse({ ...data, results }); + } + + /** Get a single SBIR/STTR topic by topic_id (`/api/sbir/topics/{topic_id}/`). */ + async getSbirTopic( + topicId: string, + options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, + ): Promise> { + if (!topicId) throw new TangoValidationError("topic_id is required"); + + const { shape, flat = false, flatLists = false, joiner = "." } = options; + const params: AnyRecord = {}; + + const shapeToUse = shape ?? ShapeConfig.SBIR_TOPICS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) { + params.flat = "true"; + if (joiner) params.joiner = joiner; + } + if (flatLists) params.flat_lists = "true"; + } + + const data = await this.http.get(`/api/sbir/topics/${encodeURIComponent(topicId)}/`, params); + return this.materializeOne("SbirTopic", shapeSpec, data, flat, joiner); + } + + /** List DoD DSIP SBIR/STTR solicitations (`/api/sbir/solicitations/`). */ + async listSbirSolicitations(options: ListSbirSolicitationsOptions = {}): Promise>> { + const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; + + const params: AnyRecord = { + page, + limit: Math.min(limit, 100), + }; + + const shapeToUse = shape ?? ShapeConfig.SBIR_SOLICITATIONS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) params.flat = "true"; + if (flatLists) params.flat_lists = "true"; + } + + Object.assign(params, filters); + + const data = await this.http.get("/api/sbir/solicitations/", params); + const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; + + const results = this.materializeList("SbirSolicitation", shapeSpec, rawResults, flat); + + return buildPaginatedResponse({ ...data, results }); + } + + /** Get a single DoD DSIP SBIR/STTR solicitation by solicitation_id (`/api/sbir/solicitations/{solicitation_id}/`). */ + async getSbirSolicitation( + solicitationId: string, + options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, + ): Promise> { + if (!solicitationId) throw new TangoValidationError("solicitation_id is required"); + + const { shape, flat = false, flatLists = false, joiner = "." } = options; + const params: AnyRecord = {}; + + const shapeToUse = shape ?? ShapeConfig.SBIR_SOLICITATIONS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) { + params.flat = "true"; + if (joiner) params.joiner = joiner; + } + if (flatLists) params.flat_lists = "true"; + } + + const data = await this.http.get(`/api/sbir/solicitations/${encodeURIComponent(solicitationId)}/`, params); + return this.materializeOne("SbirSolicitation", shapeSpec, data, flat, joiner); + } + // --------------------------------------------------------------------------- // Protests + IT Dashboard + Metrics // --------------------------------------------------------------------------- diff --git a/src/config.ts b/src/config.ts index 9d3a00d..9aa8212 100644 --- a/src/config.ts +++ b/src/config.ts @@ -98,4 +98,33 @@ export const ShapeConfig = { "uii,agency_code,agency_name,bureau_code,bureau_name," + "investment_title,type_of_investment,part_of_it_portfolio," + "updated_time,url", + + // Default for listDibbsRfqs() + DIBBS_RFQS_MINIMAL: + "uuid,solicitation,nsn,part_number,nomenclature,quantity,issue_date,return_by_date,is_open", + + // Default for listDibbsRfps() + DIBBS_RFPS_MINIMAL: + "uuid,solicitation,nsn,part_number,nomenclature,issued_date,closes_date,is_open", + + // Default for listDibbsAwards(). total_contract_price is the ORDER total + // repeated per line item — never sum it across rows. + DIBBS_AWARDS_MINIMAL: + "uuid,award_number,solicitation,nsn,part_number,nomenclature," + + "awardee_cage,award_date,total_contract_price", + + // Default for listExclusions() + EXCLUSIONS_MINIMAL: + "exclusion_key,display_name,entity_name,uei,classification_type,exclusion_type," + + "excluding_agency_name,activate_date,termination_date,is_currently_excluded", + + // Default for listSbirTopics() + SBIR_TOPICS_MINIMAL: + "topic_id,topic_number,title,agency,activity,year," + + "solicitation_number,open_date,close_date,listed_open", + + // Default for listSbirSolicitations() + SBIR_SOLICITATIONS_MINIMAL: + "solicitation_id,solicitation_number,title,program,activity," + + "cycle_name,solicitation_status,year,start_date,end_date", } as const; diff --git a/src/index.ts b/src/index.ts index 51e1db2..b7a4a64 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,6 +19,12 @@ export type { ListSubawardsOptions, ListGsaElibraryContractsOptions, ListLcatsOptions, + ListDibbsRfqsOptions, + ListDibbsRfpsOptions, + ListDibbsAwardsOptions, + ListExclusionsOptions, + ListSbirTopicsOptions, + ListSbirSolicitationsOptions, ListProtestsOptions, ListItDashboardOptions, ListMetricsOptions, diff --git a/src/models/Dibbs.ts b/src/models/Dibbs.ts new file mode 100644 index 0000000..565386d --- /dev/null +++ b/src/models/Dibbs.ts @@ -0,0 +1,97 @@ +/** + * DLA DIBBS records (`/api/dibbs/rfqs/`, `/api/dibbs/rfps/`, `/api/dibbs/awards/`). + * + * These endpoints use shape-on-demand: which fields appear depends on the + * `?shape=` query param, so EVERY field is optional. + */ + +/** Buying-organization reference nested under DIBBS records. */ +export interface DibbsOrganizationPayload { + organization_id?: string | null; + agency_code?: string | null; + agency_name?: string | null; + department_code?: string | null; + department_name?: string | null; + office_code?: string | null; + office_name?: string | null; +} + +/** Awardee entity reference nested under DIBBS awards. */ +export interface DibbsAwardeePayload { + cage_code?: string | null; + legal_business_name?: string | null; + uei?: string | null; +} + +/** + * DLA DIBBS request-for-quote solicitation. + * + * `is_open` is derived at query time from `return_by_date`, so it is not + * filterable as a stored field — use the `open` filter instead. + */ +export interface DibbsRfq { + uuid?: string; + solicitation?: string | null; + solicitation_formatted?: string | null; + nsn?: string | null; + part_number?: string | null; + nomenclature?: string | null; + purchase_request?: string | null; + quantity?: number | null; + unit_of_issue?: string | null; + issue_date?: string | null; + return_by_date?: string | null; + status_code?: string | null; + set_aside?: string | null; + is_open?: boolean | null; + document_url?: string | null; + organization?: DibbsOrganizationPayload | null; +} + +/** + * DLA DIBBS request-for-proposal solicitation. + * + * `is_open` is derived at query time from `closes_date` — use the `open` + * filter to select on it. + */ +export interface DibbsRfp { + uuid?: string; + solicitation?: string | null; + nsn?: string | null; + part_number?: string | null; + nomenclature?: string | null; + buyer_code?: string | null; + issued_date?: string | null; + closes_date?: string | null; + is_open?: boolean | null; + document_url?: string | null; + tech_docs_url?: string | null; + organization?: DibbsOrganizationPayload | null; +} + +/** + * DLA DIBBS award. + * + * WARNING: `total_contract_price` is the *order* total repeated on every line + * item of the award — never sum it across rows, or you will multiply the + * value by the line-item count. + */ +export interface DibbsAward { + uuid?: string; + award_number?: string | null; + delivery_order_number?: string | null; + delivery_order_counter?: number | null; + solicitation?: string | null; + purchase_request?: string | null; + nsn?: string | null; + part_number?: string | null; + nomenclature?: string | null; + awardee_cage?: string | null; + award_date?: string | null; + posted_date?: string | null; + last_mod_posting_date?: string | null; + total_contract_price?: string | null; + total_contract_price_text?: string | null; + awardee?: DibbsAwardeePayload | null; + organization?: DibbsOrganizationPayload | null; +} diff --git a/src/models/Exclusion.ts b/src/models/Exclusion.ts new file mode 100644 index 0000000..6b5bcbc --- /dev/null +++ b/src/models/Exclusion.ts @@ -0,0 +1,50 @@ +/** + * SAM.gov exclusion (debarment) record (`/api/exclusions/`). + * + * The endpoint uses shape-on-demand: which fields appear depends on the + * `?shape=` query param, so EVERY field is optional. + * + * `is_currently_excluded` is derived at query time from the + * activate/termination dates — use the `active` filter to select on it. + */ +export interface Exclusion { + exclusion_key?: string; + classification_type?: string | null; + exclusion_type?: string | null; + exclusion_program?: string | null; + display_name?: string | null; + entity_name?: string | null; + entity_uei?: string | null; + uei?: string | null; + cage_code?: string | null; + npi?: string | null; + ct_code?: string | null; + prefix?: string | null; + first_name?: string | null; + middle_name?: string | null; + last_name?: string | null; + suffix?: string | null; + excluding_agency_code?: string | null; + excluding_agency_name?: string | null; + activate_date?: string | null; + termination_date?: string | null; + termination_type?: string | null; + create_date?: string | null; + update_date?: string | null; + delisted_at?: string | null; + is_currently_excluded?: boolean | null; + is_fascsa_order?: boolean | null; + additional_comments?: string | null; + evs_investigation_status?: string | null; + dnb_open_data?: string | null; + primary_address?: Record | null; + secondary_address?: Record | null; + more_locations?: unknown; + references?: unknown; + vessel_call_sign?: string | null; + vessel_flag?: string | null; + vessel_grt?: string | null; + vessel_owner?: string | null; + vessel_tonnage?: string | null; + vessel_type?: string | null; +} diff --git a/src/models/Sbir.ts b/src/models/Sbir.ts new file mode 100644 index 0000000..9fb5efa --- /dev/null +++ b/src/models/Sbir.ts @@ -0,0 +1,57 @@ +/** + * SBIR/STTR records (`/api/sbir/topics/`, `/api/sbir/solicitations/`). + * + * These endpoints use shape-on-demand: which fields appear depends on the + * `?shape=` query param, so EVERY field is optional. + */ + +/** + * SBIR/STTR topic. + * + * `listed_open` reflects the source listing rather than a computed window. + */ +export interface SbirTopic { + topic_id?: string; + topic_node_id?: string | number | null; + topic_number?: string | null; + title?: string | null; + description?: string | null; + agency?: string | null; + activity?: string | null; + year?: number | null; + solicitation_number?: string | null; + solicitation_status?: string | null; + release_date?: string | null; + open_date?: string | null; + close_date?: string | null; + due_dates_text?: string | null; + listed_open?: boolean | null; + topic_url?: string | null; + official_solicitation_url?: string | null; + doc_source?: string | null; + source_last_updated?: string | null; + solicitation?: Record | null; + opportunity?: Record | null; + grant?: Record | null; +} + +/** DoD DSIP SBIR/STTR solicitation. */ +export interface SbirSolicitation { + solicitation_id?: string; + solicitation_number?: string | null; + solicitation_cycle_id?: string | null; + title?: string | null; + program?: string | null; + activity?: string | null; + cycle?: string | null; + cycle_name?: string | null; + solicitation_status?: string | null; + out_of_cycle?: boolean | null; + year?: number | null; + start_date?: string | null; + end_date?: string | null; + sol_download_url?: string | null; + source_last_updated?: string | null; + topics?: Record[] | null; + documents?: Record[] | null; +} diff --git a/src/models/index.ts b/src/models/index.ts index c048ccf..2d3248d 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -9,13 +9,22 @@ export type { ParentAwardReference, } from "./Contract.js"; export type { Department } from "./Department.js"; +export type { + DibbsRfq, + DibbsRfp, + DibbsAward, + DibbsOrganizationPayload, + DibbsAwardeePayload, +} from "./Dibbs.js"; export type { Entity, EntityBasic } from "./Entity.js"; +export type { Exclusion } from "./Exclusion.js"; export type { Forecast } from "./Forecast.js"; export type { Grant } from "./Grant.js"; export type { Location } from "./Location.js"; export type { Notice } from "./Notice.js"; export type { Opportunity } from "./Opportunity.js"; export type { RecipientProfile } from "./RecipientProfile.js"; +export type { SbirTopic, SbirSolicitation } from "./Sbir.js"; export type { Vehicle } from "./Vehicle.js"; export type { IDV } from "./IDV.js"; export type { diff --git a/src/shapes/explicitSchemas.ts b/src/shapes/explicitSchemas.ts index f49a88e..e6bab73 100644 --- a/src/shapes/explicitSchemas.ts +++ b/src/shapes/explicitSchemas.ts @@ -3711,6 +3711,1212 @@ export const ITDASHBOARD_INVESTMENT_SCHEMA: FieldSchemaMap = { }, }; +// Buying-organization reference nested under DIBBS RFQs/RFPs/awards. +export const DIBBS_ORGANIZATION_SCHEMA: FieldSchemaMap = { + agency_code: { + name: "agency_code", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + agency_name: { + name: "agency_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + department_code: { + name: "department_code", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + department_name: { + name: "department_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + office_code: { + name: "office_code", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + office_name: { + name: "office_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + organization_id: { + name: "organization_id", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, +}; + +// Awardee entity reference nested under DIBBS awards. +export const DIBBS_AWARDEE_SCHEMA: FieldSchemaMap = { + cage_code: { + name: "cage_code", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + legal_business_name: { + name: "legal_business_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + uei: { + name: "uei", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, +}; + +// DLA DIBBS request-for-quote solicitations (/api/dibbs/rfqs/). `is_open` is derived at query time from `return_by_date` — filter with `open`, not by shaping on `is_open`. +export const DIBBS_RFQ_SCHEMA: FieldSchemaMap = { + uuid: { + name: "uuid", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation: { + name: "solicitation", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation_formatted: { + name: "solicitation_formatted", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + nsn: { + name: "nsn", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + part_number: { + name: "part_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + nomenclature: { + name: "nomenclature", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + purchase_request: { + name: "purchase_request", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + quantity: { + name: "quantity", + type: "int", + isOptional: true, + isList: false, + nestedModel: null, + }, + unit_of_issue: { + name: "unit_of_issue", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + issue_date: { + name: "issue_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + return_by_date: { + name: "return_by_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + status_code: { + name: "status_code", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + set_aside: { + name: "set_aside", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + is_open: { + name: "is_open", + type: "bool", + isOptional: true, + isList: false, + nestedModel: null, + }, + document_url: { + name: "document_url", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + organization: { + name: "organization", + type: "dict", + isOptional: true, + isList: false, + nestedModel: "DibbsOrganization", + }, +}; + +// DLA DIBBS request-for-proposal solicitations (/api/dibbs/rfps/). `is_open` is derived at query time from `closes_date` — filter with `open`. +export const DIBBS_RFP_SCHEMA: FieldSchemaMap = { + uuid: { + name: "uuid", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation: { + name: "solicitation", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + nsn: { + name: "nsn", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + part_number: { + name: "part_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + nomenclature: { + name: "nomenclature", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + buyer_code: { + name: "buyer_code", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + issued_date: { + name: "issued_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + closes_date: { + name: "closes_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + is_open: { + name: "is_open", + type: "bool", + isOptional: true, + isList: false, + nestedModel: null, + }, + document_url: { + name: "document_url", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + tech_docs_url: { + name: "tech_docs_url", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + organization: { + name: "organization", + type: "dict", + isOptional: true, + isList: false, + nestedModel: "DibbsOrganization", + }, +}; + +// DLA DIBBS awards (/api/dibbs/awards/). `total_contract_price` is the ORDER total repeated per line item — never sum it across rows. +export const DIBBS_AWARD_SCHEMA: FieldSchemaMap = { + uuid: { + name: "uuid", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + award_number: { + name: "award_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + delivery_order_number: { + name: "delivery_order_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + delivery_order_counter: { + name: "delivery_order_counter", + type: "int", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation: { + name: "solicitation", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + purchase_request: { + name: "purchase_request", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + nsn: { + name: "nsn", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + part_number: { + name: "part_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + nomenclature: { + name: "nomenclature", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + awardee_cage: { + name: "awardee_cage", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + award_date: { + name: "award_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + posted_date: { + name: "posted_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + last_mod_posting_date: { + name: "last_mod_posting_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + total_contract_price: { + name: "total_contract_price", + type: "Decimal", + isOptional: true, + isList: false, + nestedModel: null, + }, + total_contract_price_text: { + name: "total_contract_price_text", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + awardee: { + name: "awardee", + type: "dict", + isOptional: true, + isList: false, + nestedModel: "DibbsAwardee", + }, + organization: { + name: "organization", + type: "dict", + isOptional: true, + isList: false, + nestedModel: "DibbsOrganization", + }, +}; + +// SAM.gov exclusion (debarment) records (/api/exclusions/). `is_currently_excluded` is derived at query time — filter with `active`, not by shaping on it. +export const EXCLUSION_SCHEMA: FieldSchemaMap = { + exclusion_key: { + name: "exclusion_key", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + classification_type: { + name: "classification_type", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + exclusion_type: { + name: "exclusion_type", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + exclusion_program: { + name: "exclusion_program", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + display_name: { + name: "display_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + entity_name: { + name: "entity_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + entity_uei: { + name: "entity_uei", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + uei: { + name: "uei", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + cage_code: { + name: "cage_code", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + npi: { + name: "npi", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + ct_code: { + name: "ct_code", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + prefix: { + name: "prefix", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + first_name: { + name: "first_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + middle_name: { + name: "middle_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + last_name: { + name: "last_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + suffix: { + name: "suffix", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + excluding_agency_code: { + name: "excluding_agency_code", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + excluding_agency_name: { + name: "excluding_agency_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + activate_date: { + name: "activate_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + termination_date: { + name: "termination_date", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + termination_type: { + name: "termination_type", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + create_date: { + name: "create_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + update_date: { + name: "update_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + delisted_at: { + name: "delisted_at", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + is_currently_excluded: { + name: "is_currently_excluded", + type: "bool", + isOptional: true, + isList: false, + nestedModel: null, + }, + is_fascsa_order: { + name: "is_fascsa_order", + type: "bool", + isOptional: true, + isList: false, + nestedModel: null, + }, + additional_comments: { + name: "additional_comments", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + evs_investigation_status: { + name: "evs_investigation_status", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + dnb_open_data: { + name: "dnb_open_data", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + primary_address: { + name: "primary_address", + type: "dict", + isOptional: true, + isList: false, + nestedModel: null, + }, + secondary_address: { + name: "secondary_address", + type: "dict", + isOptional: true, + isList: false, + nestedModel: null, + }, + more_locations: { + name: "more_locations", + type: "list", + isOptional: true, + isList: true, + nestedModel: null, + }, + references: { + name: "references", + type: "list", + isOptional: true, + isList: true, + nestedModel: null, + }, + vessel_call_sign: { + name: "vessel_call_sign", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + vessel_flag: { + name: "vessel_flag", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + vessel_grt: { + name: "vessel_grt", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + vessel_owner: { + name: "vessel_owner", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + vessel_tonnage: { + name: "vessel_tonnage", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + vessel_type: { + name: "vessel_type", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, +}; + +// Grants.gov opportunity reference nested under SBIR topics. +export const SBIR_TOPIC_GRANT_REF_SCHEMA: FieldSchemaMap = { + grant_id: { + name: "grant_id", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + opportunity_number: { + name: "opportunity_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + response_date: { + name: "response_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + title: { + name: "title", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, +}; + +// SAM opportunity reference nested under SBIR topics. +export const SBIR_TOPIC_OPPORTUNITY_REF_SCHEMA: FieldSchemaMap = { + opportunity_id: { + name: "opportunity_id", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + response_deadline: { + name: "response_deadline", + type: "datetime", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation_number: { + name: "solicitation_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + title: { + name: "title", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, +}; + +// DSIP solicitation reference nested under SBIR topics. +export const SBIR_TOPIC_SOLICITATION_REF_SCHEMA: FieldSchemaMap = { + solicitation_id: { + name: "solicitation_id", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation_number: { + name: "solicitation_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + title: { + name: "title", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + program: { + name: "program", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + cycle_name: { + name: "cycle_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation_status: { + name: "solicitation_status", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + out_of_cycle: { + name: "out_of_cycle", + type: "bool", + isOptional: true, + isList: false, + nestedModel: null, + }, + year: { + name: "year", + type: "int", + isOptional: true, + isList: false, + nestedModel: null, + }, + start_date: { + name: "start_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + end_date: { + name: "end_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, +}; + +// SBIR/STTR topics (/api/sbir/topics/). `listed_open` reflects the source listing rather than a computed window. +export const SBIR_TOPIC_SCHEMA: FieldSchemaMap = { + topic_id: { + name: "topic_id", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + topic_node_id: { + name: "topic_node_id", + type: "int", + isOptional: true, + isList: false, + nestedModel: null, + }, + topic_number: { + name: "topic_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + title: { + name: "title", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + description: { + name: "description", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + agency: { + name: "agency", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + activity: { + name: "activity", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + year: { + name: "year", + type: "int", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation_number: { + name: "solicitation_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation_status: { + name: "solicitation_status", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + release_date: { + name: "release_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + open_date: { + name: "open_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + close_date: { + name: "close_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + due_dates_text: { + name: "due_dates_text", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + listed_open: { + name: "listed_open", + type: "bool", + isOptional: true, + isList: false, + nestedModel: null, + }, + topic_url: { + name: "topic_url", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + official_solicitation_url: { + name: "official_solicitation_url", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + doc_source: { + name: "doc_source", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + source_last_updated: { + name: "source_last_updated", + type: "datetime", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation: { + name: "solicitation", + type: "dict", + isOptional: true, + isList: false, + nestedModel: "SbirTopicSolicitationRef", + }, + opportunity: { + name: "opportunity", + type: "dict", + isOptional: true, + isList: false, + nestedModel: "SbirTopicOpportunityRef", + }, + grant: { + name: "grant", + type: "dict", + isOptional: true, + isList: false, + nestedModel: "SbirTopicGrantRef", + }, +}; + +// Solicitation document reference nested under SBIR solicitations. +export const SBIR_SOLICITATION_DOCUMENT_SCHEMA: FieldSchemaMap = { + document_id: { + name: "document_id", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + filename: { + name: "filename", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + cycle_name: { + name: "cycle_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + extraction_status: { + name: "extraction_status", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + file_size: { + name: "file_size", + type: "int", + isOptional: true, + isList: false, + nestedModel: null, + }, + n_chars: { + name: "n_chars", + type: "int", + isOptional: true, + isList: false, + nestedModel: null, + }, + n_pages: { + name: "n_pages", + type: "int", + isOptional: true, + isList: false, + nestedModel: null, + }, + s3_key: { + name: "s3_key", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, +}; + +// Topic reference nested under SBIR solicitations. +export const SBIR_SOLICITATION_TOPIC_REF_SCHEMA: FieldSchemaMap = { + topic_id: { + name: "topic_id", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + topic_number: { + name: "topic_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + title: { + name: "title", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + agency: { + name: "agency", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + close_date: { + name: "close_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + topic_url: { + name: "topic_url", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, +}; + +// DoD DSIP SBIR/STTR solicitations (/api/sbir/solicitations/). +export const SBIR_SOLICITATION_SCHEMA: FieldSchemaMap = { + solicitation_id: { + name: "solicitation_id", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation_number: { + name: "solicitation_number", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation_cycle_id: { + name: "solicitation_cycle_id", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + title: { + name: "title", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + program: { + name: "program", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + activity: { + name: "activity", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + cycle: { + name: "cycle", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + cycle_name: { + name: "cycle_name", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + solicitation_status: { + name: "solicitation_status", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + out_of_cycle: { + name: "out_of_cycle", + type: "bool", + isOptional: true, + isList: false, + nestedModel: null, + }, + year: { + name: "year", + type: "int", + isOptional: true, + isList: false, + nestedModel: null, + }, + start_date: { + name: "start_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + end_date: { + name: "end_date", + type: "date", + isOptional: true, + isList: false, + nestedModel: null, + }, + sol_download_url: { + name: "sol_download_url", + type: "str", + isOptional: true, + isList: false, + nestedModel: null, + }, + source_last_updated: { + name: "source_last_updated", + type: "datetime", + isOptional: true, + isList: false, + nestedModel: null, + }, + topics: { + name: "topics", + type: "dict", + isOptional: true, + isList: true, + nestedModel: "SbirSolicitationTopicRef", + }, + documents: { + name: "documents", + type: "dict", + isOptional: true, + isList: true, + nestedModel: "SbirSolicitationDocument", + }, +}; export const EXPLICIT_SCHEMAS: ExplicitSchemas = { Office: OFFICE_SCHEMA, Location: LOCATION_SCHEMA, @@ -3758,4 +4964,17 @@ export const EXPLICIT_SCHEMAS: ExplicitSchemas = { GsaElibraryContract: GSA_ELIBRARY_CONTRACT_SCHEMA, GsaElibraryIdvRef: GSA_ELIBRARY_IDV_REF_SCHEMA, ITDashboardInvestment: ITDASHBOARD_INVESTMENT_SCHEMA, + DibbsRfq: DIBBS_RFQ_SCHEMA, + DibbsRfp: DIBBS_RFP_SCHEMA, + DibbsAward: DIBBS_AWARD_SCHEMA, + DibbsOrganization: DIBBS_ORGANIZATION_SCHEMA, + DibbsAwardee: DIBBS_AWARDEE_SCHEMA, + Exclusion: EXCLUSION_SCHEMA, + SbirTopic: SBIR_TOPIC_SCHEMA, + SbirTopicGrantRef: SBIR_TOPIC_GRANT_REF_SCHEMA, + SbirTopicOpportunityRef: SBIR_TOPIC_OPPORTUNITY_REF_SCHEMA, + SbirTopicSolicitationRef: SBIR_TOPIC_SOLICITATION_REF_SCHEMA, + SbirSolicitation: SBIR_SOLICITATION_SCHEMA, + SbirSolicitationDocument: SBIR_SOLICITATION_DOCUMENT_SCHEMA, + SbirSolicitationTopicRef: SBIR_SOLICITATION_TOPIC_REF_SCHEMA, }; diff --git a/tests/scripts/conformance.test.ts b/tests/scripts/conformance.test.ts index 4344e4c..7ff18ee 100644 --- a/tests/scripts/conformance.test.ts +++ b/tests/scripts/conformance.test.ts @@ -136,11 +136,12 @@ describe("check-filter-shape-conformance script", () => { }); it("fails against the vendored contract when the baseline is withheld", () => { - // Proves the gate has teeth: the pending resources (dibbs/*, exclusions, - // sbir/*) error without their baseline entries. + // Proves the gate has teeth: the permanently-baselined content endpoints + // (events, news) error without their baseline entries. const result = runConformance({ manifestPath: VENDORED_CONTRACT, baselinePath: null }); expect(result.errors.length).toBeGreaterThan(0); - expect(result.errors.some((e) => /dibbs/.test(e))).toBe(true); + expect(result.errors.some((e) => /events/.test(e))).toBe(true); + expect(result.errors.some((e) => /news/.test(e))).toBe(true); }); }); diff --git a/tests/unit/client.dibbs-exclusions-sbir.test.ts b/tests/unit/client.dibbs-exclusions-sbir.test.ts new file mode 100644 index 0000000..c3adefe --- /dev/null +++ b/tests/unit/client.dibbs-exclusions-sbir.test.ts @@ -0,0 +1,297 @@ +/** + * Tests for the DIBBS, exclusions, and SBIR/STTR endpoint families. + * + * Covers the request contract for each method — correct path, filters passed + * through under the API's own param names, the documented default shape — + * via the injected fetchImpl mock. Mirrors tango-python's + * tests/test_dibbs_exclusions_sbir.py. + */ + +import { TangoClient } from "../../src/client.js"; +import { ShapeConfig } from "../../src/config.js"; + +type RecordedCall = { url: string; init?: RequestInit | undefined }; + +interface MockResponseBody { + count?: number; + next?: string | null; + previous?: string | null; + results?: unknown[]; + [key: string]: unknown; +} + +function recordingFetch(body: MockResponseBody | unknown = { count: 0, next: null, previous: null, results: [] }): { + fetchImpl: typeof fetch; + calls: RecordedCall[]; +} { + const calls: RecordedCall[] = []; + const fetchImpl = (async (url: string | URL, init?: RequestInit) => { + calls.push({ url: String(url), init }); + return { + ok: true, + status: 200, + async text() { + return JSON.stringify(body); + }, + }; + }) as unknown as typeof fetch; + return { fetchImpl, calls }; +} + +function makeClient(body?: MockResponseBody | unknown): { client: TangoClient; calls: RecordedCall[] } { + const { fetchImpl, calls } = recordingFetch(body); + const client = new TangoClient({ + apiKey: "k", + baseUrl: "http://localhost:8000", + fetchImpl, + retries: 0, + }); + return { client, calls }; +} + +function params(calls: RecordedCall[]): URLSearchParams { + return new URL(calls[0].url).searchParams; +} + +describe("TangoClient — DIBBS RFQs", () => { + it("listDibbsRfqs hits /api/dibbs/rfqs/ with filters under API param names", async () => { + const { client, calls } = makeClient(); + await client.listDibbsRfqs({ nsn: "5310-00-000-0000", open: true, quantity_min: 5, limit: 10 }); + + expect(calls[0].url).toContain("/api/dibbs/rfqs/"); + const p = params(calls); + expect(p.get("nsn")).toBe("5310-00-000-0000"); + // `open` is the filter; `is_open` is query-time derived and not filterable. + expect(p.get("open")).toBe("true"); + expect(p.has("is_open")).toBe(false); + expect(p.get("quantity_min")).toBe("5"); + expect(p.get("page")).toBe("1"); + expect(p.get("limit")).toBe("10"); + expect(p.get("shape")).toBe(ShapeConfig.DIBBS_RFQS_MINIMAL); + }); + + it("listDibbsRfqs passes date-range and ordering params through", async () => { + const { client, calls } = makeClient(); + await client.listDibbsRfqs({ + issue_date_after: "2026-01-01", + return_by_date_before: "2026-02-01", + set_aside: "SBA", + ordering: "-return_by_date", + }); + + const p = params(calls); + expect(p.get("issue_date_after")).toBe("2026-01-01"); + expect(p.get("return_by_date_before")).toBe("2026-02-01"); + expect(p.get("set_aside")).toBe("SBA"); + expect(p.get("ordering")).toBe("-return_by_date"); + }); + + it("listDibbsRfqs honors an explicit shape and flat flags", async () => { + const { client, calls } = makeClient(); + await client.listDibbsRfqs({ shape: "uuid,nsn", flat: true, flatLists: true }); + + const p = params(calls); + expect(p.get("shape")).toBe("uuid,nsn"); + expect(p.get("flat")).toBe("true"); + expect(p.get("flat_lists")).toBe("true"); + }); + + it("getDibbsRfq uses the uuid route and the default minimal shape", async () => { + const { client, calls } = makeClient({ uuid: "abc" }); + await client.getDibbsRfq("abc"); + + expect(calls[0].url).toContain("/api/dibbs/rfqs/abc/"); + expect(params(calls).get("shape")).toBe(ShapeConfig.DIBBS_RFQS_MINIMAL); + }); + + it("getDibbsRfq requires uuid", async () => { + const { client } = makeClient(); + await expect(client.getDibbsRfq("")).rejects.toThrow(); + }); +}); + +describe("TangoClient — DIBBS RFPs", () => { + it("listDibbsRfps hits /api/dibbs/rfps/ with filters passed through", async () => { + const { client, calls } = makeClient(); + await client.listDibbsRfps({ buyer_code: "ABC", closes_date_after: "2026-01-01", open: true }); + + expect(calls[0].url).toContain("/api/dibbs/rfps/"); + const p = params(calls); + expect(p.get("buyer_code")).toBe("ABC"); + expect(p.get("closes_date_after")).toBe("2026-01-01"); + expect(p.get("open")).toBe("true"); + expect(p.has("is_open")).toBe(false); + expect(p.get("shape")).toBe(ShapeConfig.DIBBS_RFPS_MINIMAL); + }); + + it("getDibbsRfp uses the uuid route", async () => { + const { client, calls } = makeClient({ uuid: "abc" }); + await client.getDibbsRfp("abc"); + expect(calls[0].url).toContain("/api/dibbs/rfps/abc/"); + expect(params(calls).get("shape")).toBe(ShapeConfig.DIBBS_RFPS_MINIMAL); + }); + + it("getDibbsRfp requires uuid", async () => { + const { client } = makeClient(); + await expect(client.getDibbsRfp("")).rejects.toThrow(); + }); +}); + +describe("TangoClient — DIBBS awards", () => { + it("listDibbsAwards hits /api/dibbs/awards/ with price bounds and pagination", async () => { + const { client, calls } = makeClient(); + await client.listDibbsAwards({ + awardee_cage: "1ABC2", + total_contract_price_min: 1000, + total_contract_price_max: 50000, + page: 3, + limit: 50, + }); + + expect(calls[0].url).toContain("/api/dibbs/awards/"); + const p = params(calls); + expect(p.get("awardee_cage")).toBe("1ABC2"); + expect(p.get("total_contract_price_min")).toBe("1000"); + expect(p.get("total_contract_price_max")).toBe("50000"); + expect(p.get("page")).toBe("3"); + expect(p.get("limit")).toBe("50"); + expect(p.get("shape")).toBe(ShapeConfig.DIBBS_AWARDS_MINIMAL); + }); + + it("listDibbsAwards caps limit at 100", async () => { + const { client, calls } = makeClient(); + await client.listDibbsAwards({ limit: 500 }); + expect(params(calls).get("limit")).toBe("100"); + }); + + it("getDibbsAward uses the uuid route", async () => { + const { client, calls } = makeClient({ uuid: "abc" }); + await client.getDibbsAward("abc"); + expect(calls[0].url).toContain("/api/dibbs/awards/abc/"); + expect(params(calls).get("shape")).toBe(ShapeConfig.DIBBS_AWARDS_MINIMAL); + }); + + it("getDibbsAward requires uuid", async () => { + const { client } = makeClient(); + await expect(client.getDibbsAward("")).rejects.toThrow(); + }); +}); + +describe("TangoClient — exclusions", () => { + it("listExclusions hits /api/exclusions/ with filters under API param names", async () => { + const { client, calls } = makeClient(); + await client.listExclusions({ + uei: "ABC123DEF456", + classification_type: "Firm", + active: true, + delisted: false, + activate_date_after: "2020-01-01", + }); + + expect(calls[0].url).toContain("/api/exclusions/"); + const p = params(calls); + expect(p.get("uei")).toBe("ABC123DEF456"); + expect(p.get("classification_type")).toBe("Firm"); + // `active` is the filter; `is_currently_excluded` is query-time derived. + expect(p.get("active")).toBe("true"); + expect(p.has("is_currently_excluded")).toBe(false); + expect(p.get("delisted")).toBe("false"); + expect(p.get("activate_date_after")).toBe("2020-01-01"); + expect(p.get("shape")).toBe(ShapeConfig.EXCLUSIONS_MINIMAL); + }); + + it("getExclusion uses the exclusion_key route", async () => { + const { client, calls } = makeClient({ exclusion_key: "S4MEX-123" }); + await client.getExclusion("S4MEX-123"); + expect(calls[0].url).toContain("/api/exclusions/S4MEX-123/"); + expect(params(calls).get("shape")).toBe(ShapeConfig.EXCLUSIONS_MINIMAL); + }); + + it("getExclusion requires exclusion_key", async () => { + const { client } = makeClient(); + await expect(client.getExclusion("")).rejects.toThrow(); + }); +}); + +describe("TangoClient — SBIR topics", () => { + it("listSbirTopics hits /api/sbir/topics/ with filters passed through", async () => { + const { client, calls } = makeClient(); + await client.listSbirTopics({ + agency: "DOD", + activity: "open", + year: 2026, + close_date_after: "2026-08-01", + search: "autonomy", + }); + + expect(calls[0].url).toContain("/api/sbir/topics/"); + const p = params(calls); + expect(p.get("agency")).toBe("DOD"); + expect(p.get("activity")).toBe("open"); + expect(p.get("year")).toBe("2026"); + expect(p.get("close_date_after")).toBe("2026-08-01"); + expect(p.get("search")).toBe("autonomy"); + expect(p.get("shape")).toBe(ShapeConfig.SBIR_TOPICS_MINIMAL); + }); + + it("getSbirTopic uses the topic_id route", async () => { + const { client, calls } = makeClient({ topic_id: "T123" }); + await client.getSbirTopic("T123"); + expect(calls[0].url).toContain("/api/sbir/topics/T123/"); + expect(params(calls).get("shape")).toBe(ShapeConfig.SBIR_TOPICS_MINIMAL); + }); + + it("getSbirTopic requires topic_id", async () => { + const { client } = makeClient(); + await expect(client.getSbirTopic("")).rejects.toThrow(); + }); +}); + +describe("TangoClient — SBIR solicitations", () => { + it("listSbirSolicitations hits /api/sbir/solicitations/ with filters passed through", async () => { + const { client, calls } = makeClient(); + await client.listSbirSolicitations({ + program: "SBIR", + out_of_cycle: false, + start_date_after: "2026-01-01", + solicitation_status: "Open", + }); + + expect(calls[0].url).toContain("/api/sbir/solicitations/"); + const p = params(calls); + expect(p.get("program")).toBe("SBIR"); + expect(p.get("out_of_cycle")).toBe("false"); + expect(p.get("start_date_after")).toBe("2026-01-01"); + expect(p.get("solicitation_status")).toBe("Open"); + expect(p.get("shape")).toBe(ShapeConfig.SBIR_SOLICITATIONS_MINIMAL); + }); + + it("getSbirSolicitation uses the solicitation_id route", async () => { + const { client, calls } = makeClient({ solicitation_id: "S1" }); + await client.getSbirSolicitation("S1"); + expect(calls[0].url).toContain("/api/sbir/solicitations/S1/"); + expect(params(calls).get("shape")).toBe(ShapeConfig.SBIR_SOLICITATIONS_MINIMAL); + }); + + it("getSbirSolicitation requires solicitation_id", async () => { + const { client } = makeClient(); + await expect(client.getSbirSolicitation("")).rejects.toThrow(); + }); +}); + +describe("TangoClient — DIBBS/exclusions/SBIR list responses", () => { + it("listExclusions returns a materialized paginated response", async () => { + const { client } = makeClient({ + count: 1, + next: null, + previous: null, + results: [{ exclusion_key: "K1", display_name: "ACME", is_currently_excluded: true }], + }); + + const res = await client.listExclusions(); + expect(res.count).toBe(1); + expect(res.results).toHaveLength(1); + expect(res.results[0].exclusion_key).toBe("K1"); + expect(res.results[0].is_currently_excluded).toBe(true); + }); +}); diff --git a/tests/unit/client.iterate.test.ts b/tests/unit/client.iterate.test.ts index cf915b5..aef1016 100644 --- a/tests/unit/client.iterate.test.ts +++ b/tests/unit/client.iterate.test.ts @@ -169,6 +169,42 @@ describe("TangoClient.iterate (early termination)", () => { }); }); +describe("TangoClient.iterate (new resources)", () => { + it("iterateExclusions walks /api/exclusions/ pages and forwards filters", async () => { + const base = "https://example.test"; + const { fetchImpl, calls } = makeFetch([ + { + count: 3, + next: `${base}/api/exclusions/?page=2`, + results: [{ exclusion_key: "E1" }, { exclusion_key: "E2" }], + }, + { + count: 3, + next: null, + results: [{ exclusion_key: "E3" }], + }, + ]); + + const client = new TangoClient({ apiKey: "k", baseUrl: base, fetchImpl, retries: 0 }); + + const seen: string[] = []; + for await (const e of client.iterateExclusions({ active: true })) { + seen.push(String((e as Record).exclusion_key ?? "")); + } + + expect(seen).toEqual(["E1", "E2", "E3"]); + expect(calls.length).toBe(2); + + const u1 = new URL(calls[0]); + expect(u1.pathname).toBe("/api/exclusions/"); + expect(u1.searchParams.get("active")).toBe("true"); + + const u2 = new URL(calls[1]); + expect(u2.searchParams.get("page")).toBe("2"); + expect(u2.searchParams.get("active")).toBe("true"); + }); +}); + describe("TangoClient.iterate (generic)", () => { it("rejects unknown method names", async () => { const client = new TangoClient({ apiKey: "k", baseUrl: "https://example.test", retries: 0 }); diff --git a/tests/unit/config.shapes.parity.test.ts b/tests/unit/config.shapes.parity.test.ts index 2a7e715..7af3d36 100644 --- a/tests/unit/config.shapes.parity.test.ts +++ b/tests/unit/config.shapes.parity.test.ts @@ -1,5 +1,7 @@ import { describe, it, expect } from "vitest"; import { ShapeConfig } from "../../src/config.js"; +import { ShapeParser } from "../../src/shapes/parser.js"; +import { SchemaRegistry } from "../../src/shapes/schema.js"; /** * Parity tests for ShapeConfig presets vs the Python SDK @@ -86,6 +88,68 @@ describe("ShapeConfig parity with Python SDK", () => { ); }); + describe("DIBBS / exclusions / SBIR presets (Python v1.3.0)", () => { + it("DIBBS_RFQS_MINIMAL matches Python", () => { + expect(ShapeConfig.DIBBS_RFQS_MINIMAL).toBe( + "uuid,solicitation,nsn,part_number,nomenclature,quantity,issue_date,return_by_date,is_open", + ); + }); + + it("DIBBS_RFPS_MINIMAL matches Python", () => { + expect(ShapeConfig.DIBBS_RFPS_MINIMAL).toBe( + "uuid,solicitation,nsn,part_number,nomenclature,issued_date,closes_date,is_open", + ); + }); + + it("DIBBS_AWARDS_MINIMAL matches Python", () => { + expect(ShapeConfig.DIBBS_AWARDS_MINIMAL).toBe( + "uuid,award_number,solicitation,nsn,part_number,nomenclature," + + "awardee_cage,award_date,total_contract_price", + ); + }); + + it("EXCLUSIONS_MINIMAL matches Python", () => { + expect(ShapeConfig.EXCLUSIONS_MINIMAL).toBe( + "exclusion_key,display_name,entity_name,uei,classification_type,exclusion_type," + + "excluding_agency_name,activate_date,termination_date,is_currently_excluded", + ); + }); + + it("SBIR_TOPICS_MINIMAL matches Python", () => { + expect(ShapeConfig.SBIR_TOPICS_MINIMAL).toBe( + "topic_id,topic_number,title,agency,activity,year," + + "solicitation_number,open_date,close_date,listed_open", + ); + }); + + it("SBIR_SOLICITATIONS_MINIMAL matches Python", () => { + expect(ShapeConfig.SBIR_SOLICITATIONS_MINIMAL).toBe( + "solicitation_id,solicitation_number,title,program,activity," + + "cycle_name,solicitation_status,year,start_date,end_date", + ); + }); + + const presetToModel = [ + ["DIBBS_RFQS_MINIMAL", "DibbsRfq"], + ["DIBBS_RFPS_MINIMAL", "DibbsRfp"], + ["DIBBS_AWARDS_MINIMAL", "DibbsAward"], + ["EXCLUSIONS_MINIMAL", "Exclusion"], + ["SBIR_TOPICS_MINIMAL", "SbirTopic"], + ["SBIR_SOLICITATIONS_MINIMAL", "SbirSolicitation"], + ] as const; + + it.each(presetToModel)("%s parses and every field exists on %s", (presetName, modelName) => { + const parser = new ShapeParser(); + const registry = new SchemaRegistry(); + const shape = (ShapeConfig as Record)[presetName]; + const spec = parser.parse(shape); + const schema = registry.getSchema(modelName); + for (const field of spec.fields) { + expect(schema.fields[field.name], `${modelName}.${field.name}`).toBeDefined(); + } + }); + }); + describe("existing presets corrected to match Python", () => { it("ENTITIES_COMPREHENSIVE includes the federal_obligations(*) expansion", () => { expect(ShapeConfig.ENTITIES_COMPREHENSIVE).toContain("federal_obligations(*)"); diff --git a/tests/unit/shapes.schema.parity.test.ts b/tests/unit/shapes.schema.parity.test.ts index f7252c1..1bae326 100644 --- a/tests/unit/shapes.schema.parity.test.ts +++ b/tests/unit/shapes.schema.parity.test.ts @@ -11,6 +11,12 @@ import { ITDASHBOARD_INVESTMENT_SCHEMA, VEHICLE_METRICS_SCHEMA, ORGANIZATION_OFFICE_SCHEMA, + DIBBS_RFQ_SCHEMA, + DIBBS_RFP_SCHEMA, + DIBBS_AWARD_SCHEMA, + EXCLUSION_SCHEMA, + SBIR_TOPIC_SCHEMA, + SBIR_SOLICITATION_SCHEMA, EXPLICIT_SCHEMAS, } from "../../src/shapes/explicitSchemas.js"; @@ -168,3 +174,75 @@ describe("Ported explicit schemas — parity with Python SDK", () => { expect(EXPLICIT_SCHEMAS.OrganizationOffice).toBe(ORGANIZATION_OFFICE_SCHEMA); }); }); + +describe("DIBBS / exclusions / SBIR explicit schemas — parity with Python SDK", () => { + it("DIBBS_RFQ_SCHEMA covers the contract's 16 shape nodes with a nested organization", () => { + expect(Object.keys(DIBBS_RFQ_SCHEMA)).toHaveLength(16); + expect(DIBBS_RFQ_SCHEMA.uuid).toBeDefined(); + expect(DIBBS_RFQ_SCHEMA.quantity.type).toBe("int"); + expect(DIBBS_RFQ_SCHEMA.return_by_date.type).toBe("date"); + expect(DIBBS_RFQ_SCHEMA.is_open.type).toBe("bool"); + expect(DIBBS_RFQ_SCHEMA.organization.nestedModel).toBe("DibbsOrganization"); + }); + + it("DIBBS_RFP_SCHEMA covers the contract's 12 shape nodes", () => { + expect(Object.keys(DIBBS_RFP_SCHEMA)).toHaveLength(12); + expect(DIBBS_RFP_SCHEMA.buyer_code).toBeDefined(); + expect(DIBBS_RFP_SCHEMA.closes_date.type).toBe("date"); + expect(DIBBS_RFP_SCHEMA.tech_docs_url).toBeDefined(); + expect(DIBBS_RFP_SCHEMA.organization.nestedModel).toBe("DibbsOrganization"); + }); + + it("DIBBS_AWARD_SCHEMA covers the contract's 17 shape nodes with awardee + organization", () => { + expect(Object.keys(DIBBS_AWARD_SCHEMA)).toHaveLength(17); + expect(DIBBS_AWARD_SCHEMA.total_contract_price.type).toBe("Decimal"); + expect(DIBBS_AWARD_SCHEMA.delivery_order_counter.type).toBe("int"); + expect(DIBBS_AWARD_SCHEMA.awardee.nestedModel).toBe("DibbsAwardee"); + expect(DIBBS_AWARD_SCHEMA.organization.nestedModel).toBe("DibbsOrganization"); + }); + + it("EXCLUSION_SCHEMA covers the contract's 39 shape fields", () => { + expect(Object.keys(EXCLUSION_SCHEMA)).toHaveLength(39); + expect(EXCLUSION_SCHEMA.exclusion_key).toBeDefined(); + expect(EXCLUSION_SCHEMA.is_currently_excluded.type).toBe("bool"); + expect(EXCLUSION_SCHEMA.is_fascsa_order.type).toBe("bool"); + expect(EXCLUSION_SCHEMA.activate_date.type).toBe("date"); + expect(EXCLUSION_SCHEMA.primary_address.type).toBe("dict"); + expect(EXCLUSION_SCHEMA.vessel_call_sign).toBeDefined(); + }); + + it("SBIR_TOPIC_SCHEMA covers the contract's 22 shape nodes with 3 nested expands", () => { + expect(Object.keys(SBIR_TOPIC_SCHEMA)).toHaveLength(22); + expect(SBIR_TOPIC_SCHEMA.topic_id).toBeDefined(); + expect(SBIR_TOPIC_SCHEMA.listed_open.type).toBe("bool"); + expect(SBIR_TOPIC_SCHEMA.solicitation.nestedModel).toBe("SbirTopicSolicitationRef"); + expect(SBIR_TOPIC_SCHEMA.opportunity.nestedModel).toBe("SbirTopicOpportunityRef"); + expect(SBIR_TOPIC_SCHEMA.grant.nestedModel).toBe("SbirTopicGrantRef"); + }); + + it("SBIR_SOLICITATION_SCHEMA covers the contract's 17 shape nodes with list expands", () => { + expect(Object.keys(SBIR_SOLICITATION_SCHEMA)).toHaveLength(17); + expect(SBIR_SOLICITATION_SCHEMA.solicitation_id).toBeDefined(); + expect(SBIR_SOLICITATION_SCHEMA.out_of_cycle.type).toBe("bool"); + expect(SBIR_SOLICITATION_SCHEMA.topics.isList).toBe(true); + expect(SBIR_SOLICITATION_SCHEMA.topics.nestedModel).toBe("SbirSolicitationTopicRef"); + expect(SBIR_SOLICITATION_SCHEMA.documents.isList).toBe(true); + expect(SBIR_SOLICITATION_SCHEMA.documents.nestedModel).toBe("SbirSolicitationDocument"); + }); + + it("EXPLICIT_SCHEMAS registers the six resources and their nested refs", () => { + expect(EXPLICIT_SCHEMAS.DibbsRfq).toBe(DIBBS_RFQ_SCHEMA); + expect(EXPLICIT_SCHEMAS.DibbsRfp).toBe(DIBBS_RFP_SCHEMA); + expect(EXPLICIT_SCHEMAS.DibbsAward).toBe(DIBBS_AWARD_SCHEMA); + expect(EXPLICIT_SCHEMAS.Exclusion).toBe(EXCLUSION_SCHEMA); + expect(EXPLICIT_SCHEMAS.SbirTopic).toBe(SBIR_TOPIC_SCHEMA); + expect(EXPLICIT_SCHEMAS.SbirSolicitation).toBe(SBIR_SOLICITATION_SCHEMA); + expect(EXPLICIT_SCHEMAS.DibbsOrganization).toBeDefined(); + expect(EXPLICIT_SCHEMAS.DibbsAwardee).toBeDefined(); + expect(EXPLICIT_SCHEMAS.SbirTopicGrantRef).toBeDefined(); + expect(EXPLICIT_SCHEMAS.SbirTopicOpportunityRef).toBeDefined(); + expect(EXPLICIT_SCHEMAS.SbirTopicSolicitationRef).toBeDefined(); + expect(EXPLICIT_SCHEMAS.SbirSolicitationDocument).toBeDefined(); + expect(EXPLICIT_SCHEMAS.SbirSolicitationTopicRef).toBeDefined(); + }); +}); From f10d558e50bef42322ee679348d2acfc61128aba Mon Sep 17 00:00:00 2001 From: "V. David Zvenyach" Date: Fri, 14 Aug 2026 11:55:13 -0500 Subject: [PATCH 3/7] feat: full budget filter surface, GSA eLibrary detail, filter-warning burn-down ListBudgetAccountsOptions now carries all 96 contract params as explicit typed properties; legacy fiscal_year_gte/fiscal_year_lte/account_title aliases are remapped to the dunder wire names they silently missed before. Adds getGsaElibraryContract, psc has_awards, and explicit props for every filter previously reachable only via index signatures (contracts/idvs/otas key, entities cage, forecasts id, opportunities opportunity_id, itdashboard previous_uii, protests naics_code verbatim). Conformance gate: 0 errors, warnings down to the two permanently baselined resources. Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 6 ++ src/client.ts | 166 ++++++++++++++++++++++++++++++- tests/unit/client.parity.test.ts | 78 +++++++++++++++ 3 files changed, 249 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2c0b1d..dc4bfea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,12 @@ This project follows [Semantic Versioning](https://semver.org/). - Vendored the canonical API filter/shape contract at `contracts/filter_shape_contract.json` (API 4.22.0), so conformance checking is fully offline — no token, no sibling checkout. - New reverse shape-coverage gate `scripts/check-shape-coverage.ts` (npm script `check-shape-coverage`): walks every resource's shape tree in the vendored contract against the SDK's explicit schema registry and fails on any field or expand the SDK does not capture, unless recorded in `contracts/shape_coverage_baseline.json` as tracked backlog. - Accepted-gaps baselines: `contracts/conformance_baseline.json` (missing filters + unimplemented resources) and `contracts/shape_coverage_baseline.json` (known shape-coverage gaps). Baselined gaps report as warnings; anything new is an error. +- `getGsaElibraryContract(uuid, options)` for `/api/gsa_elibrary_contracts/{uuid}/` (parity with tango-python), with the standard `shape` / `flat` / `flatLists` / `joiner` options and the `GSA_ELIBRARY_CONTRACTS_MINIMAL` default shape. +- **Full typed filter surface on `listBudgetAccounts`** (parity with tango-python and the API contract). `ListBudgetAccountsOptions` now declares every `budget/accounts` filter param — the exact / `__gte` / `__lte` triplet for all 26 numeric lifecycle, ratio, and trend fields (`requested_ba`, `enacted_ba`, `apportioned`, `obligated_total`, `outlayed_total`, `unobligated_balance`, the contract/assistance breakdowns, the `*_pct` / `*_capped` ratios, YoY + 5-year-CAGR trends, and `actual_vs_requested_contract`), plus the `__in` / `__icontains` variants of the categorical filters (`federal_account_symbol`, `fiscal_year`, `agency_code`, `bureau_name`, `bea_category`, `subfunction_code`, `account_title__icontains`). +- Typed filter options that previously worked only through the index-signature escape hatch: `key` on `listContracts` / `listIdvs` / `listOtas` / `listOtidvs`, `cage` on `listEntities`, `id` on `listForecasts`, `opportunity_id` on `listOpportunities`, `previous_uii` on `listItDashboard`, `naics_code` on `listProtests` (sent verbatim, not remapped to `naics`), and `has_awards` on `listPsc`. The filter-shape conformance gate now reports zero index-signature warnings. + +### Fixed +- `listBudgetAccounts`: the `fiscal_year_gte`, `fiscal_year_lte`, and `account_title` options were sent verbatim, which the API silently ignores. They are kept as legacy aliases and now remapped to the forms the API understands (`fiscal_year__gte`, `fiscal_year__lte`, `account_title__icontains`); an explicitly passed dunder param wins over its alias. ### Changed - Both conformance baselines shrank with the new resources: `dibbs/*`, `exclusions`, and `sbir/*` left `unimplemented_resources` in `contracts/conformance_baseline.json`, and their `unmapped_resource` entries left `contracts/shape_coverage_baseline.json` (422 → 416 known gaps). diff --git a/src/client.ts b/src/client.ts index 1452d67..d4d5cb1 100644 --- a/src/client.ts +++ b/src/client.ts @@ -170,6 +170,8 @@ export interface ListContractsOptions extends ListOptionsBase { // Agencies / identifiers awarding_agency?: string; funding_agency?: string; + /** Exact award key (the detail-endpoint identifier). */ + key?: string; piid?: string; solicitation_identifier?: string; naics?: string; @@ -195,6 +197,8 @@ export interface ListContractsOptions extends ListOptionsBase { export interface ListEntitiesOptions extends ListOptionsBase { search?: string; + /** CAGE code (API alias of `cage_code`). */ + cage?: string; cage_code?: string; naics?: string; name?: string; @@ -257,6 +261,8 @@ export interface ListIdvsOptions { fiscal_year_gte?: number | string; fiscal_year_lte?: number | string; idv_type?: string; + /** Exact award key (the detail-endpoint identifier). */ + key?: string; last_date_to_order_gte?: string; last_date_to_order_lte?: string; naics?: string; @@ -284,6 +290,8 @@ export interface ListForecastsOptions extends ListOptionsBase { fiscal_year?: number | string; fiscal_year_gte?: number | string; fiscal_year_lte?: number | string; + /** Filter by forecast id (the detail-endpoint identifier). */ + id?: string | number; modified_after?: string; modified_before?: string; naics_code?: string; @@ -307,6 +315,8 @@ export interface ListOpportunitiesOptions extends ListOptionsBase { last_notice_date_before?: string; naics?: string; notice_type?: string; + /** Filter by opportunity id (the detail-endpoint identifier). */ + opportunity_id?: string; ordering?: string; place_of_performance?: string; psc?: string; @@ -364,17 +374,132 @@ export interface ListGrantsOptions extends ListOptionsBase { [key: string]: unknown; } +/** + * Budget account list options — matches `tango_python.TangoClient.list_budget_accounts`. + * + * Every numeric lifecycle/ratio field exposes an exact / `__gte` / `__lte` triplet, and any of them is a valid `ordering` target (e.g. `ordering: "-unobligated_balance"` ranks by largest headroom first). + */ export interface ListBudgetAccountsOptions extends ListOptionsBase { + // Identity / categorical filters (`__in` variants take a comma-separated list) federal_account_symbol?: string; + federal_account_symbol__in?: string; fiscal_year?: number | string; + fiscal_year__gte?: number | string; + fiscal_year__lte?: number | string; + fiscal_year__in?: string; + /** Legacy alias remapped to `fiscal_year__gte`. */ fiscal_year_gte?: number | string; + /** Legacy alias remapped to `fiscal_year__lte`. */ fiscal_year_lte?: number | string; agency_code?: string; + agency_code__in?: string; bureau_name?: string; + bureau_name__icontains?: string; + bureau_name__in?: string; + /** Legacy alias remapped to `account_title__icontains`. */ account_title?: string; + account_title__icontains?: string; bea_category?: string; + bea_category__in?: string; on_off_budget?: string; subfunction_code?: string; + subfunction_code__in?: string; + + // President's-budget requested BA + requested_ba?: number | string; + requested_ba__gte?: number | string; + requested_ba__lte?: number | string; + // Enacted budget authority + enacted_ba?: number | string; + enacted_ba__gte?: number | string; + enacted_ba__lte?: number | string; + // Apportioned amount + apportioned?: number | string; + apportioned__gte?: number | string; + apportioned__lte?: number | string; + // Total obligated / outlayed + obligated_total?: number | string; + obligated_total__gte?: number | string; + obligated_total__lte?: number | string; + outlayed_total?: number | string; + outlayed_total__gte?: number | string; + outlayed_total__lte?: number | string; + /** Apportioned minus obligated, in dollars. `__gte` surfaces accounts with appropriated headroom that hasn't yet hit contract. */ + unobligated_balance?: number | string; + unobligated_balance__gte?: number | string; + unobligated_balance__lte?: number | string; + // Contract-only / assistance-only obligated + outlayed breakdowns + contract_obligated?: number | string; + contract_obligated__gte?: number | string; + contract_obligated__lte?: number | string; + contract_outlayed?: number | string; + contract_outlayed__gte?: number | string; + contract_outlayed__lte?: number | string; + assistance_obligated?: number | string; + assistance_obligated__gte?: number | string; + assistance_obligated__lte?: number | string; + assistance_outlayed?: number | string; + assistance_outlayed__gte?: number | string; + assistance_outlayed__lte?: number | string; + /** Contracts as share of obligated, capped at 1.0. `__gte` filters to contract-heavy accounts. */ + contract_share_of_obligated_capped?: number | string; + contract_share_of_obligated_capped__gte?: number | string; + contract_share_of_obligated_capped__lte?: number | string; + // Burn ratio (obligated / apportioned), plus the capped-at-1.0 variant + obligated_to_apportioned_pct?: number | string; + obligated_to_apportioned_pct__gte?: number | string; + obligated_to_apportioned_pct__lte?: number | string; + obligated_to_apportioned_pct_capped?: number | string; + obligated_to_apportioned_pct_capped__gte?: number | string; + obligated_to_apportioned_pct_capped__lte?: number | string; + // Apportionment ratio (apportioned / enacted), plus capped variant + apportioned_to_enacted_pct?: number | string; + apportioned_to_enacted_pct__gte?: number | string; + apportioned_to_enacted_pct__lte?: number | string; + apportioned_to_enacted_pct_capped?: number | string; + apportioned_to_enacted_pct_capped__gte?: number | string; + apportioned_to_enacted_pct_capped__lte?: number | string; + // Obligated-to-enacted ratio, plus capped variant + obligated_to_enacted_pct?: number | string; + obligated_to_enacted_pct__gte?: number | string; + obligated_to_enacted_pct__lte?: number | string; + obligated_to_enacted_pct_capped?: number | string; + obligated_to_enacted_pct_capped__gte?: number | string; + obligated_to_enacted_pct_capped__lte?: number | string; + // Spendout ratio (outlayed / obligated), plus capped variant + outlayed_to_obligated_pct?: number | string; + outlayed_to_obligated_pct__gte?: number | string; + outlayed_to_obligated_pct__lte?: number | string; + outlayed_to_obligated_pct_capped?: number | string; + outlayed_to_obligated_pct_capped__gte?: number | string; + outlayed_to_obligated_pct_capped__lte?: number | string; + // Unobligated share of apportioned + unobligated_pct?: number | string; + unobligated_pct__gte?: number | string; + unobligated_pct__lte?: number | string; + // Year-over-year growth + 5-year CAGR trends + enacted_ba_yoy_pct?: number | string; + enacted_ba_yoy_pct__gte?: number | string; + enacted_ba_yoy_pct__lte?: number | string; + obligated_yoy_pct?: number | string; + obligated_yoy_pct__gte?: number | string; + obligated_yoy_pct__lte?: number | string; + enacted_ba_5yr_cagr?: number | string; + enacted_ba_5yr_cagr__gte?: number | string; + enacted_ba_5yr_cagr__lte?: number | string; + /** Next-year requested BA growth. `__gte` supports forward-looking pipeline discovery. */ + ba_growth_next_year_pct?: number | string; + ba_growth_next_year_pct__gte?: number | string; + ba_growth_next_year_pct__lte?: number | string; + // Realization ratio of contract obligated against the prior-year request, plus capped variant + actual_vs_requested_contract?: number | string; + actual_vs_requested_contract__gte?: number | string; + actual_vs_requested_contract__lte?: number | string; + actual_vs_requested_contract_capped?: number | string; + actual_vs_requested_contract_capped__gte?: number | string; + actual_vs_requested_contract_capped__lte?: number | string; + + /** Full-text search over account_title / agency_name / bureau_name. */ search?: string; ordering?: string; [key: string]: unknown; @@ -559,6 +684,8 @@ export interface ListNaicsOptions extends ListOptionsBase { } export interface ListPscOptions extends ListOptionsBase { + /** When true, return only codes with contract award history. */ + has_awards?: boolean; [key: string]: unknown; } @@ -594,6 +721,8 @@ export interface ListOtasOptions extends ListOptionsBase { cursor?: string | null; joiner?: string; uei?: string; + /** Exact award key (the detail-endpoint identifier). */ + key?: string; piid?: string; search?: string; awarding_agency?: string; @@ -674,6 +803,8 @@ export interface ListProtestsOptions { agency?: string; case_number?: string; solicitation_number?: string; + /** NAICS code of the protested procurement (sent verbatim as `naics_code`). */ + naics_code?: string; protester?: string; search?: string; filed_date_after?: string; @@ -695,6 +826,8 @@ export interface ListItDashboardOptions { cio_rating?: string | number; cio_rating_max?: string | number; performance_risk?: string | number; + /** Filter by an investment's prior-year UII. */ + previous_uii?: string; [key: string]: unknown; } @@ -1992,6 +2125,31 @@ export class TangoClient { return this._genericPaginatedList("/api/gsa_elibrary_contracts/", options); } + /** Get a single GSA eLibrary contract by uuid (`/api/gsa_elibrary_contracts/{uuid}/`). */ + async getGsaElibraryContract( + uuid: string, + options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, + ): Promise> { + if (!uuid) throw new TangoValidationError("GSA eLibrary contract uuid is required"); + + const { shape, flat = false, flatLists = false, joiner = "." } = options; + const params: AnyRecord = {}; + + const shapeToUse = shape ?? ShapeConfig.GSA_ELIBRARY_CONTRACTS_MINIMAL; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) { + params.flat = "true"; + if (joiner) params.joiner = joiner; + } + if (flatLists) params.flat_lists = "true"; + } + + const data = await this.http.get(`/api/gsa_elibrary_contracts/${encodeURIComponent(uuid)}/`, params); + return this.materializeOne("GsaElibraryContract", shapeSpec, data, flat, joiner); + } + /** * List Labor Categories (LCATs) for an entity or IDV. * @@ -2018,7 +2176,13 @@ export class TangoClient { /** List budget accounts (`/api/budget/accounts/`). One row per federal account x fiscal year. */ async listBudgetAccounts(options: ListBudgetAccountsOptions = {}): Promise> { - return this._genericPaginatedList("/api/budget/accounts/", options); + const { fiscal_year_gte, fiscal_year_lte, account_title, ...rest } = options; + const params: AnyRecord = { ...rest }; + // Legacy aliases predate the explicit dunder surface; the API only understands the dunder forms. + if (fiscal_year_gte !== undefined && params.fiscal_year__gte === undefined) params.fiscal_year__gte = fiscal_year_gte; + if (fiscal_year_lte !== undefined && params.fiscal_year__lte === undefined) params.fiscal_year__lte = fiscal_year_lte; + if (account_title !== undefined && params.account_title__icontains === undefined) params.account_title__icontains = account_title; + return this._genericPaginatedList("/api/budget/accounts/", params); } /** Get a single budget account by id (`/api/budget/accounts/{id}/`). */ diff --git a/tests/unit/client.parity.test.ts b/tests/unit/client.parity.test.ts index 26a2f04..e0b60b2 100644 --- a/tests/unit/client.parity.test.ts +++ b/tests/unit/client.parity.test.ts @@ -281,6 +281,84 @@ describe("TangoClient — webhook test-delivery body shape", () => { }); }); +describe("TangoClient — GSA eLibrary detail", () => { + it("getGsaElibraryContract hits the detail path with the default minimal shape", async () => { + const { client, calls } = makeClient({ uuid: "abc-123", contract_number: "GS-35F-0001", schedule: "MAS" }); + const res = await client.getGsaElibraryContract("abc-123"); + expect(calls[0].url).toContain("/api/gsa_elibrary_contracts/abc-123/"); + expect(calls[0].url).toContain("shape="); + expect((res as Record).contract_number).toBe("GS-35F-0001"); + }); + + it("getGsaElibraryContract passes an explicit shape + flat params", async () => { + const { client, calls } = makeClient({ uuid: "abc-123" }); + await client.getGsaElibraryContract("abc-123", { shape: "uuid,contract_number", flat: true }); + expect(calls[0].url).toContain("shape=uuid%2Ccontract_number"); + expect(calls[0].url).toContain("flat=true"); + expect(calls[0].url).toContain("joiner=."); + }); + + it("getGsaElibraryContract requires uuid", async () => { + const { client } = makeClient(); + await expect(client.getGsaElibraryContract("")).rejects.toThrow(); + }); +}); + +describe("TangoClient — filter-surface catch-up", () => { + it("listBudgetAccounts sends range triplets under their dunder wire names", async () => { + const { client, calls } = makeClient(); + await client.listBudgetAccounts({ + requested_ba: 1000000, + unobligated_balance__gte: 500000, + obligated_to_apportioned_pct_capped__lte: 0.85, + }); + expect(calls[0].url).toContain("/api/budget/accounts/"); + expect(calls[0].url).toContain("requested_ba=1000000"); + expect(calls[0].url).toContain("unobligated_balance__gte=500000"); + expect(calls[0].url).toContain("obligated_to_apportioned_pct_capped__lte=0.85"); + }); + + it("listBudgetAccounts remaps the legacy aliases to the forms the API understands", async () => { + const { client, calls } = makeClient(); + await client.listBudgetAccounts({ fiscal_year_gte: 2021, fiscal_year_lte: 2024, account_title: "procurement" }); + expect(calls[0].url).toContain("fiscal_year__gte=2021"); + expect(calls[0].url).toContain("fiscal_year__lte=2024"); + expect(calls[0].url).toContain("account_title__icontains=procurement"); + expect(calls[0].url).not.toContain("fiscal_year_gte=2021"); + expect(calls[0].url).not.toContain("account_title=procurement"); + }); + + it("listBudgetAccounts lets an explicit dunder param win over its legacy alias", async () => { + const { client, calls } = makeClient(); + await client.listBudgetAccounts({ fiscal_year_gte: 2021, fiscal_year__gte: 2023 }); + expect(calls[0].url).toContain("fiscal_year__gte=2023"); + expect(calls[0].url).not.toContain("2021"); + }); + + it("listNaics sends the employee_limit filters", async () => { + const { client, calls } = makeClient(); + await client.listNaics({ employee_limit: 500, employee_limit_gte: 100 }); + expect(calls[0].url).toContain("/api/naics/"); + expect(calls[0].url).toContain("employee_limit=500"); + expect(calls[0].url).toContain("employee_limit_gte=100"); + }); + + it("listPsc sends has_awards", async () => { + const { client, calls } = makeClient(); + await client.listPsc({ has_awards: true }); + expect(calls[0].url).toContain("/api/psc/"); + expect(calls[0].url).toContain("has_awards=true"); + }); + + it("listProtests sends naics_code verbatim (not remapped to naics)", async () => { + const { client, calls } = makeClient(); + await client.listProtests({ naics_code: "541511" }); + expect(calls[0].url).toContain("/api/protests/"); + expect(calls[0].url).toContain("naics_code=541511"); + expect(calls[0].url).not.toContain("naics=541511"); + }); +}); + describe("TangoClient — misc parity methods", () => { it("searchOpportunityAttachments", async () => { const { client, calls } = makeClient({ results: [] }); From cca7137313117cd84ec8c16de3c981abf06a2332 Mon Sep 17 00:00:00 2001 From: "V. David Zvenyach" Date: Fri, 14 Aug 2026 12:07:34 -0500 Subject: [PATCH 4/7] feat(shapes): generated overlay closes all 416 shape-coverage gaps; response diagnostics; structured shape errors Ports python's overlay mechanism: scripts/generate-shape-overlay.ts deterministically emits src/shapes/generatedOverlay.ts (358 fields across 25 containers + 56 nested schemas) from the vendored contract + observed types, merged under curated schemas with explicit-wins semantics. PaginatedResponse gains meta with parsed agencyWarnings/unresolvedAgencyTokens/resolvedAgencies; TangoValidationError gains issues/availableFields. Shape-coverage baseline is now empty: 0 gaps. Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 3 + contracts/observed_shape_types.json | 12073 +++++++++++++++++++ contracts/shape_coverage_baseline.json | 421 +- package.json | 1 + scripts/generate-shape-overlay.ts | 329 + src/client.ts | 41 +- src/errors.ts | 24 + src/shapes/generatedOverlay.ts | 897 ++ src/shapes/index.ts | 1 + src/shapes/schema.ts | 13 + src/types.ts | 29 + tests/unit/client.meta-diagnostics.test.ts | 115 + tests/unit/errors.test.ts | 19 + tests/unit/shapes.overlay.test.ts | 70 + tests/unit/utils.http.test.ts | 27 + 15 files changed, 13643 insertions(+), 420 deletions(-) create mode 100644 contracts/observed_shape_types.json create mode 100644 scripts/generate-shape-overlay.ts create mode 100644 src/shapes/generatedOverlay.ts create mode 100644 tests/unit/client.meta-diagnostics.test.ts create mode 100644 tests/unit/shapes.overlay.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index dc4bfea..02e6c4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ This project follows [Semantic Versioning](https://semver.org/). ## [Unreleased] ### Added +- **Generated shape-coverage overlay** (parity with tango-python v1.4.0): `src/shapes/generatedOverlay.ts`, machine-generated by the new `scripts/generate-shape-overlay.ts` from the vendored contract plus `contracts/observed_shape_types.json` (live-API type observations vendored from tango-python). `SchemaRegistry` merges the overlay over the curated explicit schemas, so the typed shape API now accepts every field and expand the API returns — including entity `relationships(type, source)`, previously-unmapped models (`Naics`, `PSC`, `MasSin`, `BudgetAccount`, `AssistanceListing`, `BusinessType`), and all the code/description expands that were flattened to scalars. The reverse shape-coverage gate now reports **zero** gaps and `contracts/shape_coverage_baseline.json` is empty (416 → 0). +- **Agency-filter diagnostics on `PaginatedResponse`** (parity with tango-python v1.5.0). Every list method now surfaces the API's `meta` payload, plus three parsed views: `agencyWarnings` (human-readable notes about dropped or loosely-matched agency tokens), `unresolvedAgencyTokens` (tokens that matched no organization, keyed by filter name), and `resolvedAgencies` (the organizations each token actually resolved to — the only way to catch a token fuzzy-matching an agency you did not intend). All three are total: absent or malformed `meta` yields empty values, never a throw. +- **Structured shape errors on `TangoValidationError`** (parity with tango-python's `.issues` / `.available_fields`): new `issues` and `availableFields` getters expose the API's structured 400 payload — entries like `{"path": "tradeoff_process", "reason": "unknown_field"}` and the endpoint's valid field set — instead of leaving callers to parse `responseData` by hand. - **DIBBS, exclusions, and SBIR/STTR endpoint support** (parity with tango-python v1.3.0). Six endpoint families had no SDK support at all — no models, no methods. Added `listDibbsRfqs`/`getDibbsRfq`, `listDibbsRfps`/`getDibbsRfp`, `listDibbsAwards`/`getDibbsAward`, `listExclusions`/`getExclusion`, `listSbirTopics`/`getSbirTopic`, and `listSbirSolicitations`/`getSbirSolicitation`, with every filter param in the API contract exposed as a typed option, explicit shape schemas (including the nested organization/awardee/topic/document expands), and `ShapeConfig` defaults. New model interfaces: `DibbsRfq`, `DibbsRfp`, `DibbsAward`, `Exclusion`, `SbirTopic`, `SbirSolicitation`. Two API behaviors are worth knowing. `is_open` (DIBBS) and `is_currently_excluded` (exclusions) are derived at query time, so filter with the `open` / `active` options rather than shaping on those fields. And DIBBS `total_contract_price` is the *order* total repeated on every line item — never sum it across rows; deduplicate on award + delivery-order number first. diff --git a/contracts/observed_shape_types.json b/contracts/observed_shape_types.json new file mode 100644 index 0000000..aa4d965 --- /dev/null +++ b/contracts/observed_shape_types.json @@ -0,0 +1,12073 @@ +{ + "agencies": { + "paths": { + "abbreviation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "department": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "department.abbreviation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.cgac": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "department.congressional_justification": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.website": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 80 + }, + "assistance_listings": { + "paths": { + "applicant_eligibility": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "archived_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "benefit_eligibility": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "objectives": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "popular_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "published_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 40 + }, + "budget/accounts": { + "paths": { + "account_narrative_excerpt": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "appendix": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "appendix.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "appendix.appendix_granule_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "appendix.appendix_pdf_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "appendix.federal_account_symbol": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "appendix.fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "appendix.has_object_classification": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "appendix.has_program_financing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "appendix.n_program_activities": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "appendix.narrative_length": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "appendix.on_off_budget": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "appendix.request": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "appendix.request.requested_contractual_services": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_equipment": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_grants_subsidies": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_insurance_claims": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_interest_dividends": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_investments_loans": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_land_structures": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_other_object_class": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_personnel_benefits": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_personnel_comp": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_printing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_rent_communications_utilities": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_supplies_materials": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_total_from_object_class": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_transportation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.request.requested_travel": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "appendix.subfunction_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "narratives.account_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives.account_heading": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives.agency_title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.appropriations_length": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives.appropriations_text": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.budget_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives.bureau_title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives.date_issued": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "narratives.federal_account_symbol": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives.fund_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.granule_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.granule_title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.narrative_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.narrative_length": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives.narrative_text": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.notes": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.on_off_budget": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives.source_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "narratives.subaccount_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "narratives.subfunction_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + } + }, + "records_seen": 80 + }, + "business_types": { + "paths": { + "code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 40 + }, + "contracts": { + "paths": { + "award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "award_type": { + "kind": "code_object" + }, + "award_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "award_type.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "awarding_office.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awarding_office.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awarding_office.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "base_and_exercised_options_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "commercial_item_acquisition_procedures": { + "kind": "code_object" + }, + "commercial_item_acquisition_procedures.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "commercial_item_acquisition_procedures.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "competition.contract_type": { + "kind": "code_object" + }, + "competition.contract_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.contract_type.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.extent_competed": { + "kind": "code_object" + }, + "competition.extent_competed.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.extent_competed.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.number_of_offers_received": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "competition.other_than_full_and_open_competition": { + "kind": "code_object" + }, + "competition.other_than_full_and_open_competition.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.other_than_full_and_open_competition.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.solicitation_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "competition.solicitation_identifier": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.solicitation_procedures": { + "kind": "code_object" + }, + "competition.solicitation_procedures.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.solicitation_procedures.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "consolidated_contract": { + "kind": "code_object" + }, + "consolidated_contract.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "consolidated_contract.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contingency_humanitarian_or_peacekeeping_operation": { + "kind": "code_object" + }, + "contingency_humanitarian_or_peacekeeping_operation.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contingency_humanitarian_or_peacekeeping_operation.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contract_bundling": { + "kind": "code_object" + }, + "contract_bundling.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contract_bundling.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contract_financing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cost_accounting_standards_clause": { + "kind": "code_object" + }, + "cost_accounting_standards_clause.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cost_accounting_standards_clause.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cost_or_pricing_data": { + "kind": "code_object" + }, + "cost_or_pricing_data.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cost_or_pricing_data.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dod_acquisition_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dod_transaction_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "domestic_or_foreign_entity": { + "kind": "code_object" + }, + "domestic_or_foreign_entity.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "domestic_or_foreign_entity.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "epa_designated_product": { + "kind": "code_object" + }, + "epa_designated_product.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "epa_designated_product.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "evaluated_preference": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fair_opportunity_limited_sources": { + "kind": "code_object" + }, + "fair_opportunity_limited_sources.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fair_opportunity_limited_sources.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fed_biz_opps": { + "kind": "code_object" + }, + "fed_biz_opps.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fed_biz_opps.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "foreign_funding": { + "kind": "code_object" + }, + "foreign_funding.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "foreign_funding.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "funding_office.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "government_furnished_property": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "information_technology_commercial_item_category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "inherently_governmental_functions": { + "kind": "code_object" + }, + "inherently_governmental_functions.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "inherently_governmental_functions.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "legislative_mandates.clinger_cohen_act_planning": { + "kind": "code_object" + }, + "legislative_mandates.clinger_cohen_act_planning.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.clinger_cohen_act_planning.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.construction_wage_rate_requirements": { + "kind": "code_object" + }, + "legislative_mandates.construction_wage_rate_requirements.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.construction_wage_rate_requirements.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.employment_eligibility_verification": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.interagency_contracting_authority": { + "kind": "code_object" + }, + "legislative_mandates.interagency_contracting_authority.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.interagency_contracting_authority.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.labor_standards": { + "kind": "code_object" + }, + "legislative_mandates.labor_standards.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.labor_standards.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.materials_supplies_articles_equipment": { + "kind": "code_object" + }, + "legislative_mandates.materials_supplies_articles_equipment.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.materials_supplies_articles_equipment.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.other_statutory_authority": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.service_contract_inventory": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "local_area_set_aside": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "major_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "naics": { + "kind": "code_object" + }, + "naics.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "naics.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "number_of_actions": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "number_of_offers_source": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "officers": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent_award": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "parent_award.key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent_award.piid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_based_service_acquisition": { + "kind": "code_object" + }, + "performance_based_service_acquisition.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_based_service_acquisition.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "period_of_performance": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "period_of_performance.current_end_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "period_of_performance.start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "period_of_performance.ultimate_completion_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "piid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_manufacture": { + "kind": "code_object" + }, + "place_of_manufacture.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_manufacture.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "place_of_performance.city_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.country_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.country_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.state_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.state_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.zip_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "price_evaluation_percent_difference": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc": { + "kind": "code_object" + }, + "psc.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "psc.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "purchase_card_as_payment_method": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "recipient.cage": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "recipient.cage_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "recipient.display_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient.legal_business_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recovered_materials_sustainability": { + "kind": "code_object" + }, + "recovered_materials_sustainability.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recovered_materials_sustainability.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "research": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "sam_exception": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside": { + "kind": "code_object" + }, + "set_aside.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "simplified_procedures_for_certain_commercial_items": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "small_business_competitiveness_demonstration_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_identifier": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "subawards_summary": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "subcontracting_plan": { + "kind": "code_object" + }, + "subcontracting_plan.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "subcontracting_plan.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "total_contract_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "tradeoff_process": { + "kind": "code_object" + }, + "tradeoff_process.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "tradeoff_process.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "transactions.action_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.approval_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "transactions.approved_by": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.base_and_all_options_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "transactions.base_and_exercised_options_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "transactions.closed_by": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.closed_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.closed_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.contingency_humanitarian_or_peacekeeping_operation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.created_by": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.created_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "transactions.current_completion_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "transactions.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.domestic_or_foreign_entity": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.last_date_to_order": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.last_modified_by": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.last_modified_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "transactions.modification_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "transactions.non_governmental_dollars": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "transactions.purchase_card_as_payment_method": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.total_estimated_order_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.transaction_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "transactions.transaction_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "transactions.ultimate_completion_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "transactions.undefinitized_action": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "type_of_set_aside_source": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "undefinitized_action": { + "kind": "code_object" + }, + "undefinitized_action.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "undefinitized_action.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "vehicle.agency_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "vehicle.award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "vehicle.contract_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.description": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "vehicle.last_date_to_order": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "vehicle.naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "vehicle.psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "vehicle.set_aside": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.solicitation_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.solicitation_description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.solicitation_identifier": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.solicitation_title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.type_of_idc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.uuid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.vehicle_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle.who_can_use": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 1560 + }, + "departments": { + "paths": { + "abbreviation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cgac": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "congressional_justification": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "website": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 40 + }, + "dibbs/awards": { + "paths": { + "award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "award_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awardee": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "awardee.cage_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awardee.legal_business_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awardee.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awardee_cage": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "delivery_order_counter": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "delivery_order_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "last_mod_posting_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "nomenclature": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "nsn": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "organization.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "part_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "posted_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "purchase_request": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "total_contract_price": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "total_contract_price_text": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "uuid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 120 + }, + "dibbs/rfps": { + "paths": { + "buyer_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "closes_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "document_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "is_open": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "issued_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "nomenclature": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "nsn": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "organization.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "part_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "tech_docs_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "uuid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 80 + }, + "dibbs/rfqs": { + "paths": { + "document_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "is_open": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "issue_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "nomenclature": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "nsn": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "organization.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "part_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "purchase_request": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "quantity": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "return_by_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "set_aside": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_formatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "status_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "unit_of_issue": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "uuid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 80 + }, + "entities": { + "paths": { + "additional_website": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "business_types": { + "kind": "code_object" + }, + "business_types.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "business_types.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cage_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "capabilities": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "capabilities_link": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "congressional_district": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "country_of_incorporation": { + "kind": "code_object" + }, + "country_of_incorporation.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "country_of_incorporation.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "county": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "current_principals": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dba_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dodaac": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "email_address": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "entity_division_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "entity_division_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "entity_start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "entity_structure": { + "kind": "code_object" + }, + "entity_structure.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "entity_structure.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "entity_type": { + "kind": "code_object" + }, + "entity_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "entity_type.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "entity_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "evs_source": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "exclusion_status_flag": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "exclusion_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "federal_obligations": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "federal_obligations.active": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "federal_obligations.active.awards_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "federal_obligations.active.awards_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "federal_obligations.active.idv_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "federal_obligations.total": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "federal_obligations.total.awards_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "federal_obligations.total.awards_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "federal_obligations.total.idv_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "federal_obligations.total.subawards_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "federal_obligations.total.subawards_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "fiscal_year_end_close_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "g2x_about": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "g2x_ai_summary": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "g2x_employee_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "highest_owner": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "highest_owner.legal_business_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "highest_owner.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "immediate_owner": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "immediate_owner.cage_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "immediate_owner.legal_business_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "keywords": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "last_update_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "legal_business_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mailing_address": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "mailing_address.addressLine1": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mailing_address.addressLine2": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mailing_address.address_line1": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mailing_address.address_line2": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mailing_address.city": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mailing_address.countryCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mailing_address.country_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mailing_address.stateOrProvinceCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "mailing_address.state_or_province_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "mailing_address.zipCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "mailing_address.zipCodePlus4": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mailing_address.zip_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "mailing_address.zip_code_plus4": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "naics_codes": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "naics_codes.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "naics_codes.sba_small_business": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "naics_small_codes": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "non_fed_govt_certifications": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization_structure": { + "kind": "code_object" + }, + "organization_structure.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization_structure.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "past_performance": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "past_performance.summary": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "past_performance.summary.agency_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "past_performance.summary.naics_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "past_performance.summary.psc_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "past_performance.summary.total_awards": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "past_performance.summary.total_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "past_performance.top_agencies": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "past_performance.top_agencies.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "past_performance.top_agencies.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "past_performance.top_agencies.awards_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "past_performance.top_agencies.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "past_performance.top_agencies.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "past_performance.top_agencies.obligations": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "past_performance.top_agencies.top_naics": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "past_performance.top_agencies.top_psc": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "physical_address": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "physical_address.addressLine1": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "physical_address.addressLine2": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "physical_address.address_line1": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "physical_address.address_line2": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "physical_address.city": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "physical_address.countryCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "physical_address.country_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "physical_address.stateOrProvinceCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "physical_address.state_or_province_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "physical_address.zipCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "physical_address.zipCodePlus4": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "physical_address.zip_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "physical_address.zip_code_plus4": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "primary_naics": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "profit_structure": { + "kind": "code_object" + }, + "profit_structure.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "profit_structure.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc_codes": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "public_display_flag": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "purpose_of_registration": { + "kind": "code_object" + }, + "purpose_of_registration.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "purpose_of_registration.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "registered": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "registration_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "relationships": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "relationships.display_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "relationships.relation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "relationships.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "sam_activation_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "sam_expiration_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "sam_registration_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "sba_business_types": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "special_equip_material": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "state_of_incorporation": { + "kind": "code_object" + }, + "state_of_incorporation.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "state_of_incorporation.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "submission_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "uei_creation_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "uei_expiration_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "uei_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "uuid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 720 + }, + "exclusions": { + "paths": { + "activate_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "additional_comments": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cage_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "classification_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "create_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "ct_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "delisted_at": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dnb_open_data": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "entity_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "entity_uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "evs_investigation_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "excluding_agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "excluding_agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "exclusion_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "exclusion_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "exclusion_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "first_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "is_currently_excluded": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "is_fascsa_order": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "last_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "middle_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "more_locations": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "npi": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "prefix": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_address": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "primary_address.city": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_address.countryCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_address.stateOrProvinceCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_address.zipCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "references": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "references.exclusionName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "references.type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "secondary_address": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "suffix": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "termination_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "termination_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "update_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "vessel_call_sign": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vessel_flag": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vessel_grt": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vessel_owner": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vessel_tonnage": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vessel_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 40 + }, + "forecasts": { + "paths": { + "agency": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "anticipated_award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "contract_vehicle": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "created": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "display.agency": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.anticipated_award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "display.contract_vehicle": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.estimated_period": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "display.naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "display.place_of_performance": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.primary_contact": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "display.primary_contact.email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.primary_contact.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.primary_contact.phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.primary_contact.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.set_aside": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "display.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "estimated_period": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "external_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "is_active": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "modified": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "organization.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "primary_contact.email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "raw_data.alternate_contact_email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.alternate_contact_first_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.alternate_contact_last_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.alternate_contact_phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.anticipatedStrategy": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.anticipated_award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.apfs_coordinator_office": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.apfs_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.award_quarter": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.coEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.coFirstName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.coLastName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.competitive": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.contractNumber": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.contract_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.contract_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.contract_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.contract_vehicle": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.contractingOfficeCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.contracting_office": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.contractor": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.created_on": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.current_state": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.divisionAcronym": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.dollar_range": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "raw_data.dollar_range.display_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.dollar_range.display_order": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "raw_data.estimated_period_of_performance_end": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.estimated_period_of_performance_start": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.estimated_release_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.estimated_solicitation_release_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "raw_data.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "raw_data.incumbentContractorName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.isCoPocSelf": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "raw_data.isProgramPocSelf": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "raw_data.last_updated_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.mission": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.naics": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.organization": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.place_of_performance_city": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.place_of_performance_state": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.previous_publish_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.previous_published_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.primaryNAICS": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "raw_data.programPocEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.programPocFirstName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.programPocLastName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.programPocOffice": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.publish_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.published_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.requirement": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.requirements_contact_email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.requirements_contact_first_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.requirements_contact_last_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.requirements_contact_phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.requirements_office": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.requirements_title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.sbReviewControlNumber": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.sbReviewReferenceId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.sbs_coordinator_email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.sbs_coordinator_first_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.sbs_coordinator_last_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.sbs_coordinator_phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.small_business_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.small_business_set_aside": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "raw_data.status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.targetAwardMonth": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "raw_data.targetAwardYear": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "raw_data.targetSolicitationMonth": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.targetSolicitationYear": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.totalContractRange": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "raw_data.uuid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "source_system": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 160 + }, + "grants": { + "paths": { + "additional_info": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "additional_info.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "additional_info.link": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "applicant_eligibility_description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "applicant_types": { + "kind": "code_object" + }, + "applicant_types.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "applicant_types.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "category": { + "kind": "code_object" + }, + "category.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "category.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cfda_numbers": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "cfda_numbers.number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "cfda_numbers.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "forecast.agencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.agencyContactEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.agencyContactEmailDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.agencyContactName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.agencyContactPhone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.agencyDetails": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "forecast.agencyDetails.agencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.agencyDetails.agencyName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.agencyDetails.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.agencyDetails.seed": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.agencyDetails.topAgencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.applicantEligibilityDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.applicantTypes": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "forecast.applicantTypes.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.applicantTypes.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "forecast.archiveDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.archiveDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.awardCeiling": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "forecast.awardCeilingFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.awardFloor": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "forecast.awardFloorFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "forecast.costSharing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "forecast.createTimeStamp": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.createTimeStampStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.createdDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estApplicationResponseDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estApplicationResponseDateDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estApplicationResponseDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estAwardDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estAwardDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estProjectStartDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estProjectStartDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estSynopsisPostingDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estSynopsisPostingDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.estimatedFunding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "forecast.estimatedFundingFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.fiscalYear": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "forecast.forecastDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.fundingActivityCategories": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "forecast.fundingActivityCategories.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.fundingActivityCategories.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.fundingActivityCategoryDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.fundingDescLinkDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.fundingDescLinkUrl": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.fundingInstruments": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "forecast.fundingInstruments.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.fundingInstruments.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.lastUpdatedDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.modComments": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.numberOfAwards": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "forecast.opportunityId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "forecast.postingDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.postingDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.sendEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "forecast.version": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_activity_category_description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_categories": { + "kind": "code_object" + }, + "funding_categories.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_categories.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_details": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "funding_details.award_ceiling": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_details.award_floor": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_details.estimated_total_funding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_details.expected_number_of_awards": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_instruments": { + "kind": "code_object" + }, + "funding_instruments.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_instruments.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "grant_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "grantor_contact": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "grantor_contact.email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "grantor_contact.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "grantor_contact.phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "important_dates": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "important_dates.estimated_application_response_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "important_dates.estimated_application_response_date_description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "important_dates.estimated_project_start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "important_dates.estimated_synopsis_post_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "important_dates.posted_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "important_dates.response_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "important_dates.response_date_description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "last_updated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "opportunity_history": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.cfdas": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.cfdas.cfdaNumber": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "opportunity_history.cfdas.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.cfdas.opportunityId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.cfdas.programTitle": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.cfdas.revision": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.forecast.actionDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.actionType": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyContactEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyContactEmailDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyContactName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyContactPhone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyDetails": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.forecast.agencyDetails.agencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyDetails.agencyName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyDetails.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyDetails.seed": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.agencyDetails.topAgencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.applicantEligibilityDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.applicantTypes": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.forecast.applicantTypes.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.applicantTypes.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.archiveDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.archiveDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.awardCeiling": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.awardCeilingFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.awardFloor": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.awardFloorFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.costSharing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "opportunity_history.forecast.createTimeStamp": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.createTimeStampStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.createdDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estApplicationResponseDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estApplicationResponseDateDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estApplicationResponseDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estAwardDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estAwardDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estProjectStartDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estProjectStartDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estSynopsisPostingDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estSynopsisPostingDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.estimatedFunding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.estimatedFundingFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.fiscalYear": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.forecastDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.fundingActivityCategories": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.forecast.fundingActivityCategories.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.fundingActivityCategories.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.fundingActivityCategoryDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.fundingDescLinkDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.fundingDescLinkUrl": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.fundingInstruments": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.forecast.fundingInstruments.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.fundingInstruments.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.lastUpdatedDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.modComments": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.numberOfAwards": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.oppHistId": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.forecast.oppHistId.opportunityId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.oppHistId.revision": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.opportunityId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.postingDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.postingDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.revision": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecast.sendEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.forecast.version": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.forecastModifiedFields": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.listed": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.oppHistId": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.oppHistId.opportunityId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.oppHistId.revision": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.opportunityCategory": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.opportunityCategory.category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.opportunityCategory.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.opportunityId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.opportunityNumber": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.opportunityTitle": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.owningAgencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.publisherUid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.revision": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.synopsis.actionDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.actionType": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyAddressDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyContactDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyContactEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyContactEmailDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyContactName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyContactPhone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyDetails": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.synopsis.agencyDetails.agencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyDetails.agencyName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyDetails.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyDetails.seed": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.agencyDetails.topAgencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.applicantEligibilityDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.applicantTypes": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.synopsis.applicantTypes.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.applicantTypes.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.archiveDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.archiveDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.awardCeiling": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.awardCeilingFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.awardFloor": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.awardFloorFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.costSharing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "opportunity_history.synopsis.createTimeStamp": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.createTimeStampStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.createdDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.estimatedFunding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.estimatedFundingFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.fundingActivityCategories": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.synopsis.fundingActivityCategories.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.fundingActivityCategories.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.fundingActivityCategoryDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.fundingDescLinkDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.fundingDescLinkUrl": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.fundingInstruments": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.synopsis.fundingInstruments.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.fundingInstruments.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.id": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity_history.synopsis.id.opportunityId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.id.revision": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.lastUpdatedDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.numberOfAwards": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.opportunityId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.postingDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.postingDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.responseDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.responseDateDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.responseDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.revision": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsis.sendEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.synopsisDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_history.synopsis.version": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "opportunity_history.synopsisModifiedFields": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "organization.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "status": { + "kind": "code_object" + }, + "status.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "status.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "synopsis.agencyAddressDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyContactDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyContactEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyContactEmailDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyContactName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyContactPhone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyDetails": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "synopsis.agencyDetails.agencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyDetails.agencyName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyDetails.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyDetails.seed": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyDetails.topAgencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.agencyPhone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.applicantEligibilityDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.applicantTypes": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "synopsis.applicantTypes.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.applicantTypes.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "synopsis.archiveDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.archiveDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.awardCeiling": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "synopsis.awardCeilingFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.awardFloor": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "synopsis.awardFloorFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "synopsis.costSharing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "synopsis.createTimeStamp": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.createTimeStampStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.createdDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.estimatedFunding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "synopsis.estimatedFundingFormatted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "synopsis.fundingActivityCategories": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "synopsis.fundingActivityCategories.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.fundingActivityCategories.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.fundingActivityCategoryDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.fundingDescLinkDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.fundingDescLinkUrl": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.fundingInstruments": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "synopsis.fundingInstruments.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.fundingInstruments.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.lastUpdatedDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.modComments": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "synopsis.numberOfAwards": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "synopsis.opportunityId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "synopsis.postingDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.postingDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.responseDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.responseDateDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.responseDateStr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.sendEmail": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.synopsisDesc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.topAgencyDetails": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "synopsis.topAgencyDetails.agencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.topAgencyDetails.agencyName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.topAgencyDetails.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.topAgencyDetails.seed": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.topAgencyDetails.topAgencyCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "synopsis.version": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 520 + }, + "gsa_elibrary_contracts": { + "paths": { + "contract_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cooperative_purchasing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "disaster_recovery_purchasing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "file_urls": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "idv": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "idv.award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "idv.key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "recipient.display_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "schedule": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "sins": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "uuid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 120 + }, + "idvs": { + "paths": { + "award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "awarding_office": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "awarding_office.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awarding_office.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awarding_office.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awards": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "awards.award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "awards.base_and_exercised_options_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "awards.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awards.fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awards.key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awards.naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awards.obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "awards.piid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awards.psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awards.total_contract_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "awards.transactions": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "commercial_item_acquisition_procedures": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "competition.contract_type": { + "kind": "code_object" + }, + "competition.contract_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "competition.contract_type.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.extent_competed": { + "kind": "code_object" + }, + "competition.extent_competed.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.extent_competed.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.number_of_offers_received": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "competition.other_than_full_and_open_competition": { + "kind": "code_object" + }, + "competition.other_than_full_and_open_competition.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.other_than_full_and_open_competition.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.solicitation_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "competition.solicitation_identifier": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.solicitation_procedures": { + "kind": "code_object" + }, + "competition.solicitation_procedures.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition.solicitation_procedures.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "consolidated_contract": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contingency_humanitarian_or_peacekeeping_operation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contract_bundling": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contract_financing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cost_accounting_standards_clause": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cost_or_pricing_data": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dod_acquisition_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dod_transaction_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "domestic_or_foreign_entity": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "email_address": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "epa_designated_product": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "evaluated_preference": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fair_opportunity_limited_sources": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fed_biz_opps": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fee_range_lower_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fee_range_upper_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "fixed_fee_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "foreign_funding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "funding_office.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "government_furnished_property": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "gsa_elibrary.contract_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.cooperative_purchasing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "gsa_elibrary.disaster_recovery_purchasing": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "gsa_elibrary.external_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.extracted_text": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.file_urls": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.schedule": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.sins": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "gsa_elibrary.source_data": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "gsa_elibrary.source_data.": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.8(a) - 8a": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.8(a) Joint Venture Eligible - 8ajv": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.8(a) Sole Souce Pool - 8aS": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.8(a) Sole Souce exit date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Address 1": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Address 2": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Alaskan Native Corporation Owned Firm - an": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.American Indian Owned - ai": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "gsa_elibrary.source_data.City": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Closed for New Award": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Contract #": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Country": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Current Option Period End Date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.HUBZone Joint Venture Eligible - hjv": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Hub Zone - h": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Large Category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Native Hawaiian Organization Owned firm - hn": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Other than Small Business - o": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Price List - Disast Recov": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.SAM UEI": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.SBA Certified Service-Disabled Veteran Owned Small Business - sdv": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.SBA Certified Veteran Owned Small Business - svo": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Service Disabled Veteran Owned - dv": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Service Disabled Veteran Owned Joint Venture Eligible - dvjv": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Small Business - s": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Small Disadv - d": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Source": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.State": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Sub Category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.T&Cs - Coop Purch": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Tribally Owned Firm - to": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.URL": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Ultimate Contract End Date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Vendor": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Veteran Owned - v": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.View Catalog": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Woman Owned - w": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Women Owned (EDWOSB) - ew": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Women Owned (WOSB) - wo": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Women Owned Joint Venture Eligible - wojv": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data.Zip": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "gsa_elibrary.source_data._duplicated_0": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "gsa_elibrary.source_data._gsa_elibrary.document_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary.extraction_method": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary.files": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary.needs_ocr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "gsa_elibrary.source_data._gsa_elibrary.original_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary.page_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary.sins": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "gsa_elibrary.source_data._gsa_elibrary.sins.large_category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary.sins.sin": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "gsa_elibrary.source_data._gsa_elibrary.sins.state_local_coop_purch": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary.sins.sub_category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary.sins.view_catalog_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.source_data._gsa_elibrary.text_length": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "gsa_elibrary.source_data._gsa_elibrary.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "gsa_elibrary.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "idv_type": { + "kind": "code_object" + }, + "idv_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "idv_type.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "idv_website": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "inherently_governmental_functions": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "legislative_mandates.clinger_cohen_act_planning": { + "kind": "code_object" + }, + "legislative_mandates.clinger_cohen_act_planning.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.clinger_cohen_act_planning.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.construction_wage_rate_requirements": { + "kind": "code_object" + }, + "legislative_mandates.construction_wage_rate_requirements.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.construction_wage_rate_requirements.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.employment_eligibility_verification": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.interagency_contracting_authority": { + "kind": "code_object" + }, + "legislative_mandates.interagency_contracting_authority.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.interagency_contracting_authority.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.labor_standards": { + "kind": "code_object" + }, + "legislative_mandates.labor_standards.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.labor_standards.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.materials_supplies_articles_equipment": { + "kind": "code_object" + }, + "legislative_mandates.materials_supplies_articles_equipment.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.materials_supplies_articles_equipment.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.other_statutory_authority": { + "kind": "code_object" + }, + "legislative_mandates.other_statutory_authority.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.other_statutory_authority.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "legislative_mandates.service_contract_inventory": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "local_area_set_aside": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "major_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "multiple_or_single_award_idv": { + "kind": "code_object" + }, + "multiple_or_single_award_idv.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "multiple_or_single_award_idv.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "naics": { + "kind": "code_object" + }, + "naics.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "naics.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "number_of_actions": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "number_of_offers_source": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "officers": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "ordering_procedure": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent_award": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "parent_award.key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent_award.piid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_based_service_acquisition": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "period_of_performance": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "period_of_performance.last_date_to_order": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "period_of_performance.start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "piid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "program_acronym": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc": { + "kind": "code_object" + }, + "psc.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "psc.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "recipient": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "recipient.cage": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "recipient.cage_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "recipient.display_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient.legal_business_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recovered_materials_sustainability": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "research": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "sam_exception": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside": { + "kind": "code_object" + }, + "set_aside.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "simplified_procedures_for_certain_commercial_items": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "small_business_competitiveness_demonstration_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_identifier": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "subawards_summary": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "subcontracting_plan": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "total_contract_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "total_estimated_order_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "tradeoff_process": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "transactions.action_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.approval_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "transactions.approved_by": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.base_and_all_options_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "transactions.base_and_exercised_options_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.closed_by": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.closed_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.closed_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.contingency_humanitarian_or_peacekeeping_operation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.created_by": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.created_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "transactions.current_completion_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.domestic_or_foreign_entity": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.last_date_to_order": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "transactions.last_modified_by": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.last_modified_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "transactions.modification_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "transactions.non_governmental_dollars": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "transactions.purchase_card_as_payment_method": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.total_estimated_order_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "transactions.transaction_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "transactions.transaction_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.ultimate_completion_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "transactions.undefinitized_action": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "type_of_fee_for_use_of_service": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "type_of_idc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "undefinitized_action": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle_uuid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "who_can_use": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 800 + }, + "itdashboard": { + "paths": { + "agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "bureau_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "bureau_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "business_case_html": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cio_evaluation": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "cio_evaluation.cioRating": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cio_evaluation.comment": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cio_evaluation.latestIndicator": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cio_evaluation.ratedDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "cio_evaluation.updatedTime": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "contracts": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "contracts.contractPIID": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contracts.referencePIID": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contracts.updatedTime": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "cost_pools_towers": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "cost_pools_towers.amount": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "cost_pools_towers.category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cost_pools_towers.fiscalYear": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "cost_pools_towers.sourceType": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cost_pools_towers.tbmType": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cost_pools_towers.updatedTime": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "details": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "details.business_case_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "details.change_in_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "details.current_uii": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "details.investment_description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "details.it_infrastructure_and_management_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "details.last_updated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "details.mission_delivery_and_management_support_area": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "details.mission_support_investment_categories": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "details.national_security_system_identifier": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "details.previous_uii": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "details.public_urls": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "details.shared_services_category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "details.shared_services_identifier": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "funding.fy2020_contribution": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2020_internal_funding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2021_contribution": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2021_internal_funding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2022_contribution": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2022_internal_funding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2023_contribution": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2023_internal_funding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2024_contribution": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2024_internal_funding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2025_contribution": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding.fy2025_internal_funding": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding_sources": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "funding_sources.agencyCode(fromBudgetAccount)": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_sources.budgetAccountCode": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_sources.budgetAccountName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_sources.bureauCode(fromBudgetAccount)": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_sources.fiscalYear": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_sources.fundingAmount": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "funding_sources.fundingType": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_sources.sourceType": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_sources.updatedTime": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "investment_title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "operational_analysis": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "operational_analysis.analysisConclusion": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "operational_analysis.analysisResults": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "operational_analysis.date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "operational_analysis.investmentTitle": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "operational_analysis.updatedTime": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "organization": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "organization.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "part_of_it_portfolio": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_actual": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "performance_actual.actualResult": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "performance_actual.comment": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_actual.dateOfActualResult": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "performance_actual.measurementCondition": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_actual.metTarget": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_actual.metricActualAgencyId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "performance_actual.metricAgencyId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "performance_actual.metricDescription": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_actual.reportingFrequency": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_actual.target2024PY": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "performance_actual.target2025CY": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "performance_actual.unitOfMeasure": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "performance_actual.updatedTime": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "performance_metrics": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "performance_metrics.agencyBaselineCapability": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "performance_metrics.dateOfLatestActualResult": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "performance_metrics.isRetired": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "performance_metrics.latestActualResult": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "performance_metrics.measurementCondition": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_metrics.metTarget": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_metrics.metricAgencyId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "performance_metrics.metricDescription": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_metrics.performanceMeasurementCategory": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_metrics.reportingFrequency": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "performance_metrics.target2024PY": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "performance_metrics.target2025CY": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "performance_metrics.unitOfMeasure": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "performance_metrics.updatedTime": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "projects": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "projects.actualCost": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "projects.actualEndDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "projects.actualStartDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "projects.agencyProjectId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "projects.costVariance($M)": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "projects.costVariance(%)": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "projects.costVarianceColor": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "projects.incrementalDevelopment": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "projects.iterationFrequencyAmount": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "projects.iterationFrequencyUnits": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "projects.iterativeDescription": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "projects.plannedCost": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "projects.plannedEndDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "projects.plannedStartDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "projects.projectGoal": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "projects.projectId": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "projects.projectName": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "projects.projectStatus": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "projects.projectedCost": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "projects.projectedEndDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "projects.projectedStartDate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "projects.scheduleVariance(%)": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "projects.scheduleVariance(days)": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "projects.scheduleVarianceColor": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "projects.softwareProject": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "projects.tmfInitiative": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "projects.updatedTime": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "type_of_investment": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "uii": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "updated_time": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 480 + }, + "mas_sins": { + "paths": { + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "expiration_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "large_category_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "large_category_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "naics_codes": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "olm": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "service_comm_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "sin": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "state_local": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "sub_category_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "sub_category_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "tdr": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 40 + }, + "naics": { + "paths": { + "code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "federal_obligations": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "federal_obligations.active": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "federal_obligations.active.awards_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "federal_obligations.active.awards_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "federal_obligations.total": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "federal_obligations.total.awards_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "federal_obligations.total.awards_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "size_standards": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "size_standards.employee_limit": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "size_standards.revenue_limit": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + } + }, + "records_seen": 120 + }, + "notices": { + "paths": { + "active": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "address": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "address.city": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "address.country": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "address.state": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "address.zip": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "archive": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "archive.date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "archive.type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachment_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "attachments": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "attachments.attachment_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.file_size": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "attachments.mime_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.posted_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.resource_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "award_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "last_updated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "meta": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "meta.link": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "meta.notice_type": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "meta.notice_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "meta.notice_type.type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "meta.parent_notice_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "meta.related_notice_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "notice_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "office": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity.link": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity.opportunity_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "place_of_performance.city": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.country": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.state": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.street_address": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.zip": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "posted_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "primary_contact.email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.fax": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.full_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "response_deadline": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "sam_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "secondary_contact": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "secondary_contact.email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "secondary_contact.fax": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "secondary_contact.full_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "secondary_contact.phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "secondary_contact.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside": { + "kind": "code_object" + }, + "set_aside.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 440 + }, + "offices": { + "paths": { + "agency": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "agency.abbreviation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "agency.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "department": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "department.abbreviation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.cgac": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "department.congressional_justification": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.website": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 120 + }, + "opportunities": { + "paths": { + "active": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "agency": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "agency.abbreviation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "agency.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "archive_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "attachments": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "attachments.attachment_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.extracted_text": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.file_size": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "attachments.mime_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.posted_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "attachments.resource_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "attachments.url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "award_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "department.abbreviation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.cgac": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "department.congressional_justification": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.website": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "first_notice_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "last_notice_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "latest_notice": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "latest_notice.link": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "latest_notice.notice_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "latest_notice_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "meta": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "meta.attachments_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "meta.notice_type": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "meta.notice_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "meta.notice_type.type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "meta.notices_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "notice_history": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "notice_history.deleted": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "notice_history.index": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "notice_history.latest": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "notice_history.notice_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "notice_history.notice_type_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "notice_history.parent_notice_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "notice_history.posted_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "notice_history.related_notice_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "notice_history.solicitation_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "notice_history.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "office": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "office.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "office.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "office.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "office.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "office.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "office.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "office.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "office_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "place_of_performance.city": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "place_of_performance.country_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.state": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.street_address": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.zip_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "primary_contact": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "primary_contact.email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.full_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "primary_contact.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "response_deadline": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "sam_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "secondary_contact": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "secondary_contact.email": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "secondary_contact.full_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "secondary_contact.phone": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside": { + "kind": "code_object" + }, + "set_aside.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "set_aside.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "snippet": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 480 + }, + "organizations": { + "paths": { + "aac_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "agency.abbreviation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "agency.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "ancestors": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "ancestors.fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "ancestors.level": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "ancestors.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "ancestors.short_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_appropriation": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "budget_appropriation.cgac": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "budget_appropriation.fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "budget_appropriation.n_accounts": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "budget_appropriation.scope": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_appropriation.summary": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "budget_appropriation.summary.apportioned": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.apportioned_to_enacted_pct": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.assistance_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.contract_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.contract_share_of_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.enacted_ba": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.enacted_to_requested_pct": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_appropriation.summary.obligated_to_apportioned_pct": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.obligated_to_enacted_pct": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.obligated_total": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.outlayed_to_obligated_pct": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.outlayed_total": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.requested_ba": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.summary.unobligated_balance": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.top_accounts": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "budget_appropriation.top_accounts.account_title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_appropriation.top_accounts.ba_growth_next_year_pct": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.top_accounts.bea_category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_appropriation.top_accounts.bureau_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_appropriation.top_accounts.contract_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.top_accounts.contract_share_of_obligated_capped": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.top_accounts.enacted_ba": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.top_accounts.federal_account_symbol": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_appropriation.top_accounts.obligated_to_apportioned_pct_capped": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.top_accounts.obligated_total": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_appropriation.top_accounts.outlayed_total": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_spending": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "budget_spending.fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "budget_spending.n_orgs_in_rollup": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "budget_spending.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_spending.summary": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "budget_spending.summary.contract_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_spending.summary.contract_outlayed": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_spending.summary.n_contracts": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "budget_spending.summary.n_distinct_accounts": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "budget_spending.summary.n_distinct_funding_offices": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "budget_spending.summary.n_distinct_recipients": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "budget_spending.top_accounts": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "budget_spending.top_accounts.account_title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_spending.top_accounts.contract_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_spending.top_accounts.contract_outlayed": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "budget_spending.top_accounts.federal_account_symbol": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "budget_spending.top_accounts.n_distinct_recipients": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "canonical_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cgac": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "children": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "children.cgac": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "children.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "children.fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "children.is_active": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "children.key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "children.level": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "children.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "children.short_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "children.type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "department": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "department.abbreviation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "department.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "department.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "end_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "fpds_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "fpds_org_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "full_parent_path_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "is_active": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "l1_fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "l2_fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "l3_fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "l4_fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "l5_fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "l6_fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "l7_fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "l8_fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "level": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "logo": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "mod_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "obligation_rank": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "obligations": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "parent": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "parent.cgac": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "parent.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "parent.fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "parent.is_active": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "parent.key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent.level": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "parent.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent.short_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent.type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent_fh_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "short_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "summary": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "total_obligations": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "tree_obligations": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 320 + }, + "otas": { + "paths": { + "award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "award_type": { + "kind": "code_object" + }, + "award_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "award_type.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "base_and_exercised_options_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "consortia": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "consortia_uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dod_acquisition_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "extent_competed": { + "kind": "code_object" + }, + "extent_competed.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "extent_competed.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "non_governmental_dollars": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "non_traditional_government_contractor_participation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "parent_award": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "parent_award.key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent_award.piid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "parent_award_modification_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "period_of_performance": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "period_of_performance.current_end_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "period_of_performance.start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "period_of_performance.ultimate_completion_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "piid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc": { + "kind": "code_object" + }, + "psc.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "psc.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "recipient": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "total_contract_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "transactions": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "type_of_ot_agreement": { + "kind": "code_object" + }, + "type_of_ot_agreement.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "type_of_ot_agreement.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 480 + }, + "otidvs": { + "paths": { + "award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "base_and_exercised_options_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "consortia": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "consortia_uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dod_acquisition_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "extent_competed": { + "kind": "code_object" + }, + "extent_competed.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "extent_competed.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "idv_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "non_governmental_dollars": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "non_traditional_government_contractor_participation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "period_of_performance": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "period_of_performance.current_end_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "period_of_performance.start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "period_of_performance.ultimate_completion_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "piid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc": { + "kind": "code_object" + }, + "psc.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "psc.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "recipient": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "total_contract_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "transactions": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "type_of_ot_agreement": { + "kind": "code_object" + }, + "type_of_ot_agreement.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "type_of_ot_agreement.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 400 + }, + "protests": { + "paths": { + "agency": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "case_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "case_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "case_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "challenged_party": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "decision_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "decision_text": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "decision_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "decisions": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "digest": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "docket_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "dockets.agency": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.base_case_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.case_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.case_type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.challenged_party": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.decision_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "dockets.decision_text": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.decision_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.digest": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.docket_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.docket_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.due_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "dockets.filed_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "dockets.judge": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.organization": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "dockets.organization.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "dockets.organization.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.organization.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "dockets.organization.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.organization.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "dockets.organization.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.organization.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.outcome": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.outcome_reason": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.posted_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "dockets.protester": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.size_standard": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.solicitation_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.source_system": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "dockets.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "due_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "filed_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "judge": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "organization.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "outcome": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "outcome_reason": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "posted_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "protester": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "resolved_agency": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "resolved_agency.key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "resolved_agency.match_confidence": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "resolved_agency.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "resolved_agency.rationale": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "resolved_protester": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "resolved_protester.match_confidence": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "resolved_protester.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "resolved_protester.rationale": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "resolved_protester.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "size_standard": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "source_system": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 240 + }, + "psc": { + "paths": { + "category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "current": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "current.active": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "current.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "current.end_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "current.excludes": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "current.includes": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "current.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "current.start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "historical": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "historical.active": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "historical.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "historical.end_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "historical.excludes": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "historical.includes": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "historical.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "historical.start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "level_1_category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "level_1_category_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "level_2_category": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "level_2_category_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "parent": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 120 + }, + "sbir/solicitations": { + "paths": { + "activity": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cycle": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "cycle_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "documents": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "end_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "out_of_cycle": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "sol_download_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_cycle_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "solicitation_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "solicitation_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "source_last_updated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "topics": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "topics.agency": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "topics.close_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "topics.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "topics.topic_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "topics.topic_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "topics.topic_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + } + }, + "records_seen": 120 + }, + "sbir/topics": { + "paths": { + "activity": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "close_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "doc_source": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "due_dates_text": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "grant": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "listed_open": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "official_solicitation_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "open_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "opportunity": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "opportunity.opportunity_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity.response_deadline": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "opportunity.solicitation_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "release_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "solicitation": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "solicitation.cycle_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation.end_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "solicitation.out_of_cycle": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation.program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation.solicitation_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation.solicitation_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "solicitation.solicitation_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation.start_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "solicitation.title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation.year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "solicitation_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "solicitation_status": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "source_last_updated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "topic_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "topic_node_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "topic_number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "topic_url": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + } + }, + "records_seen": 160 + }, + "subawards": { + "paths": { + "award_key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "awarding_office.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awarding_office.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awarding_office.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "awarding_office.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "awarding_office.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fsrs_details": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "fsrs_details.id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fsrs_details.last_modified_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "fsrs_details.month": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "fsrs_details.year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "funding_office.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "funding_office.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "funding_office.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "highly_compensated_officers": { + "is_list": true, + "is_optional": false, + "kind": "object" + }, + "highly_compensated_officers.amount": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "highly_compensated_officers.name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "key": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "piid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "place_of_performance.city": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.country_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.state": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "place_of_performance.zip": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "prime_awardee_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "prime_awardee_uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "prime_recipient": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "prime_recipient.display_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "prime_recipient.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient_business_types": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient_dba_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient_duns": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "recipient_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient_parent_duns": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "recipient_parent_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient_parent_uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "recipient_uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "subaward_details": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "subaward_details.action_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "datetime" + }, + "subaward_details.amount": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "subaward_details.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "subaward_details.fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "subaward_details.number": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "subaward_details.type": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "subaward_recipient": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "subaward_recipient.display_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "subaward_recipient.uei": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "usaspending_permalink": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 360 + }, + "vehicles": { + "paths": { + "agency_details": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "agency_details.awarding_office": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "agency_details.awarding_office.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "agency_details.awarding_office.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency_details.awarding_office.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "agency_details.awarding_office.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency_details.awarding_office.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "agency_details.awarding_office.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency_details.awarding_office.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency_details.funding_office": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "agency_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "awardee_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "competition_details": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "competition_details.commercial_item_acquisition_procedures": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition_details.evaluated_preference": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition_details.extent_competed": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition_details.most_recent_solicitation_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "competition_details.number_of_offers_received": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "competition_details.original_solicitation_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "competition_details.other_than_full_and_open_competition": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition_details.set_aside": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition_details.simplified_procedures_for_certain_commercial_items": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition_details.small_business_competitiveness_demonstration_program": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition_details.solicitation_identifier": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "competition_details.solicitation_procedures": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "contract_type": { + "kind": "code_object" + }, + "contract_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "contract_type.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "description": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "descriptions": { + "is_list": true, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "fiscal_year": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "idv_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "is_synthetic_solicitation": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "bool" + }, + "last_date_to_order": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "latest_award_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "date" + }, + "metrics": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "metrics.avg_offers_received": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "metrics.avg_order_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "metrics.award_concentration_hhi": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "metrics.competed_rate": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "metrics.days_since_last_order": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "metrics.max_order_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "metrics.obligation_to_ceiling_ratio": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "metrics.order_concentration_hhi": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "metrics.recent_obligations_24mo": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "metrics.recent_orders_24mo": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "metrics.top_recipient_share": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "metrics.using_agency_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "naics_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "opportunity_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "order_count": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization": { + "is_list": false, + "is_optional": false, + "kind": "object" + }, + "organization.agency_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.agency_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.department_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.department_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.office_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "organization.office_name": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization.organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "organization_id": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "program_acronym": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "psc_code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "int" + }, + "set_aside": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_date": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_identifier": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "solicitation_title": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "total_obligated": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "type_of_idc": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "uuid": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle_contracts_value": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "vehicle_obligations": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "Decimal" + }, + "vehicle_type": { + "kind": "code_object" + }, + "vehicle_type.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "vehicle_type.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "who_can_use": { + "kind": "code_object" + }, + "who_can_use.code": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + }, + "who_can_use.description": { + "is_list": false, + "is_optional": true, + "kind": "scalar", + "type": "str" + } + }, + "records_seen": 200 + } +} diff --git a/contracts/shape_coverage_baseline.json b/contracts/shape_coverage_baseline.json index ea74e16..fa6c0a4 100644 --- a/contracts/shape_coverage_baseline.json +++ b/contracts/shape_coverage_baseline.json @@ -1,422 +1,5 @@ { "description": "Known reverse shape-coverage gaps (Tango exposes, SDK schema lacks), accepted as a tracked backlog. check-shape-coverage.ts fails only on gaps NOT listed here. Burn down and regenerate with --update-baseline.", - "count": 416, - "known_gaps": [ - "expand_flat|agencies|(root)|department", - "expand_flat|contracts|(root)|commercial_item_acquisition_procedures", - "expand_flat|contracts|(root)|consolidated_contract", - "expand_flat|contracts|(root)|contingency_humanitarian_or_peacekeeping_operation", - "expand_flat|contracts|(root)|contract_bundling", - "expand_flat|contracts|(root)|cost_accounting_standards_clause", - "expand_flat|contracts|(root)|cost_or_pricing_data", - "expand_flat|contracts|(root)|domestic_or_foreign_entity", - "expand_flat|contracts|(root)|epa_designated_product", - "expand_flat|contracts|(root)|evaluated_preference", - "expand_flat|contracts|(root)|fair_opportunity_limited_sources", - "expand_flat|contracts|(root)|fed_biz_opps", - "expand_flat|contracts|(root)|foreign_funding", - "expand_flat|contracts|(root)|information_technology_commercial_item_category", - "expand_flat|contracts|(root)|inherently_governmental_functions", - "expand_flat|contracts|(root)|performance_based_service_acquisition", - "expand_flat|contracts|(root)|place_of_manufacture", - "expand_flat|contracts|(root)|recovered_materials_sustainability", - "expand_flat|contracts|(root)|research", - "expand_flat|contracts|(root)|sam_exception", - "expand_flat|contracts|(root)|set_aside", - "expand_flat|contracts|(root)|subcontracting_plan", - "expand_flat|contracts|(root)|tradeoff_process", - "expand_flat|contracts|(root)|transactions", - "expand_flat|contracts|(root)|undefinitized_action", - "expand_flat|entities|(root)|business_types", - "expand_flat|entities|(root)|federal_obligations", - "expand_flat|entities|(root)|highest_owner", - "expand_flat|entities|(root)|immediate_owner", - "expand_flat|entities|(root)|mailing_address", - "expand_flat|entities|(root)|naics_codes", - "expand_flat|entities|(root)|physical_address", - "expand_flat|entities|(root)|relationships", - "expand_flat|entities|(root)|sba_business_types", - "expand_flat|grants|(root)|funding_details", - "expand_flat|grants|(root)|grantor_contact", - "expand_flat|grants|(root)|important_dates", - "expand_flat|idvs|(root)|idv_type", - "expand_flat|idvs|(root)|multiple_or_single_award_idv", - "expand_flat|idvs|(root)|type_of_idc", - "expand_flat|itdashboard|(root)|details", - "expand_flat|itdashboard|(root)|funding", - "expand_flat|notices|(root)|opportunity", - "expand_flat|notices|(root)|set_aside", - "expand_flat|offices|(root)|agency", - "expand_flat|opportunities|(root)|attachments", - "expand_flat|opportunities|(root)|meta", - "expand_flat|opportunities|(root)|notice_history", - "expand_flat|opportunities|(root)|place_of_performance", - "expand_flat|opportunities|(root)|set_aside", - "expand_flat|vehicles|awardees.orders|commercial_item_acquisition_procedures", - "expand_flat|vehicles|awardees.orders|consolidated_contract", - "expand_flat|vehicles|awardees.orders|contingency_humanitarian_or_peacekeeping_operation", - "expand_flat|vehicles|awardees.orders|contract_bundling", - "expand_flat|vehicles|awardees.orders|cost_accounting_standards_clause", - "expand_flat|vehicles|awardees.orders|cost_or_pricing_data", - "expand_flat|vehicles|awardees.orders|domestic_or_foreign_entity", - "expand_flat|vehicles|awardees.orders|epa_designated_product", - "expand_flat|vehicles|awardees.orders|evaluated_preference", - "expand_flat|vehicles|awardees.orders|fair_opportunity_limited_sources", - "expand_flat|vehicles|awardees.orders|fed_biz_opps", - "expand_flat|vehicles|awardees.orders|foreign_funding", - "expand_flat|vehicles|awardees.orders|information_technology_commercial_item_category", - "expand_flat|vehicles|awardees.orders|inherently_governmental_functions", - "expand_flat|vehicles|awardees.orders|performance_based_service_acquisition", - "expand_flat|vehicles|awardees.orders|place_of_manufacture", - "expand_flat|vehicles|awardees.orders|recovered_materials_sustainability", - "expand_flat|vehicles|awardees.orders|research", - "expand_flat|vehicles|awardees.orders|sam_exception", - "expand_flat|vehicles|awardees.orders|set_aside", - "expand_flat|vehicles|awardees.orders|subcontracting_plan", - "expand_flat|vehicles|awardees.orders|tradeoff_process", - "expand_flat|vehicles|awardees.orders|transactions", - "expand_flat|vehicles|awardees.orders|undefinitized_action", - "expand_flat|vehicles|awardees|idv_type", - "expand_flat|vehicles|awardees|multiple_or_single_award_idv", - "expand_flat|vehicles|awardees|type_of_idc", - "expand_flat|vehicles|opportunity|attachments", - "expand_flat|vehicles|opportunity|meta", - "expand_flat|vehicles|opportunity|notice_history", - "expand_flat|vehicles|opportunity|place_of_performance", - "expand_flat|vehicles|opportunity|set_aside", - "missing_expand|contracts|(root)|award_type", - "missing_expand|contracts|(root)|officers", - "missing_expand|contracts|(root)|period_of_performance", - "missing_expand|contracts|(root)|vehicle", - "missing_expand|entities|(root)|country_of_incorporation", - "missing_expand|entities|(root)|entity_structure", - "missing_expand|entities|(root)|entity_type", - "missing_expand|entities|(root)|organization_structure", - "missing_expand|entities|(root)|past_performance", - "missing_expand|entities|(root)|profit_structure", - "missing_expand|entities|(root)|purpose_of_registration", - "missing_expand|entities|(root)|state_of_incorporation", - "missing_expand|forecasts|(root)|display", - "missing_expand|forecasts|(root)|organization", - "missing_expand|forecasts|(root)|raw_data", - "missing_expand|grants|(root)|additional_info", - "missing_expand|grants|(root)|organization", - "missing_expand|idvs|(root)|gsa_elibrary", - "missing_expand|notices|(root)|address", - "missing_expand|notices|(root)|archive", - "missing_expand|notices|(root)|attachments", - "missing_expand|notices|(root)|meta", - "missing_expand|notices|(root)|office", - "missing_expand|notices|(root)|place_of_performance", - "missing_expand|notices|(root)|primary_contact", - "missing_expand|notices|(root)|secondary_contact", - "missing_expand|offices|(root)|department", - "missing_expand|opportunities|(root)|agency", - "missing_expand|opportunities|(root)|department", - "missing_expand|opportunities|(root)|latest_notice", - "missing_expand|opportunities|(root)|secondary_contact", - "missing_expand|organizations|(root)|agency", - "missing_expand|organizations|(root)|ancestors", - "missing_expand|organizations|(root)|budget_appropriation", - "missing_expand|organizations|(root)|budget_spending", - "missing_expand|organizations|(root)|children", - "missing_expand|organizations|(root)|department", - "missing_expand|organizations|(root)|parent", - "missing_expand|otas|(root)|award_type", - "missing_expand|otas|(root)|awarding_office", - "missing_expand|otas|(root)|extent_competed", - "missing_expand|otas|(root)|funding_office", - "missing_expand|otas|(root)|parent_award", - "missing_expand|otas|(root)|period_of_performance", - "missing_expand|otas|(root)|place_of_performance", - "missing_expand|otas|(root)|psc", - "missing_expand|otas|(root)|transactions", - "missing_expand|otas|(root)|type_of_ot_agreement", - "missing_expand|otidvs|(root)|awarding_office", - "missing_expand|otidvs|(root)|extent_competed", - "missing_expand|otidvs|(root)|funding_office", - "missing_expand|otidvs|(root)|period_of_performance", - "missing_expand|otidvs|(root)|place_of_performance", - "missing_expand|otidvs|(root)|psc", - "missing_expand|otidvs|(root)|transactions", - "missing_expand|otidvs|(root)|type_of_ot_agreement", - "missing_expand|protests|(root)|decisions", - "missing_expand|protests|(root)|resolved_agency", - "missing_expand|protests|(root)|resolved_protester", - "missing_expand|protests|dockets|organization", - "missing_expand|vehicles|awardees.orders|award_type", - "missing_expand|vehicles|awardees.orders|officers", - "missing_expand|vehicles|awardees.orders|period_of_performance", - "missing_expand|vehicles|awardees.orders|vehicle", - "missing_expand|vehicles|awardees|gsa_elibrary", - "missing_expand|vehicles|opportunity|agency", - "missing_expand|vehicles|opportunity|department", - "missing_expand|vehicles|opportunity|latest_notice", - "missing_expand|vehicles|opportunity|secondary_contact", - "missing_field|contracts|(root)|award_type", - "missing_field|contracts|awarding_office|agency_code", - "missing_field|contracts|awarding_office|agency_name", - "missing_field|contracts|awarding_office|department_code", - "missing_field|contracts|awarding_office|department_name", - "missing_field|contracts|awarding_office|office_code", - "missing_field|contracts|awarding_office|office_name", - "missing_field|contracts|awarding_office|organization_id", - "missing_field|contracts|funding_office|agency_code", - "missing_field|contracts|funding_office|agency_name", - "missing_field|contracts|funding_office|department_code", - "missing_field|contracts|funding_office|department_name", - "missing_field|contracts|funding_office|office_code", - "missing_field|contracts|funding_office|office_name", - "missing_field|contracts|funding_office|organization_id", - "missing_field|departments|(root)|cgac", - "missing_field|departments|(root)|congressional_justification", - "missing_field|departments|(root)|description", - "missing_field|departments|(root)|website", - "missing_field|entities|(root)|additional_website", - "missing_field|entities|(root)|capabilities_link", - "missing_field|entities|(root)|county", - "missing_field|entities|(root)|current_principals", - "missing_field|entities|(root)|display_name", - "missing_field|entities|(root)|g2x_about", - "missing_field|entities|(root)|g2x_ai_summary", - "missing_field|entities|(root)|g2x_employee_count", - "missing_field|entities|(root)|naics_small_codes", - "missing_field|entities|(root)|non_fed_govt_certifications", - "missing_field|entities|(root)|past_performance", - "missing_field|entities|(root)|special_equip_material", - "missing_field|entities|(root)|uuid", - "missing_field|forecasts|(root)|created", - "missing_field|forecasts|(root)|modified", - "missing_field|forecasts|(root)|organization_id", - "missing_field|forecasts|(root)|raw_data", - "missing_field|grants|(root)|forecast", - "missing_field|grants|(root)|opportunity_history", - "missing_field|grants|(root)|organization_id", - "missing_field|grants|(root)|synopsis", - "missing_field|gsa_elibrary_contracts|(root)|uei", - "missing_field|idvs|(root)|commercial_item_acquisition_procedures", - "missing_field|idvs|(root)|consolidated_contract", - "missing_field|idvs|(root)|contingency_humanitarian_or_peacekeeping_operation", - "missing_field|idvs|(root)|contract_bundling", - "missing_field|idvs|(root)|contract_financing", - "missing_field|idvs|(root)|cost_accounting_standards_clause", - "missing_field|idvs|(root)|cost_or_pricing_data", - "missing_field|idvs|(root)|dod_acquisition_program", - "missing_field|idvs|(root)|dod_transaction_number", - "missing_field|idvs|(root)|domestic_or_foreign_entity", - "missing_field|idvs|(root)|email_address", - "missing_field|idvs|(root)|epa_designated_product", - "missing_field|idvs|(root)|evaluated_preference", - "missing_field|idvs|(root)|fair_opportunity_limited_sources", - "missing_field|idvs|(root)|fed_biz_opps", - "missing_field|idvs|(root)|fee_range_lower_value", - "missing_field|idvs|(root)|fee_range_upper_value", - "missing_field|idvs|(root)|fixed_fee_value", - "missing_field|idvs|(root)|foreign_funding", - "missing_field|idvs|(root)|government_furnished_property", - "missing_field|idvs|(root)|idv_website", - "missing_field|idvs|(root)|inherently_governmental_functions", - "missing_field|idvs|(root)|local_area_set_aside", - "missing_field|idvs|(root)|major_program", - "missing_field|idvs|(root)|number_of_actions", - "missing_field|idvs|(root)|number_of_offers_source", - "missing_field|idvs|(root)|ordering_procedure", - "missing_field|idvs|(root)|performance_based_service_acquisition", - "missing_field|idvs|(root)|program_acronym", - "missing_field|idvs|(root)|recovered_materials_sustainability", - "missing_field|idvs|(root)|research", - "missing_field|idvs|(root)|sam_exception", - "missing_field|idvs|(root)|simplified_procedures_for_certain_commercial_items", - "missing_field|idvs|(root)|small_business_competitiveness_demonstration_program", - "missing_field|idvs|(root)|solicitation_identifier", - "missing_field|idvs|(root)|subcontracting_plan", - "missing_field|idvs|(root)|total_estimated_order_value", - "missing_field|idvs|(root)|tradeoff_process", - "missing_field|idvs|(root)|type_of_fee_for_use_of_service", - "missing_field|idvs|(root)|undefinitized_action", - "missing_field|idvs|(root)|vehicle_uuid", - "missing_field|idvs|(root)|who_can_use", - "missing_field|idvs|awarding_office|organization_id", - "missing_field|idvs|funding_office|organization_id", - "missing_field|itdashboard|(root)|organization_id", - "missing_field|notices|(root)|address", - "missing_field|notices|(root)|archive", - "missing_field|notices|(root)|attachments", - "missing_field|notices|(root)|meta", - "missing_field|notices|(root)|office", - "missing_field|notices|(root)|opportunity_id", - "missing_field|notices|(root)|place_of_performance", - "missing_field|offices|(root)|agency_code", - "missing_field|offices|(root)|agency_name", - "missing_field|offices|(root)|department_code", - "missing_field|offices|(root)|department_name", - "missing_field|offices|(root)|office_code", - "missing_field|offices|(root)|office_name", - "missing_field|opportunities|(root)|agency", - "missing_field|opportunities|(root)|agency_id", - "missing_field|opportunities|(root)|archive_date", - "missing_field|opportunities|(root)|department", - "missing_field|opportunities|(root)|department_id", - "missing_field|opportunities|(root)|latest_notice", - "missing_field|opportunities|(root)|latest_notice_id", - "missing_field|opportunities|(root)|office_id", - "missing_field|opportunities|(root)|secondary_contact", - "missing_field|opportunities|(root)|snippet", - "missing_field|opportunities|office|agency_code", - "missing_field|opportunities|office|agency_name", - "missing_field|opportunities|office|department_code", - "missing_field|opportunities|office|department_name", - "missing_field|opportunities|office|office_code", - "missing_field|opportunities|office|office_name", - "missing_field|opportunities|office|organization_id", - "missing_field|organizations|(root)|aac_code", - "missing_field|organizations|(root)|canonical_code", - "missing_field|organizations|(root)|cgac", - "missing_field|organizations|(root)|code", - "missing_field|organizations|(root)|description", - "missing_field|organizations|(root)|end_date", - "missing_field|organizations|(root)|fpds_code", - "missing_field|organizations|(root)|fpds_org_id", - "missing_field|organizations|(root)|full_parent_path_name", - "missing_field|organizations|(root)|is_active", - "missing_field|organizations|(root)|l1_fh_key", - "missing_field|organizations|(root)|l2_fh_key", - "missing_field|organizations|(root)|l3_fh_key", - "missing_field|organizations|(root)|l4_fh_key", - "missing_field|organizations|(root)|l5_fh_key", - "missing_field|organizations|(root)|l6_fh_key", - "missing_field|organizations|(root)|l7_fh_key", - "missing_field|organizations|(root)|l8_fh_key", - "missing_field|organizations|(root)|logo", - "missing_field|organizations|(root)|mod_status", - "missing_field|organizations|(root)|obligation_rank", - "missing_field|organizations|(root)|obligations", - "missing_field|organizations|(root)|parent_fh_key", - "missing_field|organizations|(root)|start_date", - "missing_field|organizations|(root)|summary", - "missing_field|organizations|(root)|total_obligations", - "missing_field|organizations|(root)|tree_obligations", - "missing_field|otas|(root)|award_type", - "missing_field|otas|(root)|base_and_exercised_options_value", - "missing_field|otas|(root)|consortia", - "missing_field|otas|(root)|consortia_uei", - "missing_field|otas|(root)|dod_acquisition_program", - "missing_field|otas|(root)|extent_competed", - "missing_field|otas|(root)|fiscal_year", - "missing_field|otas|(root)|non_governmental_dollars", - "missing_field|otas|(root)|non_traditional_government_contractor_participation", - "missing_field|otas|(root)|parent_award_modification_number", - "missing_field|otas|(root)|psc_code", - "missing_field|otas|(root)|transactions", - "missing_field|otas|(root)|type_of_ot_agreement", - "missing_field|otidvs|(root)|base_and_exercised_options_value", - "missing_field|otidvs|(root)|consortia", - "missing_field|otidvs|(root)|consortia_uei", - "missing_field|otidvs|(root)|dod_acquisition_program", - "missing_field|otidvs|(root)|extent_competed", - "missing_field|otidvs|(root)|fiscal_year", - "missing_field|otidvs|(root)|non_governmental_dollars", - "missing_field|otidvs|(root)|non_traditional_government_contractor_participation", - "missing_field|otidvs|(root)|psc_code", - "missing_field|otidvs|(root)|transactions", - "missing_field|otidvs|(root)|type_of_ot_agreement", - "missing_field|protests|(root)|challenged_party", - "missing_field|protests|(root)|decision_text", - "missing_field|protests|(root)|decisions", - "missing_field|protests|(root)|judge", - "missing_field|protests|(root)|naics_code", - "missing_field|protests|(root)|outcome_reason", - "missing_field|protests|(root)|resolved_agency", - "missing_field|protests|(root)|resolved_protester", - "missing_field|protests|(root)|size_standard", - "missing_field|protests|dockets|challenged_party", - "missing_field|protests|dockets|decision_text", - "missing_field|protests|dockets|judge", - "missing_field|protests|dockets|naics_code", - "missing_field|protests|dockets|outcome_reason", - "missing_field|protests|dockets|size_standard", - "missing_field|vehicles|(root)|name", - "missing_field|vehicles|awardees.awarding_office|organization_id", - "missing_field|vehicles|awardees.funding_office|organization_id", - "missing_field|vehicles|awardees.orders.awarding_office|agency_code", - "missing_field|vehicles|awardees.orders.awarding_office|agency_name", - "missing_field|vehicles|awardees.orders.awarding_office|department_code", - "missing_field|vehicles|awardees.orders.awarding_office|department_name", - "missing_field|vehicles|awardees.orders.awarding_office|office_code", - "missing_field|vehicles|awardees.orders.awarding_office|office_name", - "missing_field|vehicles|awardees.orders.awarding_office|organization_id", - "missing_field|vehicles|awardees.orders.funding_office|agency_code", - "missing_field|vehicles|awardees.orders.funding_office|agency_name", - "missing_field|vehicles|awardees.orders.funding_office|department_code", - "missing_field|vehicles|awardees.orders.funding_office|department_name", - "missing_field|vehicles|awardees.orders.funding_office|office_code", - "missing_field|vehicles|awardees.orders.funding_office|office_name", - "missing_field|vehicles|awardees.orders.funding_office|organization_id", - "missing_field|vehicles|awardees.orders|award_type", - "missing_field|vehicles|awardees|commercial_item_acquisition_procedures", - "missing_field|vehicles|awardees|consolidated_contract", - "missing_field|vehicles|awardees|contingency_humanitarian_or_peacekeeping_operation", - "missing_field|vehicles|awardees|contract_bundling", - "missing_field|vehicles|awardees|contract_financing", - "missing_field|vehicles|awardees|cost_accounting_standards_clause", - "missing_field|vehicles|awardees|cost_or_pricing_data", - "missing_field|vehicles|awardees|dod_acquisition_program", - "missing_field|vehicles|awardees|dod_transaction_number", - "missing_field|vehicles|awardees|domestic_or_foreign_entity", - "missing_field|vehicles|awardees|email_address", - "missing_field|vehicles|awardees|epa_designated_product", - "missing_field|vehicles|awardees|evaluated_preference", - "missing_field|vehicles|awardees|fair_opportunity_limited_sources", - "missing_field|vehicles|awardees|fed_biz_opps", - "missing_field|vehicles|awardees|fee_range_lower_value", - "missing_field|vehicles|awardees|fee_range_upper_value", - "missing_field|vehicles|awardees|fixed_fee_value", - "missing_field|vehicles|awardees|foreign_funding", - "missing_field|vehicles|awardees|government_furnished_property", - "missing_field|vehicles|awardees|idv_website", - "missing_field|vehicles|awardees|inherently_governmental_functions", - "missing_field|vehicles|awardees|local_area_set_aside", - "missing_field|vehicles|awardees|major_program", - "missing_field|vehicles|awardees|number_of_actions", - "missing_field|vehicles|awardees|number_of_offers_source", - "missing_field|vehicles|awardees|ordering_procedure", - "missing_field|vehicles|awardees|performance_based_service_acquisition", - "missing_field|vehicles|awardees|program_acronym", - "missing_field|vehicles|awardees|recovered_materials_sustainability", - "missing_field|vehicles|awardees|research", - "missing_field|vehicles|awardees|sam_exception", - "missing_field|vehicles|awardees|simplified_procedures_for_certain_commercial_items", - "missing_field|vehicles|awardees|small_business_competitiveness_demonstration_program", - "missing_field|vehicles|awardees|solicitation_identifier", - "missing_field|vehicles|awardees|subcontracting_plan", - "missing_field|vehicles|awardees|total_estimated_order_value", - "missing_field|vehicles|awardees|tradeoff_process", - "missing_field|vehicles|awardees|type_of_fee_for_use_of_service", - "missing_field|vehicles|awardees|undefinitized_action", - "missing_field|vehicles|awardees|vehicle_uuid", - "missing_field|vehicles|awardees|who_can_use", - "missing_field|vehicles|opportunity.office|agency_code", - "missing_field|vehicles|opportunity.office|agency_name", - "missing_field|vehicles|opportunity.office|department_code", - "missing_field|vehicles|opportunity.office|department_name", - "missing_field|vehicles|opportunity.office|office_code", - "missing_field|vehicles|opportunity.office|office_name", - "missing_field|vehicles|opportunity.office|organization_id", - "missing_field|vehicles|opportunity|agency", - "missing_field|vehicles|opportunity|agency_id", - "missing_field|vehicles|opportunity|archive_date", - "missing_field|vehicles|opportunity|department", - "missing_field|vehicles|opportunity|department_id", - "missing_field|vehicles|opportunity|latest_notice", - "missing_field|vehicles|opportunity|latest_notice_id", - "missing_field|vehicles|opportunity|office_id", - "missing_field|vehicles|opportunity|secondary_contact", - "missing_field|vehicles|opportunity|snippet", - "unmapped_resource|assistance_listings|(root)|AssistanceListing", - "unmapped_resource|budget/accounts|(root)|BudgetAccount", - "unmapped_resource|business_types|(root)|BusinessType", - "unmapped_resource|mas_sins|(root)|MasSin", - "unmapped_resource|naics|(root)|Naics", - "unmapped_resource|psc|(root)|PSC" - ] + "count": 0, + "known_gaps": [] } diff --git a/package.json b/package.json index 161a4c2..27b8c90 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "coverage": "vitest run --coverage", "check-conformance": "tsx scripts/check-filter-shape-conformance.ts", "check-shape-coverage": "tsx scripts/check-shape-coverage.ts", + "generate-shape-overlay": "tsx scripts/generate-shape-overlay.ts", "prepare": "npm run build", "prepublishOnly": "npm run lint && npm run test && npm run build" }, diff --git a/scripts/generate-shape-overlay.ts b/scripts/generate-shape-overlay.ts new file mode 100644 index 0000000..3fdec5b --- /dev/null +++ b/scripts/generate-shape-overlay.ts @@ -0,0 +1,329 @@ +/** + * Generate src/shapes/generatedOverlay.ts — the reverse shape-coverage overlay. + * + * Port of tango-python's scripts/generate_shape_overlay.py. + * + * check-shape-coverage.ts detects fields/expands Tango's shape trees expose that the hand-curated src/shapes/explicitSchemas.ts does not capture. + * This generates the schema additions that close every such gap, and SchemaRegistry merges the result over the base so the SDK's typed shape API accepts everything the API returns. + * + * Inputs (both vendored — regenerates with no network/API key): + * contracts/filter_shape_contract.json Tango's shape trees (names + nesting). + * contracts/observed_shape_types.json per-path types/list-ness sampled from the live API (vendored from tango-python, which probes production). + * + * Reads the curated base directly from EXPLICIT_SCHEMAS — never through SchemaRegistry, which auto-merges this overlay (that would feed the generator its own output). + * + * Type resolution per field: live-API observation -> structural equivalence (vehicles.awardees mirror idvs, .orders mirror contracts) -> name heuristic. + * {code,description} expands point at the shared "CodeDescription" schema; freeform ("*") expands stay plain dicts. + * Identical nested shapes are interned to one schema. + * + * Output is deterministic: stable sort order everywhere, no timestamps. + * + * Run: npx tsx scripts/generate-shape-overlay.ts # writes the module + * npx tsx scripts/generate-shape-overlay.ts --report # print gaps, write nothing + */ + +import * as fs from "node:fs"; +import * as path from "node:path"; +import { fileURLToPath } from "node:url"; + +import { EXPLICIT_SCHEMAS } from "../src/shapes/explicitSchemas.js"; +import type { FieldSchemaMap } from "../src/shapes/schemaTypes.js"; +import { RESOURCE_TO_MODEL } from "./check-shape-coverage.js"; +import type { Contract, ShapeNode } from "./check-shape-coverage.js"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const REPO_ROOT = path.resolve(__dirname, ".."); +const CONTRACT_PATH = path.join(REPO_ROOT, "contracts", "filter_shape_contract.json"); +const OBSERVED_PATH = path.join(REPO_ROOT, "contracts", "observed_shape_types.json"); +const OUT_PATH = path.join(REPO_ROOT, "src", "shapes", "generatedOverlay.ts"); + +interface ObservedPath { + kind?: string; + type?: string; + is_list?: boolean; + is_optional?: boolean; +} + +type ObservedFile = Record }>; + +const contract = JSON.parse(fs.readFileSync(CONTRACT_PATH, "utf8")) as Contract; +const observed = JSON.parse(fs.readFileSync(OBSERVED_PATH, "utf8")) as ObservedFile; + +const DATE_NAMES = new Set(["start_date", "end_date", "award_date"]); + +interface Entry { + type: string; + isList: boolean; + nested: string | null; +} + +function baseSchema(modelName: string | undefined | null): FieldSchemaMap | null { + if (!modelName) return null; + return EXPLICIT_SCHEMAS[modelName] ?? null; +} + +function heuristic(name: string): [string, boolean] { + const n = name.toLowerCase(); + if (n.endsWith("_date") || DATE_NAMES.has(n)) return ["date", false]; + if (n.endsWith("_datetime") || n.endsWith("_at") || n.endsWith("_timestamp") || n === "created" || n === "modified") { + return ["datetime", false]; + } + if ( + n.endsWith("_amount") || + n.endsWith("_value") || + n.endsWith("_price") || + n.endsWith("_obligations") || + n.endsWith("_ceiling") || + n.endsWith("_cost") || + n.endsWith("_fee") + ) { + return ["Decimal", false]; + } + if (n.startsWith("is_") || n.startsWith("has_")) return ["bool", false]; + if (n.endsWith("_count") || n.endsWith("_rank") || n.startsWith("number_of_")) return ["int", false]; + return ["str", false]; +} + +function observedPaths(res: string): Record { + return observed[res]?.paths ?? {}; +} + +function fullPath(nodePath: string, name: string): string { + return nodePath && nodePath !== "(root)" ? `${nodePath}.${name}` : name; +} + +// Vehicles' awardees mirror idvs and awardees.orders mirror contracts, so their +// observations stand in where vehicles itself was never sampled at that depth. +function equivLookup(res: string, nodePath: string, name: string): ObservedPath | undefined { + const full = fullPath(nodePath, name); + if (res === "vehicles") { + if (full.startsWith("awardees.orders.")) { + return observedPaths("contracts")[full.slice("awardees.orders.".length)]; + } + if (full.startsWith("awardees.")) { + return observedPaths("idvs")[full.slice("awardees.".length)]; + } + } + return undefined; +} + +function resolveScalar(res: string, nodePath: string, name: string): [string, boolean] { + const full = fullPath(nodePath, name); + const d = observedPaths(res)[full]; + if (d && d.kind === "scalar" && d.type) return [d.type, Boolean(d.is_list)]; + const e = equivLookup(res, nodePath, name); + if (e && e.kind === "scalar" && e.type) return [e.type, Boolean(e.is_list)]; + return heuristic(name); +} + +function isCodeObject(node: ShapeNode, res: string, nodePath: string, name: string): boolean { + const fields = new Set(node.fields ?? []); + const expands = node.expands ?? {}; + if (fields.size === 2 && fields.has("code") && fields.has("description") && Object.keys(expands).length === 0) { + return true; + } + const d = observedPaths(res)[fullPath(nodePath, name)] ?? equivLookup(res, nodePath, name); + return Boolean(d && d.kind === "code_object"); +} + +function nodeIsList(res: string, nodePath: string, name: string): boolean { + const d = observedPaths(res)[fullPath(nodePath, name)] ?? equivLookup(res, nodePath, name); + return Boolean(d && d.is_list); +} + +function isWildcard(node: ShapeNode): boolean { + return (node.fields ?? []).includes("*"); +} + +const nestedSchemas: Record> = {}; +const bySignature = new Map(); + +function sig(schema: Record): string { + const rows = Object.entries(schema) + .map(([k, v]) => [k, v.type, v.isList, v.nested ?? null]) + .sort((a, b) => String(a[0]).localeCompare(String(b[0]))); + return JSON.stringify(rows); +} + +function titleName(name: string): string { + return name + .split("_") + .map((w) => (w ? w.charAt(0).toUpperCase() + w.slice(1).toLowerCase() : w)) + .join(""); +} + +function internNested(preferred: string, schema: Record): string { + const s = sig(schema); + const existing = bySignature.get(s); + if (existing) return existing; + let name = preferred; + let i = 2; + // Also dodge curated model names: a generated nested named e.g. "Vehicle" would + // merge its summary fields over the real Vehicle model schema in the registry. + while (name in nestedSchemas || name in EXPLICIT_SCHEMAS) { + name = `${preferred}${i}`; + i += 1; + } + nestedSchemas[name] = schema; + bySignature.set(s, name); + return name; +} + +function entry(type: string, isList: boolean, nested: string | null = null): Entry { + return { type, isList, nested }; +} + +function buildNested(res: string, nodePath: string, name: string, node: ShapeNode): string { + const npath = fullPath(nodePath, name); + const schema: Record = {}; + for (const f of node.fields ?? []) { + if (f === "*") continue; + const [t, lst] = resolveScalar(res, npath, f); + schema[f] = entry(t, lst); + } + for (const [cname, cnode] of Object.entries(node.expands ?? {})) { + schema[cname] = expandEntry(res, npath, cname, cnode); + } + return internNested(titleName(name), schema); +} + +function expandEntry(res: string, nodePath: string, ename: string, enode: ShapeNode): Entry { + if (isWildcard(enode)) return entry("dict", nodeIsList(res, nodePath, ename)); + if (isCodeObject(enode, res, nodePath, ename)) { + return entry("dict", nodeIsList(res, nodePath, ename), "CodeDescription"); + } + return entry("dict", nodeIsList(res, nodePath, ename), buildNested(res, nodePath, ename, enode)); +} + +const overlay: Record> = {}; +const reportRows: string[] = []; + +function walk(res: string, nodePath: string, node: ShapeNode, schema: FieldSchemaMap | null, container: string): void { + if (schema === null) return; + const fields = node.fields ?? []; + if (!fields.includes("*")) { + for (const f of fields) { + if (f === "*" || f in schema) continue; + const [t, lst] = resolveScalar(res, nodePath, f); + (overlay[container] ??= {})[f] = entry(t, lst); + reportRows.push(`${res}:${nodePath || "(root)"}.${f} -> ${t}${lst ? "[]" : ""}`); + } + } + for (const [ename, enode] of Object.entries(node.expands ?? {})) { + const fs_ = schema[ename]; + const childPath = fullPath(nodePath, ename); + const nestedName = fs_?.nestedModel ?? null; + const childSchema = nestedName ? baseSchema(nestedName) : null; + if (fs_ === undefined || childSchema === null) { + if (isWildcard(enode) && fs_ !== undefined) continue; + (overlay[container] ??= {})[ename] = expandEntry(res, nodePath, ename, enode); + reportRows.push(`${res}:${nodePath || "(root)"}.${ename} -> expand`); + } else { + walk(res, childPath, enode, childSchema, nestedName!); + } + } +} + +for (const [rkey, r] of Object.entries(contract.resources ?? {})) { + const shape = r.runtime?.shape; + if (!shape) continue; + const modelName = RESOURCE_TO_MODEL[rkey]; + const schema = baseSchema(modelName); + if (schema === null) { + // No curated base at all — mint the whole model schema into the overlay. + const s: Record = {}; + for (const f of shape.fields ?? []) { + if (f === "*") continue; + const [t, lst] = resolveScalar(rkey, "", f); + s[f] = entry(t, lst); + } + for (const [cname, cnode] of Object.entries(shape.expands ?? {})) { + s[cname] = expandEntry(rkey, "", cname, cnode); + } + if (modelName) { + overlay[modelName] = { ...(overlay[modelName] ?? {}), ...s }; + reportRows.push(`${rkey}:(root) -> full model schema (${Object.keys(s).length} fields)`); + } + continue; + } + walk(rkey, "", shape, schema, modelName); +} + +// --------------------------------------------------------------------------- +// Emit +// --------------------------------------------------------------------------- + +function emitKey(name: string): string { + return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name); +} + +function renderField(name: string, e: Entry): string { + const args = [JSON.stringify(name), JSON.stringify(e.type)]; + if (e.isList || e.nested) args.push(String(e.isList)); + if (e.nested) args.push(JSON.stringify(e.nested)); + return `${emitKey(name)}: f(${args.join(", ")}),`; +} + +function renderSchemaMap(schema: Record, indent: string): string[] { + return Object.keys(schema) + .sort() + .map((n) => `${indent}${renderField(n, schema[n])}`); +} + +function emit(): string { + const lines: string[] = [ + "// GENERATED by scripts/generate-shape-overlay.ts — do not edit by hand.", + "//", + "// Reverse shape-coverage overlay: the fields and expands Tango's shape trees", + "// expose that the hand-curated explicitSchemas.ts did not capture. SchemaRegistry", + "// merges this over the base schemas so the SDK's typed shape API accepts everything", + "// the API returns. Regenerate after refreshing the vendored contract or observations.", + "", + 'import type { FieldSchema, FieldSchemaMap } from "./schemaTypes.js";', + "", + "function f(name: string, type: string, isList = false, nestedModel: string | null = null): FieldSchema {", + " return { name, type, isOptional: true, isList, nestedModel };", + "}", + "", + "// Nested schemas referenced by overlay entries, registered as standalone models.", + "export const GENERATED_NESTED: Record = {", + ]; + for (const ref of Object.keys(nestedSchemas).sort()) { + lines.push(` ${emitKey(ref)}: {`); + lines.push(...renderSchemaMap(nestedSchemas[ref], " ")); + lines.push(" },"); + } + lines.push("};", ""); + lines.push("// Container model-name -> additional field schemas (merged over the base)."); + lines.push("export const GENERATED_OVERLAY: Record = {"); + for (const model of Object.keys(overlay).sort()) { + lines.push(` ${emitKey(model)}: {`); + lines.push(...renderSchemaMap(overlay[model], " ")); + lines.push(" },"); + } + lines.push("};", ""); + return lines.join("\n"); +} + +function main(): number { + const report = process.argv.includes("--report"); + const nFields = Object.values(overlay).reduce((acc, v) => acc + Object.keys(v).length, 0); + const nNested = Object.keys(nestedSchemas).length; + + if (report) { + for (const row of [...reportRows].sort()) process.stdout.write(`${row}\n`); + process.stdout.write( + `\n${nFields} additions across ${Object.keys(overlay).length} containers, ${nNested} nested schemas.\n`, + ); + return 0; + } + + fs.writeFileSync(OUT_PATH, emit(), "utf8"); + process.stdout.write( + `wrote ${path.relative(REPO_ROOT, OUT_PATH)}: ${nFields} fields across ${Object.keys(overlay).length} containers, ${nNested} nested schemas.\n`, + ); + return 0; +} + +process.exit(main()); diff --git a/src/client.ts b/src/client.ts index d4d5cb1..c390d19 100644 --- a/src/client.ts +++ b/src/client.ts @@ -64,6 +64,39 @@ function extractCursorFromUrl(url: string | null): string | null { } } +// `meta` is server-controlled, so every parser below tolerates a shape change +// rather than crashing a caller's pagination loop. +function parseAgencyWarnings(meta: AnyRecord | null): string[] { + const warnings = meta?.warnings; + return Array.isArray(warnings) ? warnings.map(String) : []; +} + +function parseUnresolvedAgencyTokens(meta: AnyRecord | null): Record { + const resolved = meta?.resolved_filters; + if (!isRecord(resolved)) return {}; + const dropped: Record = {}; + for (const [filterName, entries] of Object.entries(resolved)) { + if (!Array.isArray(entries)) continue; + const tokens = entries + .filter((e): e is AnyRecord => isRecord(e) && e.resolved === null && e.token !== null && e.token !== undefined) + .map((e) => String(e.token)); + if (tokens.length) dropped[filterName] = tokens; + } + return dropped; +} + +function parseResolvedAgencies(meta: AnyRecord | null): Record>> { + const resolved = meta?.resolved_filters; + if (!isRecord(resolved)) return {}; + const matched: Record>> = {}; + for (const [filterName, entries] of Object.entries(resolved)) { + if (!Array.isArray(entries)) continue; + const orgs = entries.filter((e): e is AnyRecord => isRecord(e) && isRecord(e.resolved)).map((e) => e.resolved as AnyRecord); + if (orgs.length) matched[filterName] = orgs; + } + return matched; +} + function buildPaginatedResponse(raw: AnyRecord): PaginatedResponse { const results = Array.isArray(raw?.results) ? (raw.results as T[]) : []; const rawCount = raw?.count; @@ -72,10 +105,12 @@ function buildPaginatedResponse(raw: AnyRecord): PaginatedRespons const nextVal = raw?.next; const previousVal = raw?.previous; const pageMetadataVal = raw?.page_metadata; + const metaVal = raw?.meta; const next = typeof nextVal === "string" ? nextVal : null; const previous = typeof previousVal === "string" ? previousVal : null; const pageMetadata = isRecord(pageMetadataVal) ? pageMetadataVal : null; + const meta = isRecord(metaVal) ? metaVal : null; const cursor = extractCursorFromUrl(next); return { @@ -83,6 +118,10 @@ function buildPaginatedResponse(raw: AnyRecord): PaginatedRespons next, previous, pageMetadata, + meta, + agencyWarnings: parseAgencyWarnings(meta), + unresolvedAgencyTokens: parseUnresolvedAgencyTokens(meta), + resolvedAgencies: parseResolvedAgencies(meta), cursor, results, }; @@ -1706,7 +1745,7 @@ export class TangoClient { // Endpoints are commonly paginated like other Tango resources, but keep this resilient. if (Array.isArray(data)) { - return { count: data.length, next: null, previous: null, pageMetadata: null, cursor: null, results: data as WebhookEndpoint[] }; + return buildPaginatedResponse({ results: data }); } return buildPaginatedResponse(data); } diff --git a/src/errors.ts b/src/errors.ts index 01cbbe1..b77c5ad 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -33,6 +33,30 @@ export class TangoValidationError extends TangoAPIError { super(message, statusCode, responseData); this.name = "TangoValidationError"; } + + /** + * Structured validation issues from the API response. For shape errors the + * API returns entries like `{"path": "tradeoff_process", "reason": "unknown_field"}`. + * Empty array when the response carried no structured issues. + */ + get issues(): Array> { + const data = this.responseData; + if (!data || typeof data !== "object" || Array.isArray(data)) return []; + const val = (data as Record).issues; + if (!Array.isArray(val)) return []; + return val.filter((item): item is Record => Boolean(item) && typeof item === "object" && !Array.isArray(item)); + } + + /** + * The endpoint's valid field set, when the API includes one. + */ + get availableFields(): Record | null { + const data = this.responseData; + if (!data || typeof data !== "object" || Array.isArray(data)) return null; + const val = (data as Record).available_fields; + if (!val || typeof val !== "object" || Array.isArray(val)) return null; + return val as Record; + } } export class TangoRateLimitError extends TangoAPIError { diff --git a/src/shapes/generatedOverlay.ts b/src/shapes/generatedOverlay.ts new file mode 100644 index 0000000..3522a90 --- /dev/null +++ b/src/shapes/generatedOverlay.ts @@ -0,0 +1,897 @@ +// GENERATED by scripts/generate-shape-overlay.ts — do not edit by hand. +// +// Reverse shape-coverage overlay: the fields and expands Tango's shape trees +// expose that the hand-curated explicitSchemas.ts did not capture. SchemaRegistry +// merges this over the base schemas so the SDK's typed shape API accepts everything +// the API returns. Regenerate after refreshing the vendored contract or observations. + +import type { FieldSchema, FieldSchemaMap } from "./schemaTypes.js"; + +function f(name: string, type: string, isList = false, nestedModel: string | null = null): FieldSchema { + return { name, type, isOptional: true, isList, nestedModel }; +} + +// Nested schemas referenced by overlay entries, registered as standalone models. +export const GENERATED_NESTED: Record = { + AdditionalInfo: { + description: f("description", "str"), + link: f("link", "str"), + }, + Address: { + city: f("city", "str"), + country: f("country", "str"), + state: f("state", "str"), + zip: f("zip", "str"), + }, + Agency2: { + abbreviation: f("abbreviation", "str"), + code: f("code", "int"), + name: f("name", "str"), + }, + Agency3: { + abbreviation: f("abbreviation", "str"), + code: f("code", "str"), + name: f("name", "str"), + }, + Ancestors: { + fh_key: f("fh_key", "int"), + level: f("level", "int"), + name: f("name", "str"), + short_name: f("short_name", "str"), + }, + Appendix: { + agency_code: f("agency_code", "int"), + appendix_granule_id: f("appendix_granule_id", "str"), + appendix_pdf_url: f("appendix_pdf_url", "str"), + federal_account_symbol: f("federal_account_symbol", "str"), + fiscal_year: f("fiscal_year", "int"), + has_object_classification: f("has_object_classification", "bool"), + has_program_financing: f("has_program_financing", "bool"), + n_program_activities: f("n_program_activities", "int"), + narrative_length: f("narrative_length", "int"), + on_off_budget: f("on_off_budget", "int"), + request: f("request", "str"), + subfunction_code: f("subfunction_code", "int"), + }, + Archive: { + date: f("date", "date"), + type: f("type", "str"), + }, + Attachments: { + attachment_id: f("attachment_id", "str"), + extracted_text: f("extracted_text", "str"), + file_size: f("file_size", "int"), + mime_type: f("mime_type", "str"), + name: f("name", "str"), + posted_date: f("posted_date", "str"), + resource_id: f("resource_id", "str"), + type: f("type", "str"), + url: f("url", "str"), + }, + Attachments2: { + attachment_id: f("attachment_id", "str"), + extracted_text: f("extracted_text", "str"), + file_size: f("file_size", "int"), + mime_type: f("mime_type", "str"), + name: f("name", "str"), + posted_date: f("posted_date", "datetime"), + resource_id: f("resource_id", "str"), + type: f("type", "str"), + url: f("url", "str"), + }, + Attachments3: { + attachment_id: f("attachment_id", "str"), + extracted_text: f("extracted_text", "str"), + file_size: f("file_size", "str"), + mime_type: f("mime_type", "str"), + name: f("name", "str"), + posted_date: f("posted_date", "date"), + resource_id: f("resource_id", "str"), + type: f("type", "str"), + url: f("url", "str"), + }, + BudgetAppropriation: { + cgac: f("cgac", "int"), + fiscal_year: f("fiscal_year", "int"), + n_accounts: f("n_accounts", "int"), + scope: f("scope", "str"), + summary: f("summary", "str"), + top_accounts: f("top_accounts", "str"), + }, + BudgetSpending: { + fiscal_year: f("fiscal_year", "int"), + n_orgs_in_rollup: f("n_orgs_in_rollup", "int"), + organization_id: f("organization_id", "str"), + summary: f("summary", "str"), + top_accounts: f("top_accounts", "str"), + }, + Children: { + cgac: f("cgac", "int"), + code: f("code", "int"), + fh_key: f("fh_key", "int"), + is_active: f("is_active", "bool"), + key: f("key", "str"), + level: f("level", "int"), + name: f("name", "str"), + short_name: f("short_name", "str"), + type: f("type", "str"), + }, + Current: { + active: f("active", "bool"), + description: f("description", "str"), + end_date: f("end_date", "str"), + excludes: f("excludes", "str"), + includes: f("includes", "str"), + name: f("name", "str"), + start_date: f("start_date", "date"), + }, + Decisions: { + courtlistener_url: f("courtlistener_url", "str"), + decision_date: f("decision_date", "date"), + document_type: f("document_type", "str"), + document_url: f("document_url", "str"), + judges: f("judges", "str"), + outcome: f("outcome", "str"), + title: f("title", "str"), + }, + Department2: { + abbreviation: f("abbreviation", "str"), + cgac: f("cgac", "str"), + code: f("code", "int"), + congressional_justification: f("congressional_justification", "str"), + description: f("description", "str"), + name: f("name", "str"), + website: f("website", "str"), + }, + Department3: { + abbreviation: f("abbreviation", "str"), + cgac: f("cgac", "str"), + code: f("code", "str"), + congressional_justification: f("congressional_justification", "str"), + description: f("description", "str"), + name: f("name", "str"), + website: f("website", "str"), + }, + Details: { + business_case_url: f("business_case_url", "str"), + change_in_status: f("change_in_status", "str"), + current_uii: f("current_uii", "str"), + investment_description: f("investment_description", "str"), + it_infrastructure_and_management_type: f("it_infrastructure_and_management_type", "int"), + last_updated: f("last_updated", "datetime"), + mission_delivery_and_management_support_area: f("mission_delivery_and_management_support_area", "int"), + mission_support_investment_categories: f("mission_support_investment_categories", "str"), + national_security_system_identifier: f("national_security_system_identifier", "int"), + previous_uii: f("previous_uii", "str"), + public_urls: f("public_urls", "str"), + shared_services_category: f("shared_services_category", "str"), + shared_services_identifier: f("shared_services_identifier", "int"), + }, + Display: { + agency: f("agency", "str"), + anticipated_award_date: f("anticipated_award_date", "date"), + contract_vehicle: f("contract_vehicle", "str"), + description: f("description", "str"), + estimated_period: f("estimated_period", "str"), + fiscal_year: f("fiscal_year", "int"), + naics_code: f("naics_code", "int"), + place_of_performance: f("place_of_performance", "str"), + primary_contact: f("primary_contact", "str"), + set_aside: f("set_aside", "str"), + status: f("status", "str"), + title: f("title", "str"), + }, + FederalObligations: { + active: f("active", "str"), + total: f("total", "str"), + }, + Funding: { + fy2020_contribution: f("fy2020_contribution", "Decimal"), + fy2020_internal_funding: f("fy2020_internal_funding", "Decimal"), + fy2021_contribution: f("fy2021_contribution", "Decimal"), + fy2021_internal_funding: f("fy2021_internal_funding", "Decimal"), + fy2022_contribution: f("fy2022_contribution", "Decimal"), + fy2022_internal_funding: f("fy2022_internal_funding", "Decimal"), + fy2023_contribution: f("fy2023_contribution", "Decimal"), + fy2023_internal_funding: f("fy2023_internal_funding", "Decimal"), + fy2024_contribution: f("fy2024_contribution", "Decimal"), + fy2024_internal_funding: f("fy2024_internal_funding", "Decimal"), + fy2025_contribution: f("fy2025_contribution", "Decimal"), + fy2025_internal_funding: f("fy2025_internal_funding", "Decimal"), + }, + FundingDetails: { + award_ceiling: f("award_ceiling", "int"), + award_floor: f("award_floor", "int"), + estimated_total_funding: f("estimated_total_funding", "int"), + expected_number_of_awards: f("expected_number_of_awards", "int"), + }, + GrantorContact: { + email: f("email", "str"), + name: f("name", "str"), + phone: f("phone", "str"), + }, + GsaElibrary: { + contract_number: f("contract_number", "str"), + cooperative_purchasing: f("cooperative_purchasing", "bool"), + disaster_recovery_purchasing: f("disaster_recovery_purchasing", "bool"), + external_id: f("external_id", "str"), + extracted_text: f("extracted_text", "str"), + file_urls: f("file_urls", "str", true), + schedule: f("schedule", "str"), + sins: f("sins", "int", true), + source_data: f("source_data", "str"), + uei: f("uei", "str"), + }, + HighestOwner: { + cage_code: f("cage_code", "str"), + legal_business_name: f("legal_business_name", "str"), + uei: f("uei", "str"), + }, + Historical: { + active: f("active", "bool"), + description: f("description", "str"), + end_date: f("end_date", "date"), + excludes: f("excludes", "str"), + includes: f("includes", "str"), + name: f("name", "str"), + start_date: f("start_date", "date"), + }, + ImportantDates: { + estimated_application_response_date: f("estimated_application_response_date", "date"), + estimated_application_response_date_description: f("estimated_application_response_date_description", "str"), + estimated_project_start_date: f("estimated_project_start_date", "date"), + estimated_synopsis_post_date: f("estimated_synopsis_post_date", "date"), + posted_date: f("posted_date", "date"), + response_date: f("response_date", "date"), + response_date_description: f("response_date_description", "str"), + }, + LatestNotice: { + link: f("link", "str"), + notice_id: f("notice_id", "str"), + }, + MailingAddress: { + address_line1: f("address_line1", "str"), + address_line2: f("address_line2", "str"), + city: f("city", "str"), + country_code: f("country_code", "str"), + country_name: f("country_name", "str"), + county: f("county", "str"), + county_code: f("county_code", "str"), + fips_code: f("fips_code", "str"), + state_or_province_code: f("state_or_province_code", "int"), + zip_code: f("zip_code", "int"), + zip_code_plus4: f("zip_code_plus4", "str"), + }, + Meta: { + link: f("link", "str"), + notice_type: f("notice_type", "dict", false, "NoticeType"), + parent_notice_id: f("parent_notice_id", "str"), + related_notice_id: f("related_notice_id", "str"), + }, + Meta2: { + attachments_count: f("attachments_count", "int"), + notice_type: f("notice_type", "dict", false, "NoticeType"), + notices_count: f("notices_count", "int"), + }, + NaicsCodes: { + code: f("code", "int"), + sba_small_business: f("sba_small_business", "str"), + }, + Narratives: { + account_code: f("account_code", "int"), + account_heading: f("account_heading", "str"), + agency_code: f("agency_code", "int"), + agency_title: f("agency_title", "str"), + appropriations_length: f("appropriations_length", "int"), + appropriations_text: f("appropriations_text", "str"), + budget_year: f("budget_year", "int"), + bureau_title: f("bureau_title", "int"), + date_issued: f("date_issued", "date"), + federal_account_symbol: f("federal_account_symbol", "str"), + fiscal_year: f("fiscal_year", "int"), + fund_type: f("fund_type", "str"), + granule_id: f("granule_id", "str"), + granule_title: f("granule_title", "str"), + narrative_id: f("narrative_id", "str"), + narrative_length: f("narrative_length", "int"), + narrative_text: f("narrative_text", "str"), + notes: f("notes", "str", true), + on_off_budget: f("on_off_budget", "int"), + source_url: f("source_url", "str"), + subaccount_code: f("subaccount_code", "int"), + subfunction_code: f("subfunction_code", "int"), + }, + NoticeHistory: { + deleted: f("deleted", "bool"), + index: f("index", "int"), + latest: f("latest", "bool"), + notice_id: f("notice_id", "str"), + notice_type_code: f("notice_type_code", "str"), + parent_notice_id: f("parent_notice_id", "str"), + posted_date: f("posted_date", "datetime"), + related_notice_id: f("related_notice_id", "str"), + solicitation_number: f("solicitation_number", "str"), + title: f("title", "str"), + }, + NoticeHistory2: { + deleted: f("deleted", "str"), + index: f("index", "str"), + latest: f("latest", "str"), + notice_id: f("notice_id", "str"), + notice_type_code: f("notice_type_code", "str"), + parent_notice_id: f("parent_notice_id", "str"), + posted_date: f("posted_date", "date"), + related_notice_id: f("related_notice_id", "str"), + solicitation_number: f("solicitation_number", "str"), + title: f("title", "str"), + }, + NoticeType: { + code: f("code", "str"), + type: f("type", "str"), + }, + Office2: { + agency_code: f("agency_code", "str"), + agency_name: f("agency_name", "str"), + department_code: f("department_code", "str"), + department_name: f("department_name", "str"), + office_code: f("office_code", "str"), + office_name: f("office_name", "str"), + organization_id: f("organization_id", "str"), + }, + Officers2: { + highly_compensated_officer_1_amount: f("highly_compensated_officer_1_amount", "Decimal"), + highly_compensated_officer_1_name: f("highly_compensated_officer_1_name", "str"), + highly_compensated_officer_2_amount: f("highly_compensated_officer_2_amount", "Decimal"), + highly_compensated_officer_2_name: f("highly_compensated_officer_2_name", "str"), + highly_compensated_officer_3_amount: f("highly_compensated_officer_3_amount", "Decimal"), + highly_compensated_officer_3_name: f("highly_compensated_officer_3_name", "str"), + highly_compensated_officer_4_amount: f("highly_compensated_officer_4_amount", "Decimal"), + highly_compensated_officer_4_name: f("highly_compensated_officer_4_name", "str"), + highly_compensated_officer_5_amount: f("highly_compensated_officer_5_amount", "Decimal"), + highly_compensated_officer_5_name: f("highly_compensated_officer_5_name", "str"), + }, + Opportunity2: { + link: f("link", "str"), + opportunity_id: f("opportunity_id", "str"), + }, + Organization2: { + agency_code: f("agency_code", "int"), + agency_name: f("agency_name", "str"), + department_code: f("department_code", "int"), + department_name: f("department_name", "str"), + office_code: f("office_code", "int"), + office_name: f("office_name", "str"), + organization_id: f("organization_id", "str"), + }, + ParentAward2: { + key: f("key", "str"), + piid: f("piid", "str"), + }, + PastPerformance: { + summary: f("summary", "str"), + top_agencies: f("top_agencies", "str"), + }, + PeriodOfPerformance: { + current_end_date: f("current_end_date", "date"), + start_date: f("start_date", "date"), + ultimate_completion_date: f("ultimate_completion_date", "date"), + }, + PhysicalAddress: { + address_line1: f("address_line1", "str"), + address_line2: f("address_line2", "str"), + city: f("city", "str"), + country_code: f("country_code", "str"), + country_name: f("country_name", "str"), + county: f("county", "str"), + county_code: f("county_code", "str"), + fips_code: f("fips_code", "str"), + state_or_province_code: f("state_or_province_code", "str"), + zip_code: f("zip_code", "int"), + zip_code_plus4: f("zip_code_plus4", "int"), + }, + PlaceOfPerformance2: { + city: f("city", "str"), + country: f("country", "str"), + state: f("state", "str"), + street_address: f("street_address", "str"), + zip: f("zip", "str"), + }, + PlaceOfPerformance3: { + city: f("city", "int"), + country: f("country", "str"), + state: f("state", "str"), + street_address: f("street_address", "str"), + zip: f("zip", "str"), + }, + PlaceOfPerformance4: { + city_name: f("city_name", "str"), + country_code: f("country_code", "str"), + country_name: f("country_name", "str"), + state_code: f("state_code", "str"), + state_name: f("state_name", "str"), + zip_code: f("zip_code", "str"), + }, + PrimaryContact: { + email: f("email", "str"), + fax: f("fax", "str"), + full_name: f("full_name", "str"), + phone: f("phone", "str"), + title: f("title", "str"), + }, + Relationships: { + confidence: f("confidence", "str"), + display_name: f("display_name", "str"), + relation: f("relation", "str"), + source: f("source", "str"), + type: f("type", "str"), + uei: f("uei", "str"), + verification_method: f("verification_method", "str"), + }, + ResolvedAgency: { + key: f("key", "str"), + match_confidence: f("match_confidence", "str"), + name: f("name", "str"), + rationale: f("rationale", "str"), + }, + ResolvedProtester: { + match_confidence: f("match_confidence", "str"), + name: f("name", "str"), + rationale: f("rationale", "str"), + uei: f("uei", "str"), + }, + SbaBusinessTypes: { + code: f("code", "str"), + description: f("description", "str"), + entry_date: f("entry_date", "date"), + exit_date: f("exit_date", "date"), + }, + SizeStandards: { + employee_limit: f("employee_limit", "str"), + revenue_limit: f("revenue_limit", "int"), + }, + Transactions: { + action_type: f("action_type", "str"), + description: f("description", "str"), + modification_number: f("modification_number", "int"), + obligated: f("obligated", "Decimal"), + transaction_date: f("transaction_date", "date"), + }, + Transactions2: { + action_type: f("action_type", "str"), + description: f("description", "str"), + modification_number: f("modification_number", "str"), + obligated: f("obligated", "str"), + transaction_date: f("transaction_date", "date"), + }, + Vehicle2: { + agency_id: f("agency_id", "int"), + award_date: f("award_date", "date"), + contract_type: f("contract_type", "str"), + description: f("description", "str", true), + fiscal_year: f("fiscal_year", "int"), + last_date_to_order: f("last_date_to_order", "date"), + naics_code: f("naics_code", "int"), + psc_code: f("psc_code", "int"), + set_aside: f("set_aside", "str"), + solicitation_date: f("solicitation_date", "str"), + solicitation_description: f("solicitation_description", "str"), + solicitation_identifier: f("solicitation_identifier", "str"), + solicitation_title: f("solicitation_title", "str"), + type_of_idc: f("type_of_idc", "str"), + uuid: f("uuid", "str"), + vehicle_type: f("vehicle_type", "str"), + who_can_use: f("who_can_use", "str"), + }, +}; + +// Container model-name -> additional field schemas (merged over the base). +export const GENERATED_OVERLAY: Record = { + Agency: { + department: f("department", "dict", false, "Department2"), + }, + AssistanceListing: { + applicant_eligibility: f("applicant_eligibility", "str"), + archived_date: f("archived_date", "date"), + benefit_eligibility: f("benefit_eligibility", "str"), + number: f("number", "Decimal"), + objectives: f("objectives", "str"), + popular_name: f("popular_name", "str"), + published_date: f("published_date", "date"), + title: f("title", "str"), + }, + AwardOffice: { + organization_id: f("organization_id", "str"), + }, + BudgetAccount: { + account_narrative_excerpt: f("account_narrative_excerpt", "str"), + account_title: f("account_title", "str"), + actual_vs_requested_contract: f("actual_vs_requested_contract", "str"), + actual_vs_requested_contract_capped: f("actual_vs_requested_contract_capped", "str"), + actual_vs_requested_contract_capped_flag: f("actual_vs_requested_contract_capped_flag", "str"), + agency_code: f("agency_code", "str"), + agency_name: f("agency_name", "str"), + appendix: f("appendix", "dict", false, "Appendix"), + appendix_pdf_url: f("appendix_pdf_url", "str"), + apportioned: f("apportioned", "str"), + apportioned_to_enacted_pct: f("apportioned_to_enacted_pct", "str"), + apportioned_to_enacted_pct_capped: f("apportioned_to_enacted_pct_capped", "str"), + apportioned_to_enacted_pct_capped_flag: f("apportioned_to_enacted_pct_capped_flag", "str"), + assistance_obligated: f("assistance_obligated", "str"), + assistance_outlayed: f("assistance_outlayed", "str"), + assistance_share_capped_flag: f("assistance_share_capped_flag", "str"), + assistance_share_of_obligated: f("assistance_share_of_obligated", "str"), + assistance_share_of_obligated_capped: f("assistance_share_of_obligated_capped", "str"), + attribution_confidence: f("attribution_confidence", "str"), + attribution_status: f("attribution_status", "str"), + ba_growth_next_year: f("ba_growth_next_year", "str"), + ba_growth_next_year_pct: f("ba_growth_next_year_pct", "str"), + bea_category: f("bea_category", "str"), + bureau_name: f("bureau_name", "str"), + contract_obligated: f("contract_obligated", "str"), + contract_obligated_5yr_cagr: f("contract_obligated_5yr_cagr", "str"), + contract_obligated_estimated: f("contract_obligated_estimated", "str"), + contract_obligated_yoy_pct: f("contract_obligated_yoy_pct", "str"), + contract_outlayed: f("contract_outlayed", "str"), + contract_share_capped_flag: f("contract_share_capped_flag", "str"), + contract_share_of_obligated: f("contract_share_of_obligated", "str"), + contract_share_of_obligated_capped: f("contract_share_of_obligated_capped", "str"), + created: f("created", "datetime"), + enacted_ba: f("enacted_ba", "str"), + enacted_ba_5yr_cagr: f("enacted_ba_5yr_cagr", "str"), + enacted_ba_yoy_pct: f("enacted_ba_yoy_pct", "str"), + enacted_to_requested_pct: f("enacted_to_requested_pct", "str"), + enacted_to_requested_pct_capped: f("enacted_to_requested_pct_capped", "str"), + enacted_to_requested_pct_capped_flag: f("enacted_to_requested_pct_capped_flag", "str"), + federal_account_symbol: f("federal_account_symbol", "str"), + fiscal_year: f("fiscal_year", "str"), + id: f("id", "str"), + modified: f("modified", "datetime"), + n_contracts: f("n_contracts", "str"), + n_grants: f("n_grants", "str"), + n_unique_contract_recipients: f("n_unique_contract_recipients", "str"), + n_unique_grant_recipients: f("n_unique_grant_recipients", "str"), + narratives: f("narratives", "dict", true, "Narratives"), + next_year_requested_ba: f("next_year_requested_ba", "str"), + obligated_to_apportioned_pct: f("obligated_to_apportioned_pct", "str"), + obligated_to_apportioned_pct_capped: f("obligated_to_apportioned_pct_capped", "str"), + obligated_to_apportioned_pct_capped_flag: f("obligated_to_apportioned_pct_capped_flag", "str"), + obligated_to_enacted_pct: f("obligated_to_enacted_pct", "str"), + obligated_to_enacted_pct_capped: f("obligated_to_enacted_pct_capped", "str"), + obligated_to_enacted_pct_capped_flag: f("obligated_to_enacted_pct_capped_flag", "str"), + obligated_total: f("obligated_total", "str"), + obligated_yoy_pct: f("obligated_yoy_pct", "str"), + on_off_budget: f("on_off_budget", "str"), + outlayed_to_obligated_pct: f("outlayed_to_obligated_pct", "str"), + outlayed_to_obligated_pct_capped: f("outlayed_to_obligated_pct_capped", "str"), + outlayed_to_obligated_pct_capped_flag: f("outlayed_to_obligated_pct_capped_flag", "str"), + outlayed_total: f("outlayed_total", "str"), + requested_ba: f("requested_ba", "str"), + requested_contractual_services: f("requested_contractual_services", "str"), + requested_personnel_share: f("requested_personnel_share", "str"), + subfunction_code: f("subfunction_code", "str"), + top_contract_recipients: f("top_contract_recipients", "str"), + top_grant_recipients: f("top_grant_recipients", "str"), + unlinked_obligated: f("unlinked_obligated", "str"), + unobligated_balance: f("unobligated_balance", "str"), + unobligated_pct: f("unobligated_pct", "str"), + }, + BusinessType: { + code: f("code", "int"), + name: f("name", "str"), + }, + Contract: { + award_type: f("award_type", "dict", false, "CodeDescription"), + commercial_item_acquisition_procedures: f("commercial_item_acquisition_procedures", "dict", false, "CodeDescription"), + consolidated_contract: f("consolidated_contract", "dict", false, "CodeDescription"), + contingency_humanitarian_or_peacekeeping_operation: f("contingency_humanitarian_or_peacekeeping_operation", "dict", false, "CodeDescription"), + contract_bundling: f("contract_bundling", "dict", false, "CodeDescription"), + cost_accounting_standards_clause: f("cost_accounting_standards_clause", "dict", false, "CodeDescription"), + cost_or_pricing_data: f("cost_or_pricing_data", "dict", false, "CodeDescription"), + domestic_or_foreign_entity: f("domestic_or_foreign_entity", "dict", false, "CodeDescription"), + epa_designated_product: f("epa_designated_product", "dict", false, "CodeDescription"), + evaluated_preference: f("evaluated_preference", "dict", false, "CodeDescription"), + fair_opportunity_limited_sources: f("fair_opportunity_limited_sources", "dict", false, "CodeDescription"), + fed_biz_opps: f("fed_biz_opps", "dict", false, "CodeDescription"), + foreign_funding: f("foreign_funding", "dict", false, "CodeDescription"), + information_technology_commercial_item_category: f("information_technology_commercial_item_category", "dict", false, "CodeDescription"), + inherently_governmental_functions: f("inherently_governmental_functions", "dict", false, "CodeDescription"), + officers: f("officers", "dict", false, "Officers2"), + performance_based_service_acquisition: f("performance_based_service_acquisition", "dict", false, "CodeDescription"), + period_of_performance: f("period_of_performance", "dict", false, "PeriodOfPerformance"), + place_of_manufacture: f("place_of_manufacture", "dict", false, "CodeDescription"), + recovered_materials_sustainability: f("recovered_materials_sustainability", "dict", false, "CodeDescription"), + research: f("research", "dict", false, "CodeDescription"), + sam_exception: f("sam_exception", "dict", false, "CodeDescription"), + set_aside: f("set_aside", "dict", false, "CodeDescription"), + subcontracting_plan: f("subcontracting_plan", "dict", false, "CodeDescription"), + tradeoff_process: f("tradeoff_process", "dict", false, "CodeDescription"), + transactions: f("transactions", "dict", true, "Transactions"), + undefinitized_action: f("undefinitized_action", "dict", false, "CodeDescription"), + vehicle: f("vehicle", "dict", false, "Vehicle2"), + }, + Department: { + cgac: f("cgac", "str"), + congressional_justification: f("congressional_justification", "str"), + description: f("description", "str"), + website: f("website", "str"), + }, + Entity: { + additional_website: f("additional_website", "str"), + business_types: f("business_types", "dict", false, "CodeDescription"), + capabilities_link: f("capabilities_link", "str"), + country_of_incorporation: f("country_of_incorporation", "dict", false, "CodeDescription"), + county: f("county", "str"), + current_principals: f("current_principals", "str"), + display_name: f("display_name", "str"), + entity_structure: f("entity_structure", "dict", false, "CodeDescription"), + entity_type: f("entity_type", "dict", false, "CodeDescription"), + federal_obligations: f("federal_obligations", "dict", false, "FederalObligations"), + g2x_about: f("g2x_about", "str"), + g2x_ai_summary: f("g2x_ai_summary", "str"), + g2x_employee_count: f("g2x_employee_count", "str"), + highest_owner: f("highest_owner", "dict", false, "HighestOwner"), + immediate_owner: f("immediate_owner", "dict", false, "HighestOwner"), + mailing_address: f("mailing_address", "dict", false, "MailingAddress"), + naics_codes: f("naics_codes", "dict", true, "NaicsCodes"), + naics_small_codes: f("naics_small_codes", "int", true), + non_fed_govt_certifications: f("non_fed_govt_certifications", "str"), + organization_structure: f("organization_structure", "dict", false, "CodeDescription"), + past_performance: f("past_performance", "dict", false, "PastPerformance"), + physical_address: f("physical_address", "dict", false, "PhysicalAddress"), + profit_structure: f("profit_structure", "dict", false, "CodeDescription"), + purpose_of_registration: f("purpose_of_registration", "dict", false, "CodeDescription"), + relationships: f("relationships", "dict", true, "Relationships"), + sba_business_types: f("sba_business_types", "dict", true, "SbaBusinessTypes"), + special_equip_material: f("special_equip_material", "str"), + state_of_incorporation: f("state_of_incorporation", "dict", false, "CodeDescription"), + uuid: f("uuid", "str"), + }, + Forecast: { + created: f("created", "datetime"), + display: f("display", "dict", false, "Display"), + modified: f("modified", "datetime"), + organization: f("organization", "dict", false, "Organization2"), + organization_id: f("organization_id", "str"), + raw_data: f("raw_data", "dict"), + }, + Grant: { + additional_info: f("additional_info", "dict", false, "AdditionalInfo"), + forecast: f("forecast", "str"), + funding_details: f("funding_details", "dict", false, "FundingDetails"), + grantor_contact: f("grantor_contact", "dict", false, "GrantorContact"), + important_dates: f("important_dates", "dict", false, "ImportantDates"), + opportunity_history: f("opportunity_history", "str"), + organization: f("organization", "dict", false, "Organization2"), + organization_id: f("organization_id", "str"), + synopsis: f("synopsis", "str"), + }, + GsaElibraryContract: { + uei: f("uei", "str"), + }, + IDV: { + commercial_item_acquisition_procedures: f("commercial_item_acquisition_procedures", "str"), + consolidated_contract: f("consolidated_contract", "str"), + contingency_humanitarian_or_peacekeeping_operation: f("contingency_humanitarian_or_peacekeeping_operation", "str"), + contract_bundling: f("contract_bundling", "str"), + contract_financing: f("contract_financing", "str"), + cost_accounting_standards_clause: f("cost_accounting_standards_clause", "str"), + cost_or_pricing_data: f("cost_or_pricing_data", "str"), + dod_acquisition_program: f("dod_acquisition_program", "str"), + dod_transaction_number: f("dod_transaction_number", "str"), + domestic_or_foreign_entity: f("domestic_or_foreign_entity", "str"), + email_address: f("email_address", "str"), + epa_designated_product: f("epa_designated_product", "str"), + evaluated_preference: f("evaluated_preference", "str"), + fair_opportunity_limited_sources: f("fair_opportunity_limited_sources", "str"), + fed_biz_opps: f("fed_biz_opps", "str"), + fee_range_lower_value: f("fee_range_lower_value", "str"), + fee_range_upper_value: f("fee_range_upper_value", "str"), + fixed_fee_value: f("fixed_fee_value", "Decimal"), + foreign_funding: f("foreign_funding", "str"), + government_furnished_property: f("government_furnished_property", "str"), + gsa_elibrary: f("gsa_elibrary", "dict", false, "GsaElibrary"), + idv_type: f("idv_type", "dict", false, "CodeDescription"), + idv_website: f("idv_website", "str"), + inherently_governmental_functions: f("inherently_governmental_functions", "str"), + local_area_set_aside: f("local_area_set_aside", "str"), + major_program: f("major_program", "str"), + multiple_or_single_award_idv: f("multiple_or_single_award_idv", "dict", false, "CodeDescription"), + number_of_actions: f("number_of_actions", "str"), + number_of_offers_source: f("number_of_offers_source", "str"), + ordering_procedure: f("ordering_procedure", "str"), + performance_based_service_acquisition: f("performance_based_service_acquisition", "str"), + program_acronym: f("program_acronym", "str"), + recovered_materials_sustainability: f("recovered_materials_sustainability", "str"), + research: f("research", "str"), + sam_exception: f("sam_exception", "str"), + simplified_procedures_for_certain_commercial_items: f("simplified_procedures_for_certain_commercial_items", "str"), + small_business_competitiveness_demonstration_program: f("small_business_competitiveness_demonstration_program", "str"), + solicitation_identifier: f("solicitation_identifier", "str"), + subcontracting_plan: f("subcontracting_plan", "str"), + total_estimated_order_value: f("total_estimated_order_value", "Decimal"), + tradeoff_process: f("tradeoff_process", "str"), + type_of_fee_for_use_of_service: f("type_of_fee_for_use_of_service", "str"), + type_of_idc: f("type_of_idc", "dict", false, "CodeDescription"), + undefinitized_action: f("undefinitized_action", "str"), + vehicle_uuid: f("vehicle_uuid", "str"), + who_can_use: f("who_can_use", "str"), + }, + ITDashboardInvestment: { + details: f("details", "dict", false, "Details"), + funding: f("funding", "dict", false, "Funding"), + organization_id: f("organization_id", "str"), + }, + MasSin: { + description: f("description", "str"), + expiration_date: f("expiration_date", "str"), + large_category_code: f("large_category_code", "str"), + large_category_name: f("large_category_name", "str"), + naics_codes: f("naics_codes", "int", true), + olm: f("olm", "bool"), + psc_code: f("psc_code", "int"), + service_comm_code: f("service_comm_code", "str"), + set_aside_code: f("set_aside_code", "str"), + sin: f("sin", "int"), + state_local: f("state_local", "bool"), + sub_category_code: f("sub_category_code", "str"), + sub_category_name: f("sub_category_name", "str"), + tdr: f("tdr", "bool"), + title: f("title", "str"), + }, + Naics: { + code: f("code", "int"), + description: f("description", "str"), + federal_obligations: f("federal_obligations", "dict", false, "FederalObligations"), + size_standards: f("size_standards", "dict", false, "SizeStandards"), + }, + Notice: { + address: f("address", "dict", false, "Address"), + archive: f("archive", "dict", false, "Archive"), + attachments: f("attachments", "dict", true, "Attachments"), + meta: f("meta", "dict", false, "Meta"), + office: f("office", "dict", false, "Office2"), + opportunity: f("opportunity", "dict", false, "Opportunity2"), + opportunity_id: f("opportunity_id", "str"), + place_of_performance: f("place_of_performance", "dict", false, "PlaceOfPerformance2"), + primary_contact: f("primary_contact", "dict", false, "PrimaryContact"), + secondary_contact: f("secondary_contact", "dict", false, "PrimaryContact"), + set_aside: f("set_aside", "dict", false, "CodeDescription"), + }, + OTA: { + award_type: f("award_type", "dict", false, "CodeDescription"), + awarding_office: f("awarding_office", "dict", false, "Office2"), + base_and_exercised_options_value: f("base_and_exercised_options_value", "Decimal"), + consortia: f("consortia", "str"), + consortia_uei: f("consortia_uei", "str"), + dod_acquisition_program: f("dod_acquisition_program", "int"), + extent_competed: f("extent_competed", "dict", false, "CodeDescription"), + fiscal_year: f("fiscal_year", "int"), + funding_office: f("funding_office", "dict", false, "Office2"), + non_governmental_dollars: f("non_governmental_dollars", "Decimal"), + non_traditional_government_contractor_participation: f("non_traditional_government_contractor_participation", "str"), + parent_award: f("parent_award", "dict", false, "ParentAward2"), + parent_award_modification_number: f("parent_award_modification_number", "int"), + period_of_performance: f("period_of_performance", "dict", false, "PeriodOfPerformance"), + place_of_performance: f("place_of_performance", "dict", false, "PlaceOfPerformance4"), + psc: f("psc", "dict", false, "CodeDescription"), + psc_code: f("psc_code", "int"), + transactions: f("transactions", "dict", true, "Transactions2"), + type_of_ot_agreement: f("type_of_ot_agreement", "dict", false, "CodeDescription"), + }, + OTIDV: { + awarding_office: f("awarding_office", "dict", false, "Office2"), + base_and_exercised_options_value: f("base_and_exercised_options_value", "Decimal"), + consortia: f("consortia", "str"), + consortia_uei: f("consortia_uei", "str"), + dod_acquisition_program: f("dod_acquisition_program", "str"), + extent_competed: f("extent_competed", "dict", false, "CodeDescription"), + fiscal_year: f("fiscal_year", "int"), + funding_office: f("funding_office", "dict", false, "Office2"), + non_governmental_dollars: f("non_governmental_dollars", "Decimal"), + non_traditional_government_contractor_participation: f("non_traditional_government_contractor_participation", "str"), + period_of_performance: f("period_of_performance", "dict", false, "PeriodOfPerformance"), + place_of_performance: f("place_of_performance", "dict", false, "PlaceOfPerformance4"), + psc: f("psc", "dict", false, "CodeDescription"), + psc_code: f("psc_code", "int"), + transactions: f("transactions", "dict", true, "Transactions2"), + type_of_ot_agreement: f("type_of_ot_agreement", "dict", false, "CodeDescription"), + }, + Office: { + agency: f("agency", "dict", false, "Agency2"), + agency_code: f("agency_code", "str"), + agency_name: f("agency_name", "str"), + department: f("department", "dict", false, "Department2"), + department_code: f("department_code", "str"), + department_name: f("department_name", "str"), + office_code: f("office_code", "str"), + office_name: f("office_name", "str"), + organization_id: f("organization_id", "str"), + }, + Opportunity: { + agency: f("agency", "dict", false, "Agency3"), + agency_id: f("agency_id", "str"), + archive_date: f("archive_date", "date"), + attachments: f("attachments", "dict", false, "Attachments3"), + department: f("department", "dict", false, "Department3"), + department_id: f("department_id", "str"), + latest_notice: f("latest_notice", "dict", false, "LatestNotice"), + latest_notice_id: f("latest_notice_id", "str"), + meta: f("meta", "dict", false, "Meta2"), + notice_history: f("notice_history", "dict", false, "NoticeHistory2"), + office_id: f("office_id", "str"), + place_of_performance: f("place_of_performance", "dict", false, "PlaceOfPerformance2"), + secondary_contact: f("secondary_contact", "dict", false, "PrimaryContact"), + set_aside: f("set_aside", "dict", false, "CodeDescription"), + snippet: f("snippet", "str"), + }, + Organization: { + aac_code: f("aac_code", "str"), + agency: f("agency", "dict", false, "Agency2"), + ancestors: f("ancestors", "dict", true, "Ancestors"), + budget_appropriation: f("budget_appropriation", "dict", false, "BudgetAppropriation"), + budget_spending: f("budget_spending", "dict", false, "BudgetSpending"), + canonical_code: f("canonical_code", "str"), + cgac: f("cgac", "int"), + children: f("children", "dict", true, "Children"), + code: f("code", "int"), + department: f("department", "dict", false, "Agency2"), + description: f("description", "str"), + end_date: f("end_date", "str"), + fpds_code: f("fpds_code", "int"), + fpds_org_id: f("fpds_org_id", "int"), + full_parent_path_name: f("full_parent_path_name", "str"), + is_active: f("is_active", "bool"), + l1_fh_key: f("l1_fh_key", "int"), + l2_fh_key: f("l2_fh_key", "int"), + l3_fh_key: f("l3_fh_key", "int"), + l4_fh_key: f("l4_fh_key", "str"), + l5_fh_key: f("l5_fh_key", "str"), + l6_fh_key: f("l6_fh_key", "str"), + l7_fh_key: f("l7_fh_key", "str"), + l8_fh_key: f("l8_fh_key", "str"), + logo: f("logo", "str"), + mod_status: f("mod_status", "str"), + obligation_rank: f("obligation_rank", "str"), + obligations: f("obligations", "Decimal"), + parent: f("parent", "dict", false, "Children"), + parent_fh_key: f("parent_fh_key", "int"), + start_date: f("start_date", "datetime"), + summary: f("summary", "str"), + total_obligations: f("total_obligations", "Decimal"), + tree_obligations: f("tree_obligations", "Decimal"), + }, + PSC: { + category: f("category", "str"), + code: f("code", "int"), + current: f("current", "dict", false, "Current"), + historical: f("historical", "dict", true, "Historical"), + level_1_category: f("level_1_category", "str"), + level_1_category_code: f("level_1_category_code", "int"), + level_2_category: f("level_2_category", "str"), + level_2_category_code: f("level_2_category_code", "Decimal"), + parent: f("parent", "str"), + }, + Protest: { + challenged_party: f("challenged_party", "str"), + decision_text: f("decision_text", "str"), + decisions: f("decisions", "dict", true, "Decisions"), + judge: f("judge", "str"), + naics_code: f("naics_code", "str"), + outcome_reason: f("outcome_reason", "str"), + resolved_agency: f("resolved_agency", "dict", false, "ResolvedAgency"), + resolved_protester: f("resolved_protester", "dict", false, "ResolvedProtester"), + size_standard: f("size_standard", "str"), + }, + ProtestDocket: { + challenged_party: f("challenged_party", "str"), + decision_text: f("decision_text", "str"), + judge: f("judge", "str"), + naics_code: f("naics_code", "str"), + organization: f("organization", "dict", false, "Organization2"), + outcome_reason: f("outcome_reason", "str"), + size_standard: f("size_standard", "str"), + }, + Vehicle: { + name: f("name", "str"), + }, +}; diff --git a/src/shapes/index.ts b/src/shapes/index.ts index 942cff7..f74e7ef 100644 --- a/src/shapes/index.ts +++ b/src/shapes/index.ts @@ -1,6 +1,7 @@ export * from "./types.js"; export * from "./schemaTypes.js"; export * from "./explicitSchemas.js"; +export * from "./generatedOverlay.js"; export * from "./schema.js"; export * from "./parser.js"; export * from "./generator.js"; diff --git a/src/shapes/schema.ts b/src/shapes/schema.ts index 3c76006..c44d96d 100644 --- a/src/shapes/schema.ts +++ b/src/shapes/schema.ts @@ -1,6 +1,7 @@ import { ShapeValidationError } from "../errors.js"; import type { FieldSchema, FieldSchemaMap } from "./schemaTypes.js"; import { EXPLICIT_SCHEMAS } from "./explicitSchemas.js"; +import { GENERATED_NESTED, GENERATED_OVERLAY } from "./generatedOverlay.js"; export interface ModelSchema { modelName: string; @@ -29,6 +30,18 @@ export class SchemaRegistry { this.schemas.set(modelName, { modelName, fields }); } + // Merge the generated reverse-coverage overlay (scripts/generate-shape-overlay.ts): + // the fields and expands Tango's shape trees expose that the curated schemas above + // missed. Spread into a fresh object so the module-level schema maps stay unmutated. + for (const [refName, fields] of Object.entries(GENERATED_NESTED)) { + const existing = this.schemas.get(refName)?.fields ?? {}; + this.schemas.set(refName, { modelName: refName, fields: { ...existing, ...fields } }); + } + for (const [modelName, additions] of Object.entries(GENERATED_OVERLAY)) { + const existing = this.schemas.get(modelName)?.fields ?? {}; + this.schemas.set(modelName, { modelName, fields: { ...existing, ...additions } }); + } + this.explicitRegistered = true; } diff --git a/src/types.ts b/src/types.ts index f98655a..e68d664 100644 --- a/src/types.ts +++ b/src/types.ts @@ -47,6 +47,35 @@ export interface PaginatedResponse { next: string | null; previous: string | null; pageMetadata: Record | null; + /** + * Response-level metadata the API attached to this page, when present. + * Currently carries agency-filter diagnostics: `resolved_filters` maps each + * agency filter to the organizations its `|`-separated tokens resolved to + * (or `null`), and `warnings` lists human-readable notes about tokens that + * were dropped or matched loosely. See `agencyWarnings`, + * `unresolvedAgencyTokens`, and `resolvedAgencies` for the parsed views. + */ + meta: Record | null; + /** + * Warnings the API raised about agency filters on this request. Empty when + * every supplied agency token resolved cleanly — a non-empty list means part + * of the filter did not apply, so a small or empty `results` is not evidence + * that no such records exist. + */ + agencyWarnings: string[]; + /** + * Agency tokens that matched no organization, keyed by filter name. Empty + * when everything resolved. Use this to fail loudly in a pipeline rather + * than treating a silently-narrowed result set as an answer. + */ + unresolvedAgencyTokens: Record; + /** + * What each agency token actually resolved to, keyed by filter name. Agency + * resolution is fuzzy, so a token can match an organization the caller did + * not intend — checking the resolved `name` is the only way to catch that + * from the client side. + */ + resolvedAgencies: Record>>; /** * Cursor for keyset-paginated endpoints, extracted from `next`. Pass it back * via the next request's `cursor` option. `null` when the endpoint is diff --git a/tests/unit/client.meta-diagnostics.test.ts b/tests/unit/client.meta-diagnostics.test.ts new file mode 100644 index 0000000..be347cb --- /dev/null +++ b/tests/unit/client.meta-diagnostics.test.ts @@ -0,0 +1,115 @@ +/** + * `meta` from the API's agency-filter diagnostics (port of Python's + * TestAgencyFilterDiagnostics, tango-python #55). + * + * Agency resolution is fuzzy, so a token can be dropped entirely or matched to + * an organization the caller did not intend. Before the API exposed `meta`, + * both were indistinguishable from "no such records exist" — and the SDK is + * the last place that distinction can reach a user. + */ + +import { TangoClient } from "../../src/client.js"; +import { TangoValidationError } from "../../src/errors.js"; + +const HUD = { + key: "3f2a0000-0000-0000-0000-000000000001", + name: "Department of Housing and Urban Development", + level: 1, + cgac: "086", + fpds_code: null, +}; + +function makeClient(body: unknown, status = 200): TangoClient { + const fetchImpl = (async () => ({ + ok: status >= 200 && status < 300, + status, + async text() { + return JSON.stringify(body); + }, + })) as unknown as typeof fetch; + return new TangoClient({ apiKey: "k", baseUrl: "http://localhost:8000", fetchImpl, retries: 0 }); +} + +function emptyPage(meta?: unknown): Record { + const payload: Record = { count: 0, next: null, previous: null, results: [] }; + if (meta !== undefined) payload.meta = meta; + return payload; +} + +describe("PaginatedResponse agency-filter diagnostics", () => { + it("meta is carried through to the response", async () => { + const meta = { + resolved_filters: { + awarding_agency: [ + { token: "HUD", resolved: HUD }, + { token: "HUDD", resolved: null }, + ], + }, + warnings: ["Agency filter 'awarding_agency': 'HUDD' did not match."], + }; + const res = await makeClient(emptyPage(meta)).listContracts({ awarding_agency: "HUD|HUDD" }); + expect(res.meta).toEqual(meta); + }); + + it("dropped tokens are reported per filter", async () => { + const res = await makeClient( + emptyPage({ + resolved_filters: { + awarding_agency: [ + { token: "HUD", resolved: HUD }, + { token: "HUDD", resolved: null }, + ], + funding_agency: [{ token: "NOPE", resolved: null }], + }, + }), + ).listContracts({ awarding_agency: "HUD|HUDD" }); + expect(res.unresolvedAgencyTokens).toEqual({ + awarding_agency: ["HUDD"], + funding_agency: ["NOPE"], + }); + }); + + it("resolvedAgencies exposes the matched organization", async () => { + // The wrong-subtree case: nothing was dropped, so only the resolved name + // reveals that a token matched an organization the caller did not intend. + const res = await makeClient( + emptyPage({ resolved_filters: { awarding_agency: [{ token: "HUD", resolved: HUD }] } }), + ).listContracts({ awarding_agency: "HUD" }); + expect(res.unresolvedAgencyTokens).toEqual({}); + expect(res.resolvedAgencies.awarding_agency.map((org) => org.name)).toEqual([ + "Department of Housing and Urban Development", + ]); + }); + + it("warnings are surfaced", async () => { + const res = await makeClient( + emptyPage({ warnings: ["Agency filter 'agency': 'X' did not match."] }), + ).listOpportunities(); + expect(res.agencyWarnings).toEqual(["Agency filter 'agency': 'X' did not match."]); + }); + + it("absent meta yields empty accessors, not errors", async () => { + const res = await makeClient(emptyPage()).listContracts(); + expect(res.meta).toBeNull(); + expect(res.agencyWarnings).toEqual([]); + expect(res.unresolvedAgencyTokens).toEqual({}); + expect(res.resolvedAgencies).toEqual({}); + }); + + it("malformed meta does not raise", async () => { + // `meta` is server-controlled; a shape change must not crash a caller's loop. + const res = await makeClient( + emptyPage({ resolved_filters: "not-a-dict", warnings: "not-a-list" }), + ).listContracts(); + expect(res.agencyWarnings).toEqual([]); + expect(res.unresolvedAgencyTokens).toEqual({}); + expect(res.resolvedAgencies).toEqual({}); + }); + + it("a full miss raises with the offending token", async () => { + // A fully-unresolvable agency filter is a 400, not an empty page. + const client = makeClient({ error: "No agency found matching 'HUDD'." }, 400); + await expect(client.listContracts({ awarding_agency: "HUDD" })).rejects.toThrow(TangoValidationError); + await expect(client.listContracts({ awarding_agency: "HUDD" })).rejects.toThrow(/HUDD/); + }); +}); diff --git a/tests/unit/errors.test.ts b/tests/unit/errors.test.ts index a510fd9..c1c9146 100644 --- a/tests/unit/errors.test.ts +++ b/tests/unit/errors.test.ts @@ -57,3 +57,22 @@ describe("Error classes", () => { expect(instErr.actualValue).toBe(123); }); }); + +describe("TangoValidationError structured shape errors", () => { + it("exposes issues and availableFields from the response body", () => { + const err = new TangoValidationError("bad shape", 400, { + issues: [{ path: "tradeoff_process", reason: "unknown_field" }, "not-a-record", null], + available_fields: { fields: ["key", "piid"], expands: { recipient: ["uei"] } }, + }); + expect(err.issues).toEqual([{ path: "tradeoff_process", reason: "unknown_field" }]); + expect(err.availableFields).toEqual({ fields: ["key", "piid"], expands: { recipient: ["uei"] } }); + }); + + it("stays total when the body carries no structured payload", () => { + expect(new TangoValidationError("bad", 400).issues).toEqual([]); + expect(new TangoValidationError("bad", 400).availableFields).toBeNull(); + const malformed = new TangoValidationError("bad", 400, { issues: "nope", available_fields: ["nope"] }); + expect(malformed.issues).toEqual([]); + expect(malformed.availableFields).toBeNull(); + }); +}); diff --git a/tests/unit/shapes.overlay.test.ts b/tests/unit/shapes.overlay.test.ts new file mode 100644 index 0000000..18be19a --- /dev/null +++ b/tests/unit/shapes.overlay.test.ts @@ -0,0 +1,70 @@ +import { SchemaRegistry } from "../../src/shapes/schema.js"; +import { ShapeParser } from "../../src/shapes/parser.js"; +import { TypeGenerator } from "../../src/shapes/generator.js"; +import { GENERATED_NESTED, GENERATED_OVERLAY } from "../../src/shapes/generatedOverlay.js"; +import { EXPLICIT_SCHEMAS } from "../../src/shapes/explicitSchemas.js"; + +describe("Generated overlay — registry merge", () => { + const registry = new SchemaRegistry(); + + it("registers full model schemas for resources with no curated base", () => { + for (const model of ["Naics", "PSC", "MasSin", "BudgetAccount", "AssistanceListing", "BusinessType"]) { + const schema = registry.getSchema(model); + expect(Object.keys(schema.fields).length).toBeGreaterThan(0); + } + expect(registry.getField("Naics", "code")).toBeDefined(); + expect(registry.getField("BudgetAccount", "fiscal_year")).toBeDefined(); + }); + + it("overlay additions win over a curated flat scalar so expand sub-fields resolve", () => { + expect(EXPLICIT_SCHEMAS.Contract.set_aside.nestedModel ?? null).toBeNull(); + const merged = registry.getField("Contract", "set_aside"); + expect(merged.nestedModel).toBe("CodeDescription"); + expect(registry.getField("CodeDescription", "code")).toBeDefined(); + }); + + it("curated fields survive the merge untouched", () => { + expect(registry.getField("Contract", "key")).toEqual(EXPLICIT_SCHEMAS.Contract.key); + expect(registry.getField("Entity", "uei")).toEqual(EXPLICIT_SCHEMAS.Entity.uei); + }); + + it("generated nested schema names never shadow curated model names", () => { + for (const name of Object.keys(GENERATED_NESTED)) { + expect(EXPLICIT_SCHEMAS[name]).toBeUndefined(); + } + }); + + it("every nested pointer in the overlay resolves through the registry", () => { + const maps = [...Object.values(GENERATED_NESTED), ...Object.values(GENERATED_OVERLAY)]; + for (const fields of maps) { + for (const field of Object.values(fields)) { + if (field.nestedModel) { + expect(Object.keys(registry.getSchema(field.nestedModel).fields).length).toBeGreaterThan(0); + } + } + } + }); +}); + +describe("Entity relationships shape coverage", () => { + const registry = new SchemaRegistry(); + + it("Entity.relationships is a list expand with a nested schema", () => { + const field = registry.getField("Entity", "relationships"); + expect(field.isList).toBe(true); + expect(field.nestedModel).toBe("Relationships"); + const nested = registry.getSchema("Relationships").fields; + for (const name of ["type", "source", "uei", "display_name", "relation", "confidence", "verification_method"]) { + expect(nested[name]).toBeDefined(); + } + }); + + it("relationships(type, source) generates a model descriptor without raising", () => { + const parser = new ShapeParser(); + const generator = new TypeGenerator({ schemaRegistry: registry }); + const spec = parser.parse("uei,relationships(type,source)"); + const model = generator.generateModelDescriptor("Entity", spec); + const rel = model.fields.find((f) => f.field.name === "relationships"); + expect(rel?.nestedModel?.fields.map((f) => f.field.name).sort()).toEqual(["source", "type"]); + }); +}); diff --git a/tests/unit/utils.http.test.ts b/tests/unit/utils.http.test.ts index 76235c3..93ce783 100644 --- a/tests/unit/utils.http.test.ts +++ b/tests/unit/utils.http.test.ts @@ -318,3 +318,30 @@ describe("HttpClient", () => { expect(calls).toBe(2); }); }); + +describe("HttpClient — structured 400 payloads", () => { + it("a shape-error 400 surfaces issues and availableFields on the thrown error", async () => { + const body = { + detail: "Invalid shape", + issues: [{ path: "tradeoff_process", reason: "unknown_field" }], + available_fields: { fields: ["key", "piid"] }, + }; + const client = new HttpClient({ + baseUrl: "https://example.test", + retries: 0, + fetchImpl: async (): Promise => ({ + ok: false, + status: 400, + async text() { + return JSON.stringify(body); + }, + }), + }); + + const err = await client.get("/api/contracts/").catch((e: unknown) => e); + expect(err).toBeInstanceOf(TangoValidationError); + const validation = err as TangoValidationError; + expect(validation.issues).toEqual([{ path: "tradeoff_process", reason: "unknown_field" }]); + expect(validation.availableFields).toEqual({ fields: ["key", "piid"] }); + }); +}); From 00dc5b0aa24b499a95514b44b5dab806e34fa7f7 Mon Sep 17 00:00:00 2001 From: "V. David Zvenyach" Date: Fri, 14 Aug 2026 12:19:39 -0500 Subject: [PATCH 5/7] test: cassette-based integration layer, production smoke suite, CI coverage Adds a record/replay harness around fetchImpl (tests/integration/harness.ts) with 44 recorded cassettes replayed offline in CI, per-resource integration tests across the full surface, an env-gated production smoke suite, and a coverage step on the Node 20 CI leg. Recording scrubs all request headers and allowlists response headers; the serializer throws if key material would be persisted. Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 7 + CHANGELOG.md | 4 + tests/cassettes/agencies-get.json | 36 ++++ tests/cassettes/agencies-list.json | 79 +++++++ tests/cassettes/budget-list.json | 118 ++++++++++ tests/cassettes/budget-range.json | 174 +++++++++++++++ tests/cassettes/contracts-cursor.json | 107 +++++++++ tests/cassettes/contracts-empty.json | 35 +++ tests/cassettes/contracts-filter.json | 54 +++++ tests/cassettes/contracts-list.json | 66 ++++++ tests/cassettes/contracts-shape.json | 51 +++++ tests/cassettes/dibbs-awards-list.json | 67 ++++++ tests/cassettes/dibbs-rfqs-list.json | 67 ++++++ tests/cassettes/dibbs-rfqs-open.json | 67 ++++++ tests/cassettes/edge-contract-404.json | 30 +++ tests/cassettes/edge-entities-empty.json | 33 +++ .../cassettes/edge-vehicles-bad-ordering.json | 30 +++ tests/cassettes/entities-filter.json | 46 ++++ tests/cassettes/entities-list.json | 76 +++++++ tests/cassettes/exclusions-active.json | 70 ++++++ tests/cassettes/exclusions-list.json | 70 ++++++ tests/cassettes/forecasts-filter.json | 49 +++++ tests/cassettes/forecasts-list.json | 58 +++++ tests/cassettes/grants-filter.json | 46 ++++ tests/cassettes/grants-list.json | 64 ++++++ tests/cassettes/idvs-filter.json | 51 +++++ tests/cassettes/idvs-list.json | 75 +++++++ tests/cassettes/naics-get.json | 45 ++++ tests/cassettes/naics-list.json | 46 ++++ tests/cassettes/notices-filter.json | 52 +++++ tests/cassettes/notices-list.json | 52 +++++ tests/cassettes/opportunities-filter.json | 49 +++++ tests/cassettes/opportunities-list.json | 55 +++++ tests/cassettes/organizations-filter.json | 79 +++++++ tests/cassettes/organizations-list.json | 79 +++++++ tests/cassettes/protests-filter.json | 112 ++++++++++ tests/cassettes/protests-list.json | 112 ++++++++++ tests/cassettes/psc-filter.json | 88 ++++++++ tests/cassettes/psc-list.json | 88 ++++++++ tests/cassettes/sbir-solicitations-list.json | 70 ++++++ tests/cassettes/sbir-topics-filter.json | 70 ++++++ tests/cassettes/sbir-topics-list.json | 70 ++++++ tests/cassettes/subawards-list.json | 181 ++++++++++++++++ tests/cassettes/subawards-ordering.json | 181 ++++++++++++++++ tests/cassettes/vehicles-list.json | 133 ++++++++++++ tests/cassettes/vehicles-search.json | 150 +++++++++++++ tests/integration/agencies.test.ts | 31 +++ tests/integration/budget.test.ts | 22 ++ tests/integration/contracts.test.ts | 51 +++++ tests/integration/dibbs.test.ts | 27 +++ tests/integration/edge-cases.test.ts | 23 ++ tests/integration/entities.test.ts | 19 ++ tests/integration/exclusions.test.ts | 20 ++ tests/integration/forecasts.test.ts | 20 ++ tests/integration/grants.test.ts | 20 ++ tests/integration/harness.ts | 203 ++++++++++++++++++ tests/integration/idvs.test.ts | 18 ++ tests/integration/notices.test.ts | 18 ++ tests/integration/opportunities.test.ts | 18 ++ tests/integration/protests.test.ts | 18 ++ tests/integration/reference-data.test.ts | 31 +++ tests/integration/sbir.test.ts | 27 +++ tests/integration/subawards.test.ts | 18 ++ tests/integration/validation.ts | 28 +++ tests/integration/vehicles.test.ts | 18 ++ tests/production/smoke.test.ts | 56 +++++ tests/unit/integration-harness.test.ts | 67 ++++++ vitest.config.ts | 10 +- 68 files changed, 4104 insertions(+), 1 deletion(-) create mode 100644 tests/cassettes/agencies-get.json create mode 100644 tests/cassettes/agencies-list.json create mode 100644 tests/cassettes/budget-list.json create mode 100644 tests/cassettes/budget-range.json create mode 100644 tests/cassettes/contracts-cursor.json create mode 100644 tests/cassettes/contracts-empty.json create mode 100644 tests/cassettes/contracts-filter.json create mode 100644 tests/cassettes/contracts-list.json create mode 100644 tests/cassettes/contracts-shape.json create mode 100644 tests/cassettes/dibbs-awards-list.json create mode 100644 tests/cassettes/dibbs-rfqs-list.json create mode 100644 tests/cassettes/dibbs-rfqs-open.json create mode 100644 tests/cassettes/edge-contract-404.json create mode 100644 tests/cassettes/edge-entities-empty.json create mode 100644 tests/cassettes/edge-vehicles-bad-ordering.json create mode 100644 tests/cassettes/entities-filter.json create mode 100644 tests/cassettes/entities-list.json create mode 100644 tests/cassettes/exclusions-active.json create mode 100644 tests/cassettes/exclusions-list.json create mode 100644 tests/cassettes/forecasts-filter.json create mode 100644 tests/cassettes/forecasts-list.json create mode 100644 tests/cassettes/grants-filter.json create mode 100644 tests/cassettes/grants-list.json create mode 100644 tests/cassettes/idvs-filter.json create mode 100644 tests/cassettes/idvs-list.json create mode 100644 tests/cassettes/naics-get.json create mode 100644 tests/cassettes/naics-list.json create mode 100644 tests/cassettes/notices-filter.json create mode 100644 tests/cassettes/notices-list.json create mode 100644 tests/cassettes/opportunities-filter.json create mode 100644 tests/cassettes/opportunities-list.json create mode 100644 tests/cassettes/organizations-filter.json create mode 100644 tests/cassettes/organizations-list.json create mode 100644 tests/cassettes/protests-filter.json create mode 100644 tests/cassettes/protests-list.json create mode 100644 tests/cassettes/psc-filter.json create mode 100644 tests/cassettes/psc-list.json create mode 100644 tests/cassettes/sbir-solicitations-list.json create mode 100644 tests/cassettes/sbir-topics-filter.json create mode 100644 tests/cassettes/sbir-topics-list.json create mode 100644 tests/cassettes/subawards-list.json create mode 100644 tests/cassettes/subawards-ordering.json create mode 100644 tests/cassettes/vehicles-list.json create mode 100644 tests/cassettes/vehicles-search.json create mode 100644 tests/integration/agencies.test.ts create mode 100644 tests/integration/budget.test.ts create mode 100644 tests/integration/contracts.test.ts create mode 100644 tests/integration/dibbs.test.ts create mode 100644 tests/integration/edge-cases.test.ts create mode 100644 tests/integration/entities.test.ts create mode 100644 tests/integration/exclusions.test.ts create mode 100644 tests/integration/forecasts.test.ts create mode 100644 tests/integration/grants.test.ts create mode 100644 tests/integration/harness.ts create mode 100644 tests/integration/idvs.test.ts create mode 100644 tests/integration/notices.test.ts create mode 100644 tests/integration/opportunities.test.ts create mode 100644 tests/integration/protests.test.ts create mode 100644 tests/integration/reference-data.test.ts create mode 100644 tests/integration/sbir.test.ts create mode 100644 tests/integration/subawards.test.ts create mode 100644 tests/integration/validation.ts create mode 100644 tests/integration/vehicles.test.ts create mode 100644 tests/production/smoke.test.ts create mode 100644 tests/unit/integration-harness.test.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce49bbc..24122f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,8 +51,15 @@ jobs: - name: Test # `vitest run` forces a single non-watch pass in CI. + # Integration tests replay the committed cassettes offline; production smoke stays excluded (env-gated on TANGO_LIVE_TESTS, never set here). run: npx vitest run + - name: Coverage summary + # One matrix leg is enough; the text reporter prints the summary. + # No fail-under gate — parity with tango-python, which has none. + if: matrix.node-version == '20' + run: npx vitest run --coverage + conformance: # Hard gate against the vendored contract (contracts/filter_shape_contract.json). # Runs unconditionally — no secrets required, so forks and tokenless runs diff --git a/CHANGELOG.md b/CHANGELOG.md index 02e6c4f..5551554 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ This project follows [Semantic Versioning](https://semver.org/). ## [Unreleased] ### Added +- **Recorded integration test layer** (parity with tango-python's VCR-cassette suite): a record/replay harness (`tests/integration/harness.ts`) around the SDK's injectable `fetchImpl`, with JSON cassettes in `tests/cassettes/` recorded against the live API. Default runs replay offline — a missing cassette is a hard failure so drift is loud, while an absent cassettes directory (a fork without the corpus) skips the suite with a warning. `TANGO_REFRESH_CASSETTES=true` re-records serially against the live API; `TANGO_USE_LIVE_API=true` bypasses cassettes. Cassettes never store request headers, keep only an allowlisted response-header subset, and the recorder throws rather than serialize API-key material anywhere in an interaction (asserted by unit tests in `tests/unit/integration-harness.test.ts`). +- Per-resource integration tests (`tests/integration/*.test.ts`, 44 tests / 44 cassettes) covering contracts (including cursor pagination and shaping), entities, IDVs, vehicles, opportunities, notices, grants, forecasts, agencies + organizations, protests, budget accounts (fiscal-year range round-trip), DIBBS, exclusions, SBIR, NAICS/PSC reference data, subawards, and edge cases (404, invalid ordering, empty result page). +- **Env-gated production smoke suite** (`tests/production/smoke.test.ts`, the node port of tango-python's `tests/production/`): runs only with `TANGO_LIVE_TESTS=true` plus `TANGO_API_KEY`, asserting light live-API invariants (pagination shape, shaping, rate-limit header parsing). Excluded from default runs and CI by `vitest.config.ts`. - **Generated shape-coverage overlay** (parity with tango-python v1.4.0): `src/shapes/generatedOverlay.ts`, machine-generated by the new `scripts/generate-shape-overlay.ts` from the vendored contract plus `contracts/observed_shape_types.json` (live-API type observations vendored from tango-python). `SchemaRegistry` merges the overlay over the curated explicit schemas, so the typed shape API now accepts every field and expand the API returns — including entity `relationships(type, source)`, previously-unmapped models (`Naics`, `PSC`, `MasSin`, `BudgetAccount`, `AssistanceListing`, `BusinessType`), and all the code/description expands that were flattened to scalars. The reverse shape-coverage gate now reports **zero** gaps and `contracts/shape_coverage_baseline.json` is empty (416 → 0). - **Agency-filter diagnostics on `PaginatedResponse`** (parity with tango-python v1.5.0). Every list method now surfaces the API's `meta` payload, plus three parsed views: `agencyWarnings` (human-readable notes about dropped or loosely-matched agency tokens), `unresolvedAgencyTokens` (tokens that matched no organization, keyed by filter name), and `resolvedAgencies` (the organizations each token actually resolved to — the only way to catch a token fuzzy-matching an agency you did not intend). All three are total: absent or malformed `meta` yields empty values, never a throw. - **Structured shape errors on `TangoValidationError`** (parity with tango-python's `.issues` / `.available_fields`): new `issues` and `availableFields` getters expose the API's structured 400 payload — entries like `{"path": "tradeoff_process", "reason": "unknown_field"}` and the endpoint's valid field set — instead of leaving callers to parse `responseData` by hand. @@ -30,6 +33,7 @@ This project follows [Semantic Versioning](https://semver.org/). - `scripts/check-filter-shape-conformance.ts` now defaults to the vendored contract instead of a sibling `../tango` checkout (`TANGO_CONTRACT_PATH` or `--manifest` still point it at a live checkout), covers every resource in the 4.22.0 contract in its resource map, and treats an unimplemented resource as an error unless baselined. ### CI +- The test job now prints a coverage summary (`npx vitest run --coverage`) on the Node 20 leg, and the default `npx vitest run` now includes the integration suite replayed offline from the committed cassettes. No coverage fail-under gate, matching tango-python. - The `conformance` job is now a hard gate that runs both conformance directions offline against the vendored contract on every PR — it no longer needs `TANGO_API_REPO_ACCESS_TOKEN` and no longer skips silently without it. A separate token-gated step diffs the vendored contract against makegov/tango HEAD and emits a staleness warning (never a failure). ## [1.1.0] - 2026-05-29 diff --git a/tests/cassettes/agencies-get.json b/tests/cassettes/agencies-get.json new file mode 100644 index 0000000..80f6c5d --- /dev/null +++ b/tests/cassettes/agencies-get.json @@ -0,0 +1,36 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/agencies/4700/" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "992", + "x-ratelimit-burst-reset": "55", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999915", + "x-ratelimit-daily-reset": "24295", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "992", + "x-ratelimit-reset": "55", + "x-tango-api-version": "4.22.0" + }, + "body": { + "abbreviation": "GSA", + "code": "4700", + "department": { + "code": 47, + "name": "General Services Administration" + }, + "name": "General Services Administration" + } + } + } + ] +} diff --git a/tests/cassettes/agencies-list.json b/tests/cassettes/agencies-list.json new file mode 100644 index 0000000..6e22603 --- /dev/null +++ b/tests/cassettes/agencies-list.json @@ -0,0 +1,79 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/agencies/?limit=5&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "993", + "x-ratelimit-burst-reset": "55", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999916", + "x-ratelimit-daily-reset": "24296", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "993", + "x-ratelimit-reset": "55", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 1496, + "next": "https://tango.makegov.com/api/agencies/?limit=5&page=2", + "previous": null, + "results": [ + { + "abbreviation": "", + "code": "21EB", + "department": { + "code": 97, + "name": "Department of Defense" + }, + "name": "1st Personnel Command" + }, + { + "abbreviation": "", + "code": "21E2", + "department": { + "code": 97, + "name": "Department of Defense" + }, + "name": "21st Theater Army Area Command" + }, + { + "abbreviation": "", + "code": "21EO", + "department": { + "code": 97, + "name": "Department of Defense" + }, + "name": "59th Ordnance Brigade" + }, + { + "abbreviation": "", + "code": "21EN", + "department": { + "code": 97, + "name": "Department of Defense" + }, + "name": "7th Army Training Command" + }, + { + "abbreviation": "", + "code": "21P8", + "department": { + "code": 97, + "name": "Department of Defense" + }, + "name": "8th U.S. Army" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/budget-list.json b/tests/cassettes/budget-list.json new file mode 100644 index 0000000..05b3910 --- /dev/null +++ b/tests/cassettes/budget-list.json @@ -0,0 +1,118 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/budget/accounts/?limit=3&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "976", + "x-ratelimit-burst-reset": "40", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999899", + "x-ratelimit-daily-reset": "24280", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "976", + "x-ratelimit-reset": "40", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 21176, + "next": "https://tango.makegov.com/api/budget/accounts/?limit=3&page=2", + "previous": null, + "results": [ + { + "account_title": "Flood Hazard Mapping and Risk Analysis Program", + "agency_code": null, + "agency_name": "Department of Homeland Security", + "apportioned": null, + "assistance_obligated": -163097.74, + "attribution_confidence": "none", + "attribution_status": "no_obligations", + "ba_growth_next_year_pct": null, + "bea_category": "Discretionary", + "bureau_name": "Federal Emergency Management Agency", + "contract_obligated": -1900635.3699999999, + "contract_obligated_estimated": null, + "contract_share_of_obligated_capped": null, + "enacted_ba": null, + "federal_account_symbol": "070-0500", + "fiscal_year": 2026, + "id": 17647, + "obligated_to_apportioned_pct_capped": null, + "obligated_to_enacted_pct_capped": null, + "obligated_total": null, + "on_off_budget": "On-budget", + "outlayed_to_obligated_pct_capped": null, + "outlayed_total": null, + "requested_ba": null, + "subfunction_code": "453", + "unobligated_balance": null + }, + { + "account_title": "Iraq and Afghanistan Service Grants Program, Office of Federal Student AID, Education", + "agency_code": null, + "agency_name": "Department of Education", + "apportioned": null, + "assistance_obligated": 0, + "attribution_confidence": "none", + "attribution_status": "no_obligations", + "ba_growth_next_year_pct": null, + "bea_category": null, + "bureau_name": "DEPARTMENT OF EDUCATION", + "contract_obligated": null, + "contract_obligated_estimated": null, + "contract_share_of_obligated_capped": null, + "enacted_ba": null, + "federal_account_symbol": "091-0248", + "fiscal_year": 2026, + "id": 18209, + "obligated_to_apportioned_pct_capped": null, + "obligated_to_enacted_pct_capped": null, + "obligated_total": null, + "on_off_budget": null, + "outlayed_to_obligated_pct_capped": null, + "outlayed_total": null, + "requested_ba": null, + "subfunction_code": null, + "unobligated_balance": null + }, + { + "account_title": "Non-Proliferation, Anti-Terrorism, Demining and Related Programs, International Security Assistance, State", + "agency_code": null, + "agency_name": "Executive Office of the President", + "apportioned": null, + "assistance_obligated": 131444259.87, + "attribution_confidence": "none", + "attribution_status": "no_obligations", + "ba_growth_next_year_pct": null, + "bea_category": "Discretionary", + "bureau_name": "State", + "contract_obligated": 58038558.83, + "contract_obligated_estimated": null, + "contract_share_of_obligated_capped": null, + "enacted_ba": null, + "federal_account_symbol": "011-1075", + "fiscal_year": 2026, + "id": 19681, + "obligated_to_apportioned_pct_capped": null, + "obligated_to_enacted_pct_capped": null, + "obligated_total": null, + "on_off_budget": "On-budget", + "outlayed_to_obligated_pct_capped": null, + "outlayed_total": null, + "requested_ba": null, + "subfunction_code": "152", + "unobligated_balance": null + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/budget-range.json b/tests/cassettes/budget-range.json new file mode 100644 index 0000000..314676b --- /dev/null +++ b/tests/cassettes/budget-range.json @@ -0,0 +1,174 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/budget/accounts/?fiscal_year__gte=2024&fiscal_year__lte=2025&limit=5&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "975", + "x-ratelimit-burst-reset": "39", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999898", + "x-ratelimit-daily-reset": "24280", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "975", + "x-ratelimit-reset": "39", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 4575, + "next": "https://tango.makegov.com/api/budget/accounts/?fiscal_year__gte=2024&fiscal_year__lte=2025&limit=5&page=2", + "previous": null, + "results": [ + { + "account_title": null, + "agency_code": null, + "agency_name": null, + "apportioned": null, + "assistance_obligated": null, + "attribution_confidence": "none", + "attribution_status": "no_obligations", + "ba_growth_next_year_pct": null, + "bea_category": null, + "bureau_name": null, + "contract_obligated": 619824889.99, + "contract_obligated_estimated": null, + "contract_share_of_obligated_capped": null, + "enacted_ba": null, + "federal_account_symbol": "010-0930", + "fiscal_year": 2025, + "id": 15646, + "obligated_to_apportioned_pct_capped": null, + "obligated_to_enacted_pct_capped": null, + "obligated_total": null, + "on_off_budget": null, + "outlayed_to_obligated_pct_capped": null, + "outlayed_total": null, + "requested_ba": null, + "subfunction_code": "752", + "unobligated_balance": null + }, + { + "account_title": "Federal Old-age and Survivors Insurance Trust Fund", + "agency_code": "028", + "agency_name": "Social Security Administration", + "apportioned": 30174108, + "assistance_obligated": null, + "attribution_confidence": "high", + "attribution_status": "file_c_covered", + "ba_growth_next_year_pct": null, + "bea_category": "Discretionary", + "bureau_name": "Social Security Administration", + "contract_obligated": null, + "contract_obligated_estimated": null, + "contract_share_of_obligated_capped": null, + "enacted_ba": 1433927806357.65, + "federal_account_symbol": "028-8006", + "fiscal_year": 2025, + "id": 16857, + "obligated_to_apportioned_pct_capped": 1, + "obligated_to_enacted_pct_capped": 1, + "obligated_total": 1433955632446.69, + "on_off_budget": "Off-budget", + "outlayed_to_obligated_pct_capped": 0.991397265639292, + "outlayed_total": 1421619693055.71, + "requested_ba": 1393363000000, + "subfunction_code": "651", + "unobligated_balance": 0 + }, + { + "account_title": "Interest on Treasury Debt Securities (gross)", + "agency_code": "020", + "agency_name": "Department of the Treasury", + "apportioned": 0, + "assistance_obligated": null, + "attribution_confidence": "none", + "attribution_status": "file_c_missing", + "ba_growth_next_year_pct": null, + "bea_category": "Net interest", + "bureau_name": "Interest on the Public Debt", + "contract_obligated": null, + "contract_obligated_estimated": null, + "contract_share_of_obligated_capped": null, + "enacted_ba": 1215613829754.39, + "federal_account_symbol": "020-0550", + "fiscal_year": 2025, + "id": 15498, + "obligated_to_apportioned_pct_capped": null, + "obligated_to_enacted_pct_capped": 1, + "obligated_total": 1215613829754.39, + "on_off_budget": "On-budget", + "outlayed_to_obligated_pct_capped": 1, + "outlayed_total": 1215613829754.39, + "requested_ba": 996122000000, + "subfunction_code": "901", + "unobligated_balance": 0 + }, + { + "account_title": "Grants to States for Medicaid", + "agency_code": "075", + "agency_name": "Department of Health and Human Services", + "apportioned": 2085587657043, + "assistance_obligated": 666810820371.43, + "attribution_confidence": "high", + "attribution_status": "file_c_covered", + "ba_growth_next_year_pct": null, + "bea_category": "Discretionary", + "bureau_name": "Centers for Medicare and Medicaid Services", + "contract_obligated": 5706220446.41, + "contract_obligated_estimated": null, + "contract_share_of_obligated_capped": 0.007877333719052351, + "enacted_ba": 672310864510.35, + "federal_account_symbol": "075-0512", + "fiscal_year": 2025, + "id": 15372, + "obligated_to_apportioned_pct_capped": 0.34732884581473855, + "obligated_to_enacted_pct_capped": 1, + "obligated_total": 724384753766.21, + "on_off_budget": "On-budget", + "outlayed_to_obligated_pct_capped": 0.9483381765610462, + "outlayed_total": 686961716515.27, + "requested_ba": 635816000000, + "subfunction_code": "551", + "unobligated_balance": 23000000 + }, + { + "account_title": "Payments to Health Care Trust Funds", + "agency_code": "075", + "agency_name": "Department of Health and Human Services", + "apportioned": 1220868753240, + "assistance_obligated": null, + "attribution_confidence": "none", + "attribution_status": "file_c_missing", + "ba_growth_next_year_pct": null, + "bea_category": "Mandatory", + "bureau_name": "Centers for Medicare and Medicaid Services", + "contract_obligated": null, + "contract_obligated_estimated": null, + "contract_share_of_obligated_capped": null, + "enacted_ba": 588955334742.92, + "federal_account_symbol": "075-0580", + "fiscal_year": 2025, + "id": 19579, + "obligated_to_apportioned_pct_capped": 0.48220311952499556, + "obligated_to_enacted_pct_capped": 0.9995778739314611, + "obligated_total": 588706721342.92, + "on_off_budget": "On-budget", + "outlayed_to_obligated_pct_capped": 0.9422232416586981, + "outlayed_total": 554693155369.99, + "requested_ba": 564824000000, + "subfunction_code": "571", + "unobligated_balance": 220022572820.92 + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/contracts-cursor.json b/tests/cassettes/contracts-cursor.json new file mode 100644 index 0000000..72e5267 --- /dev/null +++ b/tests/cassettes/contracts-cursor.json @@ -0,0 +1,107 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/contracts/?limit=2&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%29%2Cdescription%2Ctotal_contract_value" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "997", + "x-ratelimit-burst-reset": "58", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999920", + "x-ratelimit-daily-reset": "24299", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "997", + "x-ratelimit-reset": "58", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 86157384, + "next": "https://tango.makegov.com/api/contracts/?limit=2&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%29%2Cdescription%2Ctotal_contract_value&cursor=WyIyMDI2LTA4LTEzIiwgImZmMmIzNzA1LTA5NzktNWRkMC04YTE4LWFmOTgyNmEzODZmNiJd", + "previous": null, + "cursor": "WyIyMDI2LTA4LTEzIiwgImZmMmIzNzA1LTA5NzktNWRkMC04YTE4LWFmOTgyNmEzODZmNiJd", + "previous_cursor": null, + "results": [ + { + "award_date": "2026-08-13", + "description": "FY26 B1 MCKESSON PHARMACY STOCK MEDICATION JUL 26", + "key": "CONT_AWD_15B0AT26F41000011_1540_36W79720D0001_3600", + "piid": "15B0AT26F41000011", + "recipient": { + "display_name": "MCKESSON CORPORATION" + }, + "total_contract_value": 65000 + }, + { + "award_date": "2026-08-13", + "description": "FY26 Q4 COPIER REQUIREMENT", + "key": "CONT_AWD_15B31026F00000090_1540_GS03F045DA_4732", + "piid": "15B31026F00000090", + "recipient": { + "display_name": "KYOCERA DOCUMENT SOLUTIONS AMERICA INC" + }, + "total_contract_value": 5306.85 + } + ] + } + } + }, + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/contracts/?cursor=WyIyMDI2LTA4LTEzIiwgImZmMmIzNzA1LTA5NzktNWRkMC04YTE4LWFmOTgyNmEzODZmNiJd&limit=2&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%29%2Cdescription%2Ctotal_contract_value" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "996", + "x-ratelimit-burst-reset": "58", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999919", + "x-ratelimit-daily-reset": "24298", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "996", + "x-ratelimit-reset": "58", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 86157384, + "next": "https://tango.makegov.com/api/contracts/?limit=2&cursor=WyIyMDI2LTA4LTEzIiwgImZkZDU0ODUwLWE0OWUtNTQ2MC04YTdmLTE5YmI4YWNjYWY3MyJd&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%29%2Cdescription%2Ctotal_contract_value", + "previous": "https://tango.makegov.com/api/contracts/?limit=2&cursor=eyJ2IjogWyIyMDI2LTA4LTEzIiwgImZmMWIwY2JmLWVmZTItNTI0MC1iZmVlLWFkMWI2MmNlMjVkYyJdLCAiZCI6ICJwcmV2In0%3D&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%29%2Cdescription%2Ctotal_contract_value", + "cursor": "WyIyMDI2LTA4LTEzIiwgImZkZDU0ODUwLWE0OWUtNTQ2MC04YTdmLTE5YmI4YWNjYWY3MyJd", + "previous_cursor": "eyJ2IjogWyIyMDI2LTA4LTEzIiwgImZmMWIwY2JmLWVmZTItNTI0MC1iZmVlLWFkMWI2MmNlMjVkYyJdLCAiZCI6ICJwcmV2In0=", + "results": [ + { + "award_date": "2026-08-13", + "description": "FY-2026 A1 - TILT SKILLET - CULINARY DEPOT\nRP#: 0393-26\n\n* WOMEN-OWNED BUSINESS *\n\nORDERING FROM AND ADHERING TO THE TERMS AND CONDITIONS SET FORTH IN FEDERAL SUPPLY SCHEDULE GS-07F-0211V.", + "key": "CONT_AWD_15B30226F00000191_1540_GS07F0211V_4730", + "piid": "15B30226F00000191", + "recipient": { + "display_name": "CULINARY DEPOT INC." + }, + "total_contract_value": 19392.37 + }, + { + "award_date": "2026-08-13", + "description": "THIS CONTRACT PROVIDES MISSION-CRITICAL ADMINISTRATIVE, CLERICAL, AND LOGISTICAL SUPPORT TO SUPPORT FACT WITNESSES, INCLUDING WITNESS TRAVEL, LODGING.", + "key": "CONT_AWD_15JA3426F00000011_1501_GS07F0412V_4730", + "piid": "15JA3426F00000011", + "recipient": { + "display_name": "FORFEITURE SUPPORT ASSOCIATES LLC" + }, + "total_contract_value": 361574.4 + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/contracts-empty.json b/tests/cassettes/contracts-empty.json new file mode 100644 index 0000000..b19515b --- /dev/null +++ b/tests/cassettes/contracts-empty.json @@ -0,0 +1,35 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/contracts/?limit=3&search=zzzz-no-such-contract-zzzz&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%29%2Cdescription%2Ctotal_contract_value" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "994", + "x-ratelimit-burst-reset": "56", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999917", + "x-ratelimit-daily-reset": "24297", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "994", + "x-ratelimit-reset": "56", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 0, + "next": null, + "previous": null, + "cursor": null, + "previous_cursor": null, + "results": [] + } + } + } + ] +} diff --git a/tests/cassettes/contracts-filter.json b/tests/cassettes/contracts-filter.json new file mode 100644 index 0000000..a7bbd90 --- /dev/null +++ b/tests/cassettes/contracts-filter.json @@ -0,0 +1,54 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/contracts/?award_date_gte=2024-01-01&fiscal_year=2024&limit=3&shape=key%2Cpiid%2Caward_date%2Cfiscal_year" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "995", + "x-ratelimit-burst-reset": "57", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999918", + "x-ratelimit-daily-reset": "24297", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "995", + "x-ratelimit-reset": "57", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 134955, + "next": "https://tango.makegov.com/api/contracts/?limit=3&shape=key%2Cpiid%2Caward_date%2Cfiscal_year&fiscal_year=2024&award_date_gte=2024-01-01&cursor=WyIyMDI0LTA5LTMwIiwgImZmZWU2NDI2LTZlYWEtNWU0OS05MjkwLTFkNzQ2OWFhZDFiZCJd", + "previous": null, + "cursor": "WyIyMDI0LTA5LTMwIiwgImZmZWU2NDI2LTZlYWEtNWU0OS05MjkwLTFkNzQ2OWFhZDFiZCJd", + "previous_cursor": null, + "results": [ + { + "award_date": "2024-09-30", + "fiscal_year": 2024, + "key": "CONT_AWD_SPE3SU24FJJFB_9700_SPE30020DS351_9700", + "piid": "SPE3SU24FJJFB" + }, + { + "award_date": "2024-09-30", + "fiscal_year": 2024, + "key": "CONT_AWD_47QSSC24FFYM4_4732_GS02FW0003_4730", + "piid": "47QSSC24FFYM4" + }, + { + "award_date": "2024-09-30", + "fiscal_year": 2024, + "key": "CONT_AWD_FA667024C0005_9700_-NONE-_-NONE-", + "piid": "FA667024C0005" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/contracts-list.json b/tests/cassettes/contracts-list.json new file mode 100644 index 0000000..7721c81 --- /dev/null +++ b/tests/cassettes/contracts-list.json @@ -0,0 +1,66 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/contracts/?limit=3&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%29%2Cdescription%2Ctotal_contract_value" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "999", + "x-ratelimit-burst-reset": "59", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999922", + "x-ratelimit-daily-reset": "24300", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "999", + "x-ratelimit-reset": "59", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 86157384, + "next": "https://tango.makegov.com/api/contracts/?limit=3&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%29%2Cdescription%2Ctotal_contract_value&cursor=WyIyMDI2LTA4LTEzIiwgImZmMWIwY2JmLWVmZTItNTI0MC1iZmVlLWFkMWI2MmNlMjVkYyJd", + "previous": null, + "cursor": "WyIyMDI2LTA4LTEzIiwgImZmMWIwY2JmLWVmZTItNTI0MC1iZmVlLWFkMWI2MmNlMjVkYyJd", + "previous_cursor": null, + "results": [ + { + "award_date": "2026-08-13", + "description": "FY26 B1 MCKESSON PHARMACY STOCK MEDICATION JUL 26", + "key": "CONT_AWD_15B0AT26F41000011_1540_36W79720D0001_3600", + "piid": "15B0AT26F41000011", + "recipient": { + "display_name": "MCKESSON CORPORATION" + }, + "total_contract_value": 65000 + }, + { + "award_date": "2026-08-13", + "description": "FY26 Q4 COPIER REQUIREMENT", + "key": "CONT_AWD_15B31026F00000090_1540_GS03F045DA_4732", + "piid": "15B31026F00000090", + "recipient": { + "display_name": "KYOCERA DOCUMENT SOLUTIONS AMERICA INC" + }, + "total_contract_value": 5306.85 + }, + { + "award_date": "2026-08-13", + "description": "FY-2026 A1 - TILT SKILLET - CULINARY DEPOT\nRP#: 0393-26\n\n* WOMEN-OWNED BUSINESS *\n\nORDERING FROM AND ADHERING TO THE TERMS AND CONDITIONS SET FORTH IN FEDERAL SUPPLY SCHEDULE GS-07F-0211V.", + "key": "CONT_AWD_15B30226F00000191_1540_GS07F0211V_4730", + "piid": "15B30226F00000191", + "recipient": { + "display_name": "CULINARY DEPOT INC." + }, + "total_contract_value": 19392.37 + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/contracts-shape.json b/tests/cassettes/contracts-shape.json new file mode 100644 index 0000000..da17e8f --- /dev/null +++ b/tests/cassettes/contracts-shape.json @@ -0,0 +1,51 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/contracts/?limit=3&shape=key%2Cpiid%2Ctotal_contract_value" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "998", + "x-ratelimit-burst-reset": "59", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999921", + "x-ratelimit-daily-reset": "24299", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "998", + "x-ratelimit-reset": "59", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 86157384, + "next": "https://tango.makegov.com/api/contracts/?limit=3&shape=key%2Cpiid%2Ctotal_contract_value&cursor=WyIyMDI2LTA4LTEzIiwgImZmMWIwY2JmLWVmZTItNTI0MC1iZmVlLWFkMWI2MmNlMjVkYyJd", + "previous": null, + "cursor": "WyIyMDI2LTA4LTEzIiwgImZmMWIwY2JmLWVmZTItNTI0MC1iZmVlLWFkMWI2MmNlMjVkYyJd", + "previous_cursor": null, + "results": [ + { + "key": "CONT_AWD_15B0AT26F41000011_1540_36W79720D0001_3600", + "piid": "15B0AT26F41000011", + "total_contract_value": 65000 + }, + { + "key": "CONT_AWD_15B31026F00000090_1540_GS03F045DA_4732", + "piid": "15B31026F00000090", + "total_contract_value": 5306.85 + }, + { + "key": "CONT_AWD_15B30226F00000191_1540_GS07F0211V_4730", + "piid": "15B30226F00000191", + "total_contract_value": 19392.37 + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/dibbs-awards-list.json b/tests/cassettes/dibbs-awards-list.json new file mode 100644 index 0000000..ead38d6 --- /dev/null +++ b/tests/cassettes/dibbs-awards-list.json @@ -0,0 +1,67 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/dibbs/awards/?limit=3&page=1&shape=uuid%2Caward_number%2Csolicitation%2Cnsn%2Cpart_number%2Cnomenclature%2Cawardee_cage%2Caward_date%2Ctotal_contract_price" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "977", + "x-ratelimit-burst-reset": "41", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999900", + "x-ratelimit-daily-reset": "24281", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "977", + "x-ratelimit-reset": "41", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 207313, + "next": "https://tango.makegov.com/api/dibbs/awards/?limit=3&page=2&shape=uuid%2Caward_number%2Csolicitation%2Cnsn%2Cpart_number%2Cnomenclature%2Cawardee_cage%2Caward_date%2Ctotal_contract_price", + "previous": null, + "results": [ + { + "award_date": "2026-08-12", + "award_number": "SPE8E625D0003", + "awardee_cage": "55722", + "nomenclature": "BARBED WIRE, CONCERTINA", + "nsn": "5660014959566", + "part_number": null, + "solicitation": null, + "total_contract_price": 268500, + "uuid": "f998a1bf-d5fe-4595-86ae-97b384855723" + }, + { + "award_date": "2026-08-12", + "award_number": "SPE60526D1014", + "awardee_cage": "07ZM0", + "nomenclature": "DIESEL FUEL", + "nsn": "9140015240139", + "part_number": null, + "solicitation": null, + "total_contract_price": 20857.04, + "uuid": "294932af-d4a9-40c1-acdc-04880e5f9f49" + }, + { + "award_date": "2026-08-12", + "award_number": "SPE60525D1252", + "awardee_cage": "U11D1", + "nomenclature": "DIESEL FUEL", + "nsn": "9140015569156", + "part_number": null, + "solicitation": null, + "total_contract_price": 34420.15, + "uuid": "978b2a9e-66e1-4812-8e3b-8f505c98ba8d" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/dibbs-rfqs-list.json b/tests/cassettes/dibbs-rfqs-list.json new file mode 100644 index 0000000..5e8464f --- /dev/null +++ b/tests/cassettes/dibbs-rfqs-list.json @@ -0,0 +1,67 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/dibbs/rfqs/?limit=3&page=1&shape=uuid%2Csolicitation%2Cnsn%2Cpart_number%2Cnomenclature%2Cquantity%2Cissue_date%2Creturn_by_date%2Cis_open" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "979", + "x-ratelimit-burst-reset": "42", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999902", + "x-ratelimit-daily-reset": "24283", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "979", + "x-ratelimit-reset": "42", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 84451, + "next": "https://tango.makegov.com/api/dibbs/rfqs/?limit=3&page=2&shape=uuid%2Csolicitation%2Cnsn%2Cpart_number%2Cnomenclature%2Cquantity%2Cissue_date%2Creturn_by_date%2Cis_open", + "previous": null, + "results": [ + { + "is_open": true, + "issue_date": "2026-08-13", + "nomenclature": "STUD,SHOULDERED", + "nsn": "5307017062197", + "part_number": null, + "quantity": 15, + "return_by_date": "2026-08-18", + "solicitation": "SPE7L126T798H", + "uuid": "2160f63f-5f6d-40dd-9ba2-2d93c35ded0b" + }, + { + "is_open": true, + "issue_date": "2026-08-13", + "nomenclature": "TANK,HOT DIP,DIRECT", + "nsn": "3426014375654", + "part_number": null, + "quantity": 1, + "return_by_date": "2026-08-18", + "solicitation": "SPE8E626T3537", + "uuid": "ac5eb1e8-64da-4188-bb22-7aa63a8c8484" + }, + { + "is_open": false, + "issue_date": "2026-08-13", + "nomenclature": "SPLICE,CONDUCTOR", + "nsn": "5940013825664", + "part_number": null, + "quantity": 24, + "return_by_date": "2026-07-17", + "solicitation": "SPE7M126U4079", + "uuid": "ef9e2075-8c4b-49bf-aef6-875ae38e42b3" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/dibbs-rfqs-open.json b/tests/cassettes/dibbs-rfqs-open.json new file mode 100644 index 0000000..9d899a5 --- /dev/null +++ b/tests/cassettes/dibbs-rfqs-open.json @@ -0,0 +1,67 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/dibbs/rfqs/?limit=3&open=true&page=1&shape=uuid%2Csolicitation%2Cnsn%2Cpart_number%2Cnomenclature%2Cquantity%2Cissue_date%2Creturn_by_date%2Cis_open" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "978", + "x-ratelimit-burst-reset": "42", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999901", + "x-ratelimit-daily-reset": "24282", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "978", + "x-ratelimit-reset": "42", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 17935, + "next": "https://tango.makegov.com/api/dibbs/rfqs/?limit=3&open=true&page=2&shape=uuid%2Csolicitation%2Cnsn%2Cpart_number%2Cnomenclature%2Cquantity%2Cissue_date%2Creturn_by_date%2Cis_open", + "previous": null, + "results": [ + { + "is_open": true, + "issue_date": "2026-08-13", + "nomenclature": "STUD,SHOULDERED", + "nsn": "5307017062197", + "part_number": null, + "quantity": 15, + "return_by_date": "2026-08-18", + "solicitation": "SPE7L126T798H", + "uuid": "2160f63f-5f6d-40dd-9ba2-2d93c35ded0b" + }, + { + "is_open": true, + "issue_date": "2026-08-13", + "nomenclature": "TANK,HOT DIP,DIRECT", + "nsn": "3426014375654", + "part_number": null, + "quantity": 1, + "return_by_date": "2026-08-18", + "solicitation": "SPE8E626T3537", + "uuid": "ac5eb1e8-64da-4188-bb22-7aa63a8c8484" + }, + { + "is_open": true, + "issue_date": "2026-08-13", + "nomenclature": "STEAM COIL", + "nsn": "7320015059175", + "part_number": null, + "quantity": 1, + "return_by_date": "2026-08-18", + "solicitation": "SPE3SE26T1117", + "uuid": "38fd6dbf-7838-418d-8992-d350bf0ba35c" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/edge-contract-404.json b/tests/cassettes/edge-contract-404.json new file mode 100644 index 0000000..c82158b --- /dev/null +++ b/tests/cassettes/edge-contract-404.json @@ -0,0 +1,30 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/contracts/tango-node-no-such-key/?shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%29%2Cdescription%2Ctotal_contract_value" + }, + "response": { + "status": 404, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "985", + "x-ratelimit-burst-reset": "46", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999908", + "x-ratelimit-daily-reset": "24287", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "985", + "x-ratelimit-reset": "46", + "x-tango-api-version": "4.22.0" + }, + "body": { + "detail": "No Contract matches the given query." + } + } + } + ] +} diff --git a/tests/cassettes/edge-entities-empty.json b/tests/cassettes/edge-entities-empty.json new file mode 100644 index 0000000..ef1b66b --- /dev/null +++ b/tests/cassettes/edge-entities-empty.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/entities/?limit=3&page=1&search=zzzz-no-such-entity-zzzz&shape=uei%2Clegal_business_name%2Ccage_code%2Cbusiness_types" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "983", + "x-ratelimit-burst-reset": "45", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999906", + "x-ratelimit-daily-reset": "24286", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "983", + "x-ratelimit-reset": "45", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 0, + "next": null, + "previous": null, + "results": [] + } + } + } + ] +} diff --git a/tests/cassettes/edge-vehicles-bad-ordering.json b/tests/cassettes/edge-vehicles-bad-ordering.json new file mode 100644 index 0000000..fecbd4c --- /dev/null +++ b/tests/cassettes/edge-vehicles-bad-ordering.json @@ -0,0 +1,30 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/vehicles/?limit=3&ordering=not_a_real_field&page=1&shape=uuid%2Csolicitation_identifier%2Cis_synthetic_solicitation%2Cprogram_acronym%2Corganization_id%2Corganization%2Cvehicle_type%2Cdescription%2Cidv_count%2Cawardee_count%2Corder_count%2Ctotal_obligated%2Cvehicle_obligations%2Cvehicle_contracts_value%2Clatest_award_date%2Csolicitation_title%2Csolicitation_date" + }, + "response": { + "status": 400, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "984", + "x-ratelimit-burst-reset": "46", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999907", + "x-ratelimit-daily-reset": "24286", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "984", + "x-ratelimit-reset": "46", + "x-tango-api-version": "4.22.0" + }, + "body": { + "error": "Invalid ordering value(s): not_a_real_field. Allowed values are: award_date, fiscal_year, idv_count, last_date_to_order, latest_award_date, order_count, total_obligated, vehicle_obligations." + } + } + } + ] +} diff --git a/tests/cassettes/entities-filter.json b/tests/cassettes/entities-filter.json new file mode 100644 index 0000000..06cadc8 --- /dev/null +++ b/tests/cassettes/entities-filter.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/entities/?limit=3&page=1&shape=uei%2Clegal_business_name&state=VA" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "973", + "x-ratelimit-burst-reset": "37", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999896", + "x-ratelimit-daily-reset": "24277", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "973", + "x-ratelimit-reset": "37", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 844, + "next": "https://tango.makegov.com/api/entities/?limit=3&page=2&shape=uei%2Clegal_business_name&state=VA", + "previous": null, + "results": [ + { + "legal_business_name": "00ALPHA, LLC", + "uei": "N553JH75Z8K1" + }, + { + "legal_business_name": "1200 ARCHITECTURAL ENGINEERS, PLLC", + "uei": "HZKNREN1S1Y7" + }, + { + "legal_business_name": "2PROS CLEANING LLC", + "uei": "YMC2KSVRNCM5" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/entities-list.json b/tests/cassettes/entities-list.json new file mode 100644 index 0000000..2f6805d --- /dev/null +++ b/tests/cassettes/entities-list.json @@ -0,0 +1,76 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/entities/?limit=3&page=1&shape=uei%2Clegal_business_name%2Ccage_code%2Cbusiness_types" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "974", + "x-ratelimit-burst-reset": "38", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999897", + "x-ratelimit-daily-reset": "24279", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "974", + "x-ratelimit-reset": "38", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 1830156, + "next": "https://tango.makegov.com/api/entities/?limit=3&page=2&shape=uei%2Clegal_business_name%2Ccage_code%2Cbusiness_types", + "previous": null, + "results": [ + { + "business_types": [ + { + "code": "A2" + }, + { + "code": "23" + }, + { + "code": "OY" + }, + { + "code": "2X" + } + ], + "cage_code": null, + "legal_business_name": "!SCITAMEHTAM", + "uei": "JNSXDDCLHRM8" + }, + { + "business_types": [ + { + "code": "A8" + } + ], + "cage_code": "393W6", + "legal_business_name": "!YOUTHWORKS!", + "uei": "NLQ3EMTUVAT4" + }, + { + "business_types": [ + { + "code": "2X" + }, + { + "code": "XS" + } + ], + "cage_code": "4WBT9", + "legal_business_name": "\" HALL'S PUMP & WELL, INC.\"", + "uei": "XKJXMX585A76" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/exclusions-active.json b/tests/cassettes/exclusions-active.json new file mode 100644 index 0000000..b324718 --- /dev/null +++ b/tests/cassettes/exclusions-active.json @@ -0,0 +1,70 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/exclusions/?active=true&limit=3&page=1&shape=exclusion_key%2Cdisplay_name%2Centity_name%2Cuei%2Cclassification_type%2Cexclusion_type%2Cexcluding_agency_name%2Cactivate_date%2Ctermination_date%2Cis_currently_excluded" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "971", + "x-ratelimit-burst-reset": "35", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999894", + "x-ratelimit-daily-reset": "24275", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "971", + "x-ratelimit-reset": "35", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 161991, + "next": "https://tango.makegov.com/api/exclusions/?active=true&limit=3&page=2&shape=exclusion_key%2Cdisplay_name%2Centity_name%2Cuei%2Cclassification_type%2Cexclusion_type%2Cexcluding_agency_name%2Cactivate_date%2Ctermination_date%2Cis_currently_excluded", + "previous": null, + "results": [ + { + "activate_date": "2026-02-17", + "classification_type": "Individual", + "display_name": "Davendra Rampersaud", + "entity_name": "Davendra Rampersaud", + "excluding_agency_name": "AGENCY FOR INTERNATIONAL DEVELOPMENT", + "exclusion_key": "cca3d55eb11b1a2110ab5610c280ebd7c33f0b5fa7c0a85e8dd2cf807b9c4749", + "exclusion_type": "Ineligible (Proceedings Complete)", + "is_currently_excluded": true, + "termination_date": "2029-02-16", + "uei": "" + }, + { + "activate_date": "2026-07-17", + "classification_type": "Individual", + "display_name": "Esvin Fernando Marroquin Tupas", + "entity_name": "Esvin Fernando Marroquin Tupas", + "excluding_agency_name": "JUSTICE, DEPARTMENT OF", + "exclusion_key": "e9859ac007843befd8349e1d905ac10b1f003ff0aa8fd7dfa80c5ad3aa161938", + "exclusion_type": "Ineligible (Proceedings Complete)", + "is_currently_excluded": true, + "termination_date": "2031-07-16", + "uei": "" + }, + { + "activate_date": "2026-07-15", + "classification_type": "Individual", + "display_name": "Daniel Castillo-Hurtado", + "entity_name": "Daniel Castillo-Hurtado", + "excluding_agency_name": "JUSTICE, DEPARTMENT OF", + "exclusion_key": "6c263f882801d558a5cc6497d64f4893ae8cba3fe38c108c305cffcb4be66a1d", + "exclusion_type": "Ineligible (Proceedings Complete)", + "is_currently_excluded": true, + "termination_date": "2031-07-14", + "uei": "" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/exclusions-list.json b/tests/cassettes/exclusions-list.json new file mode 100644 index 0000000..49727cc --- /dev/null +++ b/tests/cassettes/exclusions-list.json @@ -0,0 +1,70 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/exclusions/?limit=3&page=1&shape=exclusion_key%2Cdisplay_name%2Centity_name%2Cuei%2Cclassification_type%2Cexclusion_type%2Cexcluding_agency_name%2Cactivate_date%2Ctermination_date%2Cis_currently_excluded" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "972", + "x-ratelimit-burst-reset": "36", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999895", + "x-ratelimit-daily-reset": "24276", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "972", + "x-ratelimit-reset": "36", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 163114, + "next": "https://tango.makegov.com/api/exclusions/?limit=3&page=2&shape=exclusion_key%2Cdisplay_name%2Centity_name%2Cuei%2Cclassification_type%2Cexclusion_type%2Cexcluding_agency_name%2Cactivate_date%2Ctermination_date%2Cis_currently_excluded", + "previous": null, + "results": [ + { + "activate_date": "2026-02-17", + "classification_type": "Individual", + "display_name": "Davendra Rampersaud", + "entity_name": "Davendra Rampersaud", + "excluding_agency_name": "AGENCY FOR INTERNATIONAL DEVELOPMENT", + "exclusion_key": "cca3d55eb11b1a2110ab5610c280ebd7c33f0b5fa7c0a85e8dd2cf807b9c4749", + "exclusion_type": "Ineligible (Proceedings Complete)", + "is_currently_excluded": true, + "termination_date": "2029-02-16", + "uei": "" + }, + { + "activate_date": "2026-07-17", + "classification_type": "Individual", + "display_name": "Esvin Fernando Marroquin Tupas", + "entity_name": "Esvin Fernando Marroquin Tupas", + "excluding_agency_name": "JUSTICE, DEPARTMENT OF", + "exclusion_key": "e9859ac007843befd8349e1d905ac10b1f003ff0aa8fd7dfa80c5ad3aa161938", + "exclusion_type": "Ineligible (Proceedings Complete)", + "is_currently_excluded": true, + "termination_date": "2031-07-16", + "uei": "" + }, + { + "activate_date": "2026-07-15", + "classification_type": "Individual", + "display_name": "Daniel Castillo-Hurtado", + "entity_name": "Daniel Castillo-Hurtado", + "excluding_agency_name": "JUSTICE, DEPARTMENT OF", + "exclusion_key": "6c263f882801d558a5cc6497d64f4893ae8cba3fe38c108c305cffcb4be66a1d", + "exclusion_type": "Ineligible (Proceedings Complete)", + "is_currently_excluded": true, + "termination_date": "2031-07-14", + "uei": "" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/forecasts-filter.json b/tests/cassettes/forecasts-filter.json new file mode 100644 index 0000000..1e0b8ea --- /dev/null +++ b/tests/cassettes/forecasts-filter.json @@ -0,0 +1,49 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/forecasts/?limit=3&naics_starts_with=54&page=1&shape=id%2Ctitle%2Cnaics_code" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "969", + "x-ratelimit-burst-reset": "33", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999892", + "x-ratelimit-daily-reset": "24274", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "969", + "x-ratelimit-reset": "33", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 7906, + "next": "https://tango.makegov.com/api/forecasts/?limit=3&naics_starts_with=54&page=2&shape=id%2Ctitle%2Cnaics_code", + "previous": null, + "results": [ + { + "id": 20210, + "naics_code": "541620", + "title": "Barker Mill CERCLA Response" + }, + { + "id": 19552, + "naics_code": "541519", + "title": "Checkpoint Enterprise Software Licenses and Support" + }, + { + "id": 18445, + "naics_code": "541519", + "title": "PrimeNG Support" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/forecasts-list.json b/tests/cassettes/forecasts-list.json new file mode 100644 index 0000000..9166965 --- /dev/null +++ b/tests/cassettes/forecasts-list.json @@ -0,0 +1,58 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/forecasts/?limit=3&page=1&shape=id%2Ctitle%2Canticipated_award_date%2Cfiscal_year%2Cnaics_code%2Cstatus" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "970", + "x-ratelimit-burst-reset": "34", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999893", + "x-ratelimit-daily-reset": "24274", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "970", + "x-ratelimit-reset": "34", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 24812, + "next": "https://tango.makegov.com/api/forecasts/?limit=3&page=2&shape=id%2Ctitle%2Canticipated_award_date%2Cfiscal_year%2Cnaics_code%2Cstatus", + "previous": null, + "results": [ + { + "anticipated_award_date": null, + "fiscal_year": 2026, + "id": 19690, + "naics_code": "561720", + "status": "Awarded", + "title": "RNC Janitorial Services" + }, + { + "anticipated_award_date": null, + "fiscal_year": 2026, + "id": 19691, + "naics_code": "811310", + "status": "Awarded", + "title": "Equipment Maintenance Services at Riverside National Cemetery" + }, + { + "anticipated_award_date": null, + "fiscal_year": 2026, + "id": 19692, + "naics_code": "561720", + "status": "Awarded", + "title": "Riverside National Cemetery Janitorial Services" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/grants-filter.json b/tests/cassettes/grants-filter.json new file mode 100644 index 0000000..b260daa --- /dev/null +++ b/tests/cassettes/grants-filter.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/grants/?limit=3&page=1&posted_date_after=2025-01-01&shape=grant_id%2Ctitle" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "969", + "x-ratelimit-burst-reset": "0", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999876", + "x-ratelimit-daily-reset": "24226", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "969", + "x-ratelimit-reset": "0", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 3967, + "next": "https://tango.makegov.com/api/grants/?limit=3&page=2&posted_date_after=2025-01-01&shape=grant_id%2Ctitle", + "previous": null, + "results": [ + { + "grant_id": 363555, + "title": "Strategies to Innovate EmeRgENcy Care Clinical Trials Network (SIREN) Infrastructure – Clinical Coordinating Center (CCC) and Data Coordinating Center (DCC)" + }, + { + "grant_id": 363557, + "title": "Alzheimer's Drug-Development Program (U01 Clinical Trial Optional)" + }, + { + "grant_id": 363556, + "title": "Strategies to Innovate EmeRgENcy Care Clinical Trials Network (SIREN) Infrastructure – Clinical Enrollment Hubs" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/grants-list.json b/tests/cassettes/grants-list.json new file mode 100644 index 0000000..6c64fcc --- /dev/null +++ b/tests/cassettes/grants-list.json @@ -0,0 +1,64 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/grants/?limit=3&page=1&shape=grant_id%2Copportunity_number%2Ctitle%2Cstatus%28*%29%2Cagency_code" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "969", + "x-ratelimit-burst-reset": "0", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999877", + "x-ratelimit-daily-reset": "24226", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "969", + "x-ratelimit-reset": "0", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 4852, + "next": "https://tango.makegov.com/api/grants/?limit=3&page=2&shape=grant_id%2Copportunity_number%2Ctitle%2Cstatus%28%2A%29%2Cagency_code", + "previous": null, + "results": [ + { + "agency_code": "HHS-NIH11", + "grant_id": 363555, + "opportunity_number": "RFA-NS-28-001", + "status": { + "code": "F", + "description": "Forecasted" + }, + "title": "Strategies to Innovate EmeRgENcy Care Clinical Trials Network (SIREN) Infrastructure – Clinical Coordinating Center (CCC) and Data Coordinating Center (DCC)" + }, + { + "agency_code": "HHS-NIH11", + "grant_id": 363557, + "opportunity_number": "RFA-AG-28-009", + "status": { + "code": "F", + "description": "Forecasted" + }, + "title": "Alzheimer's Drug-Development Program (U01 Clinical Trial Optional)" + }, + { + "agency_code": "HHS-NIH11", + "grant_id": 363556, + "opportunity_number": "RFA-NS-28-004", + "status": { + "code": "F", + "description": "Forecasted" + }, + "title": "Strategies to Innovate EmeRgENcy Care Clinical Trials Network (SIREN) Infrastructure – Clinical Enrollment Hubs" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/idvs-filter.json b/tests/cassettes/idvs-filter.json new file mode 100644 index 0000000..c351eeb --- /dev/null +++ b/tests/cassettes/idvs-filter.json @@ -0,0 +1,51 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/idvs/?fiscal_year=2024&limit=3&shape=key%2Cpiid%2Cfiscal_year" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "961", + "x-ratelimit-burst-reset": "27", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999884", + "x-ratelimit-daily-reset": "24268", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "961", + "x-ratelimit-reset": "27", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 30645, + "next": "https://tango.makegov.com/api/idvs/?limit=3&shape=key%2Cpiid%2Cfiscal_year&fiscal_year=2024&cursor=WyIyMDI0LTA5LTMwIiwgImZmM2Q3YzFiLTE2NGUtNTgwMS04NDg0LTMyMzc2OWJhOTIyMyJd", + "previous": null, + "cursor": "WyIyMDI0LTA5LTMwIiwgImZmM2Q3YzFiLTE2NGUtNTgwMS04NDg0LTMyMzc2OWJhOTIyMyJd", + "previous_cursor": null, + "results": [ + { + "fiscal_year": 2024, + "key": "CONT_IDV_47QRCA24DW144_4732", + "piid": "47QRCA24DW144" + }, + { + "fiscal_year": 2024, + "key": "CONT_IDV_47QRCA24DW254_4732", + "piid": "47QRCA24DW254" + }, + { + "fiscal_year": 2024, + "key": "CONT_IDV_75P00124A00024_7570", + "piid": "75P00124A00024" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/idvs-list.json b/tests/cassettes/idvs-list.json new file mode 100644 index 0000000..c3ceb50 --- /dev/null +++ b/tests/cassettes/idvs-list.json @@ -0,0 +1,75 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/idvs/?limit=3&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%2Cuei%29%2Cdescription%2Ctotal_contract_value%2Cobligated%2Cidv_type" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "962", + "x-ratelimit-burst-reset": "28", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999885", + "x-ratelimit-daily-reset": "24268", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "962", + "x-ratelimit-reset": "28", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 1200293, + "next": "https://tango.makegov.com/api/idvs/?limit=3&shape=key%2Cpiid%2Caward_date%2Crecipient%28display_name%2Cuei%29%2Cdescription%2Ctotal_contract_value%2Cobligated%2Cidv_type&cursor=WyIyMDI2LTA4LTEzIiwgImZiODczMTg3LWU4YTMtNWMzNi05ZGEzLWFjM2I5ZDQ2MTBhYyJd", + "previous": null, + "cursor": "WyIyMDI2LTA4LTEzIiwgImZiODczMTg3LWU4YTMtNWMzNi05ZGEzLWFjM2I5ZDQ2MTBhYyJd", + "previous_cursor": null, + "results": [ + { + "award_date": "2026-08-13", + "description": "TEMPORARY SURVEY TECHNICIAN SERVICES SUPPORTING USDA NRCS FIELD OFFICES THROUGHOUT NEBRASKA", + "idv_type": "E", + "key": "CONT_IDV_12FPC126A0001_12D0", + "obligated": 0, + "piid": "12FPC126A0001", + "recipient": { + "uei": "UX6XA5HES291", + "display_name": "TMPC INC" + }, + "total_contract_value": 6000000 + }, + { + "award_date": "2026-08-13", + "description": "WEST ZONE POTABLE & GRAY WATER TRUCK/HANDWASHING STATION (TRAILER MOUNTED) FOR REGION 6 - PACIFIC NORTHWEST REGION ONLY", + "idv_type": "B", + "key": "CONT_IDV_1204H126T8107_12C2", + "obligated": 0, + "piid": "1204H126T8107", + "recipient": { + "uei": "LFZ8HTQ77UA5", + "display_name": "SAUL'S MOBILE PRESSURE WASHING LLC" + }, + "total_contract_value": 250000 + }, + { + "award_date": "2026-08-13", + "description": "ONE ACQUISITION SOLUTION FOR INTEGRATED SERVICES PLUS (OASIS+) UNRESTRICTED MULTIPLE AGENCY CONTRACT (MAC)", + "idv_type": "B", + "key": "CONT_IDV_47QRCA26DU022_4732", + "obligated": 2500, + "piid": "47QRCA26DU022", + "recipient": { + "uei": "MLCEWFN6PHL3", + "display_name": "CLARITY INNOVATIONS LLC" + }, + "total_contract_value": 999999999999 + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/naics-get.json b/tests/cassettes/naics-get.json new file mode 100644 index 0000000..b29b0a2 --- /dev/null +++ b/tests/cassettes/naics-get.json @@ -0,0 +1,45 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/naics/541511/" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "988", + "x-ratelimit-burst-reset": "52", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999911", + "x-ratelimit-daily-reset": "24293", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "988", + "x-ratelimit-reset": "52", + "x-tango-api-version": "4.22.0" + }, + "body": { + "code": 541511, + "description": "Custom Computer Programming Services", + "federal_obligations": { + "total": { + "awards_obligated": 224981597975.28, + "awards_count": 99562 + }, + "active": { + "awards_obligated": 22822122349.79, + "awards_count": 3780 + } + }, + "size_standards": { + "employee_limit": null, + "revenue_limit": 34000000 + } + } + } + } + ] +} diff --git a/tests/cassettes/naics-list.json b/tests/cassettes/naics-list.json new file mode 100644 index 0000000..227b50a --- /dev/null +++ b/tests/cassettes/naics-list.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/naics/?limit=3&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "989", + "x-ratelimit-burst-reset": "53", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999912", + "x-ratelimit-daily-reset": "24293", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "989", + "x-ratelimit-reset": "53", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 1012, + "next": "https://tango.makegov.com/api/naics/?limit=3&page=2", + "previous": null, + "results": [ + { + "code": 111110, + "description": "Soybean Farming" + }, + { + "code": 111120, + "description": "Oilseed (except Soybean) Farming" + }, + { + "code": 111130, + "description": "Dry Pea and Bean Farming" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/notices-filter.json b/tests/cassettes/notices-filter.json new file mode 100644 index 0000000..83eba3e --- /dev/null +++ b/tests/cassettes/notices-filter.json @@ -0,0 +1,52 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/notices/?limit=3&page=1&posted_date_after=2025-01-01&shape=notice_id%2Ctitle%2Csolicitation_number%2Cposted_date" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "963", + "x-ratelimit-burst-reset": "29", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999886", + "x-ratelimit-daily-reset": "24269", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "963", + "x-ratelimit-reset": "29", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 650660, + "next": "https://tango.makegov.com/api/notices/?limit=3&page=2&posted_date_after=2025-01-01&shape=notice_id%2Ctitle%2Csolicitation_number%2Cposted_date", + "previous": null, + "results": [ + { + "notice_id": "d45af4c8-a293-338c-8a11-5581354b7b21", + "posted_date": "2029-12-20T06:18:21+00:00", + "solicitation_number": "M6740010T0104", + "title": "G--Keyboardist- Catholic Services, 1200 SUN MCAS Futenma" + }, + { + "notice_id": "ba9961ee-0b29-4dbc-b9a7-2c6d2952c54b", + "posted_date": "2026-08-14T16:29:55+00:00", + "solicitation_number": "N0018926QL330", + "title": "NCTAMS LANT HVAC Support Services" + }, + { + "notice_id": "2a274420-1974-4c74-8cc2-77369f8769e4", + "posted_date": "2026-08-14T16:29:28+00:00", + "solicitation_number": "140P1326Q0030", + "title": "324933E PUMPING OF VAULT TOILETS" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/notices-list.json b/tests/cassettes/notices-list.json new file mode 100644 index 0000000..0a3232f --- /dev/null +++ b/tests/cassettes/notices-list.json @@ -0,0 +1,52 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/notices/?limit=3&page=1&shape=notice_id%2Ctitle%2Csolicitation_number%2Cposted_date" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "964", + "x-ratelimit-burst-reset": "30", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999887", + "x-ratelimit-daily-reset": "24270", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "964", + "x-ratelimit-reset": "30", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 8280209, + "next": "https://tango.makegov.com/api/notices/?limit=3&page=2&shape=notice_id%2Ctitle%2Csolicitation_number%2Cposted_date", + "previous": null, + "results": [ + { + "notice_id": "5e141b7b-68e3-199e-4a29-fa59bdcd250e", + "posted_date": null, + "solicitation_number": null, + "title": "missing title" + }, + { + "notice_id": "576207a3-6324-d47d-bfc7-09355520361b", + "posted_date": null, + "solicitation_number": null, + "title": "missing title" + }, + { + "notice_id": "93e3f973-ca3e-8f0e-366c-b3619576c810", + "posted_date": null, + "solicitation_number": null, + "title": "missing title" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/opportunities-filter.json b/tests/cassettes/opportunities-filter.json new file mode 100644 index 0000000..136561c --- /dev/null +++ b/tests/cassettes/opportunities-filter.json @@ -0,0 +1,49 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/opportunities/?active=true&limit=3&page=1&shape=opportunity_id%2Ctitle%2Cactive" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "967", + "x-ratelimit-burst-reset": "32", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999890", + "x-ratelimit-daily-reset": "24272", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "967", + "x-ratelimit-reset": "32", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 45677, + "next": "https://tango.makegov.com/api/opportunities/?active=true&limit=3&page=2&shape=opportunity_id%2Ctitle%2Cactive", + "previous": null, + "results": [ + { + "active": true, + "opportunity_id": "ba9961ee-0b29-4dbc-b9a7-2c6d2952c54b", + "title": "NCTAMS LANT HVAC Support Services" + }, + { + "active": true, + "opportunity_id": "2a274420-1974-4c74-8cc2-77369f8769e4", + "title": "324933E PUMPING OF VAULT TOILETS" + }, + { + "active": true, + "opportunity_id": "0e333258-a75c-409a-92c9-c02001576722", + "title": "USACE Portland - Bow Thruster Propeller Purchase" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/opportunities-list.json b/tests/cassettes/opportunities-list.json new file mode 100644 index 0000000..ec38409 --- /dev/null +++ b/tests/cassettes/opportunities-list.json @@ -0,0 +1,55 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/opportunities/?limit=3&page=1&shape=opportunity_id%2Ctitle%2Csolicitation_number%2Cresponse_deadline%2Cactive" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "968", + "x-ratelimit-burst-reset": "33", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999891", + "x-ratelimit-daily-reset": "24273", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "968", + "x-ratelimit-reset": "33", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 45677, + "next": "https://tango.makegov.com/api/opportunities/?limit=3&page=2&shape=opportunity_id%2Ctitle%2Csolicitation_number%2Cresponse_deadline%2Cactive", + "previous": null, + "results": [ + { + "active": true, + "opportunity_id": "ba9961ee-0b29-4dbc-b9a7-2c6d2952c54b", + "response_deadline": "2026-08-24T14:00:00+00:00", + "solicitation_number": "N0018926QL330", + "title": "NCTAMS LANT HVAC Support Services" + }, + { + "active": true, + "opportunity_id": "2a274420-1974-4c74-8cc2-77369f8769e4", + "response_deadline": "2026-08-31T18:00:00+00:00", + "solicitation_number": "140P1326Q0030", + "title": "324933E PUMPING OF VAULT TOILETS" + }, + { + "active": true, + "opportunity_id": "0e333258-a75c-409a-92c9-c02001576722", + "response_deadline": "2026-08-19T19:00:00+00:00", + "solicitation_number": "W9127N26Q1CE6", + "title": "USACE Portland - Bow Thruster Propeller Purchase" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/organizations-filter.json b/tests/cassettes/organizations-filter.json new file mode 100644 index 0000000..53b710a --- /dev/null +++ b/tests/cassettes/organizations-filter.json @@ -0,0 +1,79 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/organizations/?level=1&limit=3&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "990", + "x-ratelimit-burst-reset": "54", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999913", + "x-ratelimit-daily-reset": "24294", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "990", + "x-ratelimit-reset": "54", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 168, + "next": "https://tango.makegov.com/api/organizations/?level=1&limit=3&page=2", + "previous": null, + "results": [ + { + "canonical_code": "L1:9700", + "cgac": "097", + "code": "097", + "fh_key": "100000000", + "fpds_code": "9700", + "full_parent_path_name": "DEPT OF DEFENSE", + "is_active": true, + "key": "2278181c-046b-5265-b4e6-74444829a573", + "level": 1, + "name": "DEPT OF DEFENSE", + "parent_fh_key": null, + "short_name": "DOD", + "type": "DEPARTMENT" + }, + { + "canonical_code": "L1:6900", + "cgac": "069", + "code": "069", + "fh_key": "100000136", + "fpds_code": "6900", + "full_parent_path_name": "TRANSPORTATION, DEPARTMENT OF", + "is_active": true, + "key": "0ae2882f-df52-52f2-941f-98cd6aa9326c", + "level": 1, + "name": "TRANSPORTATION, DEPARTMENT OF", + "parent_fh_key": null, + "short_name": "DOT", + "type": "DEPARTMENT" + }, + { + "canonical_code": "L1:8000", + "cgac": "080", + "code": "080", + "fh_key": "100000266", + "fpds_code": "8000", + "full_parent_path_name": "NATIONAL AERONAUTICS AND SPACE ADMINISTRATION", + "is_active": true, + "key": "aecc8c09-638c-5271-8915-8b499f920587", + "level": 1, + "name": "NATIONAL AERONAUTICS AND SPACE ADMINISTRATION", + "parent_fh_key": null, + "short_name": "NASA", + "type": "DEPARTMENT" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/organizations-list.json b/tests/cassettes/organizations-list.json new file mode 100644 index 0000000..2dcc08d --- /dev/null +++ b/tests/cassettes/organizations-list.json @@ -0,0 +1,79 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/organizations/?limit=3&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "991", + "x-ratelimit-burst-reset": "54", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999914", + "x-ratelimit-daily-reset": "24295", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "991", + "x-ratelimit-reset": "54", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 177142, + "next": "https://tango.makegov.com/api/organizations/?limit=3&page=2", + "previous": null, + "results": [ + { + "canonical_code": "L1:9700", + "cgac": "097", + "code": "097", + "fh_key": "100000000", + "fpds_code": "9700", + "full_parent_path_name": "DEPT OF DEFENSE", + "is_active": true, + "key": "2278181c-046b-5265-b4e6-74444829a573", + "level": 1, + "name": "DEPT OF DEFENSE", + "parent_fh_key": null, + "short_name": "DOD", + "type": "DEPARTMENT" + }, + { + "canonical_code": "L3:9700:5700:F8B6ES", + "cgac": "057", + "code": "F8B6ES", + "fh_key": "100000002", + "fpds_code": "5700", + "full_parent_path_name": "DEPT OF DEFENSE.DEPT OF THE AIR FORCE.ESSO", + "is_active": true, + "key": "1cbfdd1d-9fcf-5ef2-b162-d93caa89d354", + "level": 3, + "name": "ESSO", + "parent_fh_key": "300000251", + "short_name": null, + "type": "OFFICE" + }, + { + "canonical_code": "L3:9700:5700:F8B6FS", + "cgac": "057", + "code": "F8B6FS", + "fh_key": "100000003", + "fpds_code": "5700", + "full_parent_path_name": "DEPT OF DEFENSE.DEPT OF THE AIR FORCE.FAMILY SUPPORT", + "is_active": true, + "key": "7b84c7cc-cbbd-5ed4-848a-3e0ebce3d57e", + "level": 3, + "name": "FAMILY SUPPORT", + "parent_fh_key": "300000251", + "short_name": null, + "type": "OFFICE" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/protests-filter.json b/tests/cassettes/protests-filter.json new file mode 100644 index 0000000..c504b95 --- /dev/null +++ b/tests/cassettes/protests-filter.json @@ -0,0 +1,112 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/protests/?filed_date_after=2025-01-01&limit=3&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "955", + "x-ratelimit-burst-reset": "23", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999878", + "x-ratelimit-daily-reset": "24263", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "955", + "x-ratelimit-reset": "23", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 1587, + "next": "https://tango.makegov.com/api/protests/?filed_date_after=2025-01-01&limit=3&page=2", + "previous": null, + "results": [ + { + "agency": "Department of Homeland Security : Department of Homeland Security", + "case_id": "79b90eb7-24d4-56af-aec3-e94c8e84a302", + "case_number": "b-424490", + "case_type": "Bid Protest", + "decision_date": "2026-08-13", + "decision_url": null, + "docket_url": "https://www.gao.gov/docket/b-424490.1", + "due_date": "2026-08-17", + "filed_date": "2026-05-08", + "organization": { + "organization_id": "a8fa72a7-1423-526f-bdd4-40d8319b9f4f", + "office_code": "070", + "office_name": "HOMELAND SECURITY, DEPARTMENT OF", + "agency_code": "7000", + "agency_name": null, + "department_code": "070", + "department_name": "HOMELAND SECURITY, DEPARTMENT OF" + }, + "outcome": "Denied", + "posted_date": "2026-08-13", + "protester": "Integrity Management Consulting, Inc.", + "solicitation_number": "70RTAC25Q00000042", + "source_system": "gao", + "title": "Integrity Management Consulting, Inc. (70RTAC25Q00000042)" + }, + { + "agency": "Department of the Interior : Bureau of Indian Affairs", + "case_id": "47b02a76-79bd-5660-93b9-2f0ee5f476b2", + "case_number": "b-424540", + "case_type": "Bid Protest", + "decision_date": "2026-08-13", + "decision_url": null, + "docket_url": "https://www.gao.gov/docket/b-424540.1", + "due_date": "2026-09-08", + "filed_date": "2026-05-29", + "organization": { + "organization_id": "5439f74a-1c16-5d3d-9d10-1d23e418d6eb", + "office_code": "1450", + "office_name": "BUREAU OF INDIAN AFFAIRS", + "agency_code": "1450", + "agency_name": "BUREAU OF INDIAN AFFAIRS", + "department_code": "014", + "department_name": "INTERIOR, DEPARTMENT OF THE" + }, + "outcome": "Denied", + "posted_date": "2026-08-13", + "protester": "Oready, LLC", + "solicitation_number": "140A2326Q0129", + "source_system": "gao", + "title": "Oready, LLC (140A2326Q0129)" + }, + { + "agency": "Department of Health and Human Services : Centers for Disease Control and Prevention", + "case_id": "a105a37a-a6a6-5713-9d40-83b1d01a3547", + "case_number": "b-424675", + "case_type": "Bid Protest", + "decision_date": "2026-08-13", + "decision_url": null, + "docket_url": "https://www.gao.gov/docket/b-424675.1", + "due_date": "2026-11-02", + "filed_date": "2026-07-23", + "organization": { + "organization_id": "2a844073-ba16-53e3-ac40-22340749941e", + "office_code": "7523", + "office_name": "CENTERS FOR DISEASE CONTROL AND PREVENTION", + "agency_code": "7523", + "agency_name": "CENTERS FOR DISEASE CONTROL AND PREVENTION", + "department_code": "075", + "department_name": "HEALTH AND HUMAN SERVICES, DEPARTMENT OF" + }, + "outcome": "Dismissed", + "posted_date": "2026-08-13", + "protester": "Alpha Genesis, Inc.", + "solicitation_number": "75D30126Q79062", + "source_system": "gao", + "title": "Alpha Genesis, Inc. (75D30126Q79062)" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/protests-list.json b/tests/cassettes/protests-list.json new file mode 100644 index 0000000..00754f2 --- /dev/null +++ b/tests/cassettes/protests-list.json @@ -0,0 +1,112 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/protests/?limit=3&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "956", + "x-ratelimit-burst-reset": "23", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999879", + "x-ratelimit-daily-reset": "24264", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "956", + "x-ratelimit-reset": "23", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 15109, + "next": "https://tango.makegov.com/api/protests/?limit=3&page=2", + "previous": null, + "results": [ + { + "agency": "Department of Homeland Security : Department of Homeland Security", + "case_id": "79b90eb7-24d4-56af-aec3-e94c8e84a302", + "case_number": "b-424490", + "case_type": "Bid Protest", + "decision_date": "2026-08-13", + "decision_url": null, + "docket_url": "https://www.gao.gov/docket/b-424490.1", + "due_date": "2026-08-17", + "filed_date": "2026-05-08", + "organization": { + "organization_id": "a8fa72a7-1423-526f-bdd4-40d8319b9f4f", + "office_code": "070", + "office_name": "HOMELAND SECURITY, DEPARTMENT OF", + "agency_code": "7000", + "agency_name": null, + "department_code": "070", + "department_name": "HOMELAND SECURITY, DEPARTMENT OF" + }, + "outcome": "Denied", + "posted_date": "2026-08-13", + "protester": "Integrity Management Consulting, Inc.", + "solicitation_number": "70RTAC25Q00000042", + "source_system": "gao", + "title": "Integrity Management Consulting, Inc. (70RTAC25Q00000042)" + }, + { + "agency": "Department of the Interior : Bureau of Indian Affairs", + "case_id": "47b02a76-79bd-5660-93b9-2f0ee5f476b2", + "case_number": "b-424540", + "case_type": "Bid Protest", + "decision_date": "2026-08-13", + "decision_url": null, + "docket_url": "https://www.gao.gov/docket/b-424540.1", + "due_date": "2026-09-08", + "filed_date": "2026-05-29", + "organization": { + "organization_id": "5439f74a-1c16-5d3d-9d10-1d23e418d6eb", + "office_code": "1450", + "office_name": "BUREAU OF INDIAN AFFAIRS", + "agency_code": "1450", + "agency_name": "BUREAU OF INDIAN AFFAIRS", + "department_code": "014", + "department_name": "INTERIOR, DEPARTMENT OF THE" + }, + "outcome": "Denied", + "posted_date": "2026-08-13", + "protester": "Oready, LLC", + "solicitation_number": "140A2326Q0129", + "source_system": "gao", + "title": "Oready, LLC (140A2326Q0129)" + }, + { + "agency": "Department of Health and Human Services : Centers for Disease Control and Prevention", + "case_id": "a105a37a-a6a6-5713-9d40-83b1d01a3547", + "case_number": "b-424675", + "case_type": "Bid Protest", + "decision_date": "2026-08-13", + "decision_url": null, + "docket_url": "https://www.gao.gov/docket/b-424675.1", + "due_date": "2026-11-02", + "filed_date": "2026-07-23", + "organization": { + "organization_id": "2a844073-ba16-53e3-ac40-22340749941e", + "office_code": "7523", + "office_name": "CENTERS FOR DISEASE CONTROL AND PREVENTION", + "agency_code": "7523", + "agency_name": "CENTERS FOR DISEASE CONTROL AND PREVENTION", + "department_code": "075", + "department_name": "HEALTH AND HUMAN SERVICES, DEPARTMENT OF" + }, + "outcome": "Dismissed", + "posted_date": "2026-08-13", + "protester": "Alpha Genesis, Inc.", + "solicitation_number": "75D30126Q79062", + "source_system": "gao", + "title": "Alpha Genesis, Inc. (75D30126Q79062)" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/psc-filter.json b/tests/cassettes/psc-filter.json new file mode 100644 index 0000000..95b631b --- /dev/null +++ b/tests/cassettes/psc-filter.json @@ -0,0 +1,88 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/psc/?has_awards=true&limit=3&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "986", + "x-ratelimit-burst-reset": "47", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999909", + "x-ratelimit-daily-reset": "24287", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "986", + "x-ratelimit-reset": "47", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 2243, + "next": "https://tango.makegov.com/api/psc/?has_awards=true&limit=3&page=2", + "previous": null, + "results": [ + { + "category": "", + "code": "1005", + "current": { + "name": "GUNS, THROUGH 30MM", + "active": true, + "start_date": "2011-10-01", + "end_date": null, + "description": "Guns, through 30 mm", + "includes": "Machine guns; Brushes, Machine Gun and Pistol.", + "excludes": "Turrets, Aircraft." + }, + "level_1_category": "", + "level_1_category_code": null, + "level_2_category": "", + "level_2_category_code": null, + "parent": "" + }, + { + "category": "", + "code": "1010", + "current": { + "name": "GUNS, OVER 30MM UP TO 75MM", + "active": true, + "start_date": "2011-10-01", + "end_date": null, + "description": "Guns, over 30 mm up to 75 mm", + "includes": "Breech Mechanisms; Mounts Grenade Launchers for Integral-Cartridge Grenades, Single-Shot or Auto-Loading or Automatic-Firing.", + "excludes": "" + }, + "level_1_category": "", + "level_1_category_code": null, + "level_2_category": "", + "level_2_category_code": null, + "parent": "" + }, + { + "category": "", + "code": "1015", + "current": { + "name": "GUNS, 75MM THROUGH 125MM", + "active": true, + "start_date": "2011-10-01", + "end_date": null, + "description": "Guns, 75 mm through 125 mm", + "includes": "Breech Mechanisms; Mounts; Rammers.", + "excludes": "" + }, + "level_1_category": "", + "level_1_category_code": null, + "level_2_category": "", + "level_2_category_code": null, + "parent": "" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/psc-list.json b/tests/cassettes/psc-list.json new file mode 100644 index 0000000..68b2499 --- /dev/null +++ b/tests/cassettes/psc-list.json @@ -0,0 +1,88 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/psc/?limit=3&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "987", + "x-ratelimit-burst-reset": "52", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999910", + "x-ratelimit-daily-reset": "24292", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "987", + "x-ratelimit-reset": "52", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 2526, + "next": "https://tango.makegov.com/api/psc/?limit=3&page=2", + "previous": null, + "results": [ + { + "category": "", + "code": "10", + "current": { + "name": "WEAPONS", + "active": true, + "start_date": "1979-10-01", + "end_date": null, + "description": "", + "includes": "", + "excludes": "" + }, + "level_1_category": "", + "level_1_category_code": null, + "level_2_category": "", + "level_2_category_code": null, + "parent": "" + }, + { + "category": "", + "code": "1005", + "current": { + "name": "GUNS, THROUGH 30MM", + "active": true, + "start_date": "2011-10-01", + "end_date": null, + "description": "Guns, through 30 mm", + "includes": "Machine guns; Brushes, Machine Gun and Pistol.", + "excludes": "Turrets, Aircraft." + }, + "level_1_category": "", + "level_1_category_code": null, + "level_2_category": "", + "level_2_category_code": null, + "parent": "" + }, + { + "category": "", + "code": "1010", + "current": { + "name": "GUNS, OVER 30MM UP TO 75MM", + "active": true, + "start_date": "2011-10-01", + "end_date": null, + "description": "Guns, over 30 mm up to 75 mm", + "includes": "Breech Mechanisms; Mounts Grenade Launchers for Integral-Cartridge Grenades, Single-Shot or Auto-Loading or Automatic-Firing.", + "excludes": "" + }, + "level_1_category": "", + "level_1_category_code": null, + "level_2_category": "", + "level_2_category_code": null, + "parent": "" + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/sbir-solicitations-list.json b/tests/cassettes/sbir-solicitations-list.json new file mode 100644 index 0000000..04d86b3 --- /dev/null +++ b/tests/cassettes/sbir-solicitations-list.json @@ -0,0 +1,70 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/sbir/solicitations/?limit=3&page=1&shape=solicitation_id%2Csolicitation_number%2Ctitle%2Cprogram%2Cactivity%2Ccycle_name%2Csolicitation_status%2Cyear%2Cstart_date%2Cend_date" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "980", + "x-ratelimit-burst-reset": "43", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999903", + "x-ratelimit-daily-reset": "24284", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "980", + "x-ratelimit-reset": "43", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 240, + "next": "https://tango.makegov.com/api/sbir/solicitations/?limit=3&page=2&shape=solicitation_id%2Csolicitation_number%2Ctitle%2Cprogram%2Cactivity%2Ccycle_name%2Csolicitation_status%2Cyear%2Cstart_date%2Cend_date", + "previous": null, + "results": [ + { + "activity": "open", + "cycle_name": "DOD_SBIR_2026_P1_CBZ", + "end_date": "2026-12-31", + "program": "SBIR", + "solicitation_id": "dsip-solicitation-7c6951570946982dd502", + "solicitation_number": "26.BZ", + "solicitation_status": "active", + "start_date": "2026-04-13", + "title": "DoW SBIR 2026 BAA", + "year": 2026 + }, + { + "activity": "open", + "cycle_name": "DOD_SBIR_2026_P1_CBX", + "end_date": "2026-12-31", + "program": "SBIR", + "solicitation_id": "dsip-solicitation-45ee28cc99c45b9fa1cf", + "solicitation_number": "26.BX", + "solicitation_status": "active", + "start_date": "2026-04-13", + "title": "DoW SBIR 2026 CSO", + "year": 2026 + }, + { + "activity": "open", + "cycle_name": "DOD_STTR_2026_P1_CTZ", + "end_date": "2026-12-31", + "program": "STTR", + "solicitation_id": "dsip-solicitation-bc8eb4742bc5b8f944d8", + "solicitation_number": "26.TZ", + "solicitation_status": "active", + "start_date": "2026-04-13", + "title": "DoW STTR 2026 BAA", + "year": 2026 + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/sbir-topics-filter.json b/tests/cassettes/sbir-topics-filter.json new file mode 100644 index 0000000..335a40e --- /dev/null +++ b/tests/cassettes/sbir-topics-filter.json @@ -0,0 +1,70 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/sbir/topics/?limit=3&page=1&shape=topic_id%2Ctopic_number%2Ctitle%2Cagency%2Cactivity%2Cyear%2Csolicitation_number%2Copen_date%2Cclose_date%2Clisted_open&year=2025" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "981", + "x-ratelimit-burst-reset": "44", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999904", + "x-ratelimit-daily-reset": "24284", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "981", + "x-ratelimit-reset": "44", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 1036, + "next": "https://tango.makegov.com/api/sbir/topics/?limit=3&page=2&shape=topic_id%2Ctopic_number%2Ctitle%2Cagency%2Cactivity%2Cyear%2Csolicitation_number%2Copen_date%2Cclose_date%2Clisted_open&year=2025", + "previous": null, + "results": [ + { + "activity": "closed", + "agency": "DOD", + "close_date": "2025-06-25", + "listed_open": false, + "open_date": "2025-05-07", + "solicitation_number": "25.4", + "title": "Turn-Key Micro Optical-Frequency-Comb Module", + "topic_id": "sbir-topic-32cc59353e07e246cbae", + "topic_number": "A254-033", + "year": 2025 + }, + { + "activity": "closed", + "agency": "DOD", + "close_date": "2025-06-25", + "listed_open": false, + "open_date": "2025-05-07", + "solicitation_number": "25.4", + "title": "Small Innovative Mission Power Sources", + "topic_id": "sbir-topic-8ba0e40f742952cf9565", + "topic_number": "A254-034", + "year": 2025 + }, + { + "activity": "closed", + "agency": "NASA", + "close_date": "2025-05-21", + "listed_open": false, + "open_date": "2025-01-07", + "solicitation_number": "STTR_25_P1", + "title": "Lunar Orbital Power Beaming Technology Development", + "topic_id": "sbir-topic-6c5374fe737db5aded33", + "topic_number": "T3.05", + "year": 2025 + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/sbir-topics-list.json b/tests/cassettes/sbir-topics-list.json new file mode 100644 index 0000000..da92bcd --- /dev/null +++ b/tests/cassettes/sbir-topics-list.json @@ -0,0 +1,70 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/sbir/topics/?limit=3&page=1&shape=topic_id%2Ctopic_number%2Ctitle%2Cagency%2Cactivity%2Cyear%2Csolicitation_number%2Copen_date%2Cclose_date%2Clisted_open" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "982", + "x-ratelimit-burst-reset": "44", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999905", + "x-ratelimit-daily-reset": "24285", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "982", + "x-ratelimit-reset": "44", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 22739, + "next": "https://tango.makegov.com/api/sbir/topics/?limit=3&page=2&shape=topic_id%2Ctopic_number%2Ctitle%2Cagency%2Cactivity%2Cyear%2Csolicitation_number%2Copen_date%2Cclose_date%2Clisted_open", + "previous": null, + "results": [ + { + "activity": "closed", + "agency": "NSF", + "close_date": "2027-07-07", + "listed_open": false, + "open_date": "2026-05-22", + "solicitation_number": "NSF 26-510", + "title": "Food Waste Mitigation", + "topic_id": "sbir-topic-0cce9192d84e1dd86be5", + "topic_number": "AG3", + "year": 2026 + }, + { + "activity": "closed", + "agency": "NSF", + "close_date": "2027-07-07", + "listed_open": false, + "open_date": "2026-05-22", + "solicitation_number": "NSF 26-510", + "title": "Polyculture Systems", + "topic_id": "sbir-topic-68e91df9569ccdba9cd4", + "topic_number": "AG7", + "year": 2026 + }, + { + "activity": "closed", + "agency": "NSF", + "close_date": "2027-07-07", + "listed_open": false, + "open_date": "2026-05-22", + "solicitation_number": "NSF 26-510", + "title": "Decision Support and Optimization", + "topic_id": "sbir-topic-894261af3b97a191e396", + "topic_number": "AA3", + "year": 2026 + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/subawards-list.json b/tests/cassettes/subawards-list.json new file mode 100644 index 0000000..4611348 --- /dev/null +++ b/tests/cassettes/subawards-list.json @@ -0,0 +1,181 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/subawards/?limit=3&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "958", + "x-ratelimit-burst-reset": "25", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999881", + "x-ratelimit-daily-reset": "24265", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "958", + "x-ratelimit-reset": "25", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 2736056, + "next": "https://tango.makegov.com/api/subawards/?limit=3&page=2", + "previous": null, + "results": [ + { + "award_key": "CONT_AWD_HQ003415F0031_9700_GS35F0371N_4730", + "awarding_office": { + "office_code": "HQ0034", + "office_name": "WASHINGTON HEADQUARTERS SERVICES", + "agency_code": "97F5", + "agency_name": "Washington Headquarters Services", + "department_code": 97, + "department_name": "Department of Defense" + }, + "fsrs_details": { + "last_modified_date": "2020-11-30T00:00:00", + "id": "192EA6D8-FCB9-11EF-8E2A-E7034F2D18CD", + "year": 2020, + "month": 11 + }, + "funding_office": { + "office_code": "HQ0002", + "office_name": "OFFICE OF THE SECRETARY OF DEFENSE", + "agency_code": "97AD", + "agency_name": "Immediate Office of the Secretary of Defense", + "department_code": 97, + "department_name": "Department of Defense" + }, + "key": 34340794, + "piid": "HQ003415F0031", + "place_of_performance": { + "city": "ANNAPOLIS", + "state": "MARYLAND", + "zip": "21409", + "country_code": "USA" + }, + "prime_recipient": { + "uei": "C47BNA8GM833", + "display_name": "ACCENTURE FEDERAL SERVICES LLC" + }, + "subaward_details": { + "description": "PROCUREMENT IN SUPPORT OF CONTRACT SOW.", + "type": "sub-contract", + "number": "17652-16-001", + "amount": 526415, + "action_date": "2106-12-01T00:00:00", + "fiscal_year": 2107 + }, + "subaward_recipient": { + "uei": "Z9CJC8GFNZ87", + "display_name": "ARDALYST FEDERAL, LLC" + } + }, + { + "award_key": "CONT_AWD_75P00123F37026_7570_HHSP233201500038I_7555", + "awarding_office": { + "office_code": "75P001", + "office_name": "PROGRAM SUPPORT CENTER ACQ MGMT SVC", + "agency_code": "7570", + "agency_name": "Office of the Assistant Secretary for Administration", + "department_code": 75, + "department_name": "Department of Health and Human Services" + }, + "fsrs_details": { + "last_modified_date": "2024-10-23T00:00:00", + "id": "aa426fe8-fcb8-11ef-8e2a-e7034f2d18cd", + "year": 2024, + "month": 10 + }, + "funding_office": { + "office_code": "75P001", + "office_name": "PROGRAM SUPPORT CENTER ACQ MGMT SVC", + "agency_code": "7570", + "agency_name": "Office of the Assistant Secretary for Administration", + "department_code": 75, + "department_name": "Department of Health and Human Services" + }, + "key": 35010022, + "piid": "75P00123F37026", + "place_of_performance": { + "city": "WASHINGTON", + "state": "DISTRICT OF COLUMBIA", + "zip": "200242131", + "country_code": "USA" + }, + "prime_recipient": { + "uei": "YY46Q97AEZA8", + "display_name": "THE RAND CORPORATION" + }, + "subaward_details": { + "description": "THE PURPOSE OF THIS CONTRACT IS FOR POLICY ANALYSIS AND TECHNICAL ASSISTANCE FOR EMERGING ISSUES IN HEALTH AND HUMAN SERVICES POLICY", + "type": "sub-contract", + "number": "SCON-00000669", + "amount": 74551, + "action_date": "2026-08-24T00:00:00", + "fiscal_year": 2026 + }, + "subaward_recipient": { + "uei": "VNAYDLRGSKU3", + "display_name": "THE URBAN INSTITUTE" + } + }, + { + "award_key": "CONT_AWD_693JJ922F00003N_6940_693JJ319A000013_6925", + "awarding_office": { + "office_code": "693JJ9", + "office_name": "693JJ9 NHTSA OFFICE OF ACQUISTION", + "agency_code": "6940", + "agency_name": "National Highway Traffic Safety Administration", + "department_code": 69, + "department_name": "Department of Transportation" + }, + "fsrs_details": { + "last_modified_date": "2026-08-13T00:00:00", + "id": "54f6ff6f-bc3b-47bc-adf5-6af9c78c3751", + "year": null, + "month": null + }, + "funding_office": { + "office_code": "693JJ9", + "office_name": "693JJ9 NHTSA OFFICE OF ACQUISTION", + "agency_code": "6940", + "agency_name": "National Highway Traffic Safety Administration", + "department_code": 69, + "department_name": "Department of Transportation" + }, + "key": 36430127, + "piid": "693JJ922F00003N", + "place_of_performance": { + "city": null, + "state": null, + "zip": null, + "country_code": null + }, + "prime_recipient": { + "uei": "VMRTJLWMQRH7", + "display_name": "HALVIK, LLC" + }, + "subaward_details": { + "description": "CEMS AND SPIN O&M AND DME SUPPORT SERVICES", + "type": "sub-contract", + "number": "DELANEYADVANTAGE-SWES-TO2 - M6", + "amount": 219337.73, + "action_date": "2026-08-13T00:00:00", + "fiscal_year": 2026 + }, + "subaward_recipient": { + "uei": "HACXTELBJCZ2", + "display_name": "DELANEY ADVANTAGE TECHNOLOGIES L.L.C." + } + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/subawards-ordering.json b/tests/cassettes/subawards-ordering.json new file mode 100644 index 0000000..16ed992 --- /dev/null +++ b/tests/cassettes/subawards-ordering.json @@ -0,0 +1,181 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/subawards/?limit=3&ordering=-last_modified_date&page=1" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "957", + "x-ratelimit-burst-reset": "24", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999880", + "x-ratelimit-daily-reset": "24265", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "957", + "x-ratelimit-reset": "24", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 2736056, + "next": "https://tango.makegov.com/api/subawards/?limit=3&ordering=-last_modified_date&page=2", + "previous": null, + "results": [ + { + "award_key": "CONT_AWD_GS00Q17AHC1003_4732_-NONE-_-NONE-", + "awarding_office": { + "office_code": "47QTCB", + "office_name": "GSA/FAS ITC OFFICE OF ACQUISITION OPERATIONS, INTERAGENCY CONTRACTS", + "agency_code": "4732", + "agency_name": "Federal Acquisition Service", + "department_code": 47, + "department_name": "General Services Administration" + }, + "fsrs_details": { + "last_modified_date": "2026-08-13T00:00:00", + "id": "012d7430-ccf1-479d-a268-36f4164c3941", + "year": 2026, + "month": 7 + }, + "funding_office": { + "office_code": "47QTCB", + "office_name": "GSA/FAS ITC OFFICE OF ACQUISITION OPERATIONS, INTERAGENCY CONTRACTS", + "agency_code": "4732", + "agency_name": "Federal Acquisition Service", + "department_code": 47, + "department_name": "General Services Administration" + }, + "key": 36421828, + "piid": "GS00Q17AHC1003", + "place_of_performance": { + "city": null, + "state": null, + "zip": null, + "country_code": "USA" + }, + "prime_recipient": { + "uei": "MBSRAWAQ9559", + "display_name": "PERATON ENTERPRISE SOLUTIONS LLC" + }, + "subaward_details": { + "description": "\"IGF::CT,CL::IGF\" THE OBJECTIVE OF THIS PROCUREMENT IS TO ACQUIRE A SOLUTION THAT WILL PROVIDE THE U.S. GENERAL SERVICES ADMINISTRATION (GSA) HSPD-12 MSO USACCESS PROGRAM UNINTERRUPTED, GOVERNMENT-WIDE CONTRACTOR MANAGED SERVICES FOR IDENTITY AND CREDENTIAL MANAGEMENT SERVICES INCLUDING: 1) APPLICANT SPONSORSHIP, ENROLLMENT , BIOMETRIC SUBMISSION (FOR BACKGROUND INVESTIGATION PURPOSES); 2) CREDENTIAL ISSUANCE, MAINTENANCE (CERTIFICATE REKEY) AND MANAGEMENT AND 3) BIOGRAPHIC&AGENCY SPECIFIC SPONSORSHIP RECORD MAINTENANCE. THE CONTRACTOR SHALL PROVIDE SERVICES THAT MINIMIZE DISRUPTION TO USACCESS CUSTOMER AGENCIES AND SHALL MAINTAIN THE FULL LIFE AND FUNCTIONALITY OF CURRENTLY EXISTING, ISSUED ACTIVE PIV CARDS AND CREDENTIALS.", + "type": "sub-contract", + "number": "PO-0081094", + "amount": 42227.06, + "action_date": "2026-07-08T00:00:00", + "fiscal_year": 2026 + }, + "subaward_recipient": { + "uei": "FYLAKMN93AK5", + "display_name": "HEWLETT PACKARD ENTERPRISE CO" + } + }, + { + "award_key": "CONT_AWD_W912DQ19F3041_9700_W912DQ16D3001_9700", + "awarding_office": { + "office_code": "W912DQ", + "office_name": "W071 ENDIST KANSAS CITY", + "agency_code": "2100", + "agency_name": "Department of the Army", + "department_code": 97, + "department_name": "Department of Defense" + }, + "fsrs_details": { + "last_modified_date": "2026-08-13T00:00:00", + "id": "022d08b4-fcbc-11ef-8e2a-e7034f2d18cd", + "year": 2021, + "month": 5 + }, + "funding_office": { + "office_code": "68R000", + "office_name": "REGION 2 (FUNDING OFFICE)", + "agency_code": "6800", + "agency_name": "Environmental Protection Agency", + "department_code": 68, + "department_name": "Environmental Protection Agency" + }, + "key": 36421829, + "piid": "W912DQ19F3041", + "place_of_performance": { + "city": "CAMDEN", + "state": "NEW JERSEY", + "zip": "08110", + "country_code": "USA" + }, + "prime_recipient": { + "uei": "LEEMJD9WKDC9", + "display_name": "EA ENGINEERING, SCIENCE, AND TECHNOLOGY, INC., PBC" + }, + "subaward_details": { + "description": "PUCHACK PHASE II REMEDIAL ACTION", + "type": "sub-contract", + "number": "19466", + "amount": 5801731.74, + "action_date": "2021-03-26T00:00:00", + "fiscal_year": 2021 + }, + "subaward_recipient": { + "uei": "H715X4VVWRZ4", + "display_name": "CASCADE DRILLING, L.P." + } + }, + { + "award_key": "CONT_AWD_H9240325F0043_9700_H9240324D0002_9700", + "awarding_office": { + "office_code": "H92403", + "office_name": "HQ USSOCOM", + "agency_code": "97ZS", + "agency_name": "U.S. Special Operations Command", + "department_code": 97, + "department_name": "Department of Defense" + }, + "fsrs_details": { + "last_modified_date": "2026-08-13T00:00:00", + "id": "03da2c18-3b8f-4db6-914d-412a6ee0d1fe", + "year": null, + "month": null + }, + "funding_office": { + "office_code": "H92403", + "office_name": "HQ USSOCOM", + "agency_code": "97ZS", + "agency_name": "U.S. Special Operations Command", + "department_code": 97, + "department_name": "Department of Defense" + }, + "key": 36421830, + "piid": "H9240325F0043", + "place_of_performance": { + "city": null, + "state": null, + "zip": null, + "country_code": null + }, + "prime_recipient": { + "uei": "F125YU6SWK59", + "display_name": "BATTELLE MEMORIAL INSTITUTE" + }, + "subaward_details": { + "description": "OEM HILUX - VEHICLE A CONVERSIONS", + "type": "sub-contract", + "number": "0000919127", + "amount": 44529.15, + "action_date": "2025-08-07T00:00:00", + "fiscal_year": 2025 + }, + "subaward_recipient": { + "uei": "KX98Z47QDWK9", + "display_name": "SAFARI 4X4 LLC" + } + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/vehicles-list.json b/tests/cassettes/vehicles-list.json new file mode 100644 index 0000000..90833a9 --- /dev/null +++ b/tests/cassettes/vehicles-list.json @@ -0,0 +1,133 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/vehicles/?limit=3&page=1&shape=uuid%2Csolicitation_identifier%2Cis_synthetic_solicitation%2Cprogram_acronym%2Corganization_id%2Corganization%2Cvehicle_type%2Cdescription%2Cidv_count%2Cawardee_count%2Corder_count%2Ctotal_obligated%2Cvehicle_obligations%2Cvehicle_contracts_value%2Clatest_award_date%2Csolicitation_title%2Csolicitation_date" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "960", + "x-ratelimit-burst-reset": "26", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999883", + "x-ratelimit-daily-reset": "24267", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "960", + "x-ratelimit-reset": "26", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 20749, + "next": "https://tango.makegov.com/api/vehicles/?limit=3&page=2&shape=uuid%2Csolicitation_identifier%2Cis_synthetic_solicitation%2Cprogram_acronym%2Corganization_id%2Corganization%2Cvehicle_type%2Cdescription%2Cidv_count%2Cawardee_count%2Corder_count%2Ctotal_obligated%2Cvehicle_obligations%2Cvehicle_contracts_value%2Clatest_award_date%2Csolicitation_title%2Csolicitation_date", + "previous": null, + "results": [ + { + "awardee_count": 2, + "description": [ + "CATTLE AND SWINE BACKTAG CEMENT", + "CATTLE AND SWINE BACKTAG CEMENT TO BE DELIVERED ON AN IDIQ BASIS TO KS, MO." + ], + "idv_count": 2, + "is_synthetic_solicitation": false, + "latest_award_date": "2006-06-01", + "order_count": 25, + "organization": { + "organization_id": "767bb2b0-239a-5bb4-8f3c-16d0a418fb71", + "office_code": "126395", + "office_name": "MRPBS MINNEAPOLIS MN", + "agency_code": "12K3", + "agency_name": "ANIMAL AND PLANT HEALTH INSPECTION SERVICE", + "department_code": "012", + "department_name": "AGRICULTURE, DEPARTMENT OF" + }, + "organization_id": "767bb2b0-239a-5bb4-8f3c-16d0a418fb71", + "program_acronym": "APHIS VS", + "solicitation_date": null, + "solicitation_identifier": "002-M-APHIS-06", + "solicitation_title": null, + "total_obligated": 5388564.69, + "uuid": "8597845d-2a4c-5acd-99ff-1f5fe348501e", + "vehicle_contracts_value": 5116733.97, + "vehicle_obligations": 5388564.6899999995, + "vehicle_type": { + "code": "B", + "description": "IDC" + } + }, + { + "awardee_count": 1, + "description": [ + "WIRED TELEPHONY SERVICES" + ], + "idv_count": 2, + "is_synthetic_solicitation": false, + "latest_award_date": "2011-06-28", + "order_count": 14, + "organization": { + "organization_id": "de7791b0-2552-5303-9c41-e87e8e19ec42", + "office_code": "CL000", + "office_name": "GSA/FAS EXPANDED NETWORK SERVICES (2QTC)", + "agency_code": "4732", + "agency_name": "FEDERAL ACQUISITION SERVICE", + "department_code": "047", + "department_name": "GENERAL SERVICES ADMINISTRATION" + }, + "organization_id": "de7791b0-2552-5303-9c41-e87e8e19ec42", + "program_acronym": null, + "solicitation_date": null, + "solicitation_identifier": "02LSA090013", + "solicitation_title": "Region Local Telephony Contract - for Upstate New York, Rochester New York, New Jersey, and Puerto Rico", + "total_obligated": 1875884.39, + "uuid": "62090454-1126-5f27-8aef-c39e6df5ee7f", + "vehicle_contracts_value": 900808.74, + "vehicle_obligations": 1875884.3900000001, + "vehicle_type": { + "code": "B", + "description": "IDC" + } + }, + { + "awardee_count": 3, + "description": [ + "INDEFINITE QUANTITY ARCHITECTURAL ENGINEERING CONTRACT FOR THE MID WEST AREA.", + "INDEFINITE QUANTITY ARCHITECTURAL ENGINEERING CONTRACT FOR THE\nMID WEST AREA", + "INDEFINITE QUANTITY ARCHITECTURAL-ENGINEERING CONTRACT FOR THE MID-WEST AREA." + ], + "idv_count": 3, + "is_synthetic_solicitation": false, + "latest_award_date": "2005-02-11", + "order_count": 131, + "organization": { + "organization_id": "df10725d-8988-5bec-975c-3a2a8c60a758", + "office_code": "123K15", + "office_name": "USDA ARS AFM FD", + "agency_code": "12H2", + "agency_name": "AGRICULTURAL RESEARCH SERVICE", + "department_code": "012", + "department_name": "AGRICULTURE, DEPARTMENT OF" + }, + "organization_id": "df10725d-8988-5bec-975c-3a2a8c60a758", + "program_acronym": "IDC-BED", + "solicitation_date": null, + "solicitation_identifier": "03-3K15-04", + "solicitation_title": "C -- Indefinite Quantity Contract for A-E Services - Repair/Maintenance, Alteration, and New Construction", + "total_obligated": 6822963.21, + "uuid": "88f6c85b-b398-5396-808c-316f3f4394e3", + "vehicle_contracts_value": 3765655.47, + "vehicle_obligations": 6822963.209999999, + "vehicle_type": { + "code": "B", + "description": "IDC" + } + } + ] + } + } + } + ] +} diff --git a/tests/cassettes/vehicles-search.json b/tests/cassettes/vehicles-search.json new file mode 100644 index 0000000..7ff47ba --- /dev/null +++ b/tests/cassettes/vehicles-search.json @@ -0,0 +1,150 @@ +{ + "version": 1, + "interactions": [ + { + "request": { + "method": "GET", + "url": "https://tango.makegov.com/api/vehicles/?limit=3&page=1&search=SEWP&shape=uuid%2Csolicitation_identifier%2Cis_synthetic_solicitation%2Cprogram_acronym%2Corganization_id%2Corganization%2Cvehicle_type%2Cdescription%2Cidv_count%2Cawardee_count%2Corder_count%2Ctotal_obligated%2Cvehicle_obligations%2Cvehicle_contracts_value%2Clatest_award_date%2Csolicitation_title%2Csolicitation_date" + }, + "response": { + "status": 200, + "headers": { + "content-type": "application/json", + "x-ratelimit-burst-limit": "1000", + "x-ratelimit-burst-remaining": "959", + "x-ratelimit-burst-reset": "26", + "x-ratelimit-daily-limit": "2000000", + "x-ratelimit-daily-remaining": "1999882", + "x-ratelimit-daily-reset": "24266", + "x-ratelimit-limit": "1000", + "x-ratelimit-remaining": "959", + "x-ratelimit-reset": "26", + "x-tango-api-version": "4.22.0" + }, + "body": { + "count": 8, + "next": "https://tango.makegov.com/api/vehicles/?limit=3&page=2&search=SEWP&shape=uuid%2Csolicitation_identifier%2Cis_synthetic_solicitation%2Cprogram_acronym%2Corganization_id%2Corganization%2Cvehicle_type%2Cdescription%2Cidv_count%2Cawardee_count%2Corder_count%2Ctotal_obligated%2Cvehicle_obligations%2Cvehicle_contracts_value%2Clatest_award_date%2Csolicitation_title%2Csolicitation_date", + "previous": null, + "results": [ + { + "awardee_count": 0, + "description": [ + "NASA ITPO SEWP VI GWAC SOLICITATION. THE PRINCIPAL PURPOSE OF THIS REQUIREMENT IS TO PROVIDE THE FEDERAL GOVERNMENT WITH AN ALL-ENCOMPASSING ONE-STOP ACQUISITION VEHICLE FOR INFORMATION TECHNOLOGY PRODUCT AND SERVICE SOLUTIONS.", + "SEWP VI IS A MULTIPLE AWARD GWAC THAT PROVIDES NASA AND ALL FEDERAL AGENCIES WITH A FULL SUITE OF INFORMATION TECHNOLOGY (IT) SOLUTIONS FOR COMMUNICATION AND AUDIO-VISUAL SOLUTIONS, INCLUSIVE OF PRODUCTS AND SERVICES." + ], + "idv_count": 31, + "is_synthetic_solicitation": false, + "latest_award_date": "2026-07-09", + "order_count": 0, + "organization": { + "organization_id": "b6f7bf6f-1f84-5de7-9482-def6c8c330e1", + "office_code": "80TECH", + "office_name": "NASA IT PROCUREMENT OFFICE", + "agency_code": "8000", + "agency_name": "NATIONAL AERONAUTICS AND SPACE ADMINISTRATION", + "department_code": "080", + "department_name": "NATIONAL AERONAUTICS AND SPACE ADMINISTRATION" + }, + "organization_id": "b6f7bf6f-1f84-5de7-9482-def6c8c330e1", + "program_acronym": "SEWP VI", + "solicitation_date": null, + "solicitation_identifier": "80TECH24R0001", + "solicitation_title": null, + "total_obligated": 0, + "uuid": "9ea43c97-809c-5fec-aad2-6457a0a3e49d", + "vehicle_contracts_value": 0, + "vehicle_obligations": 0, + "vehicle_type": { + "code": "A", + "description": "GWAC" + } + }, + { + "awardee_count": 0, + "description": [ + "IGF::CT::IGF:: REQUEST FOR DESKTOPS TO BE USED WITHIN BY EPIC DEVELOPERS TO ACCESS APPLICATIONS IN DEVELOPMENT ENVIRONMENTS.", + "IGF::CT::IGF:: SERVERS TO SUPPORT THE EPIC MOBILE APPLICATION PLATFORM.", + "IGF::CT::IGF:: APPLE IMAC'S W/RETINA 5K DISPLAY.", + "IGF::CT::IGF:: VIDEO TELECONFERENCING (VTC) EQUIPMENT AND ACCESSORIES.", + "IGF::CT::IGF CISCO EQUIPMENT FOR THE ESS NETWORK.", + "IGF::CT::IGF:: RENEWAL OF SQL NAVIGATOR FOR PERIOD 8/16/2017 TO 8/15/2018.", + "IGF::CT::IGF RENEWAL OF VERITAS ESSENTIAL SUPPORT FOR POP 8/08/2017 TO 8/07/2018.", + "IGF::CT::IGF MAINTENANCE RENEWAL FOR THE VNX5300 EMC STORAGE AREA NETWORK (SAN).", + "IGF::CT::IGF RENEWAL OF SYMENTEC PROTECCTION ENTERPRISE FOR PERIOD 5/01/2017 TO 4/30/2018", + "IGF::CT::IGF VMWARE VSPHERE ENTERPRISE LICENSE AND SUPPORT", + "IGF::CT::IGF:: RED HAT LICENSE RENEWAL", + "IGF::CT::IGF:: ANNUAL RENEWAL SW SUPPORT", + "IGF::CT::IGF:: VERITAS RENEWAL", + "IGF::CT::IGF:: RED HAT ANNUAL SUBSCRIPTION RENEWAL", + "IGF::CT::IGF:: ANNUAL LICENSE RENEWAL TIBCO", + "IGF::CT::IGF:: ANNUAL MAINTENANCE RENEWAL ON F5 BIG TERM IN MONTHLY INSTALLMENTS" + ], + "idv_count": 24, + "is_synthetic_solicitation": true, + "latest_award_date": "2017-09-25", + "order_count": 0, + "organization": { + "organization_id": "41f38b64-774b-5acd-8576-b8c6b4db6f88", + "office_code": "15DDNE", + "office_name": "EL PASO INTELLIGENCE CENTER", + "agency_code": "1524", + "agency_name": "DRUG ENFORCEMENT ADMINISTRATION", + "department_code": "015", + "department_name": "JUSTICE, DEPARTMENT OF" + }, + "organization_id": "41f38b64-774b-5acd-8576-b8c6b4db6f88", + "program_acronym": "SEWP", + "solicitation_date": null, + "solicitation_identifier": "SEWP", + "solicitation_title": null, + "total_obligated": 0, + "uuid": "fb9d313a-9ad2-5764-876a-cb52ffea59c5", + "vehicle_contracts_value": 0, + "vehicle_obligations": 0, + "vehicle_type": { + "code": "A", + "description": "GWAC" + } + }, + { + "awardee_count": 43, + "description": [ + "LAN NETWORKING SYSTEMS ENGINEERING AND COMPUTER SYSTEMS DESIGN", + "GEOGRAPHIC INFORMATION SYSTEMS AND REMOTE SENSING SERVICE", + "COMMERCIAL IT SEWP III CLASS 12 - SECURITY TOOLS&EQUIPMENT", + "COMMERCIAL IT PRODUCTS", + "COMMERCIAL IT SEWP III CLASS 12 SECURITY TOOLS & EQUIPMENT" + ], + "idv_count": 6, + "is_synthetic_solicitation": true, + "latest_award_date": "2004-05-11", + "order_count": 6101, + "organization": { + "organization_id": "62da08c0-8d2a-53a9-8de9-b14cadb9e49d", + "office_code": "80GSFC", + "office_name": "NASA GODDARD SPACE FLIGHT CENTER", + "agency_code": "8000", + "agency_name": "NATIONAL AERONAUTICS AND SPACE ADMINISTRATION", + "department_code": "080", + "department_name": "NATIONAL AERONAUTICS AND SPACE ADMINISTRATION" + }, + "organization_id": "62da08c0-8d2a-53a9-8de9-b14cadb9e49d", + "program_acronym": "SEWP", + "solicitation_date": null, + "solicitation_identifier": "SEWP", + "solicitation_title": null, + "total_obligated": 782112232.62, + "uuid": "67097b84-cc39-523a-aff7-2f39814639e6", + "vehicle_contracts_value": 451489615.57000005, + "vehicle_obligations": 782112232.62, + "vehicle_type": { + "code": "A", + "description": "GWAC" + } + } + ] + } + } + } + ] +} diff --git a/tests/integration/agencies.test.ts b/tests/integration/agencies.test.ts new file mode 100644 index 0000000..01ee9e9 --- /dev/null +++ b/tests/integration/agencies.test.ts @@ -0,0 +1,31 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty } from "./validation.js"; + +describeIntegration("agencies and organizations (recorded)", () => { + it("lists agencies", async () => { + const client = integrationClient("agencies-list"); + const res = await client.listAgencies({ limit: 5 }); + const first = expectNonEmpty(res); + expect(Object.keys(first).length).toBeGreaterThan(0); + }); + + it("gets a single agency by code", async () => { + const client = integrationClient("agencies-get"); + const agency = await client.getAgency("4700"); + expect(Object.keys(agency).length).toBeGreaterThan(0); + }); + + it("lists organizations", async () => { + const client = integrationClient("organizations-list"); + const res = await client.listOrganizations({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["name", "level"]); + }); + + it("filters organizations to departments (level 1)", async () => { + const client = integrationClient("organizations-filter"); + const res = await client.listOrganizations({ limit: 3, level: 1 }); + const first = expectNonEmpty(res); + expect(Number(first.level)).toBe(1); + }); +}); diff --git a/tests/integration/budget.test.ts b/tests/integration/budget.test.ts new file mode 100644 index 0000000..40525bd --- /dev/null +++ b/tests/integration/budget.test.ts @@ -0,0 +1,22 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty } from "./validation.js"; + +describeIntegration("budget accounts (recorded)", () => { + it("lists budget accounts", async () => { + const client = integrationClient("budget-list"); + const res = await client.listBudgetAccounts({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["federal_account_symbol", "fiscal_year"]); + }); + + it("round-trips a fiscal-year range filter", async () => { + const client = integrationClient("budget-range"); + const res = await client.listBudgetAccounts({ limit: 5, fiscal_year__gte: 2024, fiscal_year__lte: 2025 }); + expectNonEmpty(res); + for (const row of res.results) { + const fy = Number(row.fiscal_year); + expect(fy).toBeGreaterThanOrEqual(2024); + expect(fy).toBeLessThanOrEqual(2025); + } + }); +}); diff --git a/tests/integration/contracts.test.ts b/tests/integration/contracts.test.ts new file mode 100644 index 0000000..69b76ad --- /dev/null +++ b/tests/integration/contracts.test.ts @@ -0,0 +1,51 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty, expectPagination } from "./validation.js"; + +describeIntegration("contracts (recorded)", () => { + it("lists contracts with the default minimal shape", async () => { + const client = integrationClient("contracts-list"); + const res = await client.listContracts({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["key", "piid", "award_date", "total_contract_value"]); + }); + + it("lists contracts with a custom shape", async () => { + const client = integrationClient("contracts-shape"); + const res = await client.listContracts({ limit: 3, shape: "key,piid,total_contract_value" }); + const first = expectNonEmpty(res); + expectFields(first, ["key", "piid", "total_contract_value"]); + expect(first).not.toHaveProperty("description"); + }); + + it("paginates with a cursor", async () => { + const client = integrationClient("contracts-cursor"); + const page1 = await client.listContracts({ limit: 2 }); + expectNonEmpty(page1); + expect(page1.cursor).toBeTruthy(); + + const page2 = await client.listContracts({ limit: 2, cursor: page1.cursor }); + const first2 = expectNonEmpty(page2); + expect(first2.key).not.toBe(page1.results[0].key); + }); + + it("filters by fiscal year and award date", async () => { + const client = integrationClient("contracts-filter"); + const res = await client.listContracts({ + limit: 3, + fiscal_year: 2024, + award_date_gte: "2024-01-01", + shape: "key,piid,award_date,fiscal_year", + }); + const first = expectNonEmpty(res); + expect(Number(first.fiscal_year)).toBe(2024); + expect(String(first.award_date) >= "2024-01-01").toBe(true); + }); + + it("returns an empty page for a hopeless search", async () => { + const client = integrationClient("contracts-empty"); + const res = await client.listContracts({ limit: 3, search: "zzzz-no-such-contract-zzzz" }); + expectPagination(res); + expect(res.count).toBe(0); + expect(res.results).toHaveLength(0); + }); +}); diff --git a/tests/integration/dibbs.test.ts b/tests/integration/dibbs.test.ts new file mode 100644 index 0000000..0408477 --- /dev/null +++ b/tests/integration/dibbs.test.ts @@ -0,0 +1,27 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty, expectPagination } from "./validation.js"; + +describeIntegration("dibbs (recorded)", () => { + it("lists RFQs with the default minimal shape", async () => { + const client = integrationClient("dibbs-rfqs-list"); + const res = await client.listDibbsRfqs({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["solicitation", "nsn"]); + }); + + it("filters RFQs to open ones", async () => { + const client = integrationClient("dibbs-rfqs-open"); + const res = await client.listDibbsRfqs({ limit: 3, open: true }); + expectPagination(res); + for (const row of res.results) { + expect(row.is_open).toBe(true); + } + }); + + it("lists DIBBS awards", async () => { + const client = integrationClient("dibbs-awards-list"); + const res = await client.listDibbsAwards({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["award_number", "award_date"]); + }); +}); diff --git a/tests/integration/edge-cases.test.ts b/tests/integration/edge-cases.test.ts new file mode 100644 index 0000000..719e0e0 --- /dev/null +++ b/tests/integration/edge-cases.test.ts @@ -0,0 +1,23 @@ +import { TangoNotFoundError, TangoValidationError } from "../../src/errors.js"; +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectPagination } from "./validation.js"; + +describeIntegration("edge cases (recorded)", () => { + it("raises TangoNotFoundError for a nonexistent contract key", async () => { + const client = integrationClient("edge-contract-404"); + await expect(client.getContract("tango-node-no-such-key")).rejects.toThrow(TangoNotFoundError); + }); + + it("raises TangoValidationError for a disallowed vehicles ordering", async () => { + const client = integrationClient("edge-vehicles-bad-ordering"); + await expect(client.listVehicles({ limit: 3, ordering: "not_a_real_field" })).rejects.toThrow(TangoValidationError); + }); + + it("returns an empty, well-formed page when a filter matches nothing", async () => { + const client = integrationClient("edge-entities-empty"); + const res = await client.listEntities({ limit: 3, search: "zzzz-no-such-entity-zzzz" }); + expectPagination(res); + expect(res.count).toBe(0); + expect(res.results).toHaveLength(0); + }); +}); diff --git a/tests/integration/entities.test.ts b/tests/integration/entities.test.ts new file mode 100644 index 0000000..4a33946 --- /dev/null +++ b/tests/integration/entities.test.ts @@ -0,0 +1,19 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty } from "./validation.js"; + +describeIntegration("entities (recorded)", () => { + it("lists entities with the default minimal shape", async () => { + const client = integrationClient("entities-list"); + const res = await client.listEntities({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["uei", "legal_business_name"]); + }); + + it("filters entities by state with a custom shape", async () => { + const client = integrationClient("entities-filter"); + const res = await client.listEntities({ limit: 3, state: "VA", shape: "uei,legal_business_name" }); + const first = expectNonEmpty(res); + expectFields(first, ["uei", "legal_business_name"]); + expect(first).not.toHaveProperty("cage_code"); + }); +}); diff --git a/tests/integration/exclusions.test.ts b/tests/integration/exclusions.test.ts new file mode 100644 index 0000000..d2e3ca4 --- /dev/null +++ b/tests/integration/exclusions.test.ts @@ -0,0 +1,20 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty, expectPagination } from "./validation.js"; + +describeIntegration("exclusions (recorded)", () => { + it("lists exclusions with the default minimal shape", async () => { + const client = integrationClient("exclusions-list"); + const res = await client.listExclusions({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["classification_type", "exclusion_type"]); + }); + + it("filters exclusions to currently-active ones", async () => { + const client = integrationClient("exclusions-active"); + const res = await client.listExclusions({ limit: 3, active: true }); + expectPagination(res); + for (const row of res.results) { + expect(row.is_currently_excluded).toBe(true); + } + }); +}); diff --git a/tests/integration/forecasts.test.ts b/tests/integration/forecasts.test.ts new file mode 100644 index 0000000..97aa9d1 --- /dev/null +++ b/tests/integration/forecasts.test.ts @@ -0,0 +1,20 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty, expectPagination } from "./validation.js"; + +describeIntegration("forecasts (recorded)", () => { + it("lists forecasts with the default minimal shape", async () => { + const client = integrationClient("forecasts-list"); + const res = await client.listForecasts({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["id", "title"]); + }); + + it("filters forecasts by NAICS prefix", async () => { + const client = integrationClient("forecasts-filter"); + const res = await client.listForecasts({ limit: 3, naics_starts_with: "54", shape: "id,title,naics_code" }); + expectPagination(res); + for (const row of res.results) { + expect(String(row.naics_code)).toMatch(/^54/); + } + }); +}); diff --git a/tests/integration/grants.test.ts b/tests/integration/grants.test.ts new file mode 100644 index 0000000..59bb40d --- /dev/null +++ b/tests/integration/grants.test.ts @@ -0,0 +1,20 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty } from "./validation.js"; + +describeIntegration("grants (recorded)", () => { + it("lists grants with the default minimal shape", async () => { + const client = integrationClient("grants-list"); + const res = await client.listGrants({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["grant_id", "title"]); + }); + + it("filters grants by posted date with a custom shape", async () => { + // posted_date is filterable but not shapeable on grants, so assert the shape narrowing instead. + const client = integrationClient("grants-filter"); + const res = await client.listGrants({ limit: 3, posted_date_after: "2025-01-01", shape: "grant_id,title" }); + const first = expectNonEmpty(res); + expectFields(first, ["grant_id", "title"]); + expect(first).not.toHaveProperty("agency_code"); + }); +}); diff --git a/tests/integration/harness.ts b/tests/integration/harness.ts new file mode 100644 index 0000000..fd1d5d3 --- /dev/null +++ b/tests/integration/harness.ts @@ -0,0 +1,203 @@ +/** + * Record/replay cassette harness around the SDK's injectable `fetchImpl` — the node equivalent of tango-python's VCR setup (tests/integration/conftest.py). + * + * Modes (mirroring python's `vcr_config`): + * - default: replay-only from `tests/cassettes/*.json`; a missing cassette is a hard failure so drift is loud (record_mode="none" semantics). + * - `TANGO_REFRESH_CASSETTES=true`: re-record against the live API (requires `TANGO_API_KEY`; record_mode="all" semantics). + * - `TANGO_USE_LIVE_API=true`: bypass cassettes entirely and hit the live API. + * + * Cassettes store only `{method, url}` per request (never request headers, so the API key cannot be serialized) and a small allowlisted subset of response headers. + * Matching is method + path + sorted query, host-insensitive. + */ + +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +import { describe } from "vitest"; + +import { TangoClient } from "../../src/client.js"; + +const HERE = path.dirname(fileURLToPath(import.meta.url)); +export const CASSETTE_DIR = path.resolve(HERE, "..", "cassettes"); + +export const REFRESH_CASSETTES = process.env.TANGO_REFRESH_CASSETTES === "true"; +export const USE_LIVE_API = process.env.TANGO_USE_LIVE_API === "true"; +export const REPLAY_ONLY = !REFRESH_CASSETTES && !USE_LIVE_API; + +/** Spacing between recorded live requests, to stay well under rate limits. */ +const RECORD_SPACING_MS = 400; + +/** Response headers worth keeping in a cassette. Everything else is dropped. */ +const RESPONSE_HEADER_ALLOWLIST = /^(content-type|retry-after|x-ratelimit-.*|x-tango-api-version)$/i; + +/** Header names that must never be serialized, even if they somehow appear. */ +const SENSITIVE_HEADERS = /^(x-api-key|authorization|proxy-authorization|cookie|set-cookie)$/i; + +export interface RecordedInteraction { + request: { method: string; url: string }; + response: { status: number; headers: Record; body: unknown }; +} + +interface Cassette { + version: 1; + interactions: RecordedInteraction[]; +} + +/** Canonical match key: method + path + sorted query. Host is ignored so a `TANGO_BASE_URL` override cannot break replay. */ +export function matchKey(method: string, url: string): string { + const u = new URL(url, "https://_/"); + const params = [...u.searchParams.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)); + const query = params.map(([k, v]) => `${k}=${v}`).join("&"); + return `${method.toUpperCase()} ${u.pathname}${query ? `?${query}` : ""}`; +} + +function sortedUrl(url: string): string { + const u = new URL(url); + const params = [...u.searchParams.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)); + const search = new URLSearchParams(params).toString(); + return `${u.origin}${u.pathname}${search ? `?${search}` : ""}`; +} + +/** + * Build the storable form of one interaction. + * Request headers are dropped entirely; response headers are reduced to the allowlist with sensitive names refused outright; and if `secret` is given, any appearance of it anywhere in the serialized output throws instead of writing. + */ +export function serializeInteraction( + method: string, + url: string, + status: number, + responseHeaders: Record, + body: unknown, + secret?: string | null, +): RecordedInteraction { + const headers: Record = {}; + for (const [name, value] of Object.entries(responseHeaders)) { + if (SENSITIVE_HEADERS.test(name)) continue; + if (RESPONSE_HEADER_ALLOWLIST.test(name)) headers[name.toLowerCase()] = value; + } + + const interaction: RecordedInteraction = { + request: { method: method.toUpperCase(), url: sortedUrl(url) }, + response: { status, headers, body }, + }; + + if (secret) { + const json = JSON.stringify(interaction); + if (json.includes(secret)) { + throw new Error("Refusing to serialize cassette interaction: API key material found in payload"); + } + } + + return interaction; +} + +function cassettePath(name: string): string { + return path.join(CASSETTE_DIR, `${name}.json`); +} + +function headersToRecord(headers: Headers): Record { + const out: Record = {}; + headers.forEach((value, key) => { + out[key.toLowerCase()] = value; + }); + return out; +} + +function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +function requireApiKey(): string { + const key = process.env.TANGO_API_KEY; + if (!key) { + throw new Error("TANGO_API_KEY is required for TANGO_REFRESH_CASSETTES / TANGO_USE_LIVE_API runs"); + } + return key; +} + +function recordingFetch(name: string): typeof fetch { + const secret = requireApiKey(); + mkdirSync(CASSETTE_DIR, { recursive: true }); + const interactions: RecordedInteraction[] = []; + + return (async (input: RequestInfo | URL, init?: RequestInit): Promise => { + await sleep(RECORD_SPACING_MS); + const res = await fetch(input, init); + + // Retryable statuses are not persisted: the SDK retries them, and only the settled outcome belongs in the cassette. + if (res.status === 429 || res.status >= 500) return res; + + const text = await res.clone().text(); + let body: unknown = null; + try { + body = text ? JSON.parse(text) : null; + } catch { + body = text; + } + + const method = init?.method ?? "GET"; + interactions.push(serializeInteraction(method, String(input), res.status, headersToRecord(res.headers), body, secret)); + writeFileSync(cassettePath(name), `${JSON.stringify({ version: 1, interactions } satisfies Cassette, null, 2)}\n`); + return res; + }) as typeof fetch; +} + +function replayFetch(name: string): typeof fetch { + const file = cassettePath(name); + if (!existsSync(file)) { + throw new Error( + `Missing cassette ${path.relative(process.cwd(), file)} — the recorded corpus has drifted from the tests. ` + + "Re-record with TANGO_REFRESH_CASSETTES=true TANGO_API_KEY=... npx vitest run tests/integration", + ); + } + + const cassette = JSON.parse(readFileSync(file, "utf8")) as Cassette; + const remaining = [...cassette.interactions]; + + return (async (input: RequestInfo | URL, init?: RequestInit): Promise => { + const method = init?.method ?? "GET"; + const key = matchKey(method, String(input)); + const idx = remaining.findIndex((i) => matchKey(i.request.method, i.request.url) === key); + if (idx === -1) { + const recorded = cassette.interactions.map((i) => matchKey(i.request.method, i.request.url)).join("\n "); + throw new Error(`No recorded interaction in ${name}.json for:\n ${key}\nRecorded:\n ${recorded}\nRe-record with TANGO_REFRESH_CASSETTES=true.`); + } + const [hit] = remaining.splice(idx, 1); + return new Response(JSON.stringify(hit.response.body), { + status: hit.response.status, + headers: hit.response.headers, + }); + }) as typeof fetch; +} + +/** Cassette-aware fetch for one test: records, replays, or passes through per mode. */ +export function cassetteFetch(name: string): typeof fetch { + if (USE_LIVE_API) return fetch; + if (REFRESH_CASSETTES) return recordingFetch(name); + return replayFetch(name); +} + +/** A TangoClient wired to `cassetteFetch(name)` with mode-appropriate auth and retries. */ +export function integrationClient(name: string): TangoClient { + if (REPLAY_ONLY) { + // Zero retries: a replay mismatch or replayed 429 should fail fast, not back off. + return new TangoClient({ apiKey: "test-key-for-cassettes", fetchImpl: cassetteFetch(name), retries: 0 }); + } + return new TangoClient({ apiKey: requireApiKey(), fetchImpl: cassetteFetch(name) }); +} + +/** + * True when the suite can run at all: always in record/live mode, and only when the cassettes directory exists in replay mode. + * An absent directory (a fork without the corpus) skips the whole suite; a missing individual file inside an existing directory still hard-fails. + */ +export function cassettesAvailable(): boolean { + return !REPLAY_ONLY || existsSync(CASSETTE_DIR); +} + +if (!cassettesAvailable()) { + console.warn("tests/cassettes/ not found — integration suite skipped (record it with TANGO_REFRESH_CASSETTES=true)"); +} + +/** `describe` that skips the whole suite when no cassette corpus is present. */ +export const describeIntegration = describe.skipIf(!cassettesAvailable()); diff --git a/tests/integration/idvs.test.ts b/tests/integration/idvs.test.ts new file mode 100644 index 0000000..a7c3f9d --- /dev/null +++ b/tests/integration/idvs.test.ts @@ -0,0 +1,18 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty } from "./validation.js"; + +describeIntegration("idvs (recorded)", () => { + it("lists IDVs with the default minimal shape", async () => { + const client = integrationClient("idvs-list"); + const res = await client.listIdvs({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["key", "piid", "idv_type"]); + }); + + it("filters IDVs by fiscal year with a custom shape", async () => { + const client = integrationClient("idvs-filter"); + const res = await client.listIdvs({ limit: 3, fiscal_year: 2024, shape: "key,piid,fiscal_year" }); + const first = expectNonEmpty(res); + expect(Number(first.fiscal_year)).toBe(2024); + }); +}); diff --git a/tests/integration/notices.test.ts b/tests/integration/notices.test.ts new file mode 100644 index 0000000..5d5375e --- /dev/null +++ b/tests/integration/notices.test.ts @@ -0,0 +1,18 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty } from "./validation.js"; + +describeIntegration("notices (recorded)", () => { + it("lists notices with the default minimal shape", async () => { + const client = integrationClient("notices-list"); + const res = await client.listNotices({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["notice_id", "title", "posted_date"]); + }); + + it("filters notices by posted date", async () => { + const client = integrationClient("notices-filter"); + const res = await client.listNotices({ limit: 3, posted_date_after: "2025-01-01" }); + const first = expectNonEmpty(res); + expect(String(first.posted_date) >= "2025-01-01").toBe(true); + }); +}); diff --git a/tests/integration/opportunities.test.ts b/tests/integration/opportunities.test.ts new file mode 100644 index 0000000..f76b139 --- /dev/null +++ b/tests/integration/opportunities.test.ts @@ -0,0 +1,18 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty } from "./validation.js"; + +describeIntegration("opportunities (recorded)", () => { + it("lists opportunities with the default minimal shape", async () => { + const client = integrationClient("opportunities-list"); + const res = await client.listOpportunities({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["opportunity_id", "title"]); + }); + + it("filters to active opportunities with a custom shape", async () => { + const client = integrationClient("opportunities-filter"); + const res = await client.listOpportunities({ limit: 3, active: true, shape: "opportunity_id,title,active" }); + const first = expectNonEmpty(res); + expect(first.active).toBe(true); + }); +}); diff --git a/tests/integration/protests.test.ts b/tests/integration/protests.test.ts new file mode 100644 index 0000000..b79dd3f --- /dev/null +++ b/tests/integration/protests.test.ts @@ -0,0 +1,18 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty } from "./validation.js"; + +describeIntegration("protests (recorded)", () => { + it("lists protests", async () => { + const client = integrationClient("protests-list"); + const res = await client.listProtests({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["case_number"]); + }); + + it("filters protests by filed date", async () => { + const client = integrationClient("protests-filter"); + const res = await client.listProtests({ limit: 3, filed_date_after: "2025-01-01" }); + const first = expectNonEmpty(res); + expect(String(first.filed_date) >= "2025-01-01").toBe(true); + }); +}); diff --git a/tests/integration/reference-data.test.ts b/tests/integration/reference-data.test.ts new file mode 100644 index 0000000..d6eecfb --- /dev/null +++ b/tests/integration/reference-data.test.ts @@ -0,0 +1,31 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectNonEmpty, expectPagination } from "./validation.js"; + +describeIntegration("reference data (recorded)", () => { + it("lists NAICS codes", async () => { + const client = integrationClient("naics-list"); + const res = await client.listNaics({ limit: 3 }); + const first = expectNonEmpty(res); + expect(Object.keys(first).length).toBeGreaterThan(0); + }); + + it("gets a single NAICS code", async () => { + const client = integrationClient("naics-get"); + const naics = await client.getNaics("541511"); + expect(JSON.stringify(naics)).toContain("541511"); + }); + + it("lists PSC codes", async () => { + const client = integrationClient("psc-list"); + const res = await client.listPsc({ limit: 3 }); + const first = expectNonEmpty(res); + expect(Object.keys(first).length).toBeGreaterThan(0); + }); + + it("filters PSC codes to ones with award history", async () => { + const client = integrationClient("psc-filter"); + const res = await client.listPsc({ limit: 3, has_awards: true }); + expectPagination(res); + expect(res.count).toBeGreaterThan(0); + }); +}); diff --git a/tests/integration/sbir.test.ts b/tests/integration/sbir.test.ts new file mode 100644 index 0000000..0e7a9c8 --- /dev/null +++ b/tests/integration/sbir.test.ts @@ -0,0 +1,27 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty, expectPagination } from "./validation.js"; + +describeIntegration("sbir (recorded)", () => { + it("lists SBIR topics with the default minimal shape", async () => { + const client = integrationClient("sbir-topics-list"); + const res = await client.listSbirTopics({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["topic_number", "title"]); + }); + + it("filters SBIR topics by year", async () => { + const client = integrationClient("sbir-topics-filter"); + const res = await client.listSbirTopics({ limit: 3, year: 2025 }); + expectPagination(res); + for (const row of res.results) { + expect(Number(row.year)).toBe(2025); + } + }); + + it("lists SBIR solicitations", async () => { + const client = integrationClient("sbir-solicitations-list"); + const res = await client.listSbirSolicitations({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["solicitation_number", "program"]); + }); +}); diff --git a/tests/integration/subawards.test.ts b/tests/integration/subawards.test.ts new file mode 100644 index 0000000..7a83a9b --- /dev/null +++ b/tests/integration/subawards.test.ts @@ -0,0 +1,18 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectNonEmpty } from "./validation.js"; + +describeIntegration("subawards (recorded)", () => { + it("lists subawards", async () => { + const client = integrationClient("subawards-list"); + const res = await client.listSubawards({ limit: 3 }); + const first = expectNonEmpty(res); + expect(Object.keys(first).length).toBeGreaterThan(0); + }); + + it("lists subawards with explicit ordering", async () => { + const client = integrationClient("subawards-ordering"); + const res = await client.listSubawards({ limit: 3, ordering: "-last_modified_date" }); + const first = expectNonEmpty(res); + expect(Object.keys(first).length).toBeGreaterThan(0); + }); +}); diff --git a/tests/integration/validation.ts b/tests/integration/validation.ts new file mode 100644 index 0000000..ff64efc --- /dev/null +++ b/tests/integration/validation.ts @@ -0,0 +1,28 @@ +/** Shared response-shape assertions, mirroring python's tests/integration/validation.py. */ + +import { expect } from "vitest"; + +import type { PaginatedResponse } from "../../src/types.js"; + +type AnyRecord = Record; + +export function expectPagination(res: PaginatedResponse): void { + expect(typeof res.count).toBe("number"); + expect(res.count).toBeGreaterThanOrEqual(0); + expect(Array.isArray(res.results)).toBe(true); + expect(res.next === null || typeof res.next === "string").toBe(true); + expect(res.previous === null || typeof res.previous === "string").toBe(true); +} + +export function expectNonEmpty(res: PaginatedResponse): AnyRecord { + expectPagination(res); + expect(res.count).toBeGreaterThan(0); + expect(res.results.length).toBeGreaterThan(0); + return res.results[0]; +} + +export function expectFields(record: AnyRecord, fields: string[]): void { + for (const field of fields) { + expect(record, `expected field '${field}'`).toHaveProperty(field); + } +} diff --git a/tests/integration/vehicles.test.ts b/tests/integration/vehicles.test.ts new file mode 100644 index 0000000..9f3f0ba --- /dev/null +++ b/tests/integration/vehicles.test.ts @@ -0,0 +1,18 @@ +import { describeIntegration, integrationClient } from "./harness.js"; +import { expectFields, expectNonEmpty } from "./validation.js"; + +describeIntegration("vehicles (recorded)", () => { + it("lists vehicles with the default minimal shape", async () => { + const client = integrationClient("vehicles-list"); + const res = await client.listVehicles({ limit: 3 }); + const first = expectNonEmpty(res); + expectFields(first, ["uuid", "vehicle_type", "total_obligated"]); + }); + + it("searches vehicles by program", async () => { + const client = integrationClient("vehicles-search"); + const res = await client.listVehicles({ limit: 3, search: "SEWP" }); + const first = expectNonEmpty(res); + expectFields(first, ["uuid", "solicitation_identifier"]); + }); +}); diff --git a/tests/production/smoke.test.ts b/tests/production/smoke.test.ts new file mode 100644 index 0000000..bc66718 --- /dev/null +++ b/tests/production/smoke.test.ts @@ -0,0 +1,56 @@ +/** + * Production smoke suite — the node port of tango-python's tests/production/. + * + * Runs ONLY when `TANGO_LIVE_TESTS=true` and `TANGO_API_KEY` are both set; it is excluded from default runs and CI by vitest.config.ts, and this gate is a second belt in case the file is targeted directly. + * Light invariants only: status, pagination shape, and rate-limit header parsing. + * + * TANGO_LIVE_TESTS=true TANGO_API_KEY=... npx vitest run tests/production + */ + +import { TangoClient } from "../../src/client.js"; +import { expectFields, expectNonEmpty, expectPagination } from "../integration/validation.js"; + +const LIVE = process.env.TANGO_LIVE_TESTS === "true" && Boolean(process.env.TANGO_API_KEY); + +function productionClient(): TangoClient { + return new TangoClient({ apiKey: process.env.TANGO_API_KEY }); +} + +describe.skipIf(!LIVE)("production smoke (live API)", () => { + it("lists contracts with the default minimal shape", async () => { + const client = productionClient(); + const res = await client.listContracts({ limit: 5 }); + const first = expectNonEmpty(res); + expectFields(first, ["key", "piid"]); + }); + + it("lists contracts with a custom shape", async () => { + const client = productionClient(); + const res = await client.listContracts({ limit: 3, shape: "key,piid,recipient(display_name),total_contract_value,award_date" }); + const first = expectNonEmpty(res); + expectFields(first, ["key", "piid"]); + }); + + it("lists entities", async () => { + const client = productionClient(); + const res = await client.listEntities({ limit: 5 }); + const first = expectNonEmpty(res); + expectFields(first, ["uei", "legal_business_name"]); + }); + + it("lists agencies", async () => { + const client = productionClient(); + const res = await client.listAgencies({ limit: 5 }); + expectNonEmpty(res); + }); + + it("parses rate-limit headers from a real response", async () => { + const client = productionClient(); + const res = await client.listNaics({ limit: 1 }); + expectPagination(res); + const info = client.rateLimitInfo; + expect(info).not.toBeNull(); + expect(typeof info?.limit === "number" || typeof info?.remaining === "number").toBe(true); + expect(client.lastResponseHeaders).not.toBeNull(); + }); +}); diff --git a/tests/unit/integration-harness.test.ts b/tests/unit/integration-harness.test.ts new file mode 100644 index 0000000..69dbfca --- /dev/null +++ b/tests/unit/integration-harness.test.ts @@ -0,0 +1,67 @@ +import { cassetteFetch, matchKey, REPLAY_ONLY, serializeInteraction } from "../integration/harness.js"; + +describe("serializeInteraction (cassette scrubbing)", () => { + const url = "https://tango.makegov.com/api/contracts/?limit=3"; + + it("refuses to serialize auth material in response headers", () => { + const out = serializeInteraction( + "GET", + url, + 200, + { + "content-type": "application/json", + "x-api-key": "super-secret-key", + authorization: "Bearer super-secret-token", + "set-cookie": "session=abc", + "x-ratelimit-remaining": "99", + }, + { count: 0, results: [] }, + ); + + const json = JSON.stringify(out); + expect(json).not.toContain("super-secret"); + expect(json).not.toContain("x-api-key"); + expect(json).not.toContain("authorization"); + expect(json).not.toContain("session=abc"); + expect(out.response.headers).toEqual({ "content-type": "application/json", "x-ratelimit-remaining": "99" }); + }); + + it("throws instead of writing when the secret leaks into the payload", () => { + expect(() => + serializeInteraction("GET", url, 200, {}, { echoed: "the-real-api-key" }, "the-real-api-key"), + ).toThrow(/Refusing to serialize/); + }); + + it("drops headers outside the allowlist", () => { + const out = serializeInteraction("GET", url, 200, { server: "nginx", date: "now", "content-type": "application/json" }, null); + expect(out.response.headers).toEqual({ "content-type": "application/json" }); + }); + + it("never stores request headers at all", () => { + const out = serializeInteraction("GET", url, 200, { "content-type": "application/json" }, null); + expect(Object.keys(out.request)).toEqual(["method", "url"]); + }); +}); + +describe("matchKey", () => { + it("is insensitive to query-param order", () => { + expect(matchKey("GET", "https://a/api/x/?b=2&a=1")).toBe(matchKey("GET", "https://b/api/x/?a=1&b=2")); + }); + + it("distinguishes method, path, and query values", () => { + const base = matchKey("GET", "https://a/api/x/?a=1"); + expect(matchKey("POST", "https://a/api/x/?a=1")).not.toBe(base); + expect(matchKey("GET", "https://a/api/y/?a=1")).not.toBe(base); + expect(matchKey("GET", "https://a/api/x/?a=2")).not.toBe(base); + }); + + it("ignores the host so a TANGO_BASE_URL override still replays", () => { + expect(matchKey("GET", "http://localhost:8000/api/x/")).toBe(matchKey("GET", "https://tango.makegov.com/api/x/")); + }); +}); + +describe("replay mode", () => { + it.skipIf(!REPLAY_ONLY)("hard-fails on a missing cassette with a re-record hint", () => { + expect(() => cassetteFetch("no-such-cassette-xyz")).toThrow(/TANGO_REFRESH_CASSETTES/); + }); +}); diff --git a/vitest.config.ts b/vitest.config.ts index 3fa3c0f..0426b87 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,10 +1,18 @@ -import { defineConfig } from "vitest/config"; +import { configDefaults, defineConfig } from "vitest/config"; + +// Production smoke tests are env-gated: they only join the run when TANGO_LIVE_TESTS=true. +// Cassette recording and live runs hit the real API, so they get serial file execution and a generous timeout. +const liveTests = process.env.TANGO_LIVE_TESTS === "true"; +const hittingLiveApi = liveTests || process.env.TANGO_REFRESH_CASSETTES === "true" || process.env.TANGO_USE_LIVE_API === "true"; export default defineConfig({ test: { environment: "node", globals: true, include: ["tests/**/*.test.ts"], + exclude: [...configDefaults.exclude, ...(liveTests ? [] : ["tests/production/**"])], + fileParallelism: !hittingLiveApi, + ...(hittingLiveApi ? { testTimeout: 60_000 } : {}), coverage: { provider: "v8", reporter: ["text", "html"], From 7b88000ff25074de4a9ada1a4b9bf6c8f9894354 Mon Sep 17 00:00:00 2001 From: "V. David Zvenyach" Date: Fri, 14 Aug 2026 12:30:24 -0500 Subject: [PATCH 6/7] docs: document the full parity surface; real CLAUDE.md; lockfile + npm ci; drop dead .eslintrc.cjs API_REFERENCE/README/SHAPES/DEVELOPERS now cover the wave-2/3 surface and the conformance + cassette workflows, and stale getIdvSummary/listIdvSummaryAwards sections are gone. package-lock.json is committed and CI/publish use npm ci for reproducible installs. Co-Authored-By: Claude Fable 5 --- .eslintrc.cjs | 20 - .github/workflows/ci.yml | 7 +- .github/workflows/publish.yml | 5 +- .gitignore | 2 - CHANGELOG.md | 32 +- CLAUDE.md | 102 + README.md | 87 +- docs/API_REFERENCE.md | 215 +- docs/DEVELOPERS.md | 108 +- docs/SHAPES.md | 43 +- package-lock.json | 4245 +++++++++++++++++++++++++++++++++ 11 files changed, 4736 insertions(+), 130 deletions(-) delete mode 100644 .eslintrc.cjs create mode 100644 CLAUDE.md create mode 100644 package-lock.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 412b909..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-env node */ -module.exports = { - root: true, - parser: "@typescript-eslint/parser", - parserOptions: { - ecmaVersion: "latest", - sourceType: "module", - }, - env: { - node: true, - es2022: true, - }, - plugins: ["@typescript-eslint"], - extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], - ignorePatterns: ["dist/", "node_modules/"], - rules: { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-explicit-any": "off", - }, -}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24122f9..0b684d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,10 +35,9 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install dependencies - # No lockfile is committed (package-lock.json is gitignored), and the - # "prepare" script runs a build that needs tsc — so ignore scripts here + # The "prepare" script runs a build that needs tsc — so ignore scripts here # and build explicitly below. - run: npm install --ignore-scripts --no-audit --no-fund + run: npm ci --ignore-scripts --no-audit --no-fund - name: Lint run: npm run lint @@ -75,7 +74,7 @@ jobs: node-version: "20" - name: Install dependencies - run: npm install --ignore-scripts --no-audit --no-fund + run: npm ci --ignore-scripts --no-audit --no-fund - name: Check SDK filter/shape conformance (vendored contract) run: npx tsx scripts/check-filter-shape-conformance.ts diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 617c357..32c70db 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -22,9 +22,8 @@ jobs: registry-url: "https://registry.npmjs.org" - name: Install dependencies - # No lockfile is committed (package-lock.json is gitignored), so npm ci will fail. - # We also ignore scripts to avoid running "prepare" during install; build is explicit below. - run: npm install --ignore-scripts --no-audit --no-fund + # Ignore scripts to avoid running "prepare" during install; build is explicit below. + run: npm ci --ignore-scripts --no-audit --no-fund - name: Lint run: npm run lint diff --git a/.gitignore b/.gitignore index 7f3b8ce..66d1aa8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* -package-lock.json pnpm-lock.yaml yarn.lock @@ -47,4 +46,3 @@ yoni/ .zed/ .idea/ # <<< mg-tools <<< -CLAUDE.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 5551554..edb5b65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,33 +8,35 @@ This project follows [Semantic Versioning](https://semver.org/). ## [Unreleased] ### Added -- **Recorded integration test layer** (parity with tango-python's VCR-cassette suite): a record/replay harness (`tests/integration/harness.ts`) around the SDK's injectable `fetchImpl`, with JSON cassettes in `tests/cassettes/` recorded against the live API. Default runs replay offline — a missing cassette is a hard failure so drift is loud, while an absent cassettes directory (a fork without the corpus) skips the suite with a warning. `TANGO_REFRESH_CASSETTES=true` re-records serially against the live API; `TANGO_USE_LIVE_API=true` bypasses cassettes. Cassettes never store request headers, keep only an allowlisted response-header subset, and the recorder throws rather than serialize API-key material anywhere in an interaction (asserted by unit tests in `tests/unit/integration-harness.test.ts`). -- Per-resource integration tests (`tests/integration/*.test.ts`, 44 tests / 44 cassettes) covering contracts (including cursor pagination and shaping), entities, IDVs, vehicles, opportunities, notices, grants, forecasts, agencies + organizations, protests, budget accounts (fiscal-year range round-trip), DIBBS, exclusions, SBIR, NAICS/PSC reference data, subawards, and edge cases (404, invalid ordering, empty result page). -- **Env-gated production smoke suite** (`tests/production/smoke.test.ts`, the node port of tango-python's `tests/production/`): runs only with `TANGO_LIVE_TESTS=true` plus `TANGO_API_KEY`, asserting light live-API invariants (pagination shape, shaping, rate-limit header parsing). Excluded from default runs and CI by `vitest.config.ts`. +- **DIBBS, exclusions, and SBIR/STTR endpoint support** (parity with tango-python v1.3.0). Six endpoint families had no SDK support at all — no models, no methods. Added `listDibbsRfqs`/`getDibbsRfq`, `listDibbsRfps`/`getDibbsRfp`, `listDibbsAwards`/`getDibbsAward`, `listExclusions`/`getExclusion`, `listSbirTopics`/`getSbirTopic`, and `listSbirSolicitations`/`getSbirSolicitation`, with every filter param in the API contract exposed as a typed option, explicit shape schemas (including the nested organization/awardee/topic/document expands), `ShapeConfig` defaults, and async iterators (`iterateDibbsRfqs`, `iterateDibbsRfps`, `iterateDibbsAwards`, `iterateExclusions`, `iterateSbirTopics`, `iterateSbirSolicitations`, plus the matching `IterableListMethod` entries for the generic `iterate()`). New model interfaces: `DibbsRfq`, `DibbsRfp`, `DibbsAward`, `Exclusion`, `SbirTopic`, `SbirSolicitation`. + + Two API behaviors are worth knowing. `is_open` (DIBBS) and `is_currently_excluded` (exclusions) are derived at query time, so filter with the `open` / `active` options rather than shaping on those fields. And DIBBS `total_contract_price` is the *order* total repeated on every line item — never sum it across rows; deduplicate on award + delivery-order number first. +- **Full typed filter surface on `listBudgetAccounts`** (parity with tango-python and the API contract). `ListBudgetAccountsOptions` now declares every `budget/accounts` filter param — the exact / `__gte` / `__lte` triplet for all 26 numeric lifecycle, ratio, and trend fields (`requested_ba`, `enacted_ba`, `apportioned`, `obligated_total`, `outlayed_total`, `unobligated_balance`, the contract/assistance breakdowns, the `*_pct` / `*_capped` ratios, YoY + 5-year-CAGR trends, and `actual_vs_requested_contract`), plus the `__in` / `__icontains` variants of the categorical filters (`federal_account_symbol`, `fiscal_year`, `agency_code`, `bureau_name`, `bea_category`, `subfunction_code`, `account_title__icontains`). +- `getGsaElibraryContract(uuid, options)` for `/api/gsa_elibrary_contracts/{uuid}/` (parity with tango-python), with the standard `shape` / `flat` / `flatLists` / `joiner` options and the `GSA_ELIBRARY_CONTRACTS_MINIMAL` default shape. +- Typed filter options that previously worked only through the index-signature escape hatch: `key` on `listContracts` / `listIdvs` / `listOtas` / `listOtidvs`, `cage` on `listEntities`, `id` on `listForecasts`, `opportunity_id` on `listOpportunities`, `previous_uii` on `listItDashboard`, `naics_code` on `listProtests` (sent verbatim, not remapped to `naics`), and `has_awards` on `listPsc`. The filter-shape conformance gate now reports zero index-signature warnings. - **Generated shape-coverage overlay** (parity with tango-python v1.4.0): `src/shapes/generatedOverlay.ts`, machine-generated by the new `scripts/generate-shape-overlay.ts` from the vendored contract plus `contracts/observed_shape_types.json` (live-API type observations vendored from tango-python). `SchemaRegistry` merges the overlay over the curated explicit schemas, so the typed shape API now accepts every field and expand the API returns — including entity `relationships(type, source)`, previously-unmapped models (`Naics`, `PSC`, `MasSin`, `BudgetAccount`, `AssistanceListing`, `BusinessType`), and all the code/description expands that were flattened to scalars. The reverse shape-coverage gate now reports **zero** gaps and `contracts/shape_coverage_baseline.json` is empty (416 → 0). - **Agency-filter diagnostics on `PaginatedResponse`** (parity with tango-python v1.5.0). Every list method now surfaces the API's `meta` payload, plus three parsed views: `agencyWarnings` (human-readable notes about dropped or loosely-matched agency tokens), `unresolvedAgencyTokens` (tokens that matched no organization, keyed by filter name), and `resolvedAgencies` (the organizations each token actually resolved to — the only way to catch a token fuzzy-matching an agency you did not intend). All three are total: absent or malformed `meta` yields empty values, never a throw. - **Structured shape errors on `TangoValidationError`** (parity with tango-python's `.issues` / `.available_fields`): new `issues` and `availableFields` getters expose the API's structured 400 payload — entries like `{"path": "tradeoff_process", "reason": "unknown_field"}` and the endpoint's valid field set — instead of leaving callers to parse `responseData` by hand. -- **DIBBS, exclusions, and SBIR/STTR endpoint support** (parity with tango-python v1.3.0). Six endpoint families had no SDK support at all — no models, no methods. Added `listDibbsRfqs`/`getDibbsRfq`, `listDibbsRfps`/`getDibbsRfp`, `listDibbsAwards`/`getDibbsAward`, `listExclusions`/`getExclusion`, `listSbirTopics`/`getSbirTopic`, and `listSbirSolicitations`/`getSbirSolicitation`, with every filter param in the API contract exposed as a typed option, explicit shape schemas (including the nested organization/awardee/topic/document expands), and `ShapeConfig` defaults. New model interfaces: `DibbsRfq`, `DibbsRfp`, `DibbsAward`, `Exclusion`, `SbirTopic`, `SbirSolicitation`. - - Two API behaviors are worth knowing. `is_open` (DIBBS) and `is_currently_excluded` (exclusions) are derived at query time, so filter with the `open` / `active` options rather than shaping on those fields. And DIBBS `total_contract_price` is the *order* total repeated on every line item — never sum it across rows; deduplicate on award + delivery-order number first. -- Async iteration for the six new resources: `iterateDibbsRfqs`, `iterateDibbsRfps`, `iterateDibbsAwards`, `iterateExclusions`, `iterateSbirTopics`, and `iterateSbirSolicitations` (plus the matching `IterableListMethod` entries for the generic `iterate()`). - Vendored the canonical API filter/shape contract at `contracts/filter_shape_contract.json` (API 4.22.0), so conformance checking is fully offline — no token, no sibling checkout. - New reverse shape-coverage gate `scripts/check-shape-coverage.ts` (npm script `check-shape-coverage`): walks every resource's shape tree in the vendored contract against the SDK's explicit schema registry and fails on any field or expand the SDK does not capture, unless recorded in `contracts/shape_coverage_baseline.json` as tracked backlog. - Accepted-gaps baselines: `contracts/conformance_baseline.json` (missing filters + unimplemented resources) and `contracts/shape_coverage_baseline.json` (known shape-coverage gaps). Baselined gaps report as warnings; anything new is an error. -- `getGsaElibraryContract(uuid, options)` for `/api/gsa_elibrary_contracts/{uuid}/` (parity with tango-python), with the standard `shape` / `flat` / `flatLists` / `joiner` options and the `GSA_ELIBRARY_CONTRACTS_MINIMAL` default shape. -- **Full typed filter surface on `listBudgetAccounts`** (parity with tango-python and the API contract). `ListBudgetAccountsOptions` now declares every `budget/accounts` filter param — the exact / `__gte` / `__lte` triplet for all 26 numeric lifecycle, ratio, and trend fields (`requested_ba`, `enacted_ba`, `apportioned`, `obligated_total`, `outlayed_total`, `unobligated_balance`, the contract/assistance breakdowns, the `*_pct` / `*_capped` ratios, YoY + 5-year-CAGR trends, and `actual_vs_requested_contract`), plus the `__in` / `__icontains` variants of the categorical filters (`federal_account_symbol`, `fiscal_year`, `agency_code`, `bureau_name`, `bea_category`, `subfunction_code`, `account_title__icontains`). -- Typed filter options that previously worked only through the index-signature escape hatch: `key` on `listContracts` / `listIdvs` / `listOtas` / `listOtidvs`, `cage` on `listEntities`, `id` on `listForecasts`, `opportunity_id` on `listOpportunities`, `previous_uii` on `listItDashboard`, `naics_code` on `listProtests` (sent verbatim, not remapped to `naics`), and `has_awards` on `listPsc`. The filter-shape conformance gate now reports zero index-signature warnings. +- **Recorded integration test layer** (parity with tango-python's VCR-cassette suite): a record/replay harness (`tests/integration/harness.ts`) around the SDK's injectable `fetchImpl`, with JSON cassettes in `tests/cassettes/` recorded against the live API. Default runs replay offline — a missing cassette is a hard failure so drift is loud, while an absent cassettes directory (a fork without the corpus) skips the suite with a warning. `TANGO_REFRESH_CASSETTES=true` re-records serially against the live API; `TANGO_USE_LIVE_API=true` bypasses cassettes. Cassettes never store request headers, keep only an allowlisted response-header subset, and the recorder throws rather than serialize API-key material anywhere in an interaction (asserted by unit tests in `tests/unit/integration-harness.test.ts`). +- Per-resource integration tests (`tests/integration/*.test.ts`, 44 tests / 44 cassettes) covering contracts (including cursor pagination and shaping), entities, IDVs, vehicles, opportunities, notices, grants, forecasts, agencies + organizations, protests, budget accounts (fiscal-year range round-trip), DIBBS, exclusions, SBIR, NAICS/PSC reference data, subawards, and edge cases (404, invalid ordering, empty result page). +- **Env-gated production smoke suite** (`tests/production/smoke.test.ts`, the node port of tango-python's `tests/production/`): runs only with `TANGO_LIVE_TESTS=true` plus `TANGO_API_KEY`, asserting light live-API invariants (pagination shape, shaping, rate-limit header parsing). Excluded from default runs and CI by `vitest.config.ts`. + +### Changed +- Both conformance baselines shrank with the new resources: `dibbs/*`, `exclusions`, and `sbir/*` left `unimplemented_resources` in `contracts/conformance_baseline.json`, and their `unmapped_resource` entries left `contracts/shape_coverage_baseline.json` (422 → 416 known gaps, then 416 → 0 with the generated overlay above). +- `scripts/check-filter-shape-conformance.ts` now defaults to the vendored contract instead of a checked-out tango API repo (`TANGO_CONTRACT_PATH` or `--manifest` still point it at one), covers every resource in the 4.22.0 contract in its resource map, and treats an unimplemented resource as an error unless baselined. +- Removed the dead legacy `.eslintrc.cjs` — the flat `eslint.config.js` has been the operative ESLint config since the flat-config migration, and the leftover file only invited divergent edits. ### Fixed - `listBudgetAccounts`: the `fiscal_year_gte`, `fiscal_year_lte`, and `account_title` options were sent verbatim, which the API silently ignores. They are kept as legacy aliases and now remapped to the forms the API understands (`fiscal_year__gte`, `fiscal_year__lte`, `account_title__icontains`); an explicitly passed dunder param wins over its alias. - -### Changed -- Both conformance baselines shrank with the new resources: `dibbs/*`, `exclusions`, and `sbir/*` left `unimplemented_resources` in `contracts/conformance_baseline.json`, and their `unmapped_resource` entries left `contracts/shape_coverage_baseline.json` (422 → 416 known gaps). -- `scripts/check-filter-shape-conformance.ts` now defaults to the vendored contract instead of a sibling `../tango` checkout (`TANGO_CONTRACT_PATH` or `--manifest` still point it at a live checkout), covers every resource in the 4.22.0 contract in its resource map, and treats an unimplemented resource as an error unless baselined. +- Docs: removed the stale `getIdvSummary` / `listIdvSummaryAwards` sections from `README.md` and `docs/API_REFERENCE.md` — those methods were removed from the SDK in 1.1.0. Documented the full new surface (DIBBS/exclusions/SBIR, budget accounts and their filter surface, `getGsaElibraryContract`, the newly typed filters, `PaginatedResponse` meta diagnostics, structured `TangoValidationError` details), completed the `ShapeConfig` preset table in `docs/SHAPES.md`, and rewrote the maintainer half of `docs/DEVELOPERS.md` around the conformance gates and the cassette record/replay workflow (the old text still claimed the SDK had no cassette mechanism). ### CI +- `package-lock.json` is now committed, and the CI + publish workflows install with `npm ci --ignore-scripts` instead of `npm install` — installs are reproducible from the lockfile instead of re-resolving dependency ranges on every run. - The test job now prints a coverage summary (`npx vitest run --coverage`) on the Node 20 leg, and the default `npx vitest run` now includes the integration suite replayed offline from the committed cassettes. No coverage fail-under gate, matching tango-python. -- The `conformance` job is now a hard gate that runs both conformance directions offline against the vendored contract on every PR — it no longer needs `TANGO_API_REPO_ACCESS_TOKEN` and no longer skips silently without it. A separate token-gated step diffs the vendored contract against makegov/tango HEAD and emits a staleness warning (never a failure). +- The `conformance` job is now a hard gate that runs both conformance directions offline against the vendored contract on every PR — it no longer needs `TANGO_API_REPO_ACCESS_TOKEN` and no longer skips silently without it. A separate token-gated step diffs the vendored contract against the tango API repo's HEAD and emits a staleness warning (never a failure). ## [1.1.0] - 2026-05-29 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..7fcadc6 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,102 @@ +# tango-node + + + +## Non-Negotiables + +- **Node.js >= 18, ESM-only.** The package is `"type": "module"`, built for native `fetch`; no CommonJS output, no `require()` in source. +- **Public SDK — surface is contract.** Method names, option names, and return shapes are promises. Deprecate, don't break. If you rename a method, leave an alias + `@deprecated` JSDoc for at least one minor version. +- **Always update `CHANGELOG.md`** under `## [Unreleased]` when source files change. Follow [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) + [SemVer](https://semver.org/). +- **Strict TypeScript.** `npm run typecheck` (`tsc --noEmit`) must pass cleanly; don't loosen `tsconfig.json` to make an error go away. +- **No untyped filter bags on new surface.** Every accepted filter on a new `list*` method must be an explicit typed property on its `Options` interface. The `[key: string]: unknown` index signature exists only for forward-compatibility with not-yet-ported server filters — never as a substitute for typing known ones. +- **Both conformance gates stay green.** `npm run check-conformance` and `npm run check-shape-coverage` are hard CI gates against the vendored contract in `contracts/`. Shrink the baselines as gaps close; never grow them to silence a legitimate failure. +- **Never edit `src/shapes/generatedOverlay.ts` by hand** — regenerate it with `npm run generate-shape-overlay`. +- **Never `git commit` / `push` / `merge` without the user's explicit permission.** +- Use the `gh` CLI for GitHub operations. + +## Project conventions + +### Toolchain + +- **Package manager:** npm, with a committed `package-lock.json` — CI installs with `npm ci --ignore-scripts`. Run `npm install` after changing dependencies so the lockfile stays in sync. +- **Formatter:** Prettier (`npm run format`). **Linter:** ESLint flat config in `eslint.config.js` (`npm run lint`). +- **Type checker:** `tsc` strict mode via `npm run typecheck`. +- **Tests:** Vitest (`npm test` for watch mode, `npx vitest run` for a single pass). +- **Base branch:** `main`. + +### Commands + +```bash +# install +npm install + +# lint / format / types / build +npm run lint +npm run format +npm run typecheck +npm run build + +# tests +npx vitest run # unit + integration (cassette replay, offline) +npm run coverage # single pass with v8 coverage + +# conformance gates (offline, against contracts/filter_shape_contract.json) +npm run check-conformance # SDK filters/shapes -> contract +npm run check-shape-coverage # contract shape fields -> SDK schemas +npm run generate-shape-overlay # regenerate src/shapes/generatedOverlay.ts +``` + +### Tests + +- **Unit** (`tests/unit/`): fast, offline, mock responses injected via the `fetchImpl` constructor option. +- **Integration** (`tests/integration/`): cassette record/replay via `tests/integration/harness.ts`; default runs replay `tests/cassettes/*.json` offline, and a missing cassette is a hard failure. +- **Cassette refresh:** `TANGO_REFRESH_CASSETTES=true` re-records against the live API (needs `TANGO_API_KEY`); `TANGO_USE_LIVE_API=true` bypasses cassettes. When an API change invalidates a cassette, refresh and commit it in the same PR. +- **Production smoke** (`tests/production/`): live-API-gated behind `TANGO_LIVE_TESTS=true` + `TANGO_API_KEY`; excluded from default runs and CI. +- Cassettes must never contain credentials — the harness refuses to serialize request headers; keep it that way. + +### Release flow + +1. Bump `version` in `package.json`. +2. Promote `## [Unreleased]` → a dated version section in `CHANGELOG.md`. +3. Open a PR to `main` and merge it. +4. Create a GitHub Release (tag + notes) — the publish workflow (`.github/workflows/publish.yml`) lints, tests, builds, and publishes to npm with provenance. + +### Style + +- camelCase methods and options on the client surface; snake_case filter params pass through to the API as-is unless an explicit alias remap is documented. +- American English everywhere. + +## Where things live in this repo + +| What | Where | +| ---- | ----- | +| SDK source | `src/` (client in `src/client.ts`, shaping pipeline in `src/shapes/`) | +| Shape presets | `src/config.ts` (`ShapeConfig`) | +| Vendored API contract + baselines | `contracts/` | +| Conformance gates + overlay generator + smoke scripts | `scripts/` | +| Tests | `tests/` (`unit/`, `integration/`, `cassettes/`, `production/`, `scripts/`, `webhooks/`) | +| User-facing docs | `docs/` (API reference, shapes, client, webhooks, developer guide) | +| Maintainer guide (gates, cassettes, release) | `docs/DEVELOPERS.md` | +| README | `README.md` | +| Changelog | `CHANGELOG.md` | +| CI + publish workflows | `.github/workflows/` | + +## Context precedence (read order) + +1. This `CLAUDE.md` — **start here**, then follow the pointers in "Where things live" +2. Files named in "Where things live" above +3. Community / language defaults (last resort) + +Don't fall back to community defaults while local pointers remain unread. + +## Contributing + +External contributors: see the repo's GitHub issues for how to propose changes. Lint, typecheck, tests, and both conformance gates should pass locally before opening a PR. diff --git a/README.md b/README.md index 11e6951..281ba2b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ A modern Node.js SDK for the [Tango API](https://tango.makegov.com), featuring d - **Dynamic Response Shaping** – Ask Tango for exactly the fields you want using a simple shape syntax. - **Type-Safe by Design** – Shape strings are validated against Tango schemas and mapped to generated TypeScript types. -- **Full Tango API surface** – Awards (contracts, IDVs, OTAs, OTIDVs, subawards, vehicles, GSA eLibrary), opportunities + notices, forecasts, grants, protests, IT Dashboard, entities (with sub-resources), agencies/organizations/offices/departments, lookups (NAICS, PSC, MAS SINs, assistance listings, business types), metrics, resolve/validate, webhooks. See `## API Methods` below for the full list. +- **Full Tango API surface** – Awards (contracts, IDVs, OTAs, OTIDVs, subawards, vehicles, GSA eLibrary), opportunities + notices, forecasts, grants, protests, IT Dashboard, budget accounts, exclusions, SBIR/STTR, DIBBS, entities (with sub-resources), agencies/organizations/offices/departments, lookups (NAICS, PSC, MAS SINs, assistance listings, business types), metrics, resolve/validate, webhooks. See `## API Methods` below for the full list. - **Flexible Data Access** – Plain JavaScript objects backed by runtime validation and parsing, materialized via the dynamic model pipeline. - **Modern Node.js** – Built for Node.js 18+ with native `fetch` and ESM-first design. - **Tested Against the Real API** – Integration tests (mirroring the Python SDK) keep behavior aligned. @@ -180,34 +180,50 @@ The Node.js client mirrors the Python SDK's high-level API. Selected highlights: **Contracts / IDVs / OTAs / OTIDVs / Subawards** -- `listContracts(options)` / `listIdvs(options)` / `getIdv(key, options)` +- `listContracts(options)` / `getContract(key, options)` / `getContractSubawards(key, options)` / `getContractTransactions(key, options)` +- `listIdvs(options)` / `getIdv(key, options)` - `listIdvAwards(key, options)` / `listIdvChildIdvs({key, ...options})` / `listIdvTransactions(key, options)` -- `getIdvSummary(identifier)` / `listIdvSummaryAwards(identifier, options)` - `listOtas(options)` / `getOta(key)` / `listOtidvs(options)` / `getOtidv(key)` / `listOtidvAwards(key, options)` -- `listSubawards(options)` +- `listSubawards(options)` / `getSubaward(key)` **Vehicles** -- `listVehicles(options)` / `getVehicle(uuid, options)` / `listVehicleAwardees(uuid, options)` +- `listVehicles(options)` / `getVehicle(uuid, options)` / `listVehicleAwardees(uuid, options)` / `listVehicleOrders(uuid, options)` **Entities** - `listEntities(options)` / `getEntity(ueiOrCage, options)` - `listEntityContracts(uei, options)` / `listEntityIdvs(uei, options)` / `listEntityOtas(uei, options)` - `listEntityOtidvs(uei, options)` / `listEntitySubawards(uei, options)` / `listEntityLcats(uei, options)` -- `getEntityMetrics(uei, months, periodGrouping)` +- `getEntityMetrics(uei, months, periodGrouping)` / `getEntityBudgetFlows(uei)` **Forecasts / Opportunities / Notices / Grants** - `listForecasts(options)` / `listOpportunities(options)` / `listNotices(options)` / `listGrants(options)` +- `getForecast(id, options)` / `getOpportunity(opportunityId, options)` / `getNotice(noticeId, options)` / `getGrant(grantId, options)` - `searchOpportunityAttachments(options)` -**GSA eLibrary / Protests / IT Dashboard / Subawards / LCATs** +**GSA eLibrary / Protests / IT Dashboard / LCATs** -- `listGsaElibraryContracts(options)` / `listProtests(options)` / `getProtest(caseNumber)` +- `listGsaElibraryContracts(options)` / `getGsaElibraryContract(uuid, options)` +- `listProtests(options)` / `getProtest(caseNumber)` - `listItDashboard(options)` / `getItDashboard(uii)` - `listLcats(options)` / `listIdvLcats(key, options)` +**Budget Accounts** + +- `listBudgetAccounts(options)` / `getBudgetAccount(id, options)` +- `getBudgetAccountQuarters(id, options)` / `getBudgetAccountRecipients(id, options)` + +**Exclusions / SBIR / DIBBS** + +- `listExclusions(options)` / `getExclusion(exclusionKey, options)` +- `listSbirTopics(options)` / `getSbirTopic(topicId, options)` +- `listSbirSolicitations(options)` / `getSbirSolicitation(solicitationId, options)` +- `listDibbsRfqs(options)` / `getDibbsRfq(uuid, options)` +- `listDibbsRfps(options)` / `getDibbsRfp(uuid, options)` +- `listDibbsAwards(options)` / `getDibbsAward(uuid, options)` + **Reference / Lookups** - `listBusinessTypes(options)` / `getBusinessType(code)` @@ -237,6 +253,8 @@ The Node.js client mirrors the Python SDK's high-level API. Selected highlights: - `iterate(method, options)` — generic async iterator over any supported list method - `iterateContracts` / `iterateEntities` / `iterateOpportunities` / `iterateNotices` - `iterateGrants` / `iterateForecasts` / `iterateIdvs` / `iterateVehicles` +- `iterateDibbsRfqs` / `iterateDibbsRfps` / `iterateDibbsAwards` +- `iterateExclusions` / `iterateSbirTopics` / `iterateSbirSolicitations` **Utility** @@ -252,10 +270,18 @@ interface PaginatedResponse { next: string | null; previous: string | null; pageMetadata: Record | null; + meta: Record | null; + agencyWarnings: string[]; + unresolvedAgencyTokens: Record; + resolvedAgencies: Record>>; + cursor: string | null; results: T[]; } ``` +`meta` surfaces response-level metadata from the API, and the three `agency*` fields are parsed views of its agency-filter diagnostics — see [API Reference § Pagination](docs/API_REFERENCE.md#pagination) for how to use them to catch silently-narrowed agency filters. +`cursor` is extracted from `next` on keyset-paginated endpoints so you can pass it straight back as the next request's `cursor` option. + ## Error Handling Errors are surfaced as typed exceptions, aligned with the Python SDK: @@ -263,7 +289,7 @@ Errors are surfaced as typed exceptions, aligned with the Python SDK: - `TangoAPIError` – Base error for unexpected issues. - `TangoAuthError` – Authentication problems (e.g., invalid API key, 401). - `TangoNotFoundError` – Resource not found (404). -- `TangoValidationError` – Invalid request parameters (400). +- `TangoValidationError` – Invalid request parameters (400). Exposes the API's structured 400 payload via `issues` and `availableFields` (see the [API Reference](docs/API_REFERENCE.md#error-types)). - `TangoRateLimitError` – Rate limit exceeded (429). - `TangoTimeoutError` – Request exceeded the configured `timeoutMs`. @@ -306,6 +332,7 @@ tango-node/ │ ├── models/ # Lightweight model interfaces (Contract, Entity, etc.) │ ├── shapes/ # Shape system (parser, generator, factory) │ │ ├── explicitSchemas.ts # Predefined schemas for resources +│ │ ├── generatedOverlay.ts # Machine-generated schema overlay (see scripts/) │ │ ├── factory.ts # Instantiate typed models from data │ │ ├── generator.ts # Type generation from shape specs │ │ ├── index.ts # Shapes exports @@ -313,27 +340,28 @@ tango-node/ │ │ ├── schema.ts # Schema registry + validation │ │ ├── schemaTypes.ts # Schema data structures │ │ └── types.ts # Shape spec types -│ └── utils/ # Helpers -│ ├── dates.ts # Date/time parsing utilities -│ ├── http.ts # HTTP client wrapper -│ ├── number.ts # Numeric parsing/formatting -│ └── unflatten.ts # Unflatten dotted-key responses +│ ├── utils/ # Helpers +│ │ ├── dates.ts # Date/time parsing utilities +│ │ ├── http.ts # HTTP client wrapper +│ │ ├── number.ts # Numeric parsing/formatting +│ │ └── unflatten.ts # Unflatten dotted-key responses +│ └── webhooks/ # Signing, receiver, simulator, CLI +├── contracts/ # Vendored API contract + conformance baselines +├── scripts/ # Conformance gates, overlay generator, live smoke scripts ├── docs/ # Documentation │ ├── API_REFERENCE.md +│ ├── CLIENT.md +│ ├── DEVELOPERS.md │ ├── DYNAMIC_MODELS.md -│ └── SHAPES.md +│ ├── SHAPES.md +│ └── WEBHOOKS.md ├── tests/ # Test suite (Vitest) -│ └── unit/ -│ ├── client.test.ts -│ ├── errors.test.ts -│ ├── shapes.factory.test.ts -│ ├── shapes.generator.test.ts -│ ├── shapes.parser.test.ts -│ ├── shapes.schema.test.ts -│ ├── utils.dates.test.ts -│ ├── utils.http.test.ts -│ ├── utils.number.test.ts -│ └── utils.unflatten.test.ts +│ ├── unit/ # Offline unit tests (fetchImpl mocks) +│ ├── integration/ # Cassette-replayed integration tests +│ ├── cassettes/ # Recorded API interactions (JSON) +│ ├── production/ # Env-gated live smoke suite (TANGO_LIVE_TESTS) +│ ├── scripts/ # Tests for the conformance gates +│ └── webhooks/ # Receiver / simulator / CLI tests ├── dist/ # Build output (compiled JS + d.ts) from `npm run build` ├── eslint.config.js # ESLint flat config ├── .prettierrc # Prettier config @@ -357,11 +385,16 @@ npm test Useful scripts: - `npm run build` – Compile TypeScript to `dist/`. -- `npm test` – Run unit and integration tests. +- `npm test` – Run unit and integration tests (integration replays committed cassettes offline). - `npm run coverage` – Get test coverage report. - `npm run lint` – Run ESLint. - `npm run format` – Run Prettier. - `npm run typecheck` – TS type checking without emit. +- `npm run check-conformance` – SDK filters/shapes vs the vendored API contract. +- `npm run check-shape-coverage` – Reverse gate: every contract shape field is captured by the SDK. +- `npm run generate-shape-overlay` – Regenerate `src/shapes/generatedOverlay.ts` from the vendored contract. + +See [docs/DEVELOPERS.md](docs/DEVELOPERS.md) for the conformance architecture and the cassette record/replay workflow. ## Requirements diff --git a/docs/API_REFERENCE.md b/docs/API_REFERENCE.md index a29a3f0..c98ba50 100644 --- a/docs/API_REFERENCE.md +++ b/docs/API_REFERENCE.md @@ -80,6 +80,9 @@ These mirror the Python SDK: | `recipient_uei` | `uei` | | `set_aside_type` | `set_aside` | +`key` is also a typed filter — pass a contract key (or several separated by `|`) to fetch specific records through the list endpoint. +The same `key` filter exists on `listIdvs`, `listOtas`, and `listOtidvs`. + Sorting: ```ts @@ -197,15 +200,6 @@ const children = await client.listIdvChildIdvs({ key: "SOME_IDV_KEY", limit: 25 const tx = await client.listIdvTransactions("SOME_IDV_KEY", { limit: 100 }); ``` -### `getIdvSummary(identifier)` / `listIdvSummaryAwards(identifier, options?)` - -> **Deprecated.** These methods wrap the `/api/idvs/{identifier}/summary/` and `/api/idvs/{identifier}/summary/awards/` routes, which were removed server-side and now return **404**. The methods will be removed from the SDK in a future release. For solicitation-grouped views, query `/api/vehicles/` instead (see [Vehicles](#vehicles)). - -```ts -const summary = await client.getIdvSummary("SOLICITATION_IDENTIFIER"); -const awards = await client.listIdvSummaryAwards("SOLICITATION_IDENTIFIER", { limit: 25 }); -``` - --- ## Entities @@ -222,6 +216,7 @@ const resp = await client.listEntities({ Filters: - `search` +- `cage` (CAGE code, typed alongside the existing `cage_code`) - any field names supported by the API ### `getEntity(uei, options?)` @@ -237,6 +232,7 @@ Returns a shaped entity object with nested addresses/fields based on the shape. ### `listForecasts(options)` Forecast search, with optional shaping. +`id` is a typed filter for fetching specific forecast records through the list endpoint. --- @@ -245,6 +241,7 @@ Forecast search, with optional shaping. ### `listOpportunities(options)` Search SAM.gov opportunities with shaping. +`opportunity_id` is a typed filter for fetching specific opportunities through the list endpoint. --- @@ -373,6 +370,17 @@ const subs = await client.listSubawards({ prime_uei: "ABC123DEF456", limit: 25 } const contracts = await client.listGsaElibraryContracts({ schedule: "MAS", limit: 25 }); ``` +### `getGsaElibraryContract(uuid, options?)` + +Fetch a single GSA eLibrary contract by UUID, with the standard `shape` / `flat` / `flatLists` / `joiner` options. +Defaults to `ShapeConfig.GSA_ELIBRARY_CONTRACTS_MINIMAL` when no shape is passed. + +```ts +const contract = await client.getGsaElibraryContract("00000000-0000-0000-0000-000000000001", { + shape: ShapeConfig.GSA_ELIBRARY_CONTRACTS_MINIMAL, +}); +``` + --- ## Protests @@ -383,6 +391,8 @@ const contracts = await client.listGsaElibraryContracts({ schedule: "MAS", limit const protests = await client.listProtests({ source_system: "gao", limit: 25 }); ``` +`naics_code` is a typed filter sent to the API verbatim (it is **not** remapped to `naics`, unlike the contracts alias). + ### `getProtest(caseNumber)` ```ts @@ -405,6 +415,143 @@ const investments = await client.listItDashboard({ search: "cloud", limit: 25 }) const investment = await client.getItDashboard("023-000001234"); ``` +`listItDashboard` also accepts `previous_uii` as a typed filter, for tracing an investment across UII renumbering. + +--- + +## Budget Accounts + +OMB budget appendix accounts with lifecycle amounts (requested → enacted → apportioned → obligated → outlayed), derived ratios, and trends. + +### `listBudgetAccounts(options?)` + +```ts +const accounts = await client.listBudgetAccounts({ + fiscal_year: 2025, + agency_code: "097", + unobligated_balance__gte: 1_000_000_000, + ordering: "-unobligated_balance", +}); +``` + +`ListBudgetAccountsOptions` types the **full** filter surface of `/api/budget/accounts/` — every numeric lifecycle, ratio, and trend field exposes an exact / `__gte` / `__lte` triplet, and categorical filters carry `__in` / `__icontains` variants. +The range filters use the API's **dunder wire names** (double underscore, e.g. `fiscal_year__gte`) — these are passed through verbatim. +A representative sample: + +| Filter family | Example params | +| ------------- | -------------- | +| Identity / categorical | `federal_account_symbol`, `fiscal_year`, `agency_code__in`, `bureau_name__icontains`, `bea_category`, `subfunction_code`, `account_title__icontains` | +| Lifecycle amounts | `requested_ba__gte`, `enacted_ba__lte`, `apportioned__gte`, `obligated_total__gte`, `outlayed_total__lte`, `unobligated_balance__gte` | +| Contract / assistance breakdowns | `contract_obligated__gte`, `assistance_outlayed__lte`, `contract_share_of_obligated_capped__gte` | +| Ratios | `obligated_to_apportioned_pct__gte`, `apportioned_to_enacted_pct_capped__lte`, `outlayed_to_obligated_pct__gte`, `unobligated_pct__gte` | +| Trends | `enacted_ba_yoy_pct__gte`, `obligated_yoy_pct__lte`, `enacted_ba_5yr_cagr__gte`, `ba_growth_next_year_pct__gte`, `actual_vs_requested_contract__gte` | + +See `ListBudgetAccountsOptions` in `src/client.ts` for the complete list — every filter is a typed, autocompleted option. +Any of the numeric fields is a valid `ordering` target (`ordering: "-unobligated_balance"` ranks by largest headroom first), and `search` covers account title, agency name, and bureau name. + +**Legacy aliases.** Three pre-1.2 option names are kept and remapped to the params the API actually understands: `fiscal_year_gte` → `fiscal_year__gte`, `fiscal_year_lte` → `fiscal_year__lte`, and `account_title` → `account_title__icontains`. +An explicitly passed dunder param wins over its alias. + +### `getBudgetAccount(id, options?)` + +```ts +const account = await client.getBudgetAccount("ACCOUNT_ID"); +``` + +### `getBudgetAccountQuarters(id, options?)` / `getBudgetAccountRecipients(id, options?)` + +Quarterly lifecycle history and top recipients for one account. + +```ts +const quarters = await client.getBudgetAccountQuarters("ACCOUNT_ID"); +const recipients = await client.getBudgetAccountRecipients("ACCOUNT_ID"); +``` + +--- + +## DIBBS + +DLA DIBBS solicitations and awards: RFQs, RFPs, and award history. + +### `listDibbsRfqs(options?)` / `getDibbsRfq(uuid, options?)` + +```ts +const rfqs = await client.listDibbsRfqs({ + nsn: "5310-01-234-5678", + open: true, + shape: ShapeConfig.DIBBS_RFQS_MINIMAL, +}); +``` + +Typed filters: `nsn`, `part_number`, `solicitation`, `purchase_request`, `organization`, `status_code`, `set_aside`, `open`, `quantity_min` / `quantity_max`, `issue_date_after` / `issue_date_before`, `return_by_date_after` / `return_by_date_before`, `search`, `ordering`. + +### `listDibbsRfps(options?)` / `getDibbsRfp(uuid, options?)` + +```ts +const rfps = await client.listDibbsRfps({ open: true, limit: 25 }); +``` + +Typed filters: `nsn`, `part_number`, `solicitation`, `organization`, `buyer_code`, `open`, `issued_date_after` / `issued_date_before`, `closes_date_after` / `closes_date_before`, `search`, `ordering`. + +### `listDibbsAwards(options?)` / `getDibbsAward(uuid, options?)` + +```ts +const awards = await client.listDibbsAwards({ awardee_cage: "1ABC2", limit: 25 }); +``` + +Typed filters: `award_number`, `delivery_order_number`, `solicitation`, `purchase_request`, `nsn`, `part_number`, `awardee_cage`, `entity`, `organization`, `total_contract_price_min` / `total_contract_price_max`, `award_date_after` / `award_date_before`, `posted_date_after` / `posted_date_before`, `search`, `ordering`. + +Two API behaviors worth knowing: + +- `is_open` is **derived at query time** from `return_by_date` (RFQs) / `closes_date` (RFPs) — filter with the `open` option rather than shaping on `is_open`. +- DIBBS `total_contract_price` is the **order** total repeated on every line item — never sum it across rows; deduplicate on award + delivery-order number first. + +--- + +## Exclusions + +SAM.gov exclusion records (debarments, suspensions, and other ineligibility actions). + +### `listExclusions(options?)` / `getExclusion(exclusionKey, options?)` + +```ts +const exclusions = await client.listExclusions({ + active: true, + classification_type: "Firm", + shape: ShapeConfig.EXCLUSIONS_MINIMAL, +}); +``` + +Typed filters: `uei`, `entity_uei`, `cage_code`, `npi`, `classification_type`, `exclusion_type`, `exclusion_program`, `excluding_agency_code`, `excluding_agency_name`, `active`, `delisted`, `activate_date_after` / `activate_date_before`, `termination_date_after` / `termination_date_before`, `update_date_after` / `update_date_before`, `search`, `ordering`. + +`is_currently_excluded` is **derived at query time** — filter with `active: true` for records currently in effect rather than shaping on it. + +--- + +## SBIR / STTR + +SBIR/STTR topics and DoD DSIP solicitation cycles. + +### `listSbirTopics(options?)` / `getSbirTopic(topicId, options?)` + +```ts +const topics = await client.listSbirTopics({ + agency: "DOD", + year: 2026, + shape: ShapeConfig.SBIR_TOPICS_MINIMAL, +}); +``` + +Typed filters: `topic_number`, `solicitation_number`, `agency`, `activity`, `year`, `doc_source`, `open_date_after` / `open_date_before`, `close_date_after` / `close_date_before`, `release_date_after` / `release_date_before`, `search`, `ordering`. + +### `listSbirSolicitations(options?)` / `getSbirSolicitation(solicitationId, options?)` + +```ts +const cycles = await client.listSbirSolicitations({ program: "SBIR", year: 2026 }); +``` + +Typed filters: `solicitation_number`, `solicitation_status`, `program`, `activity`, `cycle_name`, `out_of_cycle`, `year`, `start_date_after` / `start_date_before`, `end_date_after` / `end_date_before`, `search`, `ordering`. + --- ## LCATs @@ -476,10 +623,12 @@ const code = await client.getNaics("541511"); ### `listPsc(options?)` / `getPsc(code)` ```ts -const psc = await client.listPsc(); +const psc = await client.listPsc({ has_awards: true }); const code = await client.getPsc("D302"); ``` +`has_awards: true` restricts the list to PSC codes that actually appear on awards. + ### `listMasSins(options?)` / `getMasSin(sin)` ```ts @@ -600,7 +749,7 @@ for await (const contract of client.iterate("listContracts", { awarding_agency: } ``` -Named wrappers: `iterateContracts`, `iterateEntities`, `iterateOpportunities`, `iterateNotices`, `iterateGrants`, `iterateForecasts`, `iterateIdvs`, `iterateVehicles`. +Named wrappers: `iterateContracts`, `iterateEntities`, `iterateOpportunities`, `iterateNotices`, `iterateGrants`, `iterateForecasts`, `iterateIdvs`, `iterateVehicles`, `iterateDibbsRfqs`, `iterateDibbsRfps`, `iterateDibbsAwards`, `iterateExclusions`, `iterateSbirTopics`, `iterateSbirSolicitations`. --- @@ -768,6 +917,7 @@ All thrown by async methods: - `TangoAuthError` - `TangoNotFoundError` - `TangoRateLimitError` +- `TangoTimeoutError` - `TangoValidationError` - `ShapeError` - `ShapeParseError` @@ -775,6 +925,24 @@ All thrown by async methods: - `TypeGenerationError` - `ModelInstantiationError` +### Structured validation details on `TangoValidationError` + +When the API rejects a request with a structured 400 payload (shape errors especially), `TangoValidationError` exposes it without any hand-parsing of `responseData`: + +- `err.issues` — the API's issue entries, e.g. `[{ path: "tradeoff_process", reason: "unknown_field" }]`; an empty array when the response carried no structured issues. +- `err.availableFields` — the endpoint's valid field set when the API includes one, else `null`. + +```ts +try { + await client.listContracts({ shape: "key,tradeoff_process" }); +} catch (err) { + if (err instanceof TangoValidationError) { + for (const issue of err.issues) console.error(issue.path, issue.reason); + console.error("valid fields:", err.availableFields); + } +} +``` + --- ## Pagination @@ -787,8 +955,31 @@ interface PaginatedResponse { next: string | null; previous: string | null; pageMetadata: Record | null; + meta: Record | null; + agencyWarnings: string[]; + unresolvedAgencyTokens: Record; + resolvedAgencies: Record>>; + cursor: string | null; results: T[]; } ``` -You can follow `next` / `previous` manually or use your own wrapper. +You can follow `next` / `previous` manually, pass `cursor` back on keyset-paginated endpoints, or use the `iterate*` helpers. + +### Response `meta` and agency-filter diagnostics + +`meta` carries any response-level metadata the API attached to the page — currently agency-filter resolution diagnostics. +Three parsed views are always present (empty rather than throwing when `meta` is absent or malformed): + +- `agencyWarnings` — human-readable notes about agency tokens that were dropped or matched loosely; a non-empty list means part of your filter did not apply, so a small or empty `results` is not evidence that no such records exist. +- `unresolvedAgencyTokens` — tokens that matched no organization, keyed by filter name; check this to fail loudly in a pipeline instead of trusting a silently-narrowed result set. +- `resolvedAgencies` — the organizations each token actually resolved to, keyed by filter name; agency resolution is fuzzy, so checking the resolved `name` is the only way to catch a token matching an agency you did not intend. + +```ts +const resp = await client.listContracts({ awarding_agency: "Navvy" }); +if (resp.agencyWarnings.length > 0) { + console.warn(resp.agencyWarnings); + console.warn("unresolved:", resp.unresolvedAgencyTokens); + console.warn("resolved to:", resp.resolvedAgencies); +} +``` diff --git a/docs/DEVELOPERS.md b/docs/DEVELOPERS.md index af5ae87..92c4d05 100644 --- a/docs/DEVELOPERS.md +++ b/docs/DEVELOPERS.md @@ -155,7 +155,7 @@ const client = new TangoClient({ ## Using Predefined Shapes -`ShapeConfig` ships 10+ predefined shape strings optimized for common use cases. +`ShapeConfig` ships 25+ predefined shape strings optimized for common use cases — see [SHAPES.md](SHAPES.md#shapeconfig-presets) for the full table. ### Contracts @@ -469,30 +469,20 @@ The same `fetchImpl` option is used in unit tests to inject mock responses witho ## SDK conformance (maintainers) -The Node SDK tracks the Python SDK's method surface via a parity test suite. All 111 unit tests run in CI on every push and PR (see [publish workflow](../.github/workflows/publish.yml)) and can be run locally. +The Node SDK tracks both the Tango API contract and the Python SDK's method surface. +The full suite (unit + cassette-replayed integration) plus both conformance gates run in CI on every push and PR (see [CI workflow](../.github/workflows/ci.yml)) and can be run locally. ### Test organization -All tests live in `tests/unit/`. There is one test category: unit tests with injected mock responses via the `fetchImpl` constructor option. There are no VCR cassettes or recorded HTTP fixtures — the Node SDK uses in-process `fetchImpl` mocks instead. - -| Test file | What it covers | -| --------- | -------------- | -| `client.test.ts` | Core filter/param mapping, response shaping, error handling | -| `client.parity.test.ts` | Every method present in the Python SDK has a Node counterpart | -| `client.iterate.test.ts` | Iterator methods (`iterateContracts`, etc.) | -| `client.baseurl.test.ts` | `TANGO_BASE_URL` env var and `baseUrl` constructor option | -| `shapes.parser.test.ts` | `ShapeParser` — tokenizing and parsing shape strings | -| `shapes.generator.test.ts` | `TypeGenerator` — descriptor generation | -| `shapes.factory.test.ts` | `ModelFactory` — materialization and type coercion | -| `shapes.schema.test.ts` | `SchemaRegistry` — field lookup and validation | -| `config.shapes.test.ts` | `ShapeConfig` constants are parseable and schema-valid | -| `models.dynamic.test.ts` | Dynamic model materialization end-to-end | -| `webhooks.signing.test.ts` | HMAC signing and signature verification | -| `utils.http.test.ts` | HTTP utility helpers (pagination, query params) | -| `utils.dates.test.ts` | Date parsing utilities | -| `utils.number.test.ts` | Decimal normalization | -| `utils.unflatten.test.ts` | Dot-notation key unflattening | -| `errors.test.ts` | Error class hierarchy | +Tests live under `tests/` in five groups: + +| Directory | What it covers | Network | +| --------- | -------------- | ------- | +| `tests/unit/` | Client param mapping, shaping pipeline, iterators, meta diagnostics, error classes, utils — mock responses injected via the `fetchImpl` constructor option | None | +| `tests/integration/` | Per-resource round-trips against **recorded cassettes** (`tests/cassettes/*.json`) — contracts, entities, IDVs, vehicles, opportunities, notices, grants, forecasts, agencies, protests, budget, DIBBS, exclusions, SBIR, reference data, subawards, edge cases | None by default (replay) | +| `tests/production/` | Env-gated live smoke suite — light invariants against the real API | Live, only with `TANGO_LIVE_TESTS=true` | +| `tests/scripts/` | The conformance and shape-coverage gate scripts themselves | None | +| `tests/webhooks/` | `WebhookReceiver`, simulator, and CLI (real local HTTP round-trips) | Loopback only | ### Running tests locally @@ -503,6 +493,49 @@ npm test -- --run # single-pass, no watch npm run coverage # single-pass with v8 coverage report ``` +### Integration cassettes (record/replay) + +The integration suite is the node equivalent of tango-python's VCR setup: `tests/integration/harness.ts` wraps the SDK's injectable `fetchImpl` and records each interaction as JSON in `tests/cassettes/`. + +- **Default runs replay offline.** A missing cassette is a hard failure so drift is loud; an absent cassettes directory (a fork without the corpus) skips the suite with a warning. +- **`TANGO_REFRESH_CASSETTES=true`** re-records serially against the live API (requires `TANGO_API_KEY`). Refresh cassettes and commit them in the same PR as the API change that invalidated them. +- **`TANGO_USE_LIVE_API=true`** bypasses cassettes entirely and hits the live API without writing anything. + +```bash +npx vitest run tests/integration # replay from committed cassettes +TANGO_REFRESH_CASSETTES=true TANGO_API_KEY=... npx vitest run tests/integration # re-record +TANGO_USE_LIVE_API=true TANGO_API_KEY=... npx vitest run tests/integration # live, no recording +``` + +Cassettes never store request headers (so an API key cannot be serialized), keep only an allowlisted response-header subset, and match on method + path + sorted query, host-insensitive. + +### Production smoke suite + +`tests/production/smoke.test.ts` asserts light live-API invariants (pagination shape, shaping, rate-limit header parsing). +It only joins the run when `TANGO_LIVE_TESTS=true` **and** `TANGO_API_KEY` are set; `vitest.config.ts` excludes it otherwise, so it never runs in CI. + +```bash +TANGO_LIVE_TESTS=true TANGO_API_KEY=... npx vitest run tests/production +``` + +### Conformance gates + +Conformance checking is fully offline: the canonical API filter/shape contract is **vendored** at `contracts/filter_shape_contract.json`, so no token or sibling checkout is needed and forks get the full check. +Two gates run in CI and locally, in opposite directions: + +- **`npm run check-conformance`** (`scripts/check-filter-shape-conformance.ts`) — walks each `list*` method's `Options` interface with the TypeScript compiler AST and validates the SDK's filters and shapes against the contract. `TANGO_CONTRACT_PATH` or `--manifest` can point it at a live tango checkout instead. +- **`npm run check-shape-coverage`** (`scripts/check-shape-coverage.ts`) — the reverse gate: fails when Tango's shape trees expose a field or expand the SDK schema doesn't capture and it isn't recorded in `contracts/shape_coverage_baseline.json`. + +Accepted gaps live in `contracts/conformance_baseline.json` (missing filters, unimplemented resources) and `contracts/shape_coverage_baseline.json` (shape-coverage backlog). +Baselined gaps report as warnings; anything new is an error. +Shrink the baselines as gaps close — never grow them to silence a legitimate failure. + +**`npm run generate-shape-overlay`** (`scripts/generate-shape-overlay.ts`) regenerates `src/shapes/generatedOverlay.ts` — the machine-generated schema additions that close the coverage gaps — from the vendored contract plus `contracts/observed_shape_types.json` (live-API type observations vendored from tango-python). +`SchemaRegistry` merges the overlay over the curated explicit schemas; never edit `generatedOverlay.ts` by hand. + +To refresh the vendored contract, copy `contracts/filter_shape_contract.json` from the tango API repo and re-run both gates. +CI also emits a best-effort staleness notice when the vendored contract differs from tango HEAD (token-gated, never a failure). + ### Lint and type-check ```bash @@ -521,7 +554,7 @@ npm run clean # rm -rf dist Releases are triggered by creating a GitHub Release (tag + notes). The [publish workflow](../.github/workflows/publish.yml) then: -1. Installs dependencies (`npm install --ignore-scripts`) +1. Installs dependencies from the committed lockfile (`npm ci --ignore-scripts`) 2. Lints (`npm run lint`) 3. Tests (`npm test`) 4. Builds (`npm run build`) @@ -536,9 +569,9 @@ npm run build npm pack --dry-run # inspect what would be published ``` -### Smoke tests (integration) +### Smoke scripts (ad hoc, live) -The `scripts/` directory contains smoke test scripts that run against a live Tango API instance. These are **not** part of the regular `npm test` suite — they require a valid `TANGO_API_KEY` and (optionally) `TANGO_BASE_URL`. +The `scripts/smoke-*.ts` scripts run against a live Tango API instance. These are **not** part of the regular `npm test` suite — they require a valid `TANGO_API_KEY` and (optionally) `TANGO_BASE_URL`. ```bash # Run with tsx (install globally or via npx) @@ -549,8 +582,7 @@ TANGO_API_KEY=your-key node --import tsx/esm scripts/smoke-extras.ts ``` These scripts hit every client method and report PASS/FAIL per call. Useful when you've changed the client and want to sanity-check against production or a local API instance. - -> **Note:** There is no VCR/cassette mechanism in the Node SDK. The Python SDK records and replays HTTP fixtures via `pytest-recording`; the Node equivalent is the `fetchImpl` mock pattern used in unit tests. Integration coverage against real API responses is provided by the smoke scripts. +For repeatable coverage of real API responses, prefer the cassette-based integration suite above. ### Repo layout @@ -574,24 +606,34 @@ tango-node/ │ │ ├── schema.ts # SchemaRegistry │ │ ├── generator.ts # TypeGenerator │ │ ├── factory.ts # ModelFactory -│ │ ├── explicitSchemas.ts # Field schema definitions for all models +│ │ ├── explicitSchemas.ts # Curated field schema definitions +│ │ ├── generatedOverlay.ts # Machine-generated schema overlay (do not edit) │ │ └── types.ts # Internal shape types │ ├── utils/ │ │ ├── http.ts # Pagination, query-param helpers │ │ ├── dates.ts # Date/datetime parsing │ │ ├── number.ts # Decimal normalization │ │ └── unflatten.ts # Dot-notation key unflattening -│ └── webhooks/ -│ └── signing.ts # HMAC-SHA256 signing + verification -├── tests/unit/ # All tests (vitest, fetchImpl mocks) -├── scripts/ # Smoke tests (require live API key) +│ └── webhooks/ # Signing, receiver, simulator, CLI +├── contracts/ # Vendored API contract + conformance baselines +├── tests/ +│ ├── unit/ # Offline unit tests (fetchImpl mocks) +│ ├── integration/ # Cassette-replayed integration tests + harness.ts +│ ├── cassettes/ # Recorded API interactions (JSON, committed) +│ ├── production/ # Env-gated live smoke suite +│ ├── scripts/ # Tests for the conformance gates +│ └── webhooks/ # Receiver / simulator / CLI tests +├── scripts/ # Conformance gates, overlay generator, live smoke scripts ├── docs/ # Developer documentation │ ├── API_REFERENCE.md +│ ├── CLIENT.md # Client constructor, retries, errors │ ├── DEVELOPERS.md # ← this file │ ├── DYNAMIC_MODELS.md # Internal pipeline deep-dive -│ └── SHAPES.md # Shape grammar + examples +│ ├── SHAPES.md # Shape grammar + examples +│ └── WEBHOOKS.md # Receiving + verifying webhook deliveries ├── dist/ # Compiled output (gitignored) ├── package.json +├── package-lock.json # Committed — CI installs with `npm ci` ├── tsconfig.json ├── vitest.config.ts └── eslint.config.js diff --git a/docs/SHAPES.md b/docs/SHAPES.md index c2e336b..e25df6c 100644 --- a/docs/SHAPES.md +++ b/docs/SHAPES.md @@ -72,20 +72,35 @@ The SDK ships with a `ShapeConfig` object of ready-made shape strings for common import { TangoClient, ShapeConfig } from "@makegov/tango-node"; ``` -| Constant | Intended use | -| ------------------------------ | ------------------------------- | -| `ShapeConfig.CONTRACTS_MINIMAL` | `listContracts()` | -| `ShapeConfig.ENTITIES_MINIMAL` | `listEntities()` | -| `ShapeConfig.ENTITIES_COMPREHENSIVE` | `getEntity()` | -| `ShapeConfig.FORECASTS_MINIMAL` | `listForecasts()` | -| `ShapeConfig.OPPORTUNITIES_MINIMAL` | `listOpportunities()` | -| `ShapeConfig.NOTICES_MINIMAL` | `listNotices()` | -| `ShapeConfig.GRANTS_MINIMAL` | `listGrants()` | -| `ShapeConfig.IDVS_MINIMAL` | `listIdvs()` | -| `ShapeConfig.IDVS_COMPREHENSIVE` | `getIdv()` | -| `ShapeConfig.VEHICLES_MINIMAL` | `listVehicles()` | -| `ShapeConfig.VEHICLES_COMPREHENSIVE` | `getVehicle()` | -| `ShapeConfig.VEHICLE_AWARDEES_MINIMAL` | `listVehicleAwardees()` | +| Constant | Intended use | +| --------------------------------------------------- | --------------------------- | +| `ShapeConfig.CONTRACTS_MINIMAL` | `listContracts()` | +| `ShapeConfig.ENTITIES_MINIMAL` | `listEntities()` | +| `ShapeConfig.ENTITIES_COMPREHENSIVE` | `getEntity()` | +| `ShapeConfig.FORECASTS_MINIMAL` | `listForecasts()` | +| `ShapeConfig.OPPORTUNITIES_MINIMAL` | `listOpportunities()` | +| `ShapeConfig.NOTICES_MINIMAL` | `listNotices()` | +| `ShapeConfig.PROTESTS_MINIMAL` | `listProtests()` | +| `ShapeConfig.GRANTS_MINIMAL` | `listGrants()` | +| `ShapeConfig.IDVS_MINIMAL` | `listIdvs()` | +| `ShapeConfig.IDVS_COMPREHENSIVE` | `getIdv()` | +| `ShapeConfig.VEHICLES_MINIMAL` | `listVehicles()` | +| `ShapeConfig.VEHICLES_COMPREHENSIVE` | `getVehicle()` | +| `ShapeConfig.VEHICLE_AWARDEES_MINIMAL` | `listVehicleAwardees()` | +| `ShapeConfig.VEHICLE_ORDERS_MINIMAL` | `listVehicleOrders()` | +| `ShapeConfig.ORGANIZATIONS_MINIMAL` | `listOrganizations()` | +| `ShapeConfig.OTAS_MINIMAL` | `listOtas()` | +| `ShapeConfig.OTIDVS_MINIMAL` | `listOtidvs()` | +| `ShapeConfig.SUBAWARDS_MINIMAL` | `listSubawards()` | +| `ShapeConfig.GSA_ELIBRARY_CONTRACTS_MINIMAL` | `listGsaElibraryContracts()` / `getGsaElibraryContract()` | +| `ShapeConfig.ITDASHBOARD_INVESTMENTS_MINIMAL` | `listItDashboard()` | +| `ShapeConfig.ITDASHBOARD_INVESTMENTS_COMPREHENSIVE` | `getItDashboard()` | +| `ShapeConfig.DIBBS_RFQS_MINIMAL` | `listDibbsRfqs()` | +| `ShapeConfig.DIBBS_RFPS_MINIMAL` | `listDibbsRfps()` | +| `ShapeConfig.DIBBS_AWARDS_MINIMAL` | `listDibbsAwards()` | +| `ShapeConfig.EXCLUSIONS_MINIMAL` | `listExclusions()` | +| `ShapeConfig.SBIR_TOPICS_MINIMAL` | `listSbirTopics()` | +| `ShapeConfig.SBIR_SOLICITATIONS_MINIMAL` | `listSbirSolicitations()` | These are plain strings — you can use them directly or as a starting point: diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..44bb0f2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4245 @@ +{ + "name": "@makegov/tango-node", + "version": "1.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@makegov/tango-node", + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "commander": "^12.1.0" + }, + "bin": { + "tango-node": "dist/bin/tango-node.js" + }, + "devDependencies": { + "@types/node": "22.19.19", + "@typescript-eslint/eslint-plugin": "8.59.3", + "@typescript-eslint/parser": "8.59.3", + "@vitest/coverage-v8": "2.1.9", + "eslint": "9.39.4", + "globals": "15.15.0", + "prettier": "3.8.3", + "tsx": "4.21.0", + "typescript": "5.9.3", + "vitest": "2.1.9" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.3.0", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", + "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", + "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", + "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", + "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", + "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", + "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", + "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", + "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", + "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", + "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", + "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", + "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", + "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", + "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", + "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", + "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", + "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", + "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", + "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", + "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", + "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", + "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", + "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", + "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", + "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz", + "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.3.tgz", + "integrity": "sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/type-utils": "8.59.3", + "@typescript-eslint/utils": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.59.3", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.3.tgz", + "integrity": "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.3.tgz", + "integrity": "sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.59.3", + "@typescript-eslint/types": "^8.59.3", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.3.tgz", + "integrity": "sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.3.tgz", + "integrity": "sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.3.tgz", + "integrity": "sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3", + "@typescript-eslint/utils": "8.59.3", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.3.tgz", + "integrity": "sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.3.tgz", + "integrity": "sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.59.3", + "@typescript-eslint/tsconfig-utils": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/visitor-keys": "8.59.3", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.3.tgz", + "integrity": "sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.3", + "@typescript-eslint/types": "8.59.3", + "@typescript-eslint/typescript-estree": "8.59.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.3.tgz", + "integrity": "sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.3", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitest/coverage-v8": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.9.tgz", + "integrity": "sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.7", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.6", + "istanbul-reports": "^3.1.7", + "magic-string": "^0.30.12", + "magicast": "^0.3.5", + "std-env": "^3.8.0", + "test-exclude": "^7.0.1", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "2.1.9", + "vitest": "2.1.9" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-tsconfig": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.2.tgz", + "integrity": "sha512-XpwZALwwl/BaKTAyC6+c5T8y6kCg2jk+XGqOVrKIQmW49pNypYLMRjCUXqa28tQgJlhS2RlzP7sc+Rx7W6qsfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ignore": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-yaml": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.17", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/rollup": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", + "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.62.4", + "@rollup/rollup-android-arm64": "4.62.4", + "@rollup/rollup-darwin-arm64": "4.62.4", + "@rollup/rollup-darwin-x64": "4.62.4", + "@rollup/rollup-freebsd-arm64": "4.62.4", + "@rollup/rollup-freebsd-x64": "4.62.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", + "@rollup/rollup-linux-arm-musleabihf": "4.62.4", + "@rollup/rollup-linux-arm64-gnu": "4.62.4", + "@rollup/rollup-linux-arm64-musl": "4.62.4", + "@rollup/rollup-linux-loong64-gnu": "4.62.4", + "@rollup/rollup-linux-loong64-musl": "4.62.4", + "@rollup/rollup-linux-ppc64-gnu": "4.62.4", + "@rollup/rollup-linux-ppc64-musl": "4.62.4", + "@rollup/rollup-linux-riscv64-gnu": "4.62.4", + "@rollup/rollup-linux-riscv64-musl": "4.62.4", + "@rollup/rollup-linux-s390x-gnu": "4.62.4", + "@rollup/rollup-linux-x64-gnu": "4.62.4", + "@rollup/rollup-linux-x64-musl": "4.62.4", + "@rollup/rollup-openbsd-x64": "4.62.4", + "@rollup/rollup-openharmony-arm64": "4.62.4", + "@rollup/rollup-win32-arm64-msvc": "4.62.4", + "@rollup/rollup-win32-ia32-msvc": "4.62.4", + "@rollup/rollup-win32-x64-gnu": "4.62.4", + "@rollup/rollup-win32-x64-msvc": "4.62.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz", + "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^10.2.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", + "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vitest": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", + "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} From 49a2df951e27110d5fd946aa906895ccba45ee60 Mon Sep 17 00:00:00 2001 From: "V. David Zvenyach" Date: Fri, 14 Aug 2026 12:52:43 -0500 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20review=20findings=20=E2=80=94=20join?= =?UTF-8?q?er=20threading,=20optional=20response=20diagnostics,=20CI=20gat?= =?UTF-8?q?e=20strength,=20harness=20fidelity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Collapses the 13 new resource methods into _shapedPaginatedList/_shapedGet helpers, fixing the joiner leak the copy-paste introduced; makes the new PaginatedResponse diagnostic fields optional so existing consumer literals keep compiling; restores hard token-present conformance gates against tango HEAD and adds an overlay regen-diff gate; replays non-JSON cassette bodies verbatim; shares one isRecord guard; unwraps hard-wrapped comments; single coverage-aware CI test run with npm caching. Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 50 ++- CHANGELOG.md | 8 +- CLAUDE.md | 8 +- docs/DEVELOPERS.md | 6 +- scripts/generate-shape-overlay.ts | 16 +- src/client.ts | 373 +++++------------- src/errors.ts | 19 +- src/models/Dibbs.ts | 13 +- src/models/Exclusion.ts | 6 +- src/models/Sbir.ts | 3 +- src/types.ts | 34 +- src/utils/guards.ts | 6 + src/utils/http.ts | 5 +- tests/integration/harness.ts | 24 +- .../unit/client.dibbs-exclusions-sbir.test.ts | 28 ++ tests/unit/client.meta-diagnostics.test.ts | 27 +- tests/unit/integration-harness.test.ts | 24 +- 17 files changed, 285 insertions(+), 365 deletions(-) create mode 100644 src/utils/guards.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b684d1..d00ee7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,11 +5,12 @@ name: CI # The SDK filter/shape conformance check and the reverse shape-coverage check # are HARD gates that run offline against the vendored contract at # contracts/filter_shape_contract.json — no secrets needed, so forks and -# tokenless runs get the full check instead of a silent skip. A second, -# token-gated step compares the vendored contract against the tango repo's -# HEAD and emits a staleness notice (never a failure — tango HEAD may carry -# unreleased changes). Refresh the vendored contract by copying -# contracts/filter_shape_contract.json from makegov/tango. +# tokenless runs get the full check instead of a silent skip. When +# TANGO_API_REPO_ACCESS_TOKEN is available, the same two checks ALSO run as +# hard gates against the fresh contract at makegov/tango HEAD, plus a warning +# annotation when the vendored copy has drifted (re-vendor reminder). Refresh +# the vendored contract by copying contracts/filter_shape_contract.json from +# makegov/tango. on: push: branches: [ main ] @@ -33,6 +34,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} + cache: npm - name: Install dependencies # The "prepare" script runs a build that needs tsc — so ignore scripts here @@ -49,15 +51,10 @@ jobs: run: npm run build - name: Test - # `vitest run` forces a single non-watch pass in CI. + # `vitest run` forces a single non-watch pass in CI; the Node 20 leg adds `--coverage` so the suite runs exactly once per leg. + # No coverage fail-under gate — parity with tango-python, which has none. # Integration tests replay the committed cassettes offline; production smoke stays excluded (env-gated on TANGO_LIVE_TESTS, never set here). - run: npx vitest run - - - name: Coverage summary - # One matrix leg is enough; the text reporter prints the summary. - # No fail-under gate — parity with tango-python, which has none. - if: matrix.node-version == '20' - run: npx vitest run --coverage + run: npx vitest run ${{ matrix.node-version == '20' && '--coverage' || '' }} conformance: # Hard gate against the vendored contract (contracts/filter_shape_contract.json). @@ -72,6 +69,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: "20" + cache: npm - name: Install dependencies run: npm ci --ignore-scripts --no-audit --no-fund @@ -86,7 +84,13 @@ jobs: # against the vendored contract — no secrets, works on forks. run: npx tsx scripts/check-shape-coverage.ts - # --- Staleness notice (best-effort, never fails the job) --------------- + - name: Check generated overlay is current + # Regenerates the overlay and fails on drift, so a contract or curated-schema change that alters generator output can't land without `npm run generate-shape-overlay`. + run: | + npm run generate-shape-overlay + git diff --exit-code src/shapes/generatedOverlay.ts + + # --- Fresh-contract gates (token-gated hard checks against tango HEAD) -- - name: Determine token availability id: gate env: @@ -96,7 +100,7 @@ jobs: echo "ready=true" >> "$GITHUB_OUTPUT" else echo "ready=false" >> "$GITHUB_OUTPUT" - echo "::notice::Contract staleness check skipped — TANGO_API_REPO_ACCESS_TOKEN not configured." + echo "::notice::Fresh-contract gates skipped — TANGO_API_REPO_ACCESS_TOKEN not configured." fi - name: Checkout tango API repo (contract source) @@ -107,11 +111,23 @@ jobs: path: tango-api token: ${{ secrets.TANGO_API_REPO_ACCESS_TOKEN }} - - name: Compare vendored contract against tango HEAD + - name: Warn when the vendored contract has drifted from tango HEAD if: steps.gate.outputs.ready == 'true' run: | if ! diff -q contracts/filter_shape_contract.json tango-api/contracts/filter_shape_contract.json >/dev/null; then - echo "::warning::Vendored contract differs from makegov/tango HEAD. Refresh contracts/filter_shape_contract.json and re-run the conformance gates." + echo "::warning::Vendored contract differs from makegov/tango HEAD. Re-vendor contracts/filter_shape_contract.json and regenerate the overlay." else echo "Vendored contract matches makegov/tango HEAD." fi + + - name: Check SDK filter/shape conformance (fresh contract, hard gate) + if: steps.gate.outputs.ready == 'true' + env: + TANGO_CONTRACT_PATH: tango-api/contracts/filter_shape_contract.json + run: npx tsx scripts/check-filter-shape-conformance.ts + + - name: Check reverse shape coverage (fresh contract, hard gate) + if: steps.gate.outputs.ready == 'true' + env: + TANGO_CONTRACT_PATH: tango-api/contracts/filter_shape_contract.json + run: npx tsx scripts/check-shape-coverage.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index edb5b65..bb71d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ This project follows [Semantic Versioning](https://semver.org/). - `getGsaElibraryContract(uuid, options)` for `/api/gsa_elibrary_contracts/{uuid}/` (parity with tango-python), with the standard `shape` / `flat` / `flatLists` / `joiner` options and the `GSA_ELIBRARY_CONTRACTS_MINIMAL` default shape. - Typed filter options that previously worked only through the index-signature escape hatch: `key` on `listContracts` / `listIdvs` / `listOtas` / `listOtidvs`, `cage` on `listEntities`, `id` on `listForecasts`, `opportunity_id` on `listOpportunities`, `previous_uii` on `listItDashboard`, `naics_code` on `listProtests` (sent verbatim, not remapped to `naics`), and `has_awards` on `listPsc`. The filter-shape conformance gate now reports zero index-signature warnings. - **Generated shape-coverage overlay** (parity with tango-python v1.4.0): `src/shapes/generatedOverlay.ts`, machine-generated by the new `scripts/generate-shape-overlay.ts` from the vendored contract plus `contracts/observed_shape_types.json` (live-API type observations vendored from tango-python). `SchemaRegistry` merges the overlay over the curated explicit schemas, so the typed shape API now accepts every field and expand the API returns — including entity `relationships(type, source)`, previously-unmapped models (`Naics`, `PSC`, `MasSin`, `BudgetAccount`, `AssistanceListing`, `BusinessType`), and all the code/description expands that were flattened to scalars. The reverse shape-coverage gate now reports **zero** gaps and `contracts/shape_coverage_baseline.json` is empty (416 → 0). -- **Agency-filter diagnostics on `PaginatedResponse`** (parity with tango-python v1.5.0). Every list method now surfaces the API's `meta` payload, plus three parsed views: `agencyWarnings` (human-readable notes about dropped or loosely-matched agency tokens), `unresolvedAgencyTokens` (tokens that matched no organization, keyed by filter name), and `resolvedAgencies` (the organizations each token actually resolved to — the only way to catch a token fuzzy-matching an agency you did not intend). All three are total: absent or malformed `meta` yields empty values, never a throw. +- **Agency-filter diagnostics on `PaginatedResponse`** (parity with tango-python v1.5.0). Every list method now surfaces the API's `meta` payload, plus three parsed views: `agencyWarnings` (human-readable notes about dropped or loosely-matched agency tokens), `unresolvedAgencyTokens` (tokens that matched no organization, keyed by filter name), and `resolvedAgencies` (the organizations each token actually resolved to — the only way to catch a token fuzzy-matching an agency you did not intend). All three are total: absent or malformed `meta` yields empty values, never a throw. On the `PaginatedResponse` type, `meta` and the three parsed views are declared as optional properties — responses built by the client always populate them, but existing code that constructs the type without them keeps compiling. - **Structured shape errors on `TangoValidationError`** (parity with tango-python's `.issues` / `.available_fields`): new `issues` and `availableFields` getters expose the API's structured 400 payload — entries like `{"path": "tradeoff_process", "reason": "unknown_field"}` and the endpoint's valid field set — instead of leaving callers to parse `responseData` by hand. - Vendored the canonical API filter/shape contract at `contracts/filter_shape_contract.json` (API 4.22.0), so conformance checking is fully offline — no token, no sibling checkout. - New reverse shape-coverage gate `scripts/check-shape-coverage.ts` (npm script `check-shape-coverage`): walks every resource's shape tree in the vendored contract against the SDK's explicit schema registry and fails on any field or expand the SDK does not capture, unless recorded in `contracts/shape_coverage_baseline.json` as tracked backlog. @@ -30,13 +30,15 @@ This project follows [Semantic Versioning](https://semver.org/). - Removed the dead legacy `.eslintrc.cjs` — the flat `eslint.config.js` has been the operative ESLint config since the flat-config migration, and the leftover file only invited divergent edits. ### Fixed +- The six new list methods (`listDibbsRfqs`, `listDibbsRfps`, `listDibbsAwards`, `listExclusions`, `listSbirTopics`, `listSbirSolicitations`) leaked a caller-supplied `joiner` to the server as a bare query param and ignored it when unflattening `flat: true` responses (always unflattening on the default `.`). `joiner` is now threaded the same way as `listIdvs`: sent only alongside `flat=true`, and used as the unflatten separator. - `listBudgetAccounts`: the `fiscal_year_gte`, `fiscal_year_lte`, and `account_title` options were sent verbatim, which the API silently ignores. They are kept as legacy aliases and now remapped to the forms the API understands (`fiscal_year__gte`, `fiscal_year__lte`, `account_title__icontains`); an explicitly passed dunder param wins over its alias. - Docs: removed the stale `getIdvSummary` / `listIdvSummaryAwards` sections from `README.md` and `docs/API_REFERENCE.md` — those methods were removed from the SDK in 1.1.0. Documented the full new surface (DIBBS/exclusions/SBIR, budget accounts and their filter surface, `getGsaElibraryContract`, the newly typed filters, `PaginatedResponse` meta diagnostics, structured `TangoValidationError` details), completed the `ShapeConfig` preset table in `docs/SHAPES.md`, and rewrote the maintainer half of `docs/DEVELOPERS.md` around the conformance gates and the cassette record/replay workflow (the old text still claimed the SDK had no cassette mechanism). ### CI - `package-lock.json` is now committed, and the CI + publish workflows install with `npm ci --ignore-scripts` instead of `npm install` — installs are reproducible from the lockfile instead of re-resolving dependency ranges on every run. -- The test job now prints a coverage summary (`npx vitest run --coverage`) on the Node 20 leg, and the default `npx vitest run` now includes the integration suite replayed offline from the committed cassettes. No coverage fail-under gate, matching tango-python. -- The `conformance` job is now a hard gate that runs both conformance directions offline against the vendored contract on every PR — it no longer needs `TANGO_API_REPO_ACCESS_TOKEN` and no longer skips silently without it. A separate token-gated step diffs the vendored contract against the tango API repo's HEAD and emits a staleness warning (never a failure). +- The test job's Node 20 leg runs the suite once with `--coverage` (instead of a second full pass), the default `npx vitest run` now includes the integration suite replayed offline from the committed cassettes, and both setup-node steps cache the npm store off the committed lockfile. No coverage fail-under gate, matching tango-python. +- The `conformance` job is now a hard gate that runs both conformance directions offline against the vendored contract on every PR — it no longer needs `TANGO_API_REPO_ACCESS_TOKEN` and no longer skips silently without it. When the token is configured, both checks additionally run as hard gates against the fresh contract at makegov/tango HEAD, with a re-vendor warning when the vendored copy has drifted. +- The `conformance` job also regenerates `src/shapes/generatedOverlay.ts` and fails on any diff, so a contract or curated-schema change that alters generator output can't land without a regenerated overlay. `scripts/generate-shape-overlay.ts` honors the same `TANGO_CONTRACT_PATH` / `--contract` override as the two check scripts. ## [1.1.0] - 2026-05-29 diff --git a/CLAUDE.md b/CLAUDE.md index 7fcadc6..37abf5d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,13 +1,9 @@ # tango-node ## Non-Negotiables diff --git a/docs/DEVELOPERS.md b/docs/DEVELOPERS.md index 92c4d05..10e0112 100644 --- a/docs/DEVELOPERS.md +++ b/docs/DEVELOPERS.md @@ -532,9 +532,11 @@ Shrink the baselines as gaps close — never grow them to silence a legitimate f **`npm run generate-shape-overlay`** (`scripts/generate-shape-overlay.ts`) regenerates `src/shapes/generatedOverlay.ts` — the machine-generated schema additions that close the coverage gaps — from the vendored contract plus `contracts/observed_shape_types.json` (live-API type observations vendored from tango-python). `SchemaRegistry` merges the overlay over the curated explicit schemas; never edit `generatedOverlay.ts` by hand. +It honors the same `TANGO_CONTRACT_PATH` env var / `--contract` flag as the two check scripts. +CI regenerates the overlay and fails on any diff against the committed file, so a contract refresh or curated-schema change that alters generator output must land alongside a rerun of `npm run generate-shape-overlay`. -To refresh the vendored contract, copy `contracts/filter_shape_contract.json` from the tango API repo and re-run both gates. -CI also emits a best-effort staleness notice when the vendored contract differs from tango HEAD (token-gated, never a failure). +To refresh the vendored contract, copy `contracts/filter_shape_contract.json` from the tango API repo, regenerate the overlay, and re-run both gates. +When the `TANGO_API_REPO_ACCESS_TOKEN` secret is configured, CI additionally runs both gates as hard checks against the fresh contract at tango HEAD, and emits a re-vendor warning when the vendored copy has drifted. ### Lint and type-check diff --git a/scripts/generate-shape-overlay.ts b/scripts/generate-shape-overlay.ts index 3fdec5b..6766a70 100644 --- a/scripts/generate-shape-overlay.ts +++ b/scripts/generate-shape-overlay.ts @@ -20,6 +20,8 @@ * * Run: npx tsx scripts/generate-shape-overlay.ts # writes the module * npx tsx scripts/generate-shape-overlay.ts --report # print gaps, write nothing + * + * `TANGO_CONTRACT_PATH` (env) or `--contract PATH` points the generator at a non-vendored contract, matching the two check scripts. */ import * as fs from "node:fs"; @@ -34,7 +36,19 @@ import type { Contract, ShapeNode } from "./check-shape-coverage.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const REPO_ROOT = path.resolve(__dirname, ".."); -const CONTRACT_PATH = path.join(REPO_ROOT, "contracts", "filter_shape_contract.json"); +const VENDORED_CONTRACT_PATH = path.join(REPO_ROOT, "contracts", "filter_shape_contract.json"); + +function resolveContractPath(): string { + const argv = process.argv.slice(2); + for (let i = 0; i < argv.length; i += 1) { + if (argv[i] === "--contract" && argv[i + 1]) return path.resolve(argv[i + 1]); + if (argv[i].startsWith("--contract=")) return path.resolve(argv[i].slice("--contract=".length)); + } + if (process.env.TANGO_CONTRACT_PATH) return path.resolve(process.env.TANGO_CONTRACT_PATH); + return VENDORED_CONTRACT_PATH; +} + +const CONTRACT_PATH = resolveContractPath(); const OBSERVED_PATH = path.join(REPO_ROOT, "contracts", "observed_shape_types.json"); const OUT_PATH = path.join(REPO_ROOT, "src", "shapes", "generatedOverlay.ts"); diff --git a/src/client.ts b/src/client.ts index c390d19..1be7130 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3,6 +3,7 @@ import { TangoNotFoundError, TangoValidationError } from "./errors.js"; import { ModelFactory } from "./shapes/factory.js"; import { ShapeParser } from "./shapes/parser.js"; import type { ShapeSpec } from "./shapes/types.js"; +import { isRecord } from "./utils/guards.js"; import { HttpClient } from "./utils/http.js"; import { unflattenResponse } from "./utils/unflatten.js"; import { @@ -27,10 +28,6 @@ import type { type AnyRecord = Record; -function isRecord(value: unknown): value is Record { - return Boolean(value) && typeof value === "object" && !Array.isArray(value); -} - /** * Normalize a webhook-endpoint create/update input into the wire body. * @@ -64,8 +61,7 @@ function extractCursorFromUrl(url: string | null): string | null { } } -// `meta` is server-controlled, so every parser below tolerates a shape change -// rather than crashing a caller's pagination loop. +// `meta` is server-controlled, so every parser below tolerates a shape change rather than crashing a caller's pagination loop. function parseAgencyWarnings(meta: AnyRecord | null): string[] { const warnings = meta?.warnings; return Array.isArray(warnings) ? warnings.map(String) : []; @@ -548,6 +544,7 @@ export interface ListBudgetAccountsOptions extends ListOptionsBase { * DIBBS RFQ list options — matches `tango_python.TangoClient.list_dibbs_rfqs`. */ export interface ListDibbsRfqsOptions extends ListOptionsBase { + joiner?: string; nsn?: string; part_number?: string; solicitation?: string; @@ -573,6 +570,7 @@ export interface ListDibbsRfqsOptions extends ListOptionsBase { * DIBBS RFP list options — matches `tango_python.TangoClient.list_dibbs_rfps`. */ export interface ListDibbsRfpsOptions extends ListOptionsBase { + joiner?: string; nsn?: string; part_number?: string; solicitation?: string; @@ -594,6 +592,7 @@ export interface ListDibbsRfpsOptions extends ListOptionsBase { * DIBBS award list options — matches `tango_python.TangoClient.list_dibbs_awards`. */ export interface ListDibbsAwardsOptions extends ListOptionsBase { + joiner?: string; award_number?: string; delivery_order_number?: string; solicitation?: string; @@ -619,6 +618,7 @@ export interface ListDibbsAwardsOptions extends ListOptionsBase { * Exclusions list options — matches `tango_python.TangoClient.list_exclusions`. */ export interface ListExclusionsOptions extends ListOptionsBase { + joiner?: string; uei?: string; entity_uei?: string; cage_code?: string; @@ -647,6 +647,7 @@ export interface ListExclusionsOptions extends ListOptionsBase { * SBIR topic list options — matches `tango_python.TangoClient.list_sbir_topics`. */ export interface ListSbirTopicsOptions extends ListOptionsBase { + joiner?: string; topic_number?: string; solicitation_number?: string; agency?: string; @@ -669,6 +670,7 @@ export interface ListSbirTopicsOptions extends ListOptionsBase { * SBIR solicitation list options — matches `tango_python.TangoClient.list_sbir_solicitations`. */ export interface ListSbirSolicitationsOptions extends ListOptionsBase { + joiner?: string; solicitation_number?: string; solicitation_status?: string; program?: string; @@ -2036,6 +2038,68 @@ export class TangoClient { return buildPaginatedResponse(data); } + /** + * Shared page-based list flow for shape-materialized resources: default shape, `flat`/`flatLists`/`joiner` threading (joiner is sent only with `flat` and always drives unflattening), passthrough filters, and model materialization. + */ + private async _shapedPaginatedList( + path: string, + baseModel: string, + defaultShape: string | null, + options: ListOptionsBase & { joiner?: string; [key: string]: unknown } = {}, + ): Promise>> { + const { page = 1, limit = 25, shape, flat = false, flatLists = false, joiner = ".", ...filters } = options; + + const params: AnyRecord = { + page, + limit: Math.min(limit, 100), + }; + + const shapeToUse = shape ?? defaultShape; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) { + params.flat = "true"; + if (joiner) params.joiner = joiner; + } + if (flatLists) params.flat_lists = "true"; + } + + Object.assign(params, filters); + + const data = await this.http.get(path, params); + const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; + + const results = this.materializeList(baseModel, shapeSpec, rawResults, flat, joiner); + + return buildPaginatedResponse({ ...data, results }); + } + + /** Shared detail-GET flow for shape-materialized resources — the single-object counterpart of `_shapedPaginatedList`. */ + private async _shapedGet( + path: string, + baseModel: string, + defaultShape: string | null, + options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, + ): Promise> { + const { shape, flat = false, flatLists = false, joiner = "." } = options; + const params: AnyRecord = {}; + + const shapeToUse = shape ?? defaultShape; + const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); + if (shapeToUse) { + params.shape = shapeToUse; + if (flat) { + params.flat = "true"; + if (joiner) params.joiner = joiner; + } + if (flatLists) params.flat_lists = "true"; + } + + const data = await this.http.get(path, params); + return this.materializeOne(baseModel, shapeSpec, data, flat, joiner); + } + /** List NAICS codes. */ async listNaics(options: ListNaicsOptions = {}): Promise> { return this._genericPaginatedList("/api/naics/", options); @@ -2170,23 +2234,12 @@ export class TangoClient { options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, ): Promise> { if (!uuid) throw new TangoValidationError("GSA eLibrary contract uuid is required"); - - const { shape, flat = false, flatLists = false, joiner = "." } = options; - const params: AnyRecord = {}; - - const shapeToUse = shape ?? ShapeConfig.GSA_ELIBRARY_CONTRACTS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) { - params.flat = "true"; - if (joiner) params.joiner = joiner; - } - if (flatLists) params.flat_lists = "true"; - } - - const data = await this.http.get(`/api/gsa_elibrary_contracts/${encodeURIComponent(uuid)}/`, params); - return this.materializeOne("GsaElibraryContract", shapeSpec, data, flat, joiner); + return this._shapedGet( + `/api/gsa_elibrary_contracts/${encodeURIComponent(uuid)}/`, + "GsaElibraryContract", + ShapeConfig.GSA_ELIBRARY_CONTRACTS_MINIMAL, + options, + ); } /** @@ -2287,33 +2340,10 @@ export class TangoClient { /** * List DLA DIBBS request-for-quote solicitations (`/api/dibbs/rfqs/`). * - * `is_open` is derived at query time from `return_by_date`, so filter with - * the `open` option rather than shaping on `is_open`. + * `is_open` is derived at query time from `return_by_date`, so filter with the `open` option rather than shaping on `is_open`. */ async listDibbsRfqs(options: ListDibbsRfqsOptions = {}): Promise>> { - const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; - - const params: AnyRecord = { - page, - limit: Math.min(limit, 100), - }; - - const shapeToUse = shape ?? ShapeConfig.DIBBS_RFQS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) params.flat = "true"; - if (flatLists) params.flat_lists = "true"; - } - - Object.assign(params, filters); - - const data = await this.http.get("/api/dibbs/rfqs/", params); - const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; - - const results = this.materializeList("DibbsRfq", shapeSpec, rawResults, flat); - - return buildPaginatedResponse({ ...data, results }); + return this._shapedPaginatedList("/api/dibbs/rfqs/", "DibbsRfq", ShapeConfig.DIBBS_RFQS_MINIMAL, options); } /** Get a single DIBBS RFQ by uuid (`/api/dibbs/rfqs/{uuid}/`). */ @@ -2322,55 +2352,16 @@ export class TangoClient { options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, ): Promise> { if (!uuid) throw new TangoValidationError("DIBBS RFQ uuid is required"); - - const { shape, flat = false, flatLists = false, joiner = "." } = options; - const params: AnyRecord = {}; - - const shapeToUse = shape ?? ShapeConfig.DIBBS_RFQS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) { - params.flat = "true"; - if (joiner) params.joiner = joiner; - } - if (flatLists) params.flat_lists = "true"; - } - - const data = await this.http.get(`/api/dibbs/rfqs/${encodeURIComponent(uuid)}/`, params); - return this.materializeOne("DibbsRfq", shapeSpec, data, flat, joiner); + return this._shapedGet(`/api/dibbs/rfqs/${encodeURIComponent(uuid)}/`, "DibbsRfq", ShapeConfig.DIBBS_RFQS_MINIMAL, options); } /** * List DLA DIBBS request-for-proposal solicitations (`/api/dibbs/rfps/`). * - * `is_open` is derived at query time from `closes_date`, so filter with the - * `open` option rather than shaping on `is_open`. + * `is_open` is derived at query time from `closes_date`, so filter with the `open` option rather than shaping on `is_open`. */ async listDibbsRfps(options: ListDibbsRfpsOptions = {}): Promise>> { - const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; - - const params: AnyRecord = { - page, - limit: Math.min(limit, 100), - }; - - const shapeToUse = shape ?? ShapeConfig.DIBBS_RFPS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) params.flat = "true"; - if (flatLists) params.flat_lists = "true"; - } - - Object.assign(params, filters); - - const data = await this.http.get("/api/dibbs/rfps/", params); - const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; - - const results = this.materializeList("DibbsRfp", shapeSpec, rawResults, flat); - - return buildPaginatedResponse({ ...data, results }); + return this._shapedPaginatedList("/api/dibbs/rfps/", "DibbsRfp", ShapeConfig.DIBBS_RFPS_MINIMAL, options); } /** Get a single DIBBS RFP by uuid (`/api/dibbs/rfps/{uuid}/`). */ @@ -2379,57 +2370,18 @@ export class TangoClient { options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, ): Promise> { if (!uuid) throw new TangoValidationError("DIBBS RFP uuid is required"); - - const { shape, flat = false, flatLists = false, joiner = "." } = options; - const params: AnyRecord = {}; - - const shapeToUse = shape ?? ShapeConfig.DIBBS_RFPS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) { - params.flat = "true"; - if (joiner) params.joiner = joiner; - } - if (flatLists) params.flat_lists = "true"; - } - - const data = await this.http.get(`/api/dibbs/rfps/${encodeURIComponent(uuid)}/`, params); - return this.materializeOne("DibbsRfp", shapeSpec, data, flat, joiner); + return this._shapedGet(`/api/dibbs/rfps/${encodeURIComponent(uuid)}/`, "DibbsRfp", ShapeConfig.DIBBS_RFPS_MINIMAL, options); } /** * List DLA DIBBS awards (`/api/dibbs/awards/`). * - * WARNING: `total_contract_price` is the *order* total repeated on every - * line item of the award. Never sum it across rows — doing so multiplies - * the value by the line-item count. Deduplicate on `award_number` + - * `delivery_order_number` first. + * WARNING: `total_contract_price` is the *order* total repeated on every line item of the award. + * Never sum it across rows — doing so multiplies the value by the line-item count. + * Deduplicate on `award_number` + `delivery_order_number` first. */ async listDibbsAwards(options: ListDibbsAwardsOptions = {}): Promise>> { - const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; - - const params: AnyRecord = { - page, - limit: Math.min(limit, 100), - }; - - const shapeToUse = shape ?? ShapeConfig.DIBBS_AWARDS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) params.flat = "true"; - if (flatLists) params.flat_lists = "true"; - } - - Object.assign(params, filters); - - const data = await this.http.get("/api/dibbs/awards/", params); - const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; - - const results = this.materializeList("DibbsAward", shapeSpec, rawResults, flat); - - return buildPaginatedResponse({ ...data, results }); + return this._shapedPaginatedList("/api/dibbs/awards/", "DibbsAward", ShapeConfig.DIBBS_AWARDS_MINIMAL, options); } /** Get a single DIBBS award by uuid (`/api/dibbs/awards/{uuid}/`). */ @@ -2438,23 +2390,7 @@ export class TangoClient { options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, ): Promise> { if (!uuid) throw new TangoValidationError("DIBBS award uuid is required"); - - const { shape, flat = false, flatLists = false, joiner = "." } = options; - const params: AnyRecord = {}; - - const shapeToUse = shape ?? ShapeConfig.DIBBS_AWARDS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) { - params.flat = "true"; - if (joiner) params.joiner = joiner; - } - if (flatLists) params.flat_lists = "true"; - } - - const data = await this.http.get(`/api/dibbs/awards/${encodeURIComponent(uuid)}/`, params); - return this.materializeOne("DibbsAward", shapeSpec, data, flat, joiner); + return this._shapedGet(`/api/dibbs/awards/${encodeURIComponent(uuid)}/`, "DibbsAward", ShapeConfig.DIBBS_AWARDS_MINIMAL, options); } // --------------------------------------------------------------------------- @@ -2464,34 +2400,10 @@ export class TangoClient { /** * List SAM.gov exclusion (debarment) records (`/api/exclusions/`). * - * `is_currently_excluded` is derived at query time from the - * activate/termination dates, so filter with the `active` option rather - * than shaping on `is_currently_excluded`. + * `is_currently_excluded` is derived at query time from the activate/termination dates, so filter with the `active` option rather than shaping on `is_currently_excluded`. */ async listExclusions(options: ListExclusionsOptions = {}): Promise>> { - const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; - - const params: AnyRecord = { - page, - limit: Math.min(limit, 100), - }; - - const shapeToUse = shape ?? ShapeConfig.EXCLUSIONS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) params.flat = "true"; - if (flatLists) params.flat_lists = "true"; - } - - Object.assign(params, filters); - - const data = await this.http.get("/api/exclusions/", params); - const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; - - const results = this.materializeList("Exclusion", shapeSpec, rawResults, flat); - - return buildPaginatedResponse({ ...data, results }); + return this._shapedPaginatedList("/api/exclusions/", "Exclusion", ShapeConfig.EXCLUSIONS_MINIMAL, options); } /** Get a single exclusion by its deterministic exclusion_key (`/api/exclusions/{exclusion_key}/`). */ @@ -2500,23 +2412,7 @@ export class TangoClient { options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, ): Promise> { if (!exclusionKey) throw new TangoValidationError("exclusion_key is required"); - - const { shape, flat = false, flatLists = false, joiner = "." } = options; - const params: AnyRecord = {}; - - const shapeToUse = shape ?? ShapeConfig.EXCLUSIONS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) { - params.flat = "true"; - if (joiner) params.joiner = joiner; - } - if (flatLists) params.flat_lists = "true"; - } - - const data = await this.http.get(`/api/exclusions/${encodeURIComponent(exclusionKey)}/`, params); - return this.materializeOne("Exclusion", shapeSpec, data, flat, joiner); + return this._shapedGet(`/api/exclusions/${encodeURIComponent(exclusionKey)}/`, "Exclusion", ShapeConfig.EXCLUSIONS_MINIMAL, options); } // --------------------------------------------------------------------------- @@ -2525,29 +2421,7 @@ export class TangoClient { /** List SBIR/STTR topics (`/api/sbir/topics/`). */ async listSbirTopics(options: ListSbirTopicsOptions = {}): Promise>> { - const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; - - const params: AnyRecord = { - page, - limit: Math.min(limit, 100), - }; - - const shapeToUse = shape ?? ShapeConfig.SBIR_TOPICS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) params.flat = "true"; - if (flatLists) params.flat_lists = "true"; - } - - Object.assign(params, filters); - - const data = await this.http.get("/api/sbir/topics/", params); - const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; - - const results = this.materializeList("SbirTopic", shapeSpec, rawResults, flat); - - return buildPaginatedResponse({ ...data, results }); + return this._shapedPaginatedList("/api/sbir/topics/", "SbirTopic", ShapeConfig.SBIR_TOPICS_MINIMAL, options); } /** Get a single SBIR/STTR topic by topic_id (`/api/sbir/topics/{topic_id}/`). */ @@ -2556,50 +2430,12 @@ export class TangoClient { options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, ): Promise> { if (!topicId) throw new TangoValidationError("topic_id is required"); - - const { shape, flat = false, flatLists = false, joiner = "." } = options; - const params: AnyRecord = {}; - - const shapeToUse = shape ?? ShapeConfig.SBIR_TOPICS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) { - params.flat = "true"; - if (joiner) params.joiner = joiner; - } - if (flatLists) params.flat_lists = "true"; - } - - const data = await this.http.get(`/api/sbir/topics/${encodeURIComponent(topicId)}/`, params); - return this.materializeOne("SbirTopic", shapeSpec, data, flat, joiner); + return this._shapedGet(`/api/sbir/topics/${encodeURIComponent(topicId)}/`, "SbirTopic", ShapeConfig.SBIR_TOPICS_MINIMAL, options); } /** List DoD DSIP SBIR/STTR solicitations (`/api/sbir/solicitations/`). */ async listSbirSolicitations(options: ListSbirSolicitationsOptions = {}): Promise>> { - const { page = 1, limit = 25, shape, flat = false, flatLists = false, ...filters } = options; - - const params: AnyRecord = { - page, - limit: Math.min(limit, 100), - }; - - const shapeToUse = shape ?? ShapeConfig.SBIR_SOLICITATIONS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) params.flat = "true"; - if (flatLists) params.flat_lists = "true"; - } - - Object.assign(params, filters); - - const data = await this.http.get("/api/sbir/solicitations/", params); - const rawResults = Array.isArray(data?.results) ? (data.results as AnyRecord[]) : []; - - const results = this.materializeList("SbirSolicitation", shapeSpec, rawResults, flat); - - return buildPaginatedResponse({ ...data, results }); + return this._shapedPaginatedList("/api/sbir/solicitations/", "SbirSolicitation", ShapeConfig.SBIR_SOLICITATIONS_MINIMAL, options); } /** Get a single DoD DSIP SBIR/STTR solicitation by solicitation_id (`/api/sbir/solicitations/{solicitation_id}/`). */ @@ -2608,23 +2444,12 @@ export class TangoClient { options: { shape?: string | null; flat?: boolean; flatLists?: boolean; joiner?: string } = {}, ): Promise> { if (!solicitationId) throw new TangoValidationError("solicitation_id is required"); - - const { shape, flat = false, flatLists = false, joiner = "." } = options; - const params: AnyRecord = {}; - - const shapeToUse = shape ?? ShapeConfig.SBIR_SOLICITATIONS_MINIMAL; - const shapeSpec = this.parseShape(shapeToUse, flat, flatLists); - if (shapeToUse) { - params.shape = shapeToUse; - if (flat) { - params.flat = "true"; - if (joiner) params.joiner = joiner; - } - if (flatLists) params.flat_lists = "true"; - } - - const data = await this.http.get(`/api/sbir/solicitations/${encodeURIComponent(solicitationId)}/`, params); - return this.materializeOne("SbirSolicitation", shapeSpec, data, flat, joiner); + return this._shapedGet( + `/api/sbir/solicitations/${encodeURIComponent(solicitationId)}/`, + "SbirSolicitation", + ShapeConfig.SBIR_SOLICITATIONS_MINIMAL, + options, + ); } // --------------------------------------------------------------------------- diff --git a/src/errors.ts b/src/errors.ts index b77c5ad..119abb1 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,3 +1,5 @@ +import { isRecord } from "./utils/guards.js"; + export class TangoAPIError extends Error { readonly statusCode?: number; readonly responseData?: unknown; @@ -35,16 +37,16 @@ export class TangoValidationError extends TangoAPIError { } /** - * Structured validation issues from the API response. For shape errors the - * API returns entries like `{"path": "tradeoff_process", "reason": "unknown_field"}`. + * Structured validation issues from the API response. + * For shape errors the API returns entries like `{"path": "tradeoff_process", "reason": "unknown_field"}`. * Empty array when the response carried no structured issues. */ get issues(): Array> { const data = this.responseData; - if (!data || typeof data !== "object" || Array.isArray(data)) return []; - const val = (data as Record).issues; + if (!isRecord(data)) return []; + const val = data.issues; if (!Array.isArray(val)) return []; - return val.filter((item): item is Record => Boolean(item) && typeof item === "object" && !Array.isArray(item)); + return val.filter(isRecord); } /** @@ -52,10 +54,9 @@ export class TangoValidationError extends TangoAPIError { */ get availableFields(): Record | null { const data = this.responseData; - if (!data || typeof data !== "object" || Array.isArray(data)) return null; - const val = (data as Record).available_fields; - if (!val || typeof val !== "object" || Array.isArray(val)) return null; - return val as Record; + if (!isRecord(data)) return null; + const val = data.available_fields; + return isRecord(val) ? val : null; } } diff --git a/src/models/Dibbs.ts b/src/models/Dibbs.ts index 565386d..ae69219 100644 --- a/src/models/Dibbs.ts +++ b/src/models/Dibbs.ts @@ -1,8 +1,7 @@ /** * DLA DIBBS records (`/api/dibbs/rfqs/`, `/api/dibbs/rfps/`, `/api/dibbs/awards/`). * - * These endpoints use shape-on-demand: which fields appear depends on the - * `?shape=` query param, so EVERY field is optional. + * These endpoints use shape-on-demand: which fields appear depends on the `?shape=` query param, so EVERY field is optional. */ /** Buying-organization reference nested under DIBBS records. */ @@ -26,8 +25,7 @@ export interface DibbsAwardeePayload { /** * DLA DIBBS request-for-quote solicitation. * - * `is_open` is derived at query time from `return_by_date`, so it is not - * filterable as a stored field — use the `open` filter instead. + * `is_open` is derived at query time from `return_by_date`, so it is not filterable as a stored field — use the `open` filter instead. */ export interface DibbsRfq { uuid?: string; @@ -51,8 +49,7 @@ export interface DibbsRfq { /** * DLA DIBBS request-for-proposal solicitation. * - * `is_open` is derived at query time from `closes_date` — use the `open` - * filter to select on it. + * `is_open` is derived at query time from `closes_date` — use the `open` filter to select on it. */ export interface DibbsRfp { uuid?: string; @@ -72,9 +69,7 @@ export interface DibbsRfp { /** * DLA DIBBS award. * - * WARNING: `total_contract_price` is the *order* total repeated on every line - * item of the award — never sum it across rows, or you will multiply the - * value by the line-item count. + * WARNING: `total_contract_price` is the *order* total repeated on every line item of the award — never sum it across rows, or you will multiply the value by the line-item count. */ export interface DibbsAward { uuid?: string; diff --git a/src/models/Exclusion.ts b/src/models/Exclusion.ts index 6b5bcbc..481e8f8 100644 --- a/src/models/Exclusion.ts +++ b/src/models/Exclusion.ts @@ -1,11 +1,9 @@ /** * SAM.gov exclusion (debarment) record (`/api/exclusions/`). * - * The endpoint uses shape-on-demand: which fields appear depends on the - * `?shape=` query param, so EVERY field is optional. + * The endpoint uses shape-on-demand: which fields appear depends on the `?shape=` query param, so EVERY field is optional. * - * `is_currently_excluded` is derived at query time from the - * activate/termination dates — use the `active` filter to select on it. + * `is_currently_excluded` is derived at query time from the activate/termination dates — use the `active` filter to select on it. */ export interface Exclusion { exclusion_key?: string; diff --git a/src/models/Sbir.ts b/src/models/Sbir.ts index 9fb5efa..cd68b6a 100644 --- a/src/models/Sbir.ts +++ b/src/models/Sbir.ts @@ -1,8 +1,7 @@ /** * SBIR/STTR records (`/api/sbir/topics/`, `/api/sbir/solicitations/`). * - * These endpoints use shape-on-demand: which fields appear depends on the - * `?shape=` query param, so EVERY field is optional. + * These endpoints use shape-on-demand: which fields appear depends on the `?shape=` query param, so EVERY field is optional. */ /** diff --git a/src/types.ts b/src/types.ts index e68d664..c3b3473 100644 --- a/src/types.ts +++ b/src/types.ts @@ -49,33 +49,27 @@ export interface PaginatedResponse { pageMetadata: Record | null; /** * Response-level metadata the API attached to this page, when present. - * Currently carries agency-filter diagnostics: `resolved_filters` maps each - * agency filter to the organizations its `|`-separated tokens resolved to - * (or `null`), and `warnings` lists human-readable notes about tokens that - * were dropped or matched loosely. See `agencyWarnings`, - * `unresolvedAgencyTokens`, and `resolvedAgencies` for the parsed views. + * Currently carries agency-filter diagnostics: `resolved_filters` maps each agency filter to the organizations its `|`-separated tokens resolved to (or `null`), and `warnings` lists human-readable notes about tokens that were dropped or matched loosely. + * See `agencyWarnings`, `unresolvedAgencyTokens`, and `resolvedAgencies` for the parsed views. + * Optional (like the other three diagnostics) so pre-existing code constructing a `PaginatedResponse` still compiles; responses built by the client always populate it. */ - meta: Record | null; + meta?: Record | null; /** - * Warnings the API raised about agency filters on this request. Empty when - * every supplied agency token resolved cleanly — a non-empty list means part - * of the filter did not apply, so a small or empty `results` is not evidence - * that no such records exist. + * Warnings the API raised about agency filters on this request. + * Empty when every supplied agency token resolved cleanly — a non-empty list means part of the filter did not apply, so a small or empty `results` is not evidence that no such records exist. */ - agencyWarnings: string[]; + agencyWarnings?: string[]; /** - * Agency tokens that matched no organization, keyed by filter name. Empty - * when everything resolved. Use this to fail loudly in a pipeline rather - * than treating a silently-narrowed result set as an answer. + * Agency tokens that matched no organization, keyed by filter name. + * Empty when everything resolved. + * Use this to fail loudly in a pipeline rather than treating a silently-narrowed result set as an answer. */ - unresolvedAgencyTokens: Record; + unresolvedAgencyTokens?: Record; /** - * What each agency token actually resolved to, keyed by filter name. Agency - * resolution is fuzzy, so a token can match an organization the caller did - * not intend — checking the resolved `name` is the only way to catch that - * from the client side. + * What each agency token actually resolved to, keyed by filter name. + * Agency resolution is fuzzy, so a token can match an organization the caller did not intend — checking the resolved `name` is the only way to catch that from the client side. */ - resolvedAgencies: Record>>; + resolvedAgencies?: Record>>; /** * Cursor for keyset-paginated endpoints, extracted from `next`. Pass it back * via the next request's `cursor` option. `null` when the endpoint is diff --git a/src/utils/guards.ts b/src/utils/guards.ts new file mode 100644 index 0000000..841f0b9 --- /dev/null +++ b/src/utils/guards.ts @@ -0,0 +1,6 @@ +// Dependency-free type guards. This module must not import from errors/http, which both import it. + +/** Narrow an unknown value to a plain (non-array, non-null) object. */ +export function isRecord(value: unknown): value is Record { + return Boolean(value) && typeof value === "object" && !Array.isArray(value); +} diff --git a/src/utils/http.ts b/src/utils/http.ts index 215eafd..63cc96f 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -1,6 +1,7 @@ import { TangoAPIError, TangoAuthError, TangoNotFoundError, TangoRateLimitError, TangoTimeoutError, TangoValidationError } from "../errors.js"; import { DEFAULT_BASE_URL } from "../config.js"; import type { RateLimitInfo } from "../types.js"; +import { isRecord } from "./guards.js"; export interface HttpClientOptions { baseUrl?: string; @@ -20,10 +21,6 @@ export interface RequestOptions { body?: unknown; } -function isRecord(value: unknown): value is Record { - return Boolean(value) && typeof value === "object" && !Array.isArray(value); -} - function isSafePrimitive(value: unknown): value is string | number | boolean | symbol | bigint { const type = typeof value; return type === "string" || type === "number" || type === "boolean" || type === "symbol" || type === "bigint"; diff --git a/tests/integration/harness.ts b/tests/integration/harness.ts index fd1d5d3..1243985 100644 --- a/tests/integration/harness.ts +++ b/tests/integration/harness.ts @@ -36,7 +36,8 @@ const SENSITIVE_HEADERS = /^(x-api-key|authorization|proxy-authorization|cookie| export interface RecordedInteraction { request: { method: string; url: string }; - response: { status: number; headers: Record; body: unknown }; + /** `bodyKind` discriminates replay encoding; absent means `"json"`, so every pre-existing cassette (all JSON bodies) stays valid. */ + response: { status: number; headers: Record; body: unknown; bodyKind?: "json" | "text" }; } interface Cassette { @@ -70,6 +71,7 @@ export function serializeInteraction( responseHeaders: Record, body: unknown, secret?: string | null, + bodyKind: "json" | "text" = "json", ): RecordedInteraction { const headers: Record = {}; for (const [name, value] of Object.entries(responseHeaders)) { @@ -79,7 +81,8 @@ export function serializeInteraction( const interaction: RecordedInteraction = { request: { method: method.toUpperCase(), url: sortedUrl(url) }, - response: { status, headers, body }, + // `bodyKind` is only written for text bodies, keeping JSON cassettes on the original schema. + response: bodyKind === "text" ? { status, headers, body, bodyKind } : { status, headers, body }, }; if (secret) { @@ -130,14 +133,17 @@ function recordingFetch(name: string): typeof fetch { const text = await res.clone().text(); let body: unknown = null; + let bodyKind: "json" | "text" = "json"; try { body = text ? JSON.parse(text) : null; } catch { + // Non-JSON payload: store the raw text so replay can be byte-faithful. body = text; + bodyKind = "text"; } const method = init?.method ?? "GET"; - interactions.push(serializeInteraction(method, String(input), res.status, headersToRecord(res.headers), body, secret)); + interactions.push(serializeInteraction(method, String(input), res.status, headersToRecord(res.headers), body, secret, bodyKind)); writeFileSync(cassettePath(name), `${JSON.stringify({ version: 1, interactions } satisfies Cassette, null, 2)}\n`); return res; }) as typeof fetch; @@ -164,13 +170,17 @@ function replayFetch(name: string): typeof fetch { throw new Error(`No recorded interaction in ${name}.json for:\n ${key}\nRecorded:\n ${recorded}\nRe-record with TANGO_REFRESH_CASSETTES=true.`); } const [hit] = remaining.splice(idx, 1); - return new Response(JSON.stringify(hit.response.body), { - status: hit.response.status, - headers: hit.response.headers, - }); + return responseFromRecorded(hit); }) as typeof fetch; } +/** Rebuild the wire Response for a recorded interaction: text bodies replay verbatim; JSON bodies re-serialize (the pre-`bodyKind` behavior). */ +export function responseFromRecorded(interaction: RecordedInteraction): Response { + const { status, headers, body, bodyKind } = interaction.response; + const raw = bodyKind === "text" ? String(body) : JSON.stringify(body); + return new Response(raw, { status, headers }); +} + /** Cassette-aware fetch for one test: records, replays, or passes through per mode. */ export function cassetteFetch(name: string): typeof fetch { if (USE_LIVE_API) return fetch; diff --git a/tests/unit/client.dibbs-exclusions-sbir.test.ts b/tests/unit/client.dibbs-exclusions-sbir.test.ts index c3adefe..6b6f271 100644 --- a/tests/unit/client.dibbs-exclusions-sbir.test.ts +++ b/tests/unit/client.dibbs-exclusions-sbir.test.ts @@ -279,6 +279,34 @@ describe("TangoClient — SBIR solicitations", () => { }); }); +describe("TangoClient — joiner threading on the new list methods", () => { + it("listDibbsRfqs does not send a caller-supplied joiner when flat is off", async () => { + const { client, calls } = makeClient(); + await client.listDibbsRfqs({ joiner: "__" }); + + const p = params(calls); + expect(p.has("joiner")).toBe(false); + expect(p.has("flat")).toBe(false); + }); + + it("listDibbsRfqs sends joiner with flat=true and unflattens with it", async () => { + const { client, calls } = makeClient({ + count: 1, + next: null, + previous: null, + results: [{ uuid: "u1", "organization__agency_name": "DLA" }], + }); + + const res = await client.listDibbsRfqs({ shape: "uuid,organization(agency_name)", flat: true, joiner: "__" }); + + const p = params(calls); + expect(p.get("flat")).toBe("true"); + expect(p.get("joiner")).toBe("__"); + expect(res.results[0].uuid).toBe("u1"); + expect((res.results[0].organization as Record).agency_name).toBe("DLA"); + }); +}); + describe("TangoClient — DIBBS/exclusions/SBIR list responses", () => { it("listExclusions returns a materialized paginated response", async () => { const { client } = makeClient({ diff --git a/tests/unit/client.meta-diagnostics.test.ts b/tests/unit/client.meta-diagnostics.test.ts index be347cb..e8d5014 100644 --- a/tests/unit/client.meta-diagnostics.test.ts +++ b/tests/unit/client.meta-diagnostics.test.ts @@ -1,15 +1,13 @@ /** - * `meta` from the API's agency-filter diagnostics (port of Python's - * TestAgencyFilterDiagnostics, tango-python #55). + * `meta` from the API's agency-filter diagnostics (port of Python's TestAgencyFilterDiagnostics, tango-python #55). * - * Agency resolution is fuzzy, so a token can be dropped entirely or matched to - * an organization the caller did not intend. Before the API exposed `meta`, - * both were indistinguishable from "no such records exist" — and the SDK is - * the last place that distinction can reach a user. + * Agency resolution is fuzzy, so a token can be dropped entirely or matched to an organization the caller did not intend. + * Before the API exposed `meta`, both were indistinguishable from "no such records exist" — and the SDK is the last place that distinction can reach a user. */ import { TangoClient } from "../../src/client.js"; import { TangoValidationError } from "../../src/errors.js"; +import type { PaginatedResponse } from "../../src/types.js"; const HUD = { key: "3f2a0000-0000-0000-0000-000000000001", @@ -113,3 +111,20 @@ describe("PaginatedResponse agency-filter diagnostics", () => { await expect(client.listContracts({ awarding_agency: "HUDD" })).rejects.toThrow(/HUDD/); }); }); + +describe("PaginatedResponse type compatibility", () => { + it("a bare literal without the meta diagnostic fields still typechecks", () => { + const bare: PaginatedResponse> = { + count: 0, + next: null, + previous: null, + pageMetadata: null, + cursor: null, + results: [], + }; + expect(bare.meta).toBeUndefined(); + expect(bare.agencyWarnings).toBeUndefined(); + expect(bare.unresolvedAgencyTokens).toBeUndefined(); + expect(bare.resolvedAgencies).toBeUndefined(); + }); +}); diff --git a/tests/unit/integration-harness.test.ts b/tests/unit/integration-harness.test.ts index 69dbfca..8c3b47d 100644 --- a/tests/unit/integration-harness.test.ts +++ b/tests/unit/integration-harness.test.ts @@ -1,4 +1,4 @@ -import { cassetteFetch, matchKey, REPLAY_ONLY, serializeInteraction } from "../integration/harness.js"; +import { cassetteFetch, matchKey, REPLAY_ONLY, responseFromRecorded, serializeInteraction } from "../integration/harness.js"; describe("serializeInteraction (cassette scrubbing)", () => { const url = "https://tango.makegov.com/api/contracts/?limit=3"; @@ -60,6 +60,28 @@ describe("matchKey", () => { }); }); +describe("body round-trip (record → replay)", () => { + const url = "https://tango.makegov.com/api/contracts/?limit=3"; + + it("replays a text/plain body byte-faithfully instead of as a quoted JSON string", async () => { + const raw = "plain text, not JSON"; + const recorded = serializeInteraction("GET", url, 502, { "content-type": "text/plain" }, raw, null, "text"); + expect(recorded.response.bodyKind).toBe("text"); + + const replayed = responseFromRecorded(recorded); + expect(await replayed.text()).toBe(raw); + expect(replayed.status).toBe(502); + }); + + it("replays a JSON body without bodyKind (pre-existing cassette schema) as JSON", async () => { + const recorded = serializeInteraction("GET", url, 200, { "content-type": "application/json" }, { count: 1, results: [] }); + expect(recorded.response.bodyKind).toBeUndefined(); + + const replayed = responseFromRecorded(recorded); + expect(await replayed.json()).toEqual({ count: 1, results: [] }); + }); +}); + describe("replay mode", () => { it.skipIf(!REPLAY_ONLY)("hard-fails on a missing cassette with a re-record hint", () => { expect(() => cassetteFetch("no-such-cassette-xyz")).toThrow(/TANGO_REFRESH_CASSETTES/);