dotansimha / graphql-code-generator-community

MIT License
118 stars 155 forks source link

escapeDartKeywords parameter is ignored #439

Open astubenbord opened 1 year ago

astubenbord commented 1 year ago

Which packages are impacted by your issue?

@graphql-codegen/flutter-freezed

Describe the bug

My graphql schema contains meta-data fields, which are prefixed with an '_' (underscore). At the same time, I also have definitions of the same fields as "public" fields, which are not automatically generated, but have the same name as these metadata fields without the underscore prefix. Example:

type MyTypeWithDuplicateUnderscoreFields {
    field1: String
    _field1: String
}

In the generated app_models.dart file, the freezed factory constructor is created with the same field name field1 twice, causing an error.

Your Example Website or App

None

Steps to Reproduce the Bug or Issue

  1. Create new empty flutter project
  2. Add required dependencies (freezed, freezed_annotation, json_annotation, build_runner)
  3. Run npm init -y
  4. Install graphql-codegen and graphql-codegen-flutter
  5. Add codegen.ts configuration
  6. Add schema to root of project
  7. Run npm run generate as defined in User Guide

Expected behavior

Given the documentation of the escapeDartKeywords property used in the provided codegen.ts file, I expect the generator to create a class with the two properties $field1 and field1.

The resulting app_models.dart should contain the following code:

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';

part 'app_models.freezed.dart';
part 'app_models.g.dart';

@freezed
class MyTypeWithUnderscoreProperties with _$MyTypeWithUnderscoreProperties {
  const MyTypeWithUnderscoreProperties._();

  const factory MyTypeWithUnderscoreProperties({
    @JsonKey(name: '_field1')
    double? $field1, // Change here!
    double? field1,
  }) = _MyTypeWithUnderscoreProperties;

  factory MyTypeWithUnderscoreProperties.fromJson(Map<String, dynamic> json) => _$MyTypeWithUnderscorePropertiesFromJson(json);
}

However, the produced code looks as follows:

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';

part 'app_models.freezed.dart';
part 'app_models.g.dart';

@freezed
class MyTypeWithUnderscoreProperties with _$MyTypeWithUnderscoreProperties {
  const MyTypeWithUnderscoreProperties._();

  const factory MyTypeWithUnderscoreProperties({
    @JsonKey(name: '_field1')
    double? field1,
    double? field1, // Error
  }) = _MyTypeWithUnderscoreProperties;

  factory MyTypeWithUnderscoreProperties.fromJson(Map<String, dynamic> json) => _$MyTypeWithUnderscorePropertiesFromJson(json);
}

Screenshots or Videos

No response

Platform

Codegen Config File

import type { CodegenConfig } from '@graphql-codegen/cli'
import { FieldNamePattern } from '@graphql-codegen/flutter-freezed';

const config: CodegenConfig = {
    generates: {
        'lib/data/models/app_models.dart': {
            schema: 'my-schema.graphql',
            plugins: {
                'flutter-freezed': {
                    escapeDartKeywords: [
                        [
                            FieldNamePattern.forAllFieldNamesOfAllTypeNames(),
                            '$',
                            undefined,
                            undefined
                        ],
                    ],
                }
            }
        }
    }
}
export default config

Additional context

No response

Parables commented 10 months ago

The escapeDartKeywords only specifies how these Dart keywords defined here should be escaped.

Parables commented 10 months ago

How did you handle this issue? Did you manually change the generated file?

I am willing to assist you address this issue. Do forgive me for the late reply... If I was mentioned on when this issue when it was posted, I would have resolved it as soon as possible

astubenbord commented 10 months ago

Hi, I could not resolve the issue using this package, therefore I am now using https://github.com/heftapp/graphql_codegen. It also had some issues with escaping keywords prefixed with underscores in some very specific cases but I could resolve it through an easy fix in a PR. I'm also not that familiar with the typescript/npm ecosystem, so using a pure flutter/dart system was more suited for my specific use-case. However, since this package is the more or less "official" way to synchronize the client and server side schema, I'll have an eye on it in the future! I didn't know I had to tag any contributors.

Manually changing the generated files would not have been a viable option in our case since we have to update the schema every now and then, which would introduce lots of overhead or additional scripts to fix these in the generated dart files. Overall I think the way it is solved in graphql_codegen is a good compromise, where every property starting with an underscore is prefixed with the defined escape character (like $) to avoid fields being unintentionally marked as private. I'm not sure how often GraphQL properties start with an underscore, but some content management systems (like the one we use) automatically generate metadata keys with are prefixed with an underscore.

Parables commented 9 months ago

I'm glad you found a solution to you issue.

Before your issue, I had plans to add a feature that will allow you to rename the types and fields in the generated output. This would have worked like this "if you see this field in the Type, then use this name instead and use it original name as the JsonKey in the generated output"...

This would have offered much flexibility to rename fields and types in the generated models.

But I doubt there would be a use-case for it so I didn't proceed with that feature.

Since you have found a solution you are comfortable with, I guess I wouldn't be working on this feature anytime soon until someone else has a need for it.