public void GenerateTypeScriptByClientInterface()
        {
            var assembly = Assembly.Load("Common");
            var models   = assembly.GetTypes();

            var generator = new TypeScriptFluent()
                            .WithConvertor <Guid>(c => "string");

            foreach (var model in models)
            {
                if (model.FullName.Contains("Rb.Services.Protocol"))
                {
                    generator.ModelBuilder.Add(model);
                }
            }

            var targetPath = Path.Combine(TS_DATA_TYPE_PATH, "types");

            var tsEnumDefinitions = generator.Generate(TsGeneratorOutput.Enums);

            var tsClassDefinitions = generator.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields);

            WriteFileToJsonFolder(targetPath, TS_DEFINEDATA_TYPE_PATH, tsClassDefinitions);
            WriteFileToJsonFolder(targetPath, TS_ENUMDATA_TYPE_PATH, tsEnumDefinitions);
        }
        private static void GenerateTypeScriptContracts(Options options)
        {
            var generator = new TypeScriptFluent()
                            .WithConvertor <Guid>(c => "string");

            foreach (var assemblyName in options.Assemblies)
            {
                var fi = new FileInfo(assemblyName);
                // Load all input assemblies from the same location to ensure duplicates aren't generated (as the same type loaded from
                // two different places will appear to be diffent, so both would otherwise be generated).
                var assembly = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, workingPath, fi.Name));
                Console.WriteLine("Loaded assembly: " + assemblyName);

                // Get the WebAPI controllers...
                var controllers = assembly.GetTypes().Where(t => typeof(ApiController).IsAssignableFrom(t));

                // Get the return types...
                var actions = controllers
                              .SelectMany(c => c.GetMethods()
                                          .Where(m => m.IsPublic)
                                          .Where(m => m.DeclaringType == c));
                ProcessMethods(actions, generator);

                var signalrHubs = assembly.GetTypes().Where(t => t.GetInterfaces().ToList().Exists(i => i.FullName != null && i.FullName.Contains(SignalRGenerator.IHUB_TYPE)));
                var methods     = signalrHubs
                                  .SelectMany(h => h.GetMethods()
                                              .Where(m => m.IsPublic)
                                              .Where(m => m.GetBaseDefinition().DeclaringType == h));
                ProcessMethods(methods, generator);

                var clientInterfaceTypes = signalrHubs.Where(t => t.BaseType.IsGenericType)
                                           .Select(t => t.BaseType.GetGenericArguments()[0]);
                var clientMethods = clientInterfaceTypes
                                    .SelectMany(h => h.GetMethods()
                                                .Where(m => m.IsPublic)
                                                .Where(m => m.DeclaringType == h));
                ProcessMethods(clientMethods, generator);

                // Add all classes that are declared inside the specified namespace
                if (options.Namespaces != null && options.Namespaces.Any())
                {
                    var types = assembly.GetTypes()
                                .Where(t => IncludedNamespace(options, t));
                    ProcessTypes(types, generator);
                }

                generator.AsConstEnums(false);
            }

            var tsEnumDefinitions = generator.Generate(TsGeneratorOutput.Enums);

            File.WriteAllText(Path.Combine(options.OutputFilePath, "enums.ts"), tsEnumDefinitions);

            //Generate interface definitions for all classes
            var tsClassDefinitions = generator.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields);

            File.WriteAllText(Path.Combine(options.OutputFilePath, "classes.d.ts"), tsClassDefinitions);
        }
        private static void ProcessMethods(IEnumerable <MethodInfo> methods, TypeScriptFluent generator)
        {
            var returnTypes = methods.Select(m => m.ReturnType);

            ProcessTypes(returnTypes, generator);
            var inputTypes = methods.SelectMany(m => m.GetParameters()).Select(p => p.ParameterType);

            ProcessTypes(inputTypes, generator);
        }
        /// <summary>
        /// Adds all classes annotated with the TsClassAttribute from all curently loaded assemblies.
        /// </summary>
        /// <returns>Instance of the TypeScriptFluent that enables fluent configuration.</returns>
        public static TypeScriptFluent ForLoadedAssemblies(this TypeScriptFluent ts)
        {
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                ts.ModelBuilder.Add(assembly);
            }

            return(ts);
        }
