public ActionsGroupNode ReadController(Type type, AssemblyNode assemblyNode)
        {
            var controller = new ActionsGroupNode
            {
                Assembly = assemblyNode
            };

            string routePrefix = null;
            var routePrefixAttribute = type.GetTypeInfo().GetCustomAttribute<RouteAttribute>(false) ?? type.GetTypeInfo().GetCustomAttribute<RouteAttribute>();
            if (routePrefixAttribute != null)
            {
                routePrefix = routePrefixAttribute.Template;
            }

            controller.Name = type.Name.Replace("Controller", string.Empty);
            controller.Name = NameCleaner.Replace(controller.Name, string.Empty);
            controller.Documentation = documentation.GetDocumentation(type);

            foreach (var methodInfo in type.GetMethods().Where(x => x.IsPublic))
            {
                if (methodInfo.GetCustomAttribute<NonActionAttribute>() != null) continue;
                if (methodInfo.IsSpecialName) continue;

                var action = ReadAction(routePrefix, methodInfo, controller);
                if (action != null)
                {
                    controller.Actions.Add(action);
                }
            }
            return controller;
        }
 public AssemblyNode ReadControllers(IEnumerable<Type> controllers)
 {
     var assemblyNode = new AssemblyNode();
     foreach (var controllerType in controllers)
     {
         var controller = ReadController(controllerType, assemblyNode);
         if (controller.Actions.Any())
         {
             assemblyNode.Controllers.Add(controller);
         }
     }
     return assemblyNode;
 }
        public void WriteAssembly(AssemblyNode assemblyNode)
        {
            var controllers = assemblyNode.Controllers.OrderBy(x => x.Name).ToArray();
            foreach (var controllerNode in controllers)
            {
                WriteController(controllerNode);
            }

            WriteViews(assemblyNode);
            if (assemblyNode.Types.Values.Any(x => x.IsObservable))
                WriteKoViews(assemblyNode);

            var output = new StringBuilder();
            foreach (var controllerNode in controllers)
            {
                output.AppendLine($"import * as {StringHelpers.ToCamelCase(controllerNode.Name)}Group from './{StringHelpers.ToCamelCase(controllerNode.Name)}';");
            }
            output.AppendLine("import * as views from './views';");
            output.AppendLine("import * as koViews from './ko-views';");
            output.AppendLine($"import {{ loading }} from '{serviceHelpersModule}';");
            output.AppendLine("export * from './views';");
            output.AppendLine("export * from './ko-views';");
            output.AppendLine($"export {{ loading }} from '{serviceHelpersModule}';");
            output.AppendLine();

            foreach (var controllerNode in controllers)
            {
                var moduleName = StringHelpers.ToCamelCase(controllerNode.Name);
                output.AppendLine($"export const {moduleName} = new {moduleName}Group.{controllerNode.Name}Controller();");
            }

            output.AppendLine("export const services = {");
            
            foreach (var controllerNode in controllers)
            {
                var moduleName = StringHelpers.ToCamelCase(controllerNode.Name);
                output.AppendLine($"{Tab}{moduleName}: {moduleName},");
            }

            output.AppendLine($"{Tab}factories: {{");
            foreach (var type in assemblyNode.Types.Values.Where(x => x.IsObservable))
            {
                output.AppendLine($"{Tab}{Tab}create{StringHelpers.ToPascalCase(type.Name)}: (data: views.{type.CleanName}) => new koViews.{type.Name}(data),");
            }
            output.AppendLine($"{Tab}}},");
            output.AppendLine($"{Tab}loading: loading");
            output.AppendLine("}");
            output.AppendLine();
         
            OutputModules.Add("services", output.ToString());
        }
 public ActionsGroupNode(AssemblyNode assembly, string name) => (Assembly, Name) = (assembly, name);
        private void WriteKoViews(AssemblyNode assemblyNode)
        {
            var result = new StringBuilder();
            result.AppendLine("import * as ko from 'knockout';");
            result.AppendLine("import * as views from './views';");
            result.AppendLine($"import * as validation from '{validationModule}';");
            result.AppendLine($"import {{ loading }} from '{serviceHelpersModule}';");
            result.AppendLine();
            result.AppendLine("function toDate(date:string) {");
            result.AppendLine($"{Tab}return date != undefined ? new Date(date) : undefined;");
            result.AppendLine("}");
            result.AppendLine("function fromDate(date:Date) {");
            result.AppendLine($"{Tab}return date != undefined ? date.toISOString() : undefined;");
            result.AppendLine("}");
            result.AppendLine("function arrayChanged<T>(array: KnockoutObservableArray<T>, original: T[]) {");
            result.AppendLine($"{Tab}return array() && (!original || array().length !== original.length);");
            result.AppendLine("}");
            result.AppendLine("function dateArrayChanged(array: KnockoutObservableArray<Date>, original: string[]) {");
            result.AppendLine($"{Tab}return array() && (!original || array().length !== original.length);");
            result.AppendLine("}");

            foreach (var classNode in assemblyNode.Types.Where(x => x.Value.IsObservable))
            {
                WriteKoTypeDefinition(classNode.Value, result);
            }
            OutputModules.Add("ko-views", result.ToString());
        }
        private void WriteViews(AssemblyNode assemblyNode)
        {
            StringBuilder result = new StringBuilder();

            foreach (var classNode in assemblyNode.Types)
            {
                WriteTypeDefinition(classNode.Value, result, false);
            }

            OutputModules.Add("views", result.ToString());
        }
        private PropertyNode ReadProperty(PropertyInfo propertyInfo, Type[] newParents, AssemblyNode assembly, string version)
        {
            var propertyType = propertyInfo.PropertyType;
            var propertyNode = new PropertyNode
            {
                Name = StringHelpers.ToCamelCase(propertyInfo.Name),
                IsRequired = RemoveNullable(ref propertyType),
                Documentation = documentation.GetDocumentation(propertyInfo)
            };

            var returnTypeAttributes = propertyInfo.GetCustomAttributes<ReturnTypeAttribute>().ToArray();
            if (returnTypeAttributes.Any())
            {
                if (returnTypeAttributes.Length == 1)
                {
                    FillType(propertyNode, returnTypeAttributes[0].ReturnType, assembly, newParents, version);
                }
                else
                {
                    propertyNode.Type = new TypeNode
                    {
                        Type = TypeIdentifier.Union,
                        Union = returnTypeAttributes.Select(x => ReadType(x.ReturnType, assembly, newParents, version)).ToArray()
                    };
                }
            }
            else
            {
                FillType(propertyNode, propertyType, assembly, newParents, version);
            }

            var readOnly = propertyInfo.GetCustomAttribute<ReadOnlyAttribute>();
            if (readOnly != null && readOnly.IsReadOnly)
            {
                propertyNode.IsReadOnly = true;
            }
            var editable = propertyInfo.GetCustomAttribute<EditableAttribute>();
            if (editable != null && !editable.AllowEdit)
            {
                propertyNode.IsReadOnly = true;
            }

            propertyNode.IsObservable = propertyNode.Name != "id" && !propertyNode.IsReadOnly;

            GetConstraints(propertyInfo.GetCustomAttributes().ToArray(), propertyNode);

            return propertyNode;
        }
        public List<PropertyNode> ReadProperties(Type type, Type[] parents, AssemblyNode assembly, string version)
        {
            var newParents = new Type[parents.Length + 1];
            parents.CopyTo(newParents, 0);
            newParents[parents.Length] = type;

            return type.GetProperties()
                .Where(propertyInfo => !IsIgnored(propertyInfo))
                .Select(propertyInfo => ReadProperty(propertyInfo, newParents, assembly, version))
                .ToList();
        }
 private ReturnNode ReadReturn(Type responseType, AssemblyNode assembly, XElement documentationNode, string version)
 {
     var returnNode = new ReturnNode
     {
         Documentation = documentation.ParseDocumentation(documentationNode)
     };
     FillType(returnNode, responseType, assembly, new Type[0], version);
     return returnNode;
 }
