Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 30 Oct 2026. What's built · Install 0.1.0
jadpo
Reference: External services

External services

Shape and name detection

This is the detail behind layers 2, 3 and 6 of Mapping imported types to standard types, for fields: how a provider's fields that together make a standard type, such as an amount and a currency, are…

This is the detail behind layers 2, 3 and 6 of Mapping imported types to standard types, for fields: how a provider's fields that together make a standard type, such as an amount and a currency, are read as that type, and which fields the importer asks you to check. Layers 4 and 5 are under The scoped review and unconfirmed operations.

  • How a provider's shape is decoded at the edge: wire_parts:. Stripe's amount: 1050, currency: "gbp" decodes to Money, and no other decoding could do it: wire: and decode: read one member, and Wire.minor_units needs one fixed currency. A field's wire_parts: names, for each part of its standard type, the member of the object holding the field it is read from and written to; the field has no member of its own on the provider's wire, and is written as the contract writes it everywhere else. It is for the standard types made of named parts (Money's amount and currency, InstantRange's start and end, and the others sent as an object of members) and a Point, by latitude and longitude, which GeoJSON sends as a pair. Every part is spelled, as text, once (package.wire_invalid), never beside wire:, decode: or encode:. Fields may share a part's member, as a charge's amounts share its currency, but a field of its own can't take one (package.wire_name_invalid); written, two values that share a member and differ stop the call as one that doesn't encode, naming the member. None of a field's members sent is none where the field may be; some missing is a fault naming each. It follows wire_name:'s shape.
  • What the importer maps by shape. Only what the shapes type.standard_exists matches name, and only where nothing is guessed but the units: a whole number named as Money's amount (amount, value, cents, pence, minor, amount_minor) beside a currency (currency, currency_code) of the same optionality is Money read from both, the currency's field and its own enumeration gone; a latitude beside a longitude (lat, lng, lon) of the same optionality is a Point named location (position or point where that is taken). An object that is only an amount in whole numbers and a currency, or only a start and an end that are instants, each required and spelled as the contract spells it, is Money or InstantRange wherever it is used, and isn't declared, since nothing needs decoding. Any other object of a standard shape is left to type.standard_exists, whose swap needs a decoding an agent writes.
  • What it leaves to check: package.standard_candidate. A whole number named like a time (created, updated, deleted, expires, timestamp, time, or ending _at, _time or _timestamp) may be an Instant sent as seconds or milliseconds; one named like an amount (amount_ or _amount besides the shape's names) beside a currency may be Money; neither is swapped, since only the documentation says which. Each is a declinable error on the field, in a provider package's public objects, until it says how it is sent or is declined with a reason; so is a latitude beside a longitude that isn't mapped. A number named like a time that is text ("2026-10-20") isn't flagged: the page names whole numbers, and a format says when text is a time.
  • Fakes. A generated default answer writes a field's parts as their members, and a Money as the contract sends one, a whole number of minor units in the currency its type fixes or GBP.
  • The summary. The status grid counts the fields mapped by format and by shape; "Mapped by shape" lists each shape mapping and how it is read, since each is a judgement, where a format's is only counted; each guess is under "To check" with its (agent) step. --json gives every mapping as mapped, with at, standard, by and the members it is read from.

The import's own output, for a payment provider's document:

text
$ jadpo package import openapi tidepay.json✓ Imported tidepay.json into shared/providers/tidepay/v2024_06_20    package     Tidepay.v2024_06_20    read        from its schemas    resources   charges    operations  1    types       3    standard    4 by shapeMapped by shape  Charge.amount  Money, read from `amount` and `currency`  Charge.fee     Money, sent as the standard type  Charge.window  InstantRange, sent as the standard type  Shop.location  Point, read from `lat` and `lng`To check  May be `Money` in minor units, its currency in `currency`: check the  provider's documentation, then make it `Money` read from both with  `wire_parts:`, or decline `package.standard_candidate` with the reason  (agent)    Charge.amount_refunded  May be an `Instant` sent as whole seconds: check the provider's  documentation, then make it `Instant { wire: Wire.unix_seconds }`, or  decline `package.standard_candidate` with the reason (agent)    Charge.created✓ imported  1 operation · 3 types · 4 to check→ jadpo check  checks the package with the app

(The provider's two findings, its sandbox host and its failures, are left out above.)

Markdown for agents: /docs/shape-and-name-detection.md.Built from Jadpo main at a707efb.