# How the OpenAPI importer reads a document

This is the detail behind [Where packages come from](where-packages-come-from.md):
what `jadpo package import openapi <file>` reads from a provider's OpenAPI
document, what it writes, and what it leaves for you or your agent to
check.

- **Where it writes.** Always the app's own integration,
  `shared/providers/<name>/<version>/`; installing another Jadpo app's
  package into `packages/` is `jadpo package add`. The name
  and version are `--as AcmeCouriers.v1`, or the document's title in
  `UpperCamelCase` and its version's major number (`1.4.0` is `v1`), or
  its date (`2024-06-20` is `v2024_06_20`), else `v1`, as for a Jadpo
  application, whose document's version is a hash of its record.
- **What it reads.** OpenAPI 3.0 and 3.1 as JSON, from a local file. YAML
  and Swagger 2.0 are refused with what to do (`cli.package_unreadable`
  and `cli.package_not_openapi`, listed under
  [Command errors](command-errors.md)). Nothing is fetched.
- **The files.** `package.jadpo` with `Licence.proprietary` (an own
  integration may use it) and `jadpo: "1.0"`; `provider.jadpo` with
  `protocol: Protocol.json_http`, `imported: { file: digest: }` (the path
  from the project's root and `sha256:` of the file's bytes), `hosts: {
  live: }` from the first absolute server, and `credential:
  CredentialScheme.bearer` or `.basic` from the security schemes; a
  resource per tag, in `resources/`, every resource `public`; the types
  and failures the operations reach, each `public` in its own file, and
  nothing else of the description. Every operation is `source:
  PackageSource.imported`.
- **Operations.** By path, then `get`, `put`, `post`, `delete` and
  `patch`. A resource is the operation's first tag in `lower_snake_case`,
  else its path's first fixed segment that isn't a version. On the
  resource's shortest fixed path an operation is `list` or `create`; with
  one placeholder after it `get`, `update` (`replace` for a `PUT` beside a
  `PATCH`) or `delete`; any other is its `operationId` in
  `lower_snake_case`, or a Jadpo application's method and fixed segments
  (`post_archive`). Its input is its body's type when it has no
  placeholders or query parameters, else `<Resource><Operation>Input`
  holding them and the body's fields; header and cookie parameters and a
  body that isn't JSON are left out and listed. Its output is its lowest
  `2xx` answer's JSON body.
- **What it can't know from another provider** is written the safe way
  and listed: `changes: true` for every method but `GET`, no
  `idempotent:`, no failures, no `idempotency:` or `error_code:`, and no
  sandbox host.
- **Types.** The exact mappings of
  [Mapping imported types to standard types](where-packages-come-from.md#mapping-imported-types-to-standard-types)
  (`date-time` `Instant`, `date`
  `CalendarDate`, `email` `Email`, `uri` `Url`, `uuid` `Uuid`, `ipv4` and
  `ipv6` `IpAddress`, `byte` `Bytes`, `duration` `Duration`, and an
  enumeration of ISO 4217 codes `Currency` or of ISO 3166-1 codes
  `Country`), `integer` `Int`, `number`
  `Decimal`, `boolean` `Bool`, an array `List` (`Set` with
  `uniqueItems`), an object of one kind of value `Map<Text, V>`, and their
  rules (`minLength`, `maxLength`, `pattern`, `minimum`, `maximum`,
  `minItems`, `maxItems`). A field not `required`, or `nullable`, is `?`.
  An object or enumeration inside another is a type of its own,
  `<Parent><Field>`; a constrained item of a list is a refined type,
  `<Parent><Field>Element`. A schema named as a built-in type is
  `<Name>Type`, and listed. `oneOf` and `anyOf` of several shapes, and an
  object of any fields, are left out and listed. Shape and name
  detection is under "Shape and name detection".
- **A Jadpo application's document** (one whose operations carry
  `x-jadpo-changes`) is read exactly: each field's type from
  `x-jadpo-constraints`, `changes:` from `x-jadpo-changes`, `idempotent:
  true` where a key keeps the response, the provider's `idempotency:` from
  `x-jadpo-idempotency`, `error_code: "error.code"`, its failures from
  `x-jadpo-failure` (named from the code, with its kind and message), no
  host (the connection gives `host:`), and no finding. Its runtime's own
  routes (`x-jadpo-generated`: the exchange, passkeys, the served
  document) are left out. An API that signs callers in only with a
  browser session gets no credential, and a finding.
- **Importing again merges** one declaration and one member at a time:
  what the description adds is added, what both have is kept as the file
  has it, so corrections survive, and what only the file has is kept and
  listed; only `imported:` is always the description's. A file that
  doesn't read is left alone and listed.
- **The summary** says what was written where and counts what the package
  holds, lists a merge's changes, and groups what is left to check by
  what to do, each `(agent)`, with `--json` for agents.
- **Field and variant names on the wire.** A field or variant is the
  provider's name in `lower_snake_case`; where that differs (`collectAt`,
  `after-noon`, or `type` written `type_value` to avoid a reserved word),
  the importer writes the provider's spelling as the field's or variant's
  `wire_name:` ([Decoding](decoding.md)).

> Importing Smithy, Postman, HAR and `.d.ts` isn't built yet: each is
> `toolchain.not_built_yet`.
