# bundle

Source: https://apigenie.pl/techdocs/reference/cli-bundle

Bundles an OpenAPI, Swagger or AsyncAPI schema and the files it references,
or a Protobuf (`.proto`) file and the files it imports, into a single file.

## Usage

```sh
apigenie bundle [OPTIONS] --output OUTPUT INPUT
```

## Description

The command recognizes Protobuf files by the `.proto` extension. Other files
are read as JSON or YAML, and recognized as OpenAPI, Swagger or AsyncAPI
schemas by the `openapi`, `swagger` or `asyncapi` property of the document
root.

Unlike `format`, `overlay` and `lint --fix`, `bundle` does not keep the YAML
comments of OpenAPI, Swagger and AsyncAPI inputs: the output is a new document
built from several files. In YAML output, strings that YAML 1.1 parsers would
read as booleans or numbers, such as `yes`, `off`, `0755` or `1:30`, are written
in double quotes.

### OpenAPI

External references (`$ref` to other local files) are copied into the
`components` object of the output, and the references are rewritten to point
there. Remote references (URLs) are not supported. The output format, JSON or
YAML, follows the extension of the output file.

### Swagger

Swagger 2.0 documents are bundled like OpenAPI ones: schemas, parameters and
responses referenced in other local files are copied into the `definitions`,
`parameters` and `responses` objects of the output, and the references are
rewritten to point there. A path item that is a reference to another file
takes the content of that file. Remote references (URLs) are not supported.
The output format, JSON or YAML, follows the extension of the output file.

### AsyncAPI

AsyncAPI 3.x documents are bundled with the local files they reference. Root
servers, channels and operations kept in other files take the content of those
files; other referenced objects become components. Schemas in other formats,
such as Avro, are copied as they are, and references by URL are kept. The
output format, JSON or YAML, follows the extension of the output file.

### Protobuf

The input file and the files it imports, directly or indirectly, are combined
into one proto3 file, which can be compiled without the imported files:

- All declarations of the input file are kept, in their order, with their
  comments. The output is written in the layout of the `format` command.
- Of the imported files, only the messages, enums and extensions that the
  input file uses, directly or through other imported declarations, are
  copied. They follow the declarations of the input file. Imported services,
  unused declarations and the file options of imported files (such as
  `go_package` or `java_package`) are left out.
- The output has the package of the input file. Declarations from files with
  another package are renamed with a prefix made from their package: top-level
  messages and enums get the package in PascalCase, and top-level extensions
  get it in snake case. Declarations nested in them keep their names. When a
  name is already taken, a numeric suffix is added (`_2`, `_3`, and so on).
  Type names and option names that refer to renamed declarations are
  rewritten. Declarations from files with the same package keep their names.
- The well-known types (`google/protobuf/*.proto`) are not bundled: their
  imports are kept, and the imports needed by the copied declarations are
  added.

For example, with `shop.proto`:

```proto
syntax = "proto3";

package shop.v1;

import "common/money.proto";

message Order {
  common.v1.Money total = 1;
}
```

and `common/money.proto`:

```proto
syntax = "proto3";

package common.v1;

message Money {
  string currency = 1;
  int64 units = 2;
}
```

`apigenie bundle shop.proto --output bundle.proto` writes:

```proto
syntax = "proto3";

package shop.v1;

message Order {
  CommonV1Money total = 1;
}

message CommonV1Money {
  string currency = 1;
  int64 units = 2;
}
```

Renaming changes the full names of the moved declarations, e.g.
`common.v1.Money` becomes `shop.v1.CommonV1Money`, and an option such as
`(google.api.http)` becomes `(google_api_http)`. Field numbers and the wire
format do not change, but tools that depend on full names, such as JSON
encoding of `Any` values or code generators matching option names, see the new
names. Type names inside string option values are not rewritten.

Imports are searched in the proto paths given with `--proto-path`, like
`protoc` does, never relative to the importing file. Without `--proto-path`,
the directory of the input file is searched.

Nothing is written when there are errors. The command reports, with the file,
line and column:

- imports that are not found or cannot be read, including proto2 files and
  files with editions, which are not supported
- import cycles
- type names and option names that are not defined, or not visible from the
  file that uses them
- enum values that clash after the merge; enum values are in the scope of the
  package, so they cannot be renamed

## Options

| Option                   | Description                                       |
| ------------------------ | ------------------------------------------------- |
| `-o`, `--output OUTPUT`  | Path to the bundled file. Required.               |
| `-I`, `--proto-path DIR` | Directory in which Protobuf imports are searched. |

### --output OUTPUT

Path of the bundled file.

### --proto-path DIR

Directory in which Protobuf imports are searched. The option can be repeated;
the directories are searched in the given order. Write it as `-I DIR` or
`--proto-path=DIR`. Defaults to the directory of the input file.

```sh
apigenie bundle api/orders.proto -I shared -I api --output bundle.proto
```
