Migration from v5 to v6

This document contain all the breaking changes and migrations guidelines for adapting your code to the new version.

Upgraded Node to v20

We upgraded required node version from 18 to 20 to stay up to date with relevant environment.

Removed deprecated interpreter option from ProcessorOptions

The deprecated interpreter option has been removed from ProcessorOptions. You should now use the jsonSchema option instead.

Before (v5):

1const result = await generator.generate({
2  processorOptions: {
3    interpreter: {
4      // interpreter options
5    }
6  }
7});

After (v6):

1const result = await generator.generate({
2  processorOptions: {
3    jsonSchema: {
4      // JSON Schema processor options
5    }
6  }
7});

Python

Removal of deprecated importsStyle option

The importsStyle option was deprecated in v4 and has now been completely removed in v6. This option is no longer needed as all Python models now use explicit import style (from . import ${model.name}) to support circular model dependencies.

If you were still using this option in your code, simply remove it from your generator options:

1// Before (v5 and earlier)
2const generator = new PythonGenerator();
3const models = await generator.generateCompleteModels(schema, {
4  importsStyle: 'explicit', // This option is no longer available
5  packageName: 'modelina'
6});
7
8// After (v6)
9const generator = new PythonGenerator();
10const models = await generator.generateCompleteModels(schema, {
11  packageName: 'modelina'
12});

The generated Python code behavior remains unchanged - all imports will continue to use the explicit style.

Typescript

Date formats now generate Date instead of string

In Modelina v5, OpenAPI schema fields with type string and formats such as date-time, date, or time were generated as string in TypeScript models.

Starting from v6, these formats are now mapped to the native Date type.

This is a breaking change and may require updates in consumer code.

What changed

Before (v5):

1sentAt?: string; 

After(v6):

1sentAt?: Date; 

Migration notes

  • Update TypeScript type annotations that previously expected string
  • Ensure any custom serialization or parsing logic handles Date objects
  • Update mocks, tests, and fixtures that rely on string values for date fields

AsyncAPI

Improved schema naming strategy

Modelina v6 introduces a significantly improved naming strategy for AsyncAPI schemas, providing more meaningful and context-aware names for generated models to minimize the amount of Anonymous Schema. If you have explicitly defined names for all models, this should not affect you.

Channel-based naming for inline message payloads

Inline message payloads (without explicit message names) now derive their names from the channel path instead of receiving generic anonymous names.

Before (v5):

1asyncapi: 2.0.0
2channels:
3  /user/signedup:
4    subscribe:
5      message:
6        payload:
7          type: object
8          properties:
9            email:
10              type: string

Generated model: AnonymousSchema_1 or <anonymous-message-1>Payload

After (v6): Generated model: UserSignedupPayload (derived from channel path /user/signedup)

Hierarchical naming for nested schemas

Nested schemas in properties, allOf, oneOf, anyOf, dependencies, and definitions now receive hierarchical names based on their parent schema and property path.

Before (v5):

1components:
2  schemas:
3    MainSchema:
4      type: object
5      properties:
6        config:
7          type: object
8          properties:
9            setting:
10              type: string

Generated models: MainSchema, AnonymousSchema_2, AnonymousSchema_3

After (v6): Generated models: MainSchema, MainSchemaConfig, MainSchemaConfigSetting

Improved handling of composition keywords

Schemas using allOf, oneOf, and anyOf now generate more descriptive names:

Before (v5):

1components:
2  schemas:
3    Pet:
4      oneOf:
5        - type: object
6          properties:
7            bark: { type: boolean }
8        - type: object
9          properties:
10            meow: { type: boolean }

Generated models: Pet, AnonymousSchema_1, AnonymousSchema_2

After (v6): Generated models: Pet, PetOneOfOption0, PetOneOfOption1

Enhanced naming for special schema types

  • Array items: ParentSchemaItem instead of AnonymousSchema_N
  • Pattern properties: ParentSchemaPatternProperty instead of AnonymousSchema_N
  • Additional properties: ParentSchemaAdditionalProperty instead of AnonymousSchema_N
  • Dependencies: ParentSchemaDependencyName instead of AnonymousSchema_N
  • Definitions: ParentSchemaDefinitionName instead of AnonymousSchema_N

Multiple messages in operations now generate individual models

When processing AsyncAPI v3 documents with multiple messages in a single operation, Modelina now correctly generates individual models for each message payload in addition to the oneOf wrapper model.

Example AsyncAPI Document:

1asyncapi: 3.0.0
2info:
3  title: User Service
4  version: 1.0.0
5channels:
6  userEvents:
7    address: user/events
8    messages:
9      UserCreated:
10        $ref: '#/components/messages/UserCreated'
11      UserUpdated:
12        $ref: '#/components/messages/UserUpdated'
13operations:
14  onUserEvents:
15    action: receive
16    channel:
17      $ref: '#/channels/userEvents'
18    messages:
19      - $ref: '#/channels/userEvents/messages/UserCreated'
20      - $ref: '#/channels/userEvents/messages/UserUpdated'
21components:
22  messages:
23    UserCreated:
24      payload:
25        type: object
26        properties:
27          id:
28            type: string
29          name:
30            type: string
31    UserUpdated:
32      payload:
33        type: object
34        properties:
35          id:
36            type: string
37          name:
38            type: string
39          updatedAt:
40            type: string

Before (v5):

1const generator = new JavaGenerator();
2const models = await generator.generate(inputModel);
3// Problem: No UserCreated or UserUpdated classes were generated

After (v6):

1const generator = new JavaGenerator();
2const models = await generator.generate(inputModel);
3// ✓ Now generates:
4//   - UserCreatedPayload.java
5//   - UserUpdatedPayload.java
6//   - userEvents interface (discriminated union)

No code changes are required. This is an enhancement that fixes incomplete model generation. If you have custom post-processing logic that filters generated models, you may need to adjust it to handle the additional models.