Skip to content

Incorrect Code Generation for DateTime Arrays Using $ref Definition #185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
GianlucaCesari opened this issue Apr 7, 2025 · 1 comment
Labels
bug Something isn't working

Comments

@GianlucaCesari
Copy link

GianlucaCesari commented Apr 7, 2025

Description of the bug

When using a reusable definition for an array of dates, the Dart code generator interprets the schema as a custom type and incorrectly generates the following code:

disabled: DateTime.listFromJson(json[r'disabled']),

This is generated even when the schema references an array definition meant to represent an array of date strings. The expected generated code should ideally convert a list of date-time formatted strings into DateTime objects similar to:

disabled: (json[r'disabled'] as List<dynamic>)
    .map((e) => DateTime.parse(e as String))
    .toList(),

Steps to Reproduce:

  1. Define the JSON schema for a model with an array property as follows:
    • Create a reusable definition for ArrayOfDates with:
      const arrayOfDates = {
        title: 'ArrayOfDates',
        type: 'array',
        items: { type: 'Date' } // or simply { type: 'string', format: 'date-time' }
      };
  • Reference the reusable definition:
      model.properties.disabled = {
        $ref: '#/definitions/ArrayOfDates',
        default: []
      };
  1. Ensure the schema is used by the generator (via Swagger or similar tooling that feeds into the Dart generator).
  2. Run the code generation process.

Observed Behavior:
The generator outputs conversion code that calls a non-existent static method DateTime.listFromJson and falls back to a generic Iterable cast:

disabled: json[r'disabled'] is Iterable
    ? (json[r'disabled'] as Iterable).cast<String>().toList(growable: false)
    : const [],

This behavior is problematic because it does not parse the strings into DateTime objects as expected.
Expected Behavior:
The generator should interpret the schema correctly, especially when the items are defined as date-time formatted strings, and generate conversion code that transforms each item via DateTime.parse(e as String).
Workarounds Tried:

  1. Changing the item type definition explicitly to a string with a date-time format:
    const arrayOfDates = {
      type: 'array',
      items: { type: 'string', format: 'date-time' }
    };
  1. Adding vendor extensions like x-dart-type with List<DateTime> as its value.

Neither approach resulted in the expected code generation.
Environment:

  • Generator Tool Version: (specify your version, if applicable)
  • Dart version: (specify)
  • Project: FeathersJS/Swagger setup
  • Relevant Schema and Service Code: (as described above)

Additional Context:
This issue affects our ability to rely on the generated code to correctly convert date strings into DateTime objects. If the generator's behavior could be modified—either through improved schema inference, vendor extensions, or customization of templates—it would significantly ease integration for users expecting proper DateTime parsing.
Any guidance or fixes for this scenario would be greatly appreciated!

Steps to reproduce

Steps to Reproduce:

  1. Define the JSON schema for a model with an array property as follows:
    • Create a reusable definition for ArrayOfDates with:
      const arrayOfDates = {
        title: 'ArrayOfDates',
        type: 'array',
        items: { type: 'Date' } // or simply { type: 'string', format: 'date-time' }
      };
  • Reference the reusable definition:
      model.properties.disabled = {
        $ref: '#/definitions/ArrayOfDates',
        default: []
      };
  1. Ensure the schema is used by the generator (via Swagger or similar tooling that feeds into the Dart generator).
  2. Run the code generation process.

Minimal openapi specification

