YmlGeneratorConfig constructor

YmlGeneratorConfig(
  1. PubspecConfig pubspecConfig,
  2. String configContent,
  3. String fileName
)

Implementation

YmlGeneratorConfig(
    PubspecConfig pubspecConfig, String configContent, this.fileName) {
  final yamlContent = loadYaml(configContent);
  if (yamlContent == null) return; // Ignore empty file
  yamlContent.forEach((key, value) {
    final String baseDirectory =
        value['base_directory'] ?? pubspecConfig.baseDirectory;
    final String? path = value['path'];
    final String? extendsModel = value['extends'];
    final bool generateForGenerics =
        value['generate_for_generics'] ?? pubspecConfig.generateForGenerics;

    final extraImports =
        value.containsKey('extra_imports') ? <String>[] : null;
    final extraImportsVal = value['extra_imports'];
    extraImportsVal?.forEach((e) {
      if (e != null) {
        extraImports!.add(e.toString());
      }
    });

    final extraAnnotations =
        value.containsKey('extra_annotations') ? <String>[] : null;
    final extraAnnotationsVal = value['extra_annotations'];
    extraAnnotationsVal?.forEach((e) {
      if (e != null) {
        extraAnnotations!.add(e.toString());
      }
    });

    final description = value['description']?.toString();
    final dynamic properties = value['properties'];
    final YamlList? converters = value['converters'];
    final String? type = value['type'];
    if (type == 'custom') {
      models.add(CustomModel(
        name: key,
        path: path,
        baseDirectory: baseDirectory,
        extraImports: extraImports,
        extraAnnotations: extraAnnotations,
      ));
      return;
    } else if (type == 'custom_from_to_json') {
      models.add(CustomFromToJsonModel(
        name: key,
        path: path,
        baseDirectory: baseDirectory,
        extraImports: extraImports,
        extraAnnotations: extraAnnotations,
      ));
      return;
    } else if (type == 'json_converter') {
      models.add(JsonConverterModel(
        name: key,
        path: path,
        baseDirectory: baseDirectory,
        extraImports: extraImports,
        extraAnnotations: extraAnnotations,
      ));
      return;
    }
    if (properties is! YamlMap?) {
      throw Exception(
          'Properties should be a map, right now you are using a ${properties.runtimeType}. model: $key');
    }
    if (type == 'enum') {
      final deprecatedItemType = value['item_type'];
      if (deprecatedItemType != null) {
        throw Exception(
            'item_type is removed, follow the migration to version 7.0.0');
      }

      final deprecatedGenerateMap = value['generate_map'];
      if (deprecatedGenerateMap != null) {
        throw Exception(
            'generate_map is removed, follow the migration to version 7.0.0');
      }

      final uppercaseEnums =
          (value['uppercase_enums'] ?? pubspecConfig.uppercaseEnums) == true;

      final fields = <EnumField>[];
      final enumProperties = <EnumProperty>[];
      properties?.forEach((propertyKey, propertyValue) {
        final bool isJsonvalue;
        final String type;
        final String? defaultValue;
        final ItemType itemType;

        final String name = propertyKey;

        if (propertyValue is YamlMap) {
          final deprecatedValue = propertyValue['value'];
          if (deprecatedValue != null) {
            throw Exception(
                '"value" in model $key on property $name is not longer supported, the way enums are defined has been updated in v7.0.0. Follow the migration');
          }

          if (propertyValue['type'] == null) {
            throw Exception(
                'The required key "Type" is required in model $key on property $name');
          }
          type = propertyValue['type'];
          isJsonvalue = propertyValue['is_json_value'] == true;
          defaultValue = propertyValue['default_value']?.toString();
        } else {
          type = propertyValue;
          isJsonvalue = false;
          defaultValue = null;
        }

        final optional = type.endsWith('?');
        final typeString =
            optional ? type.substring(0, type.length - 1) : type;

        itemType = _parseSimpleType(typeString);

        if (itemType is! StringType &&
            itemType is! DoubleType &&
            itemType is! IntegerType &&
            itemType is! BooleanType) {
          throw Exception(
              '$propertyKey should have a type of integer, boolean, double or string');
        }

        enumProperties.add(EnumProperty(
          name: name,
          type: itemType,
          isJsonvalue: isJsonvalue,
          isOptional: optional,
          defaultValue: defaultValue,
        ));
      });

      final values = value['values'];
      if (values == null) {
        throw Exception('Values can not be null. model: $key');
      }

      ItemType? simpleType;

      values.forEach((key, value) {
        final enumValues = <EnumValue>[];
        String? description;
        if (value is YamlMap) {
          final properties = value['properties'] as YamlMap?;
          description = value['description'];

          properties?.forEach((key, value) {
            enumValues.add(
              EnumValue(
                value: value.toString(),
                propertyName: key,
              ),
            );
          });
        } else if (value != null) {
          final valueType = switch (value.runtimeType) {
            int => IntegerType(),
            double => DoubleType(),
            _ => StringType(),
          };
          if (simpleType == null) {
            simpleType = valueType;
          } else if (simpleType?.name != valueType.name) {
            throw Exception(
                'All values in a simple enum declaration should have the same value type, value ${simpleType?.name} is not ${valueType.name}. enum value: $key');
          }
          enumValues.add(EnumValue(
            value: value.toString(),
            propertyName: 'jsonValue',
          ));
        }

        fields.add(EnumField(
          name: uppercaseEnums ? key.toUpperCase() : CaseUtil(key).camelCase,
          rawName: key,
          values: enumValues,
          description: description,
        ));
      });

      if (simpleType != null) {
        if (enumProperties.isNotEmpty) {
          throw Exception(
              'Simple enum declaration only works if no properties are defined, model: $key');
        }
        enumProperties.add(
          EnumProperty(
            name: 'jsonValue',
            type: simpleType!,
            isOptional: false,
            isJsonvalue: true,
          ),
        );
      }

      final enumModel = EnumModel(
        addJsonValueToProperties: value['use_default_json_value'] ?? true,
        generateExtension: value['generate_extension'] == true,
        name: key,
        path: path,
        baseDirectory: baseDirectory,
        fields: fields,
        properties: enumProperties,
        extraImports: extraImports,
        extraAnnotations: extraAnnotations,
        description: description,
      );

      final error = enumModel.validate();

      if (error != null) {
        throw Exception(error);
      }

      models.add(enumModel);
    } else {
      final staticCreate = (value['static_create'] ?? false) == true;
      final disallowNullForDefaults =
          value.containsKey('disallow_null_for_defaults')
              ? (value['disallow_null_for_defaults'] == true)
              : pubspecConfig.disallowNullForDefaults;
      final fields = <Field>[];
      properties?.forEach((propertyKey, propertyValue) {
        if (propertyValue is YamlMap) {
          fields.add(getField(propertyKey, propertyValue,
              disallowNullForDefaults: disallowNullForDefaults));
        } else if (propertyValue is String) {
          fields.add(getSimpleField(name: propertyKey, value: propertyValue));
        } else {
          throw Exception('$propertyKey should be an object');
        }
      });
      final mappedConverters =
          converters?.map((element) => element.toString()).toList();
      models.add(ObjectModel(
        name: key,
        path: path,
        extendsModel: extendsModel,
        baseDirectory: baseDirectory,
        generateForGenerics: generateForGenerics,
        fields: fields,
        converters: mappedConverters ?? [],
        extraImports: extraImports,
        extraAnnotations: extraAnnotations,
        staticCreate: staticCreate,
        equalsAndHashCode: value['equals_and_hash_code'],
        explicitToJson: value['explicit_to_json'],
        generateToString: value['to_string'],
        description: description,
        disallowNullForDefaults: disallowNullForDefaults,
      ));
    }
  });
}