Beispiel #10
0
        public TypeNode ReadType(Type parameterType, AssemblyNode assembly, Type[] parents, string version)
        {
            var parameterTypeName = parameterType.Name;

            var classNode = new TypeNode { Version = version };

            classNode.Documentation = documentation.GetDocumentation(parameterType);

            if (parameterType.GetTypeInfo().IsEnum)
            {
                if (assembly.Types.ContainsKey(parameterTypeName))
                {
                    return assembly.Types[parameterTypeName];
                }

                var enumNames = parameterType.GetTypeInfo().GetEnumNames();
                var enumValues = parameterType.GetTypeInfo().GetEnumValues();

                classNode.Name = parameterType.Name;
                classNode.Type = TypeIdentifier.Enum;
                classNode.Values = new List<EnumValueNode>();
                for (var i = 0; i < enumValues.Length; i++)
                {
                    var enumValue = new EnumValueNode
                    {
                        Name = enumNames[i],
                        Value = Convert.ToInt32(enumValues.GetValue(i)),
                        Documentation = documentation.GetDocumentation(parameterType, enumNames[i])
                    };
                    classNode.Values.Add(enumValue);
                }
                assembly.Types[classNode.Name] = classNode;
            }
            else if (parameterType == typeof(string))
            {
                classNode.Type = TypeIdentifier.String;
            }
            else if (parameterType == typeof(long))
            {
                classNode.Type = TypeIdentifier.Long;
            }
            else if (parameterType == typeof(int) || parameterType == typeof(short))
            {
                classNode.Type = TypeIdentifier.Int;
            }
            else if (parameterType == typeof(float))
            {
                classNode.Type = TypeIdentifier.Float;
            }
            else if (parameterType == typeof(double))
            {
                classNode.Type = TypeIdentifier.Double;
            }
            else if (parameterType == typeof(DateTime))
            {
                classNode.Type = TypeIdentifier.DateTime;
            }
            else if (parameterType == typeof(bool))
            {
                classNode.Type = TypeIdentifier.Boolean;
            }
            else if (parameterType == typeof(decimal))
            {
                classNode.Type = TypeIdentifier.Decimal;
            }
            else if (parameterType == typeof(Guid))
            {
                classNode.Type = TypeIdentifier.Guid;
            }
            else if (parameterType == typeof(TimeSpan))
            {
                classNode.Type = TypeIdentifier.TimeSpan;
            }
            else if (parameterType == typeof(object))
            {
                classNode.Type = TypeIdentifier.Any;
            }
            else
            {
                if (assembly.Types.ContainsKey(parameterTypeName))
                {
                    return assembly.Types[parameterTypeName];
                }

                classNode.IsReadOnly = true;
                classNode.Name = parameterType.Name;
                classNode.Type = TypeIdentifier.Object;

                assembly.Types[classNode.Name] = classNode;

                if (parents.All(x => x != parameterType))
                {
                    classNode.Properties = ReadProperties(parameterType, parents, assembly, version);
                }

                var jsonAttribute = parameterType.GetTypeInfo().GetCustomAttribute<JsonAttribute>();
                if (jsonAttribute != null)
                {
                    classNode.IsObservable = jsonAttribute.Observable;
                }
            }


            return classNode;
        }