{
  "info": {
    "title": "Test",
    "description": "Test",
    "version": "0.9.0"
  },
  "paths": {
  },
  "schemes": [
    "https",
    "http"
  ],
  "definitions": {
    "ArrayOfDates": {
      "title": "ArrayOfDates",
      "type": "array",
      "items": {
        "type": "string",
        "format": "date-time"
      }
    },
    "vistypes": {
      "title": "vistypes",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "vistype": {
          "type": "number"
        },
        "description": {
          "type": "string"
        },
        "modalDescription": {
          "type": "string"
        },
        "hideOnModal": {
          "type": "boolean"
        },
        "timing": {
          "type": "string"
        },
        "titleDropdownHistory": {
          "type": "string"
        },
        "titleBoxVisurePage": {
          "type": "string"
        },
        "titleDropdownVisurePage": {
          "type": "string"
        },
        "urlExample": {
          "type": "string"
        },
        "isBeta": {
          "type": "boolean"
        },
        "disabled": {
          "$ref": "#/definitions/ArrayOfDates",
          "default": []
        },
        "altVistype": {
          "type": "string"
        },
        "packetType": {
          "type": "string",
          "enum": [
            "indagini",
            "monitoraggio_immobili",
            "monitoraggio_soggetti",
            "scopri_proprietari",
            "crediti_plus",
            "zone",
            "visure_catastali",
            "visure_ipotecarie",
            "visure_camerali",
            "visure_whuis",
            "planimetria_catastale",
            "ape",
            "experian"
          ]
        },
        "useCreditsPlusAbb": {
          "type": "boolean"
        },
        "useCreditsAbb": {
          "type": "boolean"
        },
        "useCreditsPacket": {
          "type": "boolean"
        },
        "calculatePriceCreditsPlus": {
          "type": "boolean"
        },
        "creditsPlusPrice": {
          "type": "number"
        },
        "creditsPrice": {
          "type": "number",
          "default": 1
        },
        "stampaNegativaCreditsPlusPrice": {
          "type": "number"
        },
        "b2cEnabled": {
          "type": "boolean"
        },
        "b2cPrice": {
          "type": "number"
        },
        "category": {
          "type": "string"
        },
        "platform": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "enum": [
            "web",
            "app"
          ],
          "default": []
        },
        "type": {
          "type": "string",
          "enum": [
            "catastale",
            "ipotecaria",
            "camerale",
            "documents"
          ]
        },
        "soggetto": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "default": []
        },
        "priceCreditiPlus": {
          "type": "number"
        },
        "externalPrice": {
          "type": "number"
        },
        "priceEuro": {
          "type": "number"
        },
        "hideVisurePage": {
          "type": "boolean"
        },
        "hideOnCronologiaInAttesa": {
          "type": "boolean"
        },
        "from": {
          "type": "string"
        },
        "titleHeaderSlider": {
          "type": "string"
        },
        "_id": {
          "type": "string",
          "pattern": "^[0-9a-fA-F]{24}$"
        },
        "createdAt": {
          "type": "string",
          "format": "date-time"
        },
        "updatedAt": {
          "type": "string",
          "format": "date-time"
        },
        "__v": {
          "type": "number"
        }
      },
      "required": [
        "name",
        "vistype",
        "isBeta",
        "altVistype",
        "useCreditsPlusAbb",
        "useCreditsAbb",
        "useCreditsPacket",
        "calculatePriceCreditsPlus",
        "creditsPrice",
        "b2cEnabled",
        "category",
        "type"
      ]
    }
  },
  "swagger": "2.0",
  "tags": [],
  "basePath": "/",
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ]
}

Annotation used

@Openapi(
  inputSpec: InputSpec(path: 'lib/engine/swagger/openapi.json'),
  generatorName: Generator.dart,
  outputDirectory: "lib/engine/swagger/generated",
)

Expected behavior

The generator should interpret the schema correctly, especially when the items are defined as date-time formatted strings, and generate conversion code that transforms each item via DateTime.parse(e as String).

The expected generated code should ideally convert a list of date-time formatted strings into DateTime objects similar to:

disabled: (json[r'disabled'] as List<dynamic>)
    .map((e) => DateTime.parse(e as String))
    .toList(),

Logs


Screenshots

No response

Platform

macOS

Library version

5.0.2

Flutter version

3.19.6

Flutter channel

stable

Additional context


@GianlucaCesari GianlucaCesari added the bug Something isn't working label Apr 7, 2025
@GianlucaCesari GianlucaCesari changed the title "ArrayOfDates":{"title":"ArrayOfDates","type":"array","items":{"type":"string","format":"date-time"}} Incorrect Code Generation for DateTime Arrays Using $ref Definition Apr 7, 2025
@quyenlv-unicloud
Copy link

It is known issue of openapi-generator OpenAPITools/openapi-generator#13432
You can wait they fix it or simple use Generator.dio which use built_value with so much more powerful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants