Skip to content

Tango Node SDK – Shaping Guide

A complete translation of the Python SHAPES.md document for Node.


Why Shapes?

Tango resources can have hundreds of fields. Shapes let you request:

  • Only what you need
  • In nested form
  • With aliases
  • With wildcards
  • With flattening options

Shape Grammar

shape       := field_list
field_list  := field ("," field)*
field       := field_name [alias] [nested]
field_name  := identifier | "*"
alias       := "::" identifier
nested      := "(" field_list ")"
identifier  := [a-zA-Z_][a-zA-Z0-9_]*

Examples

Simple

shape: "key,piid,award_date";

Nested

shape: "recipient(display_name,uei)";

Aliases

shape: "recipient::vendor(display_name)";

Wildcard

shape: "*";

Wildcard nested

shape: "recipient(*)";

ShapeConfig Presets

The SDK ships with a ShapeConfig object of ready-made shape strings for common patterns. Import from the main entry point:

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()

These are plain strings — you can use them directly or as a starting point:

const contracts = await client.listContracts({
  shape: ShapeConfig.CONTRACTS_MINIMAL,
  limit: 10,
});

Flat Responses

shape: ShapeConfig.CONTRACTS_MINIMAL,
flat: true

When flat: true is passed, the Tango API returns dotted key names instead of nested objects. The SDK automatically unflattens them back into nested objects on the client side:

// API returns:       { "recipient.display_name": "Acme" }
// SDK unflattens to: { recipient: { display_name: "Acme" } }

You can override the separator character (default ".") with the joiner option.


Validation

ShapeParser enforces syntax.

TypeGenerator enforces semantic model rules (existence of fields, nested models).


Performance Tips

  • Use minimal shapes in production.
  • Avoid full-wildcard unless you need all fields.
  • Prefer shallow nested shapes for large nested structures.