示例#5
0
        private static void ProcessTypes(IEnumerable <Type> types, TypeScriptFluent generator)
        {
            foreach (var clrType in types.Where(t => t != typeof(void)))
            {
                var clrTypeToUse = clrType;
                if (typeof(Task).IsAssignableFrom(clrTypeToUse))
                {
                    if (clrTypeToUse.IsGenericType)
                    {
                        clrTypeToUse = clrTypeToUse.GetGenericArguments()[0];
                    }
                    else
                    {
                        continue;  // Ignore non-generic Task as we can't know what type it will really be
                    }
                }
                if (clrTypeToUse.FullName?.StartsWith("Microsoft.AspNetCore.Mvc.ActionResult`1") == true)
                {
                    clrTypeToUse = clrType.GetGenericArguments().First();
                }
                if (clrTypeToUse.IsNullable())
                {
                    clrTypeToUse = clrTypeToUse.GetUnderlyingNullableType();
                }
                // Ignore compiler generated types
                if (Attribute.GetCustomAttribute(clrTypeToUse, typeof(CompilerGeneratedAttribute)) != null)
                {
                    continue;
                }

                Console.WriteLine("Processing Type: " + clrTypeToUse);
                if (clrTypeToUse == typeof(string) || clrTypeToUse.IsPrimitive || clrTypeToUse == typeof(object) || clrTypeToUse == typeof(DateTime))
                {
                    continue;
                }

                if (clrTypeToUse.IsArray)
                {
                    ProcessTypes(new[] { clrTypeToUse.GetElementType() }, generator);
                }
                else if (clrTypeToUse.IsGenericType)
                {
                    ProcessTypes(clrTypeToUse.GetGenericArguments(), generator);
                    bool isEnumerable = typeof(IEnumerable).IsAssignableFrom(clrTypeToUse);
                    if (!isEnumerable)
                    {
                        generator.ModelBuilder.Add(clrTypeToUse);
                    }
                }
                else if (!typeof(IEnumerable).IsAssignableFrom(clrTypeToUse))
                {
                    generator.ModelBuilder.Add(clrTypeToUse);
                }
            }
        }
示例#6
0
        public string Build(GapApiGeneratorOptions options = null)
        {
            var services       = new StringWriter();
            var servicesWriter = new CustomIndentedTextWriter(services, _indent);

            var enums       = new StringWriter();
            var enumsWriter = new CustomIndentedTextWriter(enums, _indent);

            var globals       = new StringWriter();
            var globalsWriter = new CustomIndentedTextWriter(globals, _indent);

            var definitions       = new StringWriter();
            var definitionsWriter = new CustomIndentedTextWriter(definitions, _indent);

            TypeScriptFluent fluent = new TypeScriptFluent();

            fluent.WithConvertor <Guid>(c => "string");
            fluent.WithIndentation(_indent);
            fluent.WithModelVisitor(_modelVisitor);

            var converter = new TypeConverter(_namespace, fluent);

            fluent.WithDictionaryMemberFormatter(converter);

            if (!string.IsNullOrEmpty(_namespace))
            {
                fluent.WithModuleNameFormatter(m => _namespace);
            }

            ProcessTypes(_general, fluent);
            fluent.ModelBuilder.Build(); // this is to fix up manually added types before GapApiGenerator

            var apiGen = new GapApiGenerator(converter, _indent, options ?? new GapApiGeneratorOptions());

            apiGen.WriteServices(_apis.ToArray(), servicesWriter);

            var signalr = new SignalRGenerator();

            signalr.WriteHubs(_hubs.ToArray(), converter, servicesWriter);

            var tsClassDefinitions = fluent.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields);

            definitionsWriter.Write(tsClassDefinitions);

            _enumGenerator.WriteEnums(enumsWriter, globalsWriter, definitionsWriter, fluent.ModelBuilder.Build().Enums, converter);

            string prepended = _generateNotice ? Resx.GeneratedNotice + "\r\n\r\n" : "";

            prepended +=
                services.GetStringBuilder() + Environment.NewLine +
                "declare global {" +
                (definitions.GetStringBuilder().ToString() + enums.GetStringBuilder()).Replace("declare namespace", "namespace").Replace("\n", "\n    ").TrimEnd() + Environment.NewLine +
                "}" + Environment.NewLine + globals.GetStringBuilder();
            return(prepended);
        }