Beispiel #11
0
        private void FillType(ITypedNode typedNode, Type parameterType, AssemblyNode assembly, Type[] parents, string version)
        {
            if (Nullable.GetUnderlyingType(parameterType) == null && parameterType.GetTypeInfo().IsGenericType)
            {
                if (parameterType.ImplementsInterface(typeof(IDictionary<,>)))
                {
                    typedNode.IsDictionary = true;
                    parameterType = parameterType.GenericTypeArguments[1];
                }
                else if (parameterType.ImplementsInterface(typeof(IEnumerable<>)))
                {
                    typedNode.IsCollection = true;
                    parameterType = parameterType.GenericTypeArguments[0];
                }
            }

            if (parameterType.IsArray)
            {
                typedNode.IsCollection = true;
                parameterType = parameterType.GetElementType();
            }

            typedNode.Type = ReadType(parameterType, assembly, parents, version);
        }
Beispiel #12
0
        public ParameterNode ReadParameter(ParameterInfo parameterInfo, XElement documentationNode, AssemblyNode assembly, Dictionary<string, bool> routeParameters, string version)
        {
            var parameterNode = new ParameterNode { Name = parameterInfo.Name };
            var parameterType = parameterInfo.ParameterType;
            parameterNode.Documentation = documentation.ParseDocumentation(documentationNode);
            parameterNode.IsRequired = RemoveNullable(ref parameterType);
            if (parameterInfo.DefaultValue != null)
                parameterNode.IsRequired = false;
            FillType(parameterNode, parameterType, assembly, new Type[0], version);

            if (routeParameters.ContainsKey(parameterInfo.Name))
            {
                parameterNode.Position = ParameterPosition.Path;
                parameterNode.IsRequired = !routeParameters[parameterInfo.Name];
            }
            else if (parameterInfo.GetCustomAttribute<FromQueryAttribute>() != null)
            {
                parameterNode.Position = ParameterPosition.Query;
            }
            else if (parameterInfo.GetCustomAttribute<FromBodyAttribute>() != null || parameterNode.Type.Type == TypeIdentifier.Object)
            {
                parameterNode.Position = ParameterPosition.Body;
                parameterNode.IsRequired = true;
            }
            else
            {
                parameterNode.Position = ParameterPosition.Query;
            }


            GetConstraints(parameterInfo.GetCustomAttributes().ToArray(), parameterNode);

            return parameterNode;
        }