npm package: @ottogroup/ui5-odata-generator
Description: Extract entities from OData metadata into Typescript interfaces
Author: Timo Stahl
Latest version: 2.4.3

# ui5-odata-generator

This package takes the `metadata.xml` of an OData service and converts it to TypeScript interfaces. It also creates a wrapper class for all the CRUD operations.

## Features

🎉 Automatically create TypeScript interfaces for

- Entity types
    - Navigation properties
    - Complex properties
- Complex types
- Function imports
    - Importing parameters
    - Return types

🎉 Automatically create TypeScript classes to access the backend

## Installation

Global installation is recommended

```bash
npm i -g @ottogroup/ui5-odata-generator
```

Local installation as a dev dependency is also possible

```bash
npm i -D @ottogroup/ui5-odata-generator
```

## Usage

### Package

Create a local copy of one or more `metadata.xml` files and store them in a `service` folder in your app. This is the tree of a sample UI5 app:

```
src
│   Component.ts
│   index.html
│   manifest.json
├───controller
├───fragment
├───i18n
├───service
|   |
│   ├───sflight
│   │   metadata.xml
│   │
│   └───northwind
│       metadata.xml
│
└───view
```

Then run the following command in the top level directory of your app

```bash
ui5-odata-generator
```

With a local installation do

```bash
npx @ottogroup/ui5-odata-generator
```

or add a script to your package.json

```json
"scripts": {
  ...
  "generate": "ui5-odata-generator"
},
```

and run

```bash
npm generate
```

### Arguments

| arg                       | desc                                                 |
| ------------------------- | ---------------------------------------------------- |
| `--verbose`               | Enable verbose logging                               |
| `--excludeServiceClasses` | Exclude service classes, only generate interfaces    |
| `--decimalAsNumber`       | Convert Edm.Decimal to number instead of string      |
| `--allPropertiesOptional` | Make all properties optional in generated interfaces |
| `--help`                  | Show this help message                               |

### Generated code

You can simply import the interfaces and use them like

```ts
import { Product } from "../service/northwind/NorthwindModelService";

const product: Product = {
    ProductID: 1,
    ProductName: "Cheese cake",
};
```

To read (or create, update, delete) entities and entity sets import the service class, create an instance and use the provided methods

```ts
import NorthwindModelService, { Product } from "../service/northwind/NorthwindModelService";
import ODataError from "../service/ODataError";
...

const service = new NorthwindModelService(this.getModel() as ODataModel);
try {
  const products: Product[] = await service.getProducts(); // type assertion is not necessary, just for documentation
} catch (oError) {
  if (oError instanceof ODataError) {
      oError.messageBox();
  }
}
```

## Limitations

A directory structure is required. The package will (recursively) look for `metadata.xml` files inside of the `src/service/` or `webapp/service/` directory.

Only one `metadata.xml` per directory is supported. If you have multiple OData services put them in different directories.

Only OData V2 is supported.

The first document in your `ui5.yaml` has to contain the property `metadata.name`.

## Changelog

- 2.4
    - new: `--allPropertiesOptional` argument to ignore nullable flag from metadata
- 2.3
    - new: error class `ODataError`
- 2.2
    - fix: Function Import with method POST (only GET was supported)
    - new: `--decimalAsNumber` argument to generate Edm.Decimal as number instead of string
    - new: enhance entity interface to include additional information
        - sap:label
        - key
        - name
        - type
        - nullable
- 2.1
    - fix: use src or webapp folder
    - fix: add ts-nocheck to generated files
    - new: generate code where mutliple entitysets had the same base entity