示例#7
0
        private static TypeScriptFluent SetupDefinitions(IEnumerable <Type> modelElements)
        {
            var definitions = new TypeScriptFluent();

            foreach (Type modelElement in modelElements)
            {
                definitions.For(modelElement).ToModule(String.Empty);
            }
            return(definitions.WithMemberFormatter((identifier) =>
                                                   Char.ToLower(identifier.Name[0]) + identifier.Name.Substring(1)
                                                   ));
        }
示例#8
0
        public static TypeScriptFluent RegisterTypeConvertor(this TypeScriptFluent fluent, Type a, TypeConvertor b)
        {
            var sg    = fluent.ScriptGenerator;
            var flags = BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance;
            var typeConvertorsField = typeof(TsGenerator).GetField("_typeConvertors", flags);
            var typeConvertors      = (TypeConvertorCollection)typeConvertorsField?.GetValue(sg);

            var convertorsField = typeof(TypeConvertorCollection).GetField("_convertors", flags);
            var convertors      = (Dictionary <Type, TypeConvertor>)convertorsField?.GetValue(typeConvertors);

            convertors?.Add(a, b);

            return(fluent);
        }
        /// <summary>
        /// Adds all Types derived from T
        /// </summary>
        /// <returns>Instance of the TypeScriptFluent that enables fluent configuration.</returns>
        public static TypeScriptFluent TypesDervivedFrom <T>(this TypeScriptFluent ts, bool includeBaseType = true)
        {
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (var type in assembly.GetTypes().Where(x => typeof(T).IsAssignableFrom(x)))
                {
                    if (includeBaseType || type != typeof(T))
                    {
                        ts.ModelBuilder.Add(type);
                    }
                }
            }

            return(ts);
        }
示例#10
0
        public ClientTypesExporter(CsharpTypeInfoProvider typeInfoProvider, ClientTypescriptGenerator scriptGenerator)
        {
            _scriptGenerator = scriptGenerator;
            var d = TypeScript.Definitions(scriptGenerator)
                    .WithTypeFormatter(FormatType)
                    .WithMemberFormatter(FormatMember)
                    .WithMemberTypeFormatter(FormatMemberType)
                    .WithVisibility((@class, name) => false)
                    .AsConstEnums(false)
                    .For <DateInterval>()
                    .For <AnalyzerBase>()
                    .WithModuleNameFormatter(module => string.Empty);

            _definitions = typeInfoProvider.ExposedTypes.Aggregate(d, (def, t) => def.For(t));
        }
        /// <summary>
        /// Adds all classes annotated with the TsClassAttribute from the referenced assembly identified by the name parameter.
        /// </summary>
        /// <param name="name">
        /// The name of the assembly to scan
        /// </param>
        /// <returns>Instance of the TypeScriptFluent that enables fluent configuration.</returns>
        public static TypeScriptFluent ForReferencedAssembly(this TypeScriptFluent ts, string name)
        {
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (var obj in assembly.GetReferencedAssemblies())
                {
                    if (obj.Name == name)
                    {
                        var assembly2 = Assembly.Load(obj);
                        if (assembly2 != null)
                        {
                            ts.ModelBuilder.Add(assembly2);
                        }
                    }
                }
            }

            return(ts);
        }
        public string Write(string moduleName)
        {
            TsGenerator generator = new TsJamesModelGenerator();
            var ts = new TypeScriptFluent(generator);
            ts.WithTypeFormatter((type, formatter) =>
                    {
                        var tsClass = ((TsClass)type);
                        if (!tsClass.GenericArguments.Any()) return "I"+tsClass.Name;
                        return "I"+tsClass.Name + "<" + string.Join(
                            ", ", 
                            tsClass.GenericArguments.Select(a => 
                                a as TsCollection != null ?
                                generator.GetFullyQualifiedTypeName(a) + "[]" :
                                generator.GetFullyQualifiedTypeName(a))
                            ) + ">";
                    });
            ts.WithMemberFormatter((identifier) => TextUtils.CamelCase(identifier.Name));
            // custom module wrapping!
            ts.WithModuleNameFormatter(module => string.Empty);
            ts.WithConvertor<Guid>(g => "string");
            generator.SetTypeVisibilityFormatter((@class, name) => true);   // export
            generator.IndentationString = "    ";

            foreach (var knownType in _knownTypes)
            {
                if ((knownType.IsClass && knownType.Namespace != "System" && !knownType.IsGenericType) || knownType.IsEnum )
                {
                    ts.For(knownType);
                }
            }

            var tsModule = ts.Generate();
            var controller = _sb.ToString();

            return string.Format("module {0}{{{1}{2}}}",
                moduleName,
                tsModule,
                controller
                );
        }
