# Importing collections

Source: https://apigenie.pl/docs/reference/cli/test/import
Part of the reference of [test](https://apigenie.pl/docs/reference/cli/test.md).
Its other pages: [Request files](https://apigenie.pl/docs/reference/cli/test/requests.md), [Variables and OAuth 2](https://apigenie.pl/docs/reference/cli/test/variables.md), [Assertions and scripts](https://apigenie.pl/docs/reference/cli/test/assertions.md), [Validation](https://apigenie.pl/docs/reference/cli/test/validation.md), [Generated requests](https://apigenie.pl/docs/reference/cli/test/generate.md), [GraphQL requests](https://apigenie.pl/docs/reference/cli/test/graphql.md), [WebSocket and MQTT requests](https://apigenie.pl/docs/reference/cli/test/websocket-mqtt.md), [Kafka requests](https://apigenie.pl/docs/reference/cli/test/kafka.md), [AMQP requests](https://apigenie.pl/docs/reference/cli/test/amqp.md), [gRPC requests](https://apigenie.pl/docs/reference/cli/test/grpc.md), [httpYac compatibility](https://apigenie.pl/docs/reference/cli/test/httpyac.md).

`apigenie test import` reads a Postman Collection Format v2.0 or v2.1 JSON export and writes
request files that `apigenie test` can run. It uses an independently implemented reader, not
Postman's JavaScript or the `postman-collection` SDK. Collection v1 is not supported: export as
v2.1 from Postman.

```sh
apigenie test import carpet-express.collection.json -o requests \
  --environment mock.environment.json --spec carpet-express.openapi.yaml
apigenie test requests --env mock --spec carpet-express.openapi.yaml \
  --var baseUrl=http://localhost:4010/v2
```

| Import option | Meaning |
| --- | --- |
| `COLLECTION` | Collection JSON file to import |
| `-o DIR`, `--output DIR` | Required output directory |
| `--environment FILE` | An exported environment JSON file; can be repeated |
| `--spec SPEC` | Bind matching requests to operation IDs and write saved response examples as an OpenAPI overlay |
| `--force` | Replace existing generated files; never delete unrelated files |

The collection's root requests go into `<collection-slug>.http`. A folder `Shipping` becomes
`shipping.http`; its nested folder `Tracking` becomes `shipping/tracking.http`. Every request
is a `###` region with a stable `# @name` slug. Collection and inherited folder variables are
written as `@name = value` defaults at the top of each file. Slug collisions get deterministic
suffixes. Collection and folder auth and pre-request/test scripts are inherited by descendant
requests; explicit `noauth` disables inherited authentication.

URLs and variables retain `{{name}}` references. Active headers and query parameters, raw,
urlencoded, multipart form-data, GraphQL and file bodies are mapped. GraphQL becomes an HTTP
POST with a JSON envelope, not the unsupported `GRAPHQL` pseudo-method and not GraphQL-specific
contract validation. Available upload files are copied into the output with relative `< ./path`
references; missing files are kept as references and reported as warnings. Relative source
upload paths are resolved against the collection file's directory. Multipart file references
are read as binary data when the request runs.

Exported environments become named entries in `http-client.env.json`. Bearer, basic and API-key
authentication becomes headers or query parameters with environment-variable references.
Literal credentials and known credential defaults are stored only in the generated
`http-client.private.env.json` (with the same `$shared` and environment entries), not in
`http-client.env.json`, request files, overlays or the import summary; `apigenie test` reads both
files. **The private environment file contains secrets: protect it and do not commit it to source
control.** The importer cannot discover arbitrary secrets hidden in unrelated application data.

OAuth 2 auth with the client credentials or password grant becomes
`Authorization: oauth2 client_credentials` (or `password`) and the
[OAuth 2 variables](/docs/reference/cli/test/variables#oauth-2): the access token URL, client id, scope, audience and client
authentication (`header` or `body`) in `http-client.env.json`, the client secret, user name and
password in `http-client.private.env.json`. Each distinct OAuth 2 configuration gets its own
prefix (`oauth2`, `oauth2_2`, ...). A token stored in the collection isn't used: a new one is
requested. The authorization code, PKCE and implicit grants need a browser: those requests are
written disabled, their auth kept as a comment without its secrets, with a warning. Adding the
token to the query and header prefixes other than `Bearer` are warnings; the token is sent in the
`Authorization` header with the type the token endpoint gives.

Imported files follow the ordinary `.http` variable precedence: file defaults override
environment values, and `--var` overrides both. This differs from Postman's precedence.
For marked files, environment discovery searches parent directories too, so nested request files
can find the generated root environment. Script changes are in memory only, not saved back to
the environment file. Files are run in the existing explicit-file or sorted-directory order;
splitting folders into separate files does not preserve arbitrary cross-folder collection order.

With `--spec`, requests that bind by method and path to an operation with an ID get
`# @operation <operationId>`. Saved responses become additive examples in
`<collection-slug>.overlay.json`; the specification is never edited. Apply the overlay explicitly:

```sh
apigenie overlay carpet-express.openapi.yaml \
  --overlay requests/carpet-express.overlay.json -o carpet-express.with-examples.yaml
```

Without a specification or a usable binding, examples are preserved as comments. Unresolved
bindings or overlay targets produce warnings rather than guessed operation IDs.

## Imported script API

Files carrying `# @postman` get a small compatibility shim in QuickJS. Unmarked files do not
get a `pm` global. Pre-request blocks go before the request; test blocks go after it.
Scripts containing their own standalone `}}` line are JSON-escaped inside the block so that
multiline strings and JavaScript tokens remain intact.
Simple `pm.test` callbacks that only assert a literal response status become `?? status == N`
instead, so they do not require scripting support.

| API | Supported subset |
| --- | --- |
| `pm.test(name, fn)` | Records a named check; a thrown assertion fails it |
| `pm.expect(value)` | `to.equal`, `to.eql`, `to.be.true`, `to.be.false`, `to.have.property`, `to.have.status`, `to.include`, `to.be.oneOf`, `to.be.a` |
| `pm.response` | `code`, `status`, `json()`, `text()`, case-insensitive `headers.get(name)`, `to.have.status(code)` |
| `pm.environment` | `get`, `set`, `unset` |
| `pm.collectionVariables` | `get`, `set` |
| `pm.variables` | `get`, `set`; request-local changes |
| `pm.globals` | `get`, `set` |
| `pm.request.headers.add({key, value})` | Adds a header before sending a marked request |

This is not the full SDK or Chai. `pm.sendRequest`, `postman.setNextRequest`, `pm.cookies` and
`pm.visualizer` cause the **whole affected script block** to be kept as comments, with warnings
that name the call and its source line. OAuth 2 auth with a grant that needs a browser is
preserved as comments and the request is disabled. The summary lists unsupported features; they
are never silently dropped.
Other unknown script APIs fail explicitly at runtime. Scripts remain subject to the existing
QuickJS time limit and lack of filesystem/network access. Imported `https://` URLs are sent over
TLS like any other request (see `--ca-cert` and `--insecure`).

Import returns 0 after a successful conversion, including one with reported warnings, 2 for
bad command usage, and 3 for input or output failures. Existing generated filenames are refused
unless `--force` is supplied. A directory literally named `import` can still be run with
`apigenie test -- import`.
