npm package: @neoimpulse/cap-js-restore-model-defined-types
Description: A CDS plugin to restore model-defined types for numeric and structured data
Author: Neoimpulse GmbH
Latest version: 1.0.0

# CAP.js Restore Model Defined Types Plugin

This plugin for the SAP Cloud Application Programming Model (CAP) automatically restores model-defined types for numeric and structured data in READ operations. It ensures that data returned from the database matches the types defined in your CDS model.

## Features

- Automatically converts string representations of numbers back to their proper types (`cds.Decimal` → `float`, `cds.Integer` → `int`)
- Handles nested structures including Associations and Compositions
- Processes structured types (`cds.Structured`) recursively
- Works with both single entities and arrays of entities
- Applies to all READ operations automatically

## Installation

To install the plugin, add it to your CAP project:

```sh
npm install @neoimpulse/cap-js-restore-model-defined-types
```

## Usage

The plugin works automatically once installed, but you can configure which entities should be processed.

### Basic Usage (All Entities)

By default, the plugin processes all entities. No additional configuration required.

### Configuration Options

You can configure the plugin in your `package.json` or `.cdsrc.json`:

```json
{
  "cds": {
    "requires": {
      "cap-js-restore-model-defined-types": {
        "enabled": true,
        "entities": "*",
        "exclude": [],
        "annotation": "@restoreTypes"
      }
    }
  }
}
```

#### Configuration Properties

- **`enabled`** (boolean, default: `true`): Enable or disable the plugin
- **`entities`** (string|array, default: `"*"`): Which entities to process
  - `"*"`: Process all entities
  - `["EntityA", "EntityB"]`: Process specific entities by name
  - `"Book*"`: Process entities matching pattern (supports glob-like patterns)
  - `"annotation"`: Only process entities with the specified annotation
- **`exclude`** (array, default: `[]`): Entity names to explicitly exclude
- **`annotation`** (string, default: `"@restoreTypes"`): Custom annotation to enable per entity

### Configuration Examples

#### 1. Process All Entities (Default)
```json
{
  "cds": {
    "requires": {
      "cap-js-restore-model-defined-types": {}
    }
  }
}
```

#### 2. Process Specific Entities
```json
{
  "cds": {
    "requires": {
      "cap-js-restore-model-defined-types": {
        "entities": ["Books", "Authors", "Orders"]
      }
    }
  }
}
```

#### 3. Process Entities with Pattern
```json
{
  "cds": {
    "requires": {
      "cap-js-restore-model-defined-types": {
        "entities": "my.bookshop.*"
      }
    }
  }
}
```

#### 4. Use Annotation-Based Configuration
```json
{
  "cds": {
    "requires": {
      "cap-js-restore-model-defined-types": {
        "entities": "annotation"
      }
    }
  }
}
```

Then annotate your entities:
```cds
namespace my.bookshop;

entity Books @restoreTypes {
    key ID : Integer;
    title : String;
    price : Decimal(10,2);
    pages : Integer;
}

entity Authors {
    key ID : Integer;
    name : String;
    // This entity will NOT be processed
}
```

#### 5. Exclude Specific Entities
```json
{
  "cds": {
    "requires": {
      "cap-js-restore-model-defined-types": {
        "entities": "*",
        "exclude": ["TechnicalEntity", "LogEntry"]
      }
    }
  }
}
```

### Example Model

```cds
namespace my.bookshop;

entity Books {
    key ID : Integer;
    title : String;
    price : Decimal(10,2);
    pages : Integer;
    author : Association to Authors;
}

entity Authors {
    key ID : Integer;
    name : String;
    age : Integer;
    books : Composition of many Books on books.author = $self;
}
```

### What It Does

When you perform READ operations, the plugin ensures that:

- `price` values are returned as proper floating-point numbers (not strings)
- `pages` and `age` values are returned as integers (not strings)
- Associated and composed entities are processed recursively
- Structured types maintain their proper data types

## How It Works

The plugin hooks into all READ operations and processes the results to restore the correct data types based on your CDS model definitions. It:

1. Scans each attribute in the returned data
2. Checks the corresponding CDS model definition
3. Converts string representations back to proper numeric types
4. Recursively processes nested structures (Associations, Compositions, Structured types)

The conversion happens automatically for:

- **cds.Decimal**: String values are converted to floating-point numbers using `parseFloat()`
- **cds.Integer**: String values are converted to integers using `parseInt()`
- **cds.Association**: Nested associated entities are processed recursively
- **cds.Composition**: Nested composed entities are processed recursively  
- **cds.Structured**: Structured types are processed recursively

## Technical Details

The plugin adds a `restoreModelDefinedTypes` method to each Application Service and hooks it into the `after READ` event handler. This ensures that all data returned from READ operations has the correct types according to your CDS model.

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

If you encounter any issues or have questions, please open an issue in the GitHub repository.```

## License

This project is licensed under the Apache License 2.0. See the [LICENSE](./LICENSE) file for more details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Acknowledgments

Thanks to the SAP CAP community for their support and contributions.