示例#13
0
        public void GenerateTypeScriptContracts()
        {
            var generator = new TypeScriptFluent()
                            .WithConvertor <Guid>(c => "string");

            // if (_options.SupportMomentJs)
            //     generator = generator.WithConvertor<DateTime>(c => "Date | Moment");

            generator.WithMemberFormatter(i =>
            {
                var identifier = i.Name;
                if (_options.CamelCase)
                {
                    identifier = Char.ToLower(identifier[0]) + identifier.Substring(1);
                }
                if (_options.GenerateServiceStackRequests)
                {
                    if (!_ssHelper.IsPropertyRequired(i.MemberInfo))
                    {
                        identifier += "?";
                    }
                }
                return(identifier);
            });

            foreach (var assemblyName in _options.Assemblies)
            {
                var fi = new FileInfo(assemblyName);
                // Load all input assemblies from the same location to ensure duplicates aren't generated (as the same type loaded from
                // two different places will appear to be different, so both would otherwise be generated).
                var assembly = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, workingPath, fi.Name));
                Console.WriteLine("Loaded assembly: " + assemblyName);

                GenerateContractsForWebApiRequestResponseClasses(assembly, generator);

                if (_options.GenerateServiceStackRequests)
                {
                    GenerateContractsForServiceStackRequestResponseClasses(assembly, generator);
                }

                // Add all classes that are declared inside the specified namespace
                if (_options.Namespaces != null && _options.Namespaces.Any())
                {
                    var types = assembly.GetTypes()
                                .Where(t => IncludedNamespace(_options, t));
                    ProcessTypes(types, generator);
                }

                generator.AsConstEnums(false);
            }

            var tsEnumDefinitions = generator.Generate(TsGeneratorOutput.Enums);

            if (_options.GenerateAsModules)
            {
                tsEnumDefinitions = tsEnumDefinitions.Replace("module ", "export module ");
            }
            if (!string.IsNullOrWhiteSpace(_options.WrapEnumsInModule))
            {
                tsEnumDefinitions = (_options.GenerateAsModules ? "export " : "") + "module " + _options.WrapEnumsInModule + " {\r\n" + tsEnumDefinitions + "\r\n}";
            }
            if (_options.UseStringEnums)
            {
                tsEnumDefinitions = Regex.Replace(tsEnumDefinitions, "\\b([a-zA-Z]*) = ([\\d]+)", "$1 = \"$1\"");
            }
            File.WriteAllText(Path.Combine(_options.OutputFilePath, "enums.ts"), tsEnumDefinitions);


            if (_options.GenerateAsModules)
            {
                //Generate interface definitions for all classes
                generator.WithMemberTypeFormatter((p, n) =>
                {
                    var asCollection = p.PropertyType as TsCollection;
                    var isCollection = asCollection != null;

                    if (isCollection)
                    {
                        var genericArguments = asCollection.ItemsType.Type.GetGenericArguments();
                        foreach (var arg in genericArguments)
                        {
                            // Really horrible hack... prefix enum generic parameters with 'Enum.'.  Makes things like Dictionary<string, AnEnum> work.
                            if (arg.IsEnum)
                            {
                                Console.WriteLine("***Replacing " + arg.FullName);
                                n = n.Replace(arg.FullName, "__Enums." + arg.FullName);
                            }
                        }

                        return((asCollection.ItemsType is TsEnum ? "__Enums." + n : n) + string.Concat(Enumerable.Repeat("[]", asCollection.Dimension)));
                    }
                    return(p.PropertyType is TsEnum ? "__Enums." + n : n);
                });
                var tsGeneratedCode    = generator.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields);
                var tsClassDefinitions = !string.IsNullOrWhiteSpace(_options.WrapEnumsInModule) ? "import {" + _options.WrapEnumsInModule + "  as __Enums} from \"./enums\";\r\n\r\n" : "import * as __Enums from \"./enums\";\r\n\r\n";
                if (_options.SupportMomentJs)
                {
                    tsClassDefinitions += "import {Moment} from \"moment\";\r\n";
                }
                if (!string.IsNullOrWhiteSpace(_options.WrapClassesInModule))
                {
                    tsClassDefinitions += "export module " + _options.WrapClassesInModule + " {\r\n";
                }
                tsClassDefinitions += tsGeneratedCode;
                if (!string.IsNullOrWhiteSpace(_options.WrapClassesInModule))
                {
                    tsClassDefinitions += "}";
                }
                tsClassDefinitions = tsClassDefinitions.Replace("declare module", "export module");
                tsClassDefinitions = tsClassDefinitions.Replace("interface", "export interface");
                tsClassDefinitions = Regex.Replace(tsClassDefinitions, @":\s*System\.Collections\.Generic\.KeyValuePair\<(?<k>[^\,]+),(?<v>[^\,]+)\>\[\];",
                                                   m => ": {[key: string]: " + m.Groups["v"].Value + "};",
                                                   RegexOptions.Multiline);
                File.WriteAllText(Path.Combine(_options.OutputFilePath, "classes.ts"), tsClassDefinitions);
            }
            else
            {
                var tsClassDefinitions = generator.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields);
                tsClassDefinitions = Regex.Replace(tsClassDefinitions, @":\s*System\.Collections\.Generic\.KeyValuePair\<(?<k>[^\,]+),(?<v>[^\,]+)\>\[\];",
                                                   m => ": {[key: string]: " + m.Groups["v"].Value + "};",
                                                   RegexOptions.Multiline);
                File.WriteAllText(Path.Combine(_options.OutputFilePath, "classes.d.ts"), tsClassDefinitions);
            }
        }
