public static string GenerateCustomQueryOptions(JToken method, JToken fields, string entityName, string returns, string rootFilePath, string entityGroup, Compilation compilation) { var optionsName = $"{TypeHelpers.GetListOptionsName(entityName, returns)}ListOptions"; var extraQueryParams = method["fields"].Where( q => q["in"].GetStringValue() == "query" && q["_key"].GetStringValue() != "after" && q["_key"].GetStringValue() != "include" && q["_key"].GetStringValue() != "limit" && q["_key"].GetStringValue() != "order" ).ToList(); var customQueryOptions = new ClassContainer(); // namespace customQueryOptions.Namespace = UsingKeys.FOUNDATION; // modifier (just public for now) customQueryOptions.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); // name customQueryOptions.Name = optionsName; // base type customQueryOptions.AddBaseType("BASE_LIST_OPTIONS", "QueryOptions"); customQueryOptions.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON); // interface customQueryOptions.AddBaseType("BASE_LIST_OPTIONS_INTERFACE", $"I{customQueryOptions.Name}"); // doc (just use the name for now) customQueryOptions.DocString = customQueryOptions.Name; // set the filepath root/groupId/Class/Class.cs customQueryOptions.FilePath = $"{rootFilePath}/{entityGroup}/{entityName}/"; customQueryOptions.FileName = $"{customQueryOptions.Name}.cs"; if (extraQueryParams.Count > 0) { extraQueryParams.ForEach(e => { var propContainer = new PropertyWithSummaryContainer { Name = e["_key"].GetStringValue().ToPascal(), PropertyType = "string", }; propContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptions.AddProperty(propContainer.Name, propContainer); }); } var filter = method["x_filter"]; if (filter.Any()) { var filterPropertyContainer = new PropertyWithSummaryContainer { Name = "Filter", PropertyType = "Filter", DocString = "Filter object", }; filterPropertyContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptions.AddUsing(nameof(UsingKeys.FILTERS), UsingKeys.FILTERS); customQueryOptions.AddProperty(filterPropertyContainer.Name, filterPropertyContainer); foreach (var filterValue in filter) { if (filterValue is JProperty filterValueProperty) { var filterValueName = filterValueProperty.Name; var filterType = "string"; var correspondingField = fields.FirstOrDefault(f => f["_key"].GetStringValue() == filterValueName); if (correspondingField != null) { filterType = TypeHelpers.GetPropertyType(correspondingField, customQueryOptions); if (filterType == "DateTime") { customQueryOptions.AddUsing(nameof(UsingKeys.SYSTEM), UsingKeys.SYSTEM); } // add usings for list if (filterType.Contains("List<") || filterType.Contains("Dictionary<")) { customQueryOptions.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS); } } var filterOperators = filterValueProperty.Children().FirstOrDefault(); if (filterOperators != null) { filterOperators.Children().ToList().ForEach(f => { var filterOperator = f.GetStringValue(); string enumerableFilterType = null; if (filterOperator == "in" || filterOperator == "nin") { enumerableFilterType = $"{filterType}[]"; customQueryOptions.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS); } var methodName = $"{filterValueName}{TypeHelpers.MapFilterName(filterOperator)}".ToPascal(); var filterMethodParams = new MethodParameterContainer { Parameters = new List <ParameterContainer>() { new ParameterContainer { Key = "value", ParamType = enumerableFilterType ?? filterType, Required = true, MyModifiers = !string.IsNullOrEmpty(enumerableFilterType) ? new Dictionary <string, SyntaxToken> { { nameof(Modifiers.PARAMS), Modifiers.PARAMS } } : new Dictionary <string, SyntaxToken>(), } } }; var filterMethodContainer = new FilterExtensionMethodContainer { Name = methodName, Returns = optionsName, MethodParams = filterMethodParams, FilterKey = filterValueName, FilterOperator = filterOperator, }; filterMethodContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptions.AddMethod(methodName, filterMethodContainer); }); } } } var customQueryOptionsConstructor = new ListOptionsConstructor { Name = customQueryOptions.Name, }; customQueryOptionsConstructor.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptions.AddConstructor(nameof(customQueryOptionsConstructor), customQueryOptionsConstructor); } compilation.AddClass($"{entityGroup}-{entityName}-{returns}", customQueryOptions); var customQueryOptionsInterface = customQueryOptions.Copy(); // entityRepositoryInterface.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); customQueryOptionsInterface.Name = $"I{optionsName}"; customQueryOptionsInterface.FilePath = $"{rootFilePath}/{entityGroup}/{entityName}/"; customQueryOptionsInterface.FileName = $"I{customQueryOptions.FileName}"; customQueryOptionsInterface.IsInterface = true; customQueryOptionsInterface.BaseTypes.Clear(); customQueryOptionsInterface.AddBaseType("BASE_LIST_OPTIONS_INTERFACE", "IQueryOptions"); compilation.AddClass($"{entityGroup}-{entityName}-{returns}-interface", customQueryOptionsInterface); return(optionsName); }
public static void GenerateEntityClass(JToken entity, string entityPascalName, string rootFilePath, string entityGroup, Compilation compilation) { var entityClass = new ClassContainer(); // namespace entityClass.Namespace = UsingKeys.FOUNDATION; // modifier (just public for now) entityClass.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); // name entityClass.Name = entityPascalName; // base type entityClass.AddBaseType("BASE_ENTITY", "Entity"); entityClass.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON); // add interface entityClass.AddBaseType("Interface", $"I{entityClass.Name}"); // doc (just use the name for now) entityClass.DocString = entityClass.Name; // set the filepath root/groupId/Class/Class.cs entityClass.FilePath = $"{rootFilePath}/{entityGroup}/{entityClass.Name}/"; entityClass.FileName = $"{entityClass.Name}.cs"; // add rename dictionary if any if (entity["field_renames"].Count() > 0) { var renameContainer = new RenameContainer(); foreach (var rename in entity["field_renames"]) { var left = rename["_key"].GetStringValue().ToPascal(); var right = rename["api_fieldname"].GetStringValue(); renameContainer.AddRename(left, right); } entityClass.AddPrivateField("RENAMES", renameContainer); entityClass.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS); } // get properties var properties = entity["fields"].Where(p => p["_key"].GetStringValue() != "id"); foreach (var property in properties) { // extract info from config var name = property["_key"].GetStringValue().ToPascal(); // docstring, fall back to name when no description is provided // TODO restore when multiline comment issue is solved // var docString = property["description"].GetStringValue() ?? property["_key"].GetStringValue(); var docString = property["_key"].GetStringValue(); var isReadOnly = property["readOnly"].GetBoolValue(); // get type var propertyType = TypeHelpers.GetPropertyType(property, entityClass); var customGetter = property["getter_custom_method"] != null; var customSetter = property["setter_custom_method"] != null; var isNullable = isNullableType(propertyType, property); if (customGetter || customSetter) { var overridePropContainer = new PropertyWithCustomGetterAndSetter { Name = name, DocString = docString, PropertyType = propertyType, GetAccessor = customGetter, SetAccessor = customSetter, CustomGetterName = property["getter_custom_method"].GetStringValue().ToPascal(), CustomSetterName = property["setter_custom_method"].GetStringValue().ToPascal(), IsNullable = isNullable, }; // can assume public overridePropContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); entityClass.AddProperty(name, overridePropContainer); // need common for custom functions entityClass.AddUsing(nameof(UsingKeys.SDK_COMMON), UsingKeys.SDK_COMMON); entityClass.AddUsing(nameof(UsingKeys.JSON), UsingKeys.JSON); var backingField = new PrivateFieldContainer { Name = name.PascalToCamel(), FieldType = propertyType, }; backingField.AddModifier(nameof(Modifiers.INTERNAL), Modifiers.INTERNAL); entityClass.AddPrivateField($"{name}_BACKING_FIELD", backingField); } else if (propertyType == "DateTime") { var format = property["format"].GetStringValue(); var propContainer = new DateTimePropertyContainer() { Name = name, DocString = docString, PropertyType = propertyType, IsNullable = isNullable, SetAccessorModifier = isReadOnly ? Modifiers.INTERNAL : Modifiers.PUBLIC, DateFormat = format, }; propContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); entityClass.AddProperty(name, propContainer); entityClass.AddUsing(nameof(UsingKeys.JSON), UsingKeys.JSON); } else { var propContainer = new PropertyWithSummaryContainer() { Name = name, DocString = docString, PropertyType = propertyType, IsNullable = isNullable, SetAccessorModifier = isReadOnly ? Modifiers.INTERNAL : Modifiers.PUBLIC, }; propContainer.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); entityClass.AddProperty(name, propContainer); } // add usings for foreign keys var foreignKey = property["items"] != null ? property["items"]["foreign_key"] : null; if (foreignKey != null) { var foreignKeyName = foreignKey["entity"].GetStringValue().ToPascal(); entityClass.AddUsing("FOREIGN_KEY", UsingKeys.FOUNDATION); } // add usings for date time if (propertyType == "DateTime") { entityClass.AddUsing(nameof(UsingKeys.SYSTEM), UsingKeys.SYSTEM); } // add usings for date time if (propertyType == "Filter") { entityClass.AddUsing(nameof(UsingKeys.FILTERS), UsingKeys.FILTERS); } // add usings for list if (propertyType.Contains("List<") || propertyType.Contains("Dictionary<")) { entityClass.AddUsing(nameof(UsingKeys.GENERIC_COLLECTIONS), UsingKeys.GENERIC_COLLECTIONS); } } compilation.AddClass(entityClass.Name, entityClass); var entityClassInterface = entityClass.Copy(); // entityRepositoryInterface.AddModifier(nameof(Modifiers.PUBLIC), Modifiers.PUBLIC); entityClassInterface.Name = $"I{entityClass.Name}"; entityClassInterface.FilePath = $"{rootFilePath}/{entityGroup}/{entityPascalName}/"; entityClassInterface.FileName = $"I{entityClass.FileName}"; entityClassInterface.BaseTypes.Clear(); entityClassInterface.IsInterface = true; compilation.AddClass(entityClassInterface.Name, entityClassInterface); }