示例#14
0
 public static TypeScriptFluent WithDictionaryMemberFormatter(this TypeScriptFluent typeScriptFluent, TypeConverter conv)
 {
     typeScriptFluent.ScriptGenerator.RegisterDictionaryMemberFormatter(conv);
     return(typeScriptFluent);
 }
示例#15
0
 public TypeConverter(string globalNamespace, TypeScriptFluent fluent)
 {
     _globalNamespace = globalNamespace;
     _fluent          = fluent;
 }
示例#16
0
        private void GenerateContractsForServiceStackRequestResponseClasses(Assembly assembly, TypeScriptFluent generator)
        {
            var requests = GetServiceStackRequestTypes(assembly);

            // Any requests that specify their return type, also generate them...
            var responseTypes = new List <Type>();

            requests.ForEach(req =>
            {
                var type = _ssHelper.GetResponseTypeForRequest(req);
                if (type != null)
                {
                    responseTypes.Add(type);
                }
            });

            ProcessTypes(requests, generator);
            ProcessTypes(responseTypes, generator);
        }
        public void GenerateTypeScriptContracts()
        {
            var generator = new TypeScriptFluent()
                            .WithConvertor <Guid>(c => "string");

            if (_options.CamelCase)
            {
                generator.WithMemberFormatter(i => Char.ToLower(i.Name[0]) + i.Name.Substring(1));
            }

            foreach (var assemblyName in _options.Assemblies)
            {
                var fi = new FileInfo(assemblyName);
                // Load all input assemblies from the same location to ensure duplicates aren't generated (as the same type loaded from
                // two different places will appear to be different, so both would otherwise be generated).
                var assembly = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, workingPath, fi.Name));
                Console.WriteLine("Loaded assembly: " + assemblyName);

                // Get the WebAPI controllers...
                var controllers = assembly.GetTypes().Where(_configuration.ControllerPredicate);

                // Get the return types...
                var actions = controllers
                              .SelectMany(c => c.GetMethods()
                                          .Where(_configuration.ActionsPredicate)
                                          .Where(m => m.DeclaringType == c)
                                          );
                ProcessMethods(actions, generator);

                var signalrHubs = assembly.GetTypes().Where(t => t.GetInterfaces().ToList().Exists(i => i != null && i.FullName?.Contains(_configuration.SignalRGenerator.IHUB_TYPE) == true));
                var methods     = signalrHubs
                                  .SelectMany(h => h.GetMethods()
                                              .Where(m => m.IsPublic)
                                              .Where(m => m.DeclaringType == h || m.GetBaseDefinition()?.DeclaringType == h));
                ProcessMethods(methods, generator);

                var clientInterfaceTypes = signalrHubs.Where(t => t.BaseType.IsGenericType)
                                           .Select(t => t.BaseType.GetGenericArguments()[0]);
                var clientMethods = clientInterfaceTypes
                                    .SelectMany(h => h.GetMethods()
                                                .Where(m => m.IsPublic)
                                                .Where(m => m.DeclaringType == h));
                ProcessMethods(clientMethods, generator);

                // Add all classes that are declared inside the specified namespace
                if (_options.Namespaces != null && _options.Namespaces.Any())
                {
                    var types = assembly.GetTypes()
                                .Where(t => IncludedNamespace(_options, t));
                    ProcessTypes(types, generator);
                }

                generator.AsConstEnums(false);
            }

            var tsEnumDefinitions = generator.Generate(TsGeneratorOutput.Enums);

            tsEnumDefinitions = tsEnumDefinitions.Replace("namespace ", "export module ");
            tsEnumDefinitions = "import * as Enums from \"../server/enums\";\r\n\r\n" + tsEnumDefinitions;
            File.WriteAllText(Path.Combine(_options.OutputFilePath, "enums.ts"), tsEnumDefinitions);


            if (_options.GenerateAsModules)
            {
                //Generate interface definitions for all classes
                generator.WithMemberTypeFormatter((p, n) =>
                {
                    var asCollection = p.PropertyType as TsCollection;
                    var isCollection = asCollection != null;

                    if (isCollection)
                    {
                        var genericArguments = asCollection.ItemsType.Type.GetGenericArguments();
                        foreach (var arg in genericArguments)
                        {
                            // Really horrible hack... prefix enum generic parameters with 'Enum.'.  Makes things like Dictionary<string, AnEnum> work.
                            if (arg.IsEnum)
                            {
                                Console.WriteLine("***Replacing " + arg.FullName);
                                n = n.Replace(arg.FullName, "Enums." + arg.FullName);
                            }
                        }

                        return((asCollection.ItemsType is TsEnum ? "Enums." + n : n) + string.Concat(Enumerable.Repeat("[]", asCollection.Dimension)));
                    }
                    return(p.PropertyType is TsEnum ? "Enums." + n : n);
                });
                var tsClassDefinitions = generator.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields);
                tsClassDefinitions = "import * as Enums from \"./enums\";\r\n\r\n" + tsClassDefinitions;
                tsClassDefinitions = tsClassDefinitions.Replace("declare namespace", "export module");
                tsClassDefinitions = tsClassDefinitions.Replace("interface", "export interface");
                tsClassDefinitions = Regex.Replace(tsClassDefinitions, @":\s*System\.Collections\.Generic\.KeyValuePair\<(?<k>[^\,]+),(?<v>[^\,]+)\>\[\];",
                                                   m => ": {[key: string]: " + m.Groups["v"].Value + "};",
                                                   RegexOptions.Multiline);
                File.WriteAllText(Path.Combine(_options.OutputFilePath, "classes.ts"), tsClassDefinitions);
            }
            else
            {
                var tsClassDefinitions = generator.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields);
                tsClassDefinitions = Regex.Replace(tsClassDefinitions, @":\s*System\.Collections\.Generic\.KeyValuePair\<(?<k>[^\,]+),(?<v>[^\,]+)\>\[\];",
                                                   m => ": {[key: string]: " + m.Groups["v"].Value + "};",
                                                   RegexOptions.Multiline);
                File.WriteAllText(Path.Combine(_options.OutputFilePath, "classes.d.ts"), tsClassDefinitions);
            }
        }
示例#18
0
        private void GenerateContractsForWebApiRequestResponseClasses(Assembly assembly, TypeScriptFluent generator)
        {
            // Get the WebAPI controllers...
            var controllers = assembly.GetTypes().Where(_configuration.ControllerPredicate);

            // Get the return types...
            var actions = controllers
                          .SelectMany(c => c.GetMethods()
                                      .Where(_configuration.ActionsPredicate)
                                      .Where(m => m.DeclaringType == c)
                                      );

            ProcessMethods(actions, generator);

            var signalrHubs = assembly.GetTypes().Where(t => _configuration.SignalRGenerator.IsHub(t));
            var methods     = signalrHubs
                              .SelectMany(h => h.GetMethods()
                                          .Where(m => m.IsPublic)
                                          .Where(m => m.GetBaseDefinition()?.DeclaringType == h));

            ProcessMethods(methods, generator);

            var clientInterfaceTypes = signalrHubs.Where(t => t.BaseType.IsGenericType)
                                       .Select(t => t.BaseType.GetGenericArguments()[0]);
            var clientMethods = clientInterfaceTypes
                                .SelectMany(h => h.GetMethods()
                                            .Where(m => m.IsPublic)
                                            .Where(m => m.DeclaringType == h));

            ProcessMethods(clientMethods, generator);
        }
示例#19
0
        private static void ProcessTypes(IEnumerable <Type> types, TypeScriptFluent generator)
        {
            foreach (var clrType in types.Where(t => t != typeof(void)))
            {
                if (generator.ModelBuilder.ContainsType(clrType))
                {
                    continue;
                }

                var clrTypeToUse = clrType;
                if (typeof(Task).GetDnxCompatible().IsAssignableFrom(clrTypeToUse))
                {
                    if (clrTypeToUse.GetDnxCompatible().IsGenericType)
                    {
                        clrTypeToUse = clrTypeToUse.GetDnxCompatible().GetGenericArguments()[0];
                    }
                    else
                    {
                        continue;  // Ignore non-generic Task as we can't know what type it will really be
                    }
                }

                if (clrTypeToUse.IsNullable())
                {
                    clrTypeToUse = clrTypeToUse.GetUnderlyingNullableType();
                }

                // Ignore compiler generated types
                if (clrTypeToUse.GetDnxCompatible().GetCustomAttribute(typeof(CompilerGeneratedAttribute)) != null)
                {
                    continue;
                }

                if (clrTypeToUse.Namespace.StartsWith("System"))
                {
                    continue;
                }

                if (clrTypeToUse.IsIDictionary())
                {
                    continue;
                }

                if (clrTypeToUse == typeof(string) || clrTypeToUse.GetDnxCompatible().IsPrimitive || clrTypeToUse == typeof(object))
                {
                    continue;
                }


                bool           isClassOrArray = clrTypeToUse.GetDnxCompatible().IsClass || clrTypeToUse.GetDnxCompatible().IsInterface;
                TsModuleMember member         = null;
                if (clrTypeToUse.IsArray)
                {
                    ProcessTypes(new[] { clrTypeToUse.GetElementType() }, generator);
                }
                else if (clrTypeToUse.GetDnxCompatible().IsGenericType)
                {
                    ProcessTypes(clrTypeToUse.GetDnxCompatible().GetGenericArguments(), generator);
                    bool isEnumerable = typeof(IEnumerable).GetDnxCompatible().IsAssignableFrom(clrTypeToUse);
                    if (!isEnumerable)
                    {
                        member = generator.ModelBuilder.Add(clrTypeToUse, !isClassOrArray);
                    }
                }
                else
                {
                    member = generator.ModelBuilder.Add(clrTypeToUse, !isClassOrArray);
                }

                var classModel = member as TsClass;
                if (isClassOrArray && classModel != null)
                {
                    var references = classModel.Properties
                                     .Where(model => !model.IsIgnored)
                                     .Select(m => m.PropertyType)
                                     .Concat(classModel.GenericArguments)
                                     .Select(m => m.Type)
                                     .Where(t => !t.IsIDictionary())
                                     .ToArray();

                    ProcessTypes(references, generator);
                }
            }
        }
 /// <summary>
 /// Register a document appender.
 /// </summary>
 /// <returns>Instance of the TypeScriptFluent that enables fluent documentation.</returns>
 public static TypeScriptFluent WithJSDoc(this TypeScriptFluent ts)
 {
     ts.ScriptGenerator.SetDocAppender(new DocAppender());
     return(ts);
 }
示例#21
0
 public TypeConverter(string globalNamespace, TypeScriptFluent fluent, Dictionary <Type, string> customConversions)
 {
     _globalNamespace   = globalNamespace;
     _fluent            = fluent;
     _customConversions = customConversions;
 }