├── .gitignore ├── LICENSE ├── TypeLitePlus.Core ├── AlternateGenerators │ ├── TsBackboneModelGenerator.cs │ └── TsKnockoutModelGenerator.cs ├── AssemblyInfo.cs ├── DocAppender.cs ├── Extensions │ ├── MemberInfoExtensions.cs │ ├── SystemTypeKindExtensions.cs │ ├── TypeExtensions.cs │ └── TypeScriptFluentExtensions.cs ├── IDocAppender.cs ├── ITsModelVisitor.cs ├── ITsTypeFormatter.cs ├── IndentationLevelScope.cs ├── ScriptBuilder.cs ├── TsClassAttribute.cs ├── TsEnumAttribute.cs ├── TsEnumModes.cs ├── TsFiles.cs ├── TsGenerationModes.cs ├── TsGenerator.cs ├── TsGeneratorOutput.cs ├── TsIgnoreAttribute.cs ├── TsInterfaceAttribute.cs ├── TsMemberIdentifierFormatter.cs ├── TsMemberTypeFormatter.cs ├── TsModel.cs ├── TsModelBuilder.cs ├── TsModelVisitor.cs ├── TsModels │ ├── SystemTypeKind.cs │ ├── TsClass.cs │ ├── TsCollection.cs │ ├── TsEnum.cs │ ├── TsEnumValue.cs │ ├── TsModule.cs │ ├── TsModuleMember.cs │ ├── TsProperty.cs │ ├── TsSystemType.cs │ ├── TsType.cs │ └── TsTypeFamily.cs ├── TsModuleNameFormatter.cs ├── TsPropertyAttribute.cs ├── TsTypeFormatter.cs ├── TsTypeFormatterCollection.cs ├── TsTypeVisibilityFormatter.cs ├── TypeConvertor.cs ├── TypeConvertorCollection.cs ├── TypeLitePlus.Core.csproj ├── TypeResolver.cs ├── TypeScript.cs ├── TypeScriptFluent.cs ├── TypeScriptFluentModuleMember.cs └── XmlDocumentationProvider.cs ├── TypeLitePlus.DotNetScript ├── TypeLite.csx └── TypeLitePlus.DotNetScript.csproj ├── TypeLitePlus.T4 ├── Scripts │ ├── Manager.ttinclude │ └── TypeLite.tt └── TypeLitePlus.T4.csproj ├── TypeLitePlus.Tests.AssemblyWithEnum ├── Properties │ └── AssemblyInfo.cs ├── TestEnum.cs └── TypeLitePlus.Tests.AssemblyWithEnum.csproj ├── TypeLitePlus.Tests.NetCore ├── Extensions │ └── TypeExtensionsTests.cs ├── GenericsTests.cs ├── RegressionTests │ ├── DateTimeTests.cs │ ├── DbGeometryIgnoreTests.cs │ ├── Generics0_8Tests.cs │ ├── Issue103_GlobalizationTypes.cs │ ├── Issue14_IgnoreAttributeIsNotWorking.cs │ ├── Issue15_ConvertSystemType.cs │ ├── Issue24_NullableEnumProperty.cs │ ├── Issue32_DuplicateInterfacesForClosedGenericPropertyTypes.cs │ ├── Issue33_EnumCollectionTypePropertyFailsToGenerateEnum.cs │ ├── Issue41_EnumsInGenericClasses.cs │ ├── Issue43_EnumsWithDeclare.cs │ ├── Issue44_EnumsWithExport.cs │ ├── Issue45_EmptyNamespaceInEmuns.cs │ ├── Issue48_ToModuleForEnums.cs │ ├── Issue51_ArrayOfArrayOutput.cs │ ├── Issue52_EnumsWithoutClass.cs │ ├── Issue63_SelfReferencingEnumerable.cs │ ├── Issue65_GenericReferencingContainingType.cs │ ├── Issue79_ModuleNameFormatterIsnNotUsed.cs │ ├── Issue82_OrderingTests.cs │ ├── Issue85_ReUseTheModifiedTsEnum.cs │ ├── Issue88_TypeformatterAppliedToOpenGenericsParameters.cs │ ├── JsDocTests.cs │ ├── ModuleNameFormatterTests.cs │ └── NullablesTests.cs ├── ScriptBuilderTests.cs ├── TestModels │ ├── Address.cs │ ├── ContactType.cs │ ├── CustomClassName.cs │ ├── CustomTypeCollectionReference.cs │ ├── CustomerKind.cs │ ├── DifferentNamespaces.cs │ ├── Employee.cs │ ├── IShippingService.cs │ ├── IgnoreTest.cs │ ├── Item.cs │ ├── Outer.cs │ ├── Person.cs │ ├── PointStruct.cs │ ├── Product.cs │ └── User.cs ├── TestScripts │ ├── Enums.ts │ ├── Knockout │ │ ├── Enums.ts │ │ ├── TsKo.d.ts │ │ └── TsKo.tt │ ├── TsUtils.d.ts │ └── TsUtils.tt ├── TsGeneratorTests.cs ├── TsModelBuilderTests.cs ├── TsModelTests.cs ├── TsModels │ ├── TsClassTests.cs │ ├── TsCollectionTests.cs │ ├── TsEnumTests.cs │ ├── TsModuleTests.cs │ ├── TsPropertyTests.cs │ ├── TsSystemTypeTests.cs │ └── TsTypeTests.cs ├── TypeConvertorCollectionTests.cs └── TypeLitePlus.Tests.NetCore.csproj ├── TypeLitePlus.sln ├── TypeLitePlus └── TypeLitePlus.csproj ├── changelog.txt └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Robert McLaws and CloudNimble, Inc. 4 | Copyright (c) 2013 Lukas Kabrt 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/AlternateGenerators/TsBackboneModelGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using TypeLitePlus.TsModels; 3 | 4 | namespace TypeLitePlus.AlternateGenerators 5 | { 6 | /// 7 | /// Generator implementation that emits classes which extend Backbone.Model 8 | /// 9 | public class TsBackboneModelGenerator : TsGenerator 10 | { 11 | 12 | protected override void AppendClassDefinition(TsClass classModel, ScriptBuilder sb, TsGeneratorOutput generatorOutput) 13 | { 14 | 15 | string typeName = this.GetTypeName(classModel); 16 | string visibility = this.GetTypeVisibility(classModel, typeName) ? "export " : ""; 17 | sb.AppendFormatIndented( 18 | "{0}class {1} extends {2}", 19 | visibility, 20 | typeName, 21 | //all bottom-level classes must extend Backbone.Model. 22 | classModel.BaseType != null ? this.GetFullyQualifiedTypeName(classModel.BaseType) : "Backbone.Model"); 23 | 24 | sb.AppendLine(" {"); 25 | 26 | var members = new List(); 27 | if ((generatorOutput & TsGeneratorOutput.Properties) == TsGeneratorOutput.Properties) 28 | { 29 | members.AddRange(classModel.Properties); 30 | } 31 | if ((generatorOutput & TsGeneratorOutput.Fields) == TsGeneratorOutput.Fields) 32 | { 33 | members.AddRange(classModel.Fields); 34 | } 35 | using (sb.IncreaseIndentation()) 36 | { 37 | foreach (var property in members) 38 | { 39 | if (property.IsIgnored) 40 | { 41 | continue; 42 | } 43 | 44 | sb.AppendLineIndented(string.Format( 45 | "get {0}(): {1} {{ return this.get(\"{0}\"); }}", 46 | this.GetPropertyName(property), this.GetPropertyType(property))); 47 | 48 | sb.AppendLineIndented(string.Format( 49 | "set {0}(v: {1}) {{ this.set(\"{0}\", v); }}", 50 | this.GetPropertyName(property), this.GetPropertyType(property))); 51 | } 52 | } 53 | 54 | sb.AppendLineIndented("}"); 55 | 56 | _generatedClasses.Add(classModel); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/AlternateGenerators/TsKnockoutModelGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using TypeLitePlus.TsModels; 3 | 4 | namespace TypeLitePlus.AlternateGenerators 5 | { 6 | 7 | /// 8 | /// Generator implementation converting member types to KnockoutObservable and KnockoutObservableArray 9 | /// 10 | public class TsKnockoutModelGenerator : TsGenerator 11 | { 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | protected override void AppendClassDefinition(TsClass classModel, ScriptBuilder sb, TsGeneratorOutput generatorOutput) 19 | { 20 | string typeName = this.GetTypeName(classModel); 21 | string visibility = this.GetTypeVisibility(classModel, typeName) ? "export " : ""; 22 | sb.AppendFormatIndented("{0}interface {1}", visibility, typeName); 23 | if (classModel.BaseType != null) 24 | sb.AppendFormat(" extends {0}", this.GetFullyQualifiedTypeName(classModel.BaseType)); 25 | sb.AppendLine(" {"); 26 | var members = new List(); 27 | if ((generatorOutput & TsGeneratorOutput.Properties) == TsGeneratorOutput.Properties) 28 | members.AddRange(classModel.Properties); 29 | if ((generatorOutput & TsGeneratorOutput.Fields) == TsGeneratorOutput.Fields) 30 | members.AddRange(classModel.Fields); 31 | using (sb.IncreaseIndentation()) 32 | { 33 | foreach (var property in members) 34 | { 35 | if (property.IsIgnored) 36 | continue; 37 | var propTypeName = this.GetPropertyType(property); 38 | if (property.PropertyType.IsCollection()) 39 | { 40 | //Note: new member functon checking if property is collection or not 41 | //Also remove the array brackets from the name 42 | if (propTypeName.Length > 2 && propTypeName.Substring(propTypeName.Length - 2) == "[]") 43 | propTypeName = propTypeName.Substring(0, propTypeName.Length - 2); 44 | propTypeName = "KnockoutObservableArray<" + propTypeName + ">"; 45 | } 46 | else 47 | propTypeName = "KnockoutObservable<" + propTypeName + ">"; 48 | sb.AppendLineIndented(string.Format("{0}: {1};", this.GetPropertyName(property), propTypeName)); 49 | } 50 | } 51 | sb.AppendLineIndented("}"); 52 | _generatedClasses.Add(classModel); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("TypeLitePlus.Tests.NetCore")] -------------------------------------------------------------------------------- /TypeLitePlus.Core/DocAppender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using TypeLitePlus.TsModels; 7 | 8 | namespace TypeLitePlus 9 | { 10 | /// 11 | /// ts document appender 12 | /// 13 | public class DocAppender : IDocAppender 14 | { 15 | /// 16 | /// xml doc provider cache 17 | /// 18 | protected Dictionary _providers; 19 | 20 | public DocAppender() 21 | { 22 | _providers = new Dictionary(); 23 | } 24 | 25 | public void AppendClassDoc(ScriptBuilder sb, TsClass classModel, string className) 26 | { 27 | AppendModelDoc(sb, classModel.Type); 28 | } 29 | 30 | public void AppendPropertyDoc(ScriptBuilder sb, TsProperty property, string propertyName, string propertyType) 31 | { 32 | AppendMemberDoc(sb, property.MemberInfo); 33 | } 34 | 35 | public void AppendConstantModuleDoc(ScriptBuilder sb, TsProperty property, string propertyName, string propertyType) 36 | { 37 | AppendMemberDoc(sb, property.MemberInfo); 38 | } 39 | 40 | public void AppendEnumDoc(ScriptBuilder sb, TsEnum enumModel, string enumName) 41 | { 42 | AppendModelDoc(sb, enumModel.Type); 43 | } 44 | 45 | public void AppendEnumValueDoc(ScriptBuilder sb, TsEnumValue value) 46 | { 47 | AppendMemberDoc(sb, value.Field); 48 | } 49 | 50 | private XmlDocumentationProvider GetXmlDocProvider(Assembly assembly) 51 | { 52 | var xmlPath = FindXmlDocPath(assembly); 53 | 54 | System.Diagnostics.Debug.Print("GetXmlDocProvider {0}", xmlPath); 55 | if (xmlPath == null || File.Exists(xmlPath) == false) 56 | { 57 | System.Diagnostics.Debug.Print("GetXmlDocProvider not found"); 58 | return null; 59 | } 60 | 61 | var key = xmlPath.ToLower(); 62 | XmlDocumentationProvider provider; 63 | if (_providers.TryGetValue(key, out provider) == false) 64 | { 65 | provider = new XmlDocumentationProvider(xmlPath); 66 | _providers[key] = provider; 67 | } 68 | 69 | return provider; 70 | } 71 | 72 | private string FindXmlDocPath(Assembly assembly) 73 | { 74 | string asmPath = Uri.UnescapeDataString((new UriBuilder(assembly.CodeBase).Path)); 75 | string xmlPath; 76 | 77 | // find same place 78 | xmlPath = Path.ChangeExtension(asmPath, ".xml"); 79 | if (File.Exists(xmlPath)) 80 | { 81 | return xmlPath; 82 | } 83 | 84 | // find from Reference Assemblies 85 | // ex. C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1 86 | var baseDir = Path.Combine( 87 | Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), 88 | @"Reference Assemblies\Microsoft\Framework\.NETFramework"); 89 | 90 | var dirInfo = new DirectoryInfo(baseDir); 91 | if (dirInfo.Exists) 92 | { 93 | // find v4.* etc. directory 94 | var pattern = assembly.ImageRuntimeVersion.Substring(0, 2) + ".*"; 95 | var verDirs = dirInfo.GetDirectories(pattern) 96 | .OrderByDescending(dir => dir.Name) 97 | .ToArray(); 98 | 99 | // find xml in version directory 100 | var xmlName = Path.GetFileNameWithoutExtension(asmPath) + ".xml"; 101 | foreach (var verDir in verDirs) 102 | { 103 | xmlPath = Path.Combine(verDir.FullName, xmlName); 104 | if (File.Exists(xmlPath)) 105 | { 106 | return xmlPath; 107 | } 108 | } 109 | } 110 | 111 | // nothing 112 | return null; 113 | } 114 | 115 | private void AppendModelDoc(ScriptBuilder sb, Type type) 116 | { 117 | var provider = GetXmlDocProvider(type.Assembly); 118 | if (provider == null) 119 | { 120 | return; 121 | } 122 | 123 | var doc = provider.GetDocumentation(type); 124 | if (string.IsNullOrWhiteSpace(doc)) 125 | { 126 | return; 127 | } 128 | 129 | sb.AppendLine(); 130 | sb.AppendFormatIndented("/**"); 131 | sb.AppendLine(); 132 | sb.AppendFormatIndented(" * {0}", doc); 133 | sb.AppendLine(); 134 | sb.AppendFormatIndented(" */"); 135 | sb.AppendLine(); 136 | } 137 | 138 | private void AppendMemberDoc(ScriptBuilder sb, MemberInfo member) 139 | { 140 | var provider = GetXmlDocProvider(member.DeclaringType.Assembly); 141 | if (provider == null) 142 | { 143 | return; 144 | } 145 | 146 | var doc = provider.GetDocumentation(member); 147 | if (string.IsNullOrWhiteSpace(doc)) 148 | { 149 | return; 150 | } 151 | 152 | sb.AppendLine(); 153 | sb.AppendFormatIndented("/**"); 154 | sb.AppendLine(); 155 | sb.AppendFormatIndented(" * {0}", doc); 156 | sb.AppendLine(); 157 | sb.AppendFormatIndented(" */"); 158 | sb.AppendLine(); 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/Extensions/MemberInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Extensions 2 | { 3 | /// 4 | /// Contains extensions for MemberInfo class 5 | /// 6 | public static class MemberInfoExtensions 7 | { 8 | /// 9 | /// Retrieves a custom attribute of a specified type that is applied to a specified member. 10 | /// 11 | /// The type of attribute to search for. 12 | /// The member to inspect. 13 | /// true to search this member's inheritance chain to find the attributes; otherwise, false. This parameter is ignored for properties and events; see Remarks. 14 | /// A custom attribute that matches T, or null if no such attribute is found. 15 | //public static TType GetCustomAttribute(this MemberInfo memberInfo, bool inherit) where TType : Attribute { 16 | // return memberInfo.GetCustomAttributes(typeof(TType), inherit).FirstOrDefault() as TType; 17 | //} 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/Extensions/SystemTypeKindExtensions.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.TsModels; 2 | 3 | namespace TypeLitePlus.Extensions 4 | { 5 | /// 6 | /// Contains extensions for SystemTypeKind enum 7 | /// 8 | public static class SystemTypeKindExtensions 9 | { 10 | /// 11 | /// Converts SystemTypeKind to the string, that can be used as system type identifier in TypeScript. 12 | /// 13 | /// The value to convert 14 | /// system type identifier for TypeScript 15 | public static string ToTypeScriptString(this SystemTypeKind type) 16 | { 17 | switch (type) 18 | { 19 | case SystemTypeKind.Date: return "Date"; 20 | case SystemTypeKind.Bool: return "boolean"; 21 | } 22 | 23 | return type.ToString().ToLower(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/Extensions/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace TypeLitePlus.Extensions 5 | { 6 | /// 7 | /// Contains extensions for PropertyInfo class 8 | /// 9 | public static class TypeExtensions 10 | { 11 | /// 12 | /// Retrieves a custom attribute of a specified type that is applied to a specified type. 13 | /// 14 | /// The type of attribute to search for. 15 | /// The type to inspect. 16 | /// true to search this member's inheritance chain to find the attributes; otherwise, false. This parameter is ignored for properties and events; see Remarks. 17 | /// A custom attribute that matches T, or null if no such attribute is found. 18 | //public static TType GetCustomAttribute(this Type type, bool inherit) where TType : Attribute { 19 | // return type.GetCustomAttributes(typeof(TType), inherit).FirstOrDefault() as TType; 20 | //} 21 | 22 | /// 23 | /// Determined whether the specific type is nullable value type. 24 | /// 25 | /// The type to inspect. 26 | /// true if the type is nullable value type otherwise false 27 | public static bool IsNullable(this Type type) 28 | { 29 | return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); 30 | } 31 | 32 | /// 33 | /// Retrieves underlaying value type of the nullable value type. 34 | /// 35 | /// The type to inspect. 36 | /// The underlaying value type. 37 | public static Type GetNullableValueType(this Type type) 38 | { 39 | return type.GetGenericArguments().Single(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/Extensions/TypeScriptFluentExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | 5 | namespace TypeLitePlus 6 | { 7 | /// 8 | /// Contains extensions methods specific for full .NET framework 9 | /// 10 | public static class TypeScriptFluentExtensions 11 | { 12 | /// 13 | /// Adds all classes annotated with the TsClassAttribute from all curently loaded assemblies. 14 | /// 15 | /// Instance of the TypeScriptFluent that enables fluent configuration. 16 | public static TypeScriptFluent ForLoadedAssemblies(this TypeScriptFluent ts) 17 | { 18 | foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) 19 | { 20 | ts.ModelBuilder.Add(assembly); 21 | } 22 | 23 | return ts; 24 | } 25 | 26 | /// 27 | /// Adds all Types derived from T 28 | /// 29 | /// Instance of the TypeScriptFluent that enables fluent configuration. 30 | public static TypeScriptFluent TypesDervivedFrom(this TypeScriptFluent ts, bool includeBaseType = true) 31 | { 32 | foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) 33 | { 34 | foreach (var type in assembly.GetTypes().Where(x => typeof(T).IsAssignableFrom(x))) 35 | { 36 | if (includeBaseType || type != typeof(T)) 37 | { 38 | ts.ModelBuilder.Add(type); 39 | } 40 | } 41 | } 42 | 43 | return ts; 44 | } 45 | 46 | /// 47 | /// Adds all classes annotated with the TsClassAttribute from the referenced assembly identified by the name parameter. 48 | /// 49 | /// 50 | /// The name of the assembly to scan 51 | /// 52 | /// Instance of the TypeScriptFluent that enables fluent configuration. 53 | public static TypeScriptFluent ForReferencedAssembly(this TypeScriptFluent ts, string name) 54 | { 55 | 56 | foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) 57 | { 58 | foreach (var obj in assembly.GetReferencedAssemblies()) 59 | { 60 | if (obj.Name == name) 61 | { 62 | var assembly2 = Assembly.Load(obj); 63 | if (assembly2 != null) 64 | { 65 | ts.ModelBuilder.Add(assembly2); 66 | } 67 | } 68 | 69 | } 70 | } 71 | 72 | return ts; 73 | } 74 | 75 | /// 76 | /// Register a document appender. 77 | /// 78 | /// Instance of the TypeScriptFluent that enables fluent documentation. 79 | public static TypeScriptFluent WithJSDoc(this TypeScriptFluent ts) 80 | { 81 | ts.ScriptGenerator.SetDocAppender(new DocAppender()); 82 | return ts; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/IDocAppender.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.TsModels; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// interface of TS document appender. 7 | /// 8 | public interface IDocAppender 9 | { 10 | /// 11 | /// Append class document. 12 | /// 13 | /// 14 | /// 15 | /// 16 | void AppendClassDoc(ScriptBuilder sb, TsClass classModel, string className); 17 | 18 | /// 19 | /// Append property document. 20 | /// 21 | /// 22 | /// 23 | /// 24 | /// 25 | void AppendPropertyDoc(ScriptBuilder sb, TsProperty property, string propertyName, string propertyType); 26 | 27 | /// 28 | /// Append constant document. 29 | /// 30 | /// 31 | /// 32 | /// 33 | /// 34 | void AppendConstantModuleDoc(ScriptBuilder sb, TsProperty property, string propertyName, string propertyType); 35 | 36 | /// 37 | /// Append Enum document. 38 | /// 39 | /// 40 | /// 41 | /// 42 | void AppendEnumDoc(ScriptBuilder sb, TsEnum enumModel, string enumName); 43 | 44 | /// 45 | /// Append Enum value document. 46 | /// 47 | /// 48 | /// 49 | void AppendEnumValueDoc(ScriptBuilder sb, TsEnumValue value); 50 | } 51 | 52 | /// 53 | /// Dummy doc appender. 54 | /// 55 | public class NullDocAppender : IDocAppender 56 | { 57 | public void AppendClassDoc(ScriptBuilder sb, TsClass classModel, string className) 58 | { 59 | } 60 | 61 | public void AppendPropertyDoc(ScriptBuilder sb, TsProperty property, string propertyName, string propertyType) 62 | { 63 | } 64 | 65 | public void AppendConstantModuleDoc(ScriptBuilder sb, TsProperty property, string propertyName, string propertyType) 66 | { 67 | } 68 | 69 | public void AppendEnumDoc(ScriptBuilder sb, TsEnum enumModel, string enumName) 70 | { 71 | } 72 | 73 | public void AppendEnumValueDoc(ScriptBuilder sb, TsEnumValue value) 74 | { 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/ITsModelVisitor.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.TsModels; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Defines an interface of TypeScript model visitor, that can be used to examine and modify TypeScript model. 7 | /// 8 | public interface ITsModelVisitor 9 | { 10 | /// 11 | /// Represents a method called once for the model. 12 | /// 13 | /// The model being visited. 14 | void VisitModel(TsModel model); 15 | 16 | /// 17 | /// Represents a method called for every module in the model. 18 | /// 19 | /// The module being visited. 20 | void VisitModule(TsModule module); 21 | 22 | /// 23 | /// Represents a method called for every class in the model. 24 | /// 25 | /// The model class being visited. 26 | void VisitClass(TsClass classModel); 27 | 28 | /// 29 | /// Represents a method called for every property in the model. 30 | /// 31 | /// The property being visited. 32 | void VisitProperty(TsProperty property); 33 | 34 | /// 35 | /// When overridden in a derived class, it can examine or modify the enum model. 36 | /// 37 | /// The model enum being visited. 38 | void VisitEnum(TsEnum enumModel); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/ITsTypeFormatter.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.TsModels; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Formats TsType for output. 7 | /// 8 | public interface ITsTypeFormatter 9 | { 10 | /// 11 | /// Formats TsType for output 12 | /// 13 | /// The type to format. 14 | /// The string representation of the type. 15 | string FormatType(TsType type); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/IndentationLevelScope.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Represents a scope of indentation level in the ScriptBuilder 7 | /// 8 | public class IndentationLevelScope : IDisposable 9 | { 10 | private ScriptBuilder _sb; 11 | 12 | /// 13 | /// Initializes a new instance of the indentationLevel class for the specific ScriptBuilder 14 | /// 15 | /// The Scriptbuilder associated with this Indentation level. 16 | internal IndentationLevelScope(ScriptBuilder sb) 17 | { 18 | _sb = sb; 19 | } 20 | 21 | /// 22 | /// Disposes the indentation level 23 | /// 24 | public void Dispose() 25 | { 26 | _sb.DecreaseIndentation(this); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/ScriptBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | 5 | namespace TypeLitePlus 6 | { 7 | /// 8 | /// Creates outptut script in memory 9 | /// 10 | public class ScriptBuilder 11 | { 12 | private StringBuilder _internalBuilder; 13 | 14 | /// 15 | /// Gets or sets string for the single indentation level. 16 | /// 17 | public string IndentationString { get; set; } 18 | 19 | /// 20 | /// Get current number of indentation levels. 21 | /// 22 | public int IndentationLevels { get; private set; } 23 | 24 | /// 25 | /// Initializes a new instance of the ScriptBuilder class 26 | /// 27 | public ScriptBuilder() : this("\t") 28 | { 29 | } 30 | 31 | /// 32 | /// Initializes a new instace of the ScriptBuilder class with the specific characters for indentation. 33 | /// 34 | /// The characters for indentation. 35 | public ScriptBuilder(string indentation) 36 | { 37 | _internalBuilder = new StringBuilder(); 38 | this.IndentationString = indentation; 39 | } 40 | 41 | /// 42 | /// Inceases indentation by one level. 43 | /// 44 | /// An IndentationLevel object that represents a scope of the indentation. 45 | public IndentationLevelScope IncreaseIndentation() 46 | { 47 | this.IndentationLevels += 1; 48 | return new IndentationLevelScope(this); 49 | } 50 | 51 | /// 52 | /// Decreases indentation by one level. 53 | /// 54 | internal void DecreaseIndentation(IndentationLevelScope indentationScope) 55 | { 56 | if (indentationScope == null) 57 | { 58 | throw new ArgumentNullException(); 59 | } 60 | 61 | if (this.IndentationLevels <= 0) 62 | { 63 | throw new InvalidOperationException("Indentation level is already set to zero."); 64 | } 65 | 66 | this.IndentationLevels -= 1; 67 | } 68 | 69 | /// 70 | /// Appends the specified string to this instance 71 | /// 72 | /// the string to append 73 | public void Append(string value) 74 | { 75 | _internalBuilder.Append(value); 76 | } 77 | 78 | /// 79 | /// Appends default line delimeter. 80 | /// 81 | public void AppendLine() 82 | { 83 | _internalBuilder.AppendLine(); 84 | } 85 | 86 | /// 87 | /// Appends the specific string ot this instace of the ScriptBuilder followed by the default new line delimiter. 88 | /// 89 | /// the string to append 90 | public void AppendLine(string value) 91 | { 92 | _internalBuilder.AppendLine(value); 93 | } 94 | 95 | /// 96 | /// Appends a string returned by processing a composite format string. 97 | /// 98 | /// A composite format string 99 | /// An array of objects to format 100 | public void AppendFormat(string format, params object[] args) 101 | { 102 | _internalBuilder.AppendFormat(format, args); 103 | } 104 | 105 | /// 106 | /// Appends indentation. 107 | /// 108 | public void AppendIndentation() 109 | { 110 | _internalBuilder.Append(string.Concat(Enumerable.Repeat(this.IndentationString, this.IndentationLevels))); 111 | } 112 | 113 | /// 114 | /// Appends an indented string to the current instance of script builder. 115 | /// 116 | /// The string to append. 117 | public void AppendIndented(string value) 118 | { 119 | this.AppendIndentation(); 120 | this.Append(value); 121 | } 122 | 123 | /// 124 | /// Appends a indented string returned by processing a composite format string. 125 | /// 126 | /// A composite format string 127 | /// An array of objects to format 128 | public void AppendFormatIndented(string format, params object[] args) 129 | { 130 | this.AppendIndentation(); 131 | this.AppendFormat(format, args); 132 | } 133 | 134 | /// 135 | /// Appends an indented string followed by the default new line delimiter. 136 | /// 137 | /// The string to append 138 | public void AppendLineIndented(string value) 139 | { 140 | this.AppendIndentation(); 141 | this.AppendLine(value); 142 | } 143 | 144 | /// 145 | /// Converts value of this builder to a string. 146 | /// 147 | /// 148 | public override string ToString() 149 | { 150 | return _internalBuilder.ToString(); 151 | } 152 | 153 | 154 | 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsClassAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Configures a class to be included in the script model. 7 | /// 8 | [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] 9 | public sealed class TsClassAttribute : Attribute 10 | { 11 | /// 12 | /// Gets or sets the name of the class in the script model. If it isn't set, the name of the CLR class is used. 13 | /// 14 | public string Name { get; set; } 15 | 16 | /// 17 | /// Gets or sets name of the module for this class. If it isn't set, the namespace is used. 18 | /// 19 | public string Module { get; set; } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsEnumAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Configures an enum to be included in the script model. 7 | /// 8 | [AttributeUsage(AttributeTargets.Enum, Inherited = false, AllowMultiple = false)] 9 | public sealed class TsEnumAttribute : Attribute 10 | { 11 | /// 12 | /// Gets or sets the name of the enum in the script model. If it isn't set, the name of the CLR enum is used. 13 | /// 14 | public string Name { get; set; } 15 | 16 | /// 17 | /// Gets or sets name of the module for the enum. If it isn't set, the namespace is used. 18 | /// 19 | public string Module { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsEnumModes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TypeLitePlus 6 | { 7 | 8 | /// 9 | /// 10 | /// 11 | public enum TsEnumModes 12 | { 13 | /// 14 | /// Renders Enum values using the underlying value type. 15 | /// 16 | Number, 17 | 18 | /// 19 | /// Renders Enum values using the string name of the value. 20 | /// 21 | String 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsFiles.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace TypeLitePlus 8 | { 9 | 10 | public static class TsFiles 11 | { 12 | 13 | public static Regex regex = new Regex("declare module (\\S+) {(.*?})\r\n}", RegexOptions.Singleline | RegexOptions.CultureInvariant); 14 | 15 | /// 16 | /// Splits the current TypeScriptFluent output into several files, one per module 17 | /// 18 | /// The path where the files should be saved. 19 | /// 20 | public static string ToModules(this TypeScriptFluent typeScriptFluent, string path) 21 | { 22 | string typeScript = typeScriptFluent.Generate(); 23 | return ToModules(typeScript, path); 24 | } 25 | 26 | /// 27 | /// Splits template output into several files, one per module 28 | /// 29 | /// The current template output 30 | /// The path where the files should be saved. 31 | /// 32 | public static string ToModules(string typeScript, string path) 33 | { 34 | StringBuilder result = new StringBuilder(); 35 | 36 | DirectoryInfo directoryInfo = new DirectoryInfo(path); 37 | if (!directoryInfo.Exists) 38 | { 39 | directoryInfo.Create(); 40 | } 41 | 42 | Dictionary moduleNames = new Dictionary(); 43 | 44 | MatchCollection matchCollection = regex.Matches(typeScript); 45 | foreach (Match match in matchCollection) 46 | { 47 | if (match.Groups.Count == 3) 48 | { 49 | string moduleName = match.Groups[1].Value; 50 | moduleNames.Add(moduleName, moduleName.convertToIdentifier()); 51 | } 52 | } 53 | 54 | foreach (Match match in matchCollection) 55 | { 56 | if (match.Groups.Count == 3) 57 | { 58 | string moduleName = match.Groups[1].Value; 59 | string moduleContent = match.Groups[2].Value; 60 | 61 | foreach (KeyValuePair namePair in moduleNames) 62 | { 63 | if (moduleContent.Contains(namePair.Key)) 64 | { 65 | var header = String.Format("import {0} = require(\"{1}\");\r\n", namePair.Value, namePair.Key); 66 | moduleContent = moduleContent.Replace(namePair.Key, namePair.Value); 67 | moduleContent = header + moduleContent; 68 | } 69 | } 70 | 71 | string fileName = String.Format("{0}\\{1}.ts", path, moduleName); 72 | moduleContent.SaveToFile(fileName); 73 | 74 | result.AppendLine(fileName); 75 | } 76 | } 77 | return result.ToString(); 78 | } 79 | 80 | /// 81 | /// Saves a string to a text file 82 | /// 83 | /// The contents to save to the text file. 84 | /// The name of the file. 85 | private static void SaveToFile(this string aString, string aFileName) 86 | { 87 | FileInfo fileInfo = new FileInfo(aFileName); 88 | if (fileInfo.Exists) 89 | { 90 | fileInfo.Delete(); 91 | } 92 | using (FileStream stream = new FileStream(fileInfo.FullName, FileMode.Create)) 93 | { 94 | using (StreamWriter sw = new StreamWriter(stream)) 95 | { 96 | sw.Write(aString); 97 | sw.Close(); 98 | } 99 | } 100 | } 101 | 102 | /// 103 | /// Converts a string to a JavaScript Identifier 104 | /// 105 | /// The text that should be converted 106 | /// 107 | private static string convertToIdentifier(this string text) 108 | { 109 | string result = text; 110 | string firstLetter = text[0].ToString().ToLower(); 111 | result = firstLetter + text.Substring(1); 112 | result = result.Replace(".", ""); 113 | return result; 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsGenerationModes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TypeLitePlus 6 | { 7 | 8 | /// 9 | /// 10 | /// 11 | public enum TsGenerationModes 12 | { 13 | /// 14 | /// Renders the file with declared namespaces and interfaces. 15 | /// 16 | Definitions, 17 | 18 | /// 19 | /// Renders the file with exported modules and classes. 20 | /// 21 | Classes 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsGeneratorOutput.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Defines output of the generator 7 | /// 8 | [Flags] 9 | public enum TsGeneratorOutput 10 | { 11 | Properties = 1, 12 | Enums = 2, 13 | Fields = 4, 14 | Constants = 8 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsIgnoreAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Configures property to be ignored by the script generator. 7 | /// 8 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, Inherited = false, AllowMultiple = false)] 9 | public sealed class TsIgnoreAttribute : Attribute 10 | { 11 | } 12 | } -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsInterfaceAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Configures an interface to be included in the script model. 7 | /// 8 | [AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] 9 | public sealed class TsInterfaceAttribute : Attribute 10 | { 11 | /// 12 | /// Gets or sets the name of the interface in the script model. If it isn't set, the name of the CLR interface is used. 13 | /// 14 | public string Name { get; set; } 15 | 16 | /// 17 | /// Gets or sets name of the module for this interface. If it isn't set, the namespace is used. 18 | /// 19 | public string Module { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsMemberIdentifierFormatter.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.TsModels; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Defines a method used to format class member identifiers. 7 | /// 8 | /// The identifier to format 9 | /// The formatted identifier. 10 | public delegate string TsMemberIdentifierFormatter(TsProperty identifier); 11 | } 12 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsMemberTypeFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TypeLitePlus.TsModels; 3 | 4 | namespace TypeLitePlus 5 | { 6 | /// 7 | /// Defines a method used to format class member types. 8 | /// 9 | /// The typescript property 10 | /// The formatted type. 11 | public delegate string TsMemberTypeFormatter(TsProperty tsProperty, string memberTypeName); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using TypeLitePlus.TsModels; 4 | 5 | namespace TypeLitePlus 6 | { 7 | /// 8 | /// Represents script model of CLR classes. 9 | /// 10 | public class TsModel 11 | { 12 | /// 13 | /// Gets a collection of classes in the model. 14 | /// 15 | public ISet Classes { get; private set; } 16 | 17 | /// 18 | /// Gets a collection of enums in the model 19 | /// 20 | public ISet Enums { get; private set; } 21 | 22 | /// 23 | /// Gets a collection of references to other d.ts files. 24 | /// 25 | public ISet References { get; private set; } 26 | 27 | /// 28 | /// Gets a collection of modules in the module. 29 | /// 30 | public ISet Modules { get; private set; } 31 | 32 | /// 33 | /// Initializes a new instance of the TsModel class. 34 | /// 35 | public TsModel() 36 | : this(new TsClass[] { }) 37 | { 38 | } 39 | 40 | /// 41 | /// Initializes a new instance of the TsModel class with collection of classes. 42 | /// 43 | /// The collection of classes to add to the model. 44 | public TsModel(IEnumerable classes) 45 | { 46 | this.Classes = new HashSet(classes); 47 | this.References = new HashSet(); 48 | this.Modules = new HashSet(); 49 | this.Enums = new HashSet(); 50 | } 51 | 52 | /// 53 | /// Initializes a new instance of the TsModel class with collection of classes and enums 54 | /// 55 | /// The collection of classes to add to the model. 56 | /// The collection of enums to add to the model. 57 | public TsModel(IEnumerable classes, IEnumerable enums) 58 | { 59 | this.Classes = new HashSet(classes); 60 | this.References = new HashSet(); 61 | this.Modules = new HashSet(); 62 | this.Enums = new HashSet(enums); 63 | } 64 | 65 | /// 66 | /// Runs specific model visitor. 67 | /// 68 | /// The model visitor to run. 69 | public void RunVisitor(ITsModelVisitor visitor) 70 | { 71 | visitor.VisitModel(this); 72 | 73 | foreach (var module in this.Modules) 74 | { 75 | visitor.VisitModule(module); 76 | } 77 | 78 | foreach (var classModel in this.Classes) 79 | { 80 | visitor.VisitClass(classModel); 81 | 82 | foreach (var property in classModel.Properties.Union(classModel.Fields).Union(classModel.Constants)) 83 | { 84 | visitor.VisitProperty(property); 85 | } 86 | } 87 | 88 | foreach (var enumModel in this.Enums) 89 | { 90 | visitor.VisitEnum(enumModel); 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModelVisitor.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.TsModels; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Provides base class for model visitor. 7 | /// 8 | public abstract class TsModelVisitor : ITsModelVisitor 9 | { 10 | /// 11 | /// When overridden in a derived class, it can examine or modify the whole model. 12 | /// 13 | /// The code model being visited. 14 | public virtual void VisitModel(TsModel model) 15 | { 16 | } 17 | 18 | /// 19 | /// When overridden in a derived class, it can examine or modify the script module. 20 | /// 21 | /// The module being visited. 22 | public virtual void VisitModule(TsModule module) 23 | { 24 | } 25 | 26 | /// 27 | /// When overridden in a derived class, it can examine or modify the class model. 28 | /// 29 | /// The model class being visited. 30 | public virtual void VisitClass(TsClass classModel) 31 | { 32 | } 33 | 34 | /// 35 | /// When overridden in a derived class, it can examine or modify the property model. 36 | /// 37 | /// The model property being visited. 38 | public virtual void VisitProperty(TsProperty property) 39 | { 40 | } 41 | 42 | /// 43 | /// When overridden in a derived class, it can examine or modify the enum model. 44 | /// 45 | /// The model enum being visited. 46 | public virtual void VisitEnum(TsEnum enumModel) 47 | { 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/SystemTypeKind.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.TsModels 2 | { 3 | /// 4 | /// Defines kind of the system type. 5 | /// 6 | public enum SystemTypeKind 7 | { 8 | /// 9 | /// Number 10 | /// 11 | Number = 1, 12 | 13 | /// 14 | /// String 15 | /// 16 | String = 2, 17 | 18 | /// 19 | /// Boolean 20 | /// 21 | Bool = 3, 22 | 23 | /// 24 | /// Date 25 | /// 26 | Date = 4 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Reflection; 6 | 7 | namespace TypeLitePlus.TsModels 8 | { 9 | /// 10 | /// Represents a class in the code model. 11 | /// 12 | [DebuggerDisplay("TsClass - Name: {Name}")] 13 | public class TsClass : TsModuleMember 14 | { 15 | /// 16 | /// Gets collection of properties of the class. 17 | /// 18 | public ICollection Properties { get; private set; } 19 | 20 | /// 21 | /// Gets collection of fields of the class. 22 | /// 23 | public ICollection Fields { get; private set; } 24 | 25 | /// 26 | /// Gets collection of GenericArguments for this class 27 | /// 28 | public IList GenericArguments { get; private set; } 29 | 30 | /// 31 | /// Gets collection of constants of the class. 32 | /// 33 | public ICollection Constants { get; private set; } 34 | 35 | /// 36 | /// Gets base type of the class 37 | /// 38 | /// 39 | /// If the class derives from the object, the BaseType property is null. 40 | /// 41 | public TsType BaseType { get; internal set; } 42 | 43 | // TODO document 44 | public IList Interfaces { get; internal set; } 45 | 46 | /// 47 | /// Gets or sets bool value indicating whether this class will be ignored by TsGenerator. 48 | /// 49 | public bool IsIgnored { get; set; } 50 | 51 | /// 52 | /// Initializes a new instance of the TsClass class with the specific CLR type. 53 | /// 54 | /// The CLR type represented by this instance of the TsClass 55 | public TsClass(Type type) 56 | : base(type) 57 | { 58 | 59 | this.Properties = this.Type 60 | .GetProperties() 61 | .Where(pi => pi.DeclaringType == this.Type) 62 | .Select(pi => new TsProperty(pi)) 63 | .ToList(); 64 | 65 | this.Fields = this.Type 66 | .GetFields() 67 | .Where(fi => fi.DeclaringType == this.Type 68 | && !(fi.IsLiteral && !fi.IsInitOnly)) // skip constants 69 | .Select(fi => new TsProperty(fi)) 70 | .ToList(); 71 | 72 | this.Constants = this.Type 73 | .GetFields() 74 | .Where(fi => fi.DeclaringType == this.Type 75 | && fi.IsLiteral && !fi.IsInitOnly) // constants only 76 | .Select(fi => new TsProperty(fi)) 77 | .ToList(); 78 | 79 | if (type.IsGenericType) 80 | { 81 | this.Name = type.Name.Remove(type.Name.IndexOf('`')); 82 | this.GenericArguments = type 83 | .GetGenericArguments() 84 | .Select(TsType.Create) 85 | .ToList(); 86 | } 87 | else 88 | { 89 | this.Name = type.Name; 90 | this.GenericArguments = new TsType[0]; 91 | } 92 | 93 | if (this.Type.BaseType != null && this.Type.BaseType != typeof(object) && this.Type.BaseType != typeof(ValueType)) 94 | { 95 | this.BaseType = new TsType(this.Type.BaseType); 96 | } 97 | 98 | var interfaces = this.Type.GetInterfaces(); 99 | this.Interfaces = interfaces 100 | .Where(@interface => @interface.GetCustomAttribute(false) != null) 101 | .Except(interfaces.SelectMany(@interface => @interface.GetInterfaces())) 102 | .Select(TsType.Create).ToList(); 103 | 104 | var attribute = this.Type.GetCustomAttribute(false); 105 | if (attribute != null) 106 | { 107 | if (!string.IsNullOrEmpty(attribute.Name)) 108 | { 109 | this.Name = attribute.Name; 110 | } 111 | 112 | if (attribute.Module != null) 113 | { 114 | this.Module.Name = attribute.Module; 115 | } 116 | } 117 | 118 | var ignoreAttribute = this.Type.GetCustomAttribute(false); 119 | if (ignoreAttribute != null) 120 | { 121 | this.IsIgnored = true; 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Diagnostics; 4 | 5 | namespace TypeLitePlus.TsModels 6 | { 7 | /// 8 | /// Represents a collection in the code model. 9 | /// 10 | [DebuggerDisplay("TsCollection - ItemsType={ItemsType}")] 11 | public class TsCollection : TsType 12 | { 13 | /// 14 | /// Gets or sets type of the items in the collection. 15 | /// 16 | /// 17 | /// If the collection isn't strongly typed, the ItemsType property is initialized to TsType.Any. 18 | /// 19 | public TsType ItemsType { get; set; } 20 | 21 | /// 22 | /// Gets or sets the dimension of the collection. 23 | /// 24 | public int Dimension { get; set; } 25 | 26 | /// 27 | /// Initializes a new instance of the TsCollection class with the specific CLR type. 28 | /// 29 | /// The CLR collection represented by this instance of the TsCollection. 30 | public TsCollection(Type type) 31 | : base(type) 32 | { 33 | 34 | var enumerableType = TsType.GetEnumerableType(this.Type); 35 | if (enumerableType == this.Type) 36 | { 37 | this.ItemsType = TsType.Any; 38 | } 39 | else if (enumerableType != null) 40 | { 41 | this.ItemsType = TsType.Create(enumerableType); 42 | } 43 | else if (typeof(IEnumerable).IsAssignableFrom(this.Type)) 44 | { 45 | this.ItemsType = TsType.Any; 46 | } 47 | else 48 | { 49 | throw new ArgumentException(string.Format("The type '{0}' is not collection.", this.Type.FullName)); 50 | } 51 | 52 | this.Dimension = GetCollectionDimension(type); 53 | } 54 | 55 | private static int GetCollectionDimension(Type t) 56 | { 57 | Type enumerableUnderlying = null; 58 | 59 | if (t.IsArray) 60 | { 61 | return GetCollectionDimension(t.GetElementType()) + 1; 62 | } 63 | else if (t != typeof(string) && (enumerableUnderlying = GetEnumerableType(t)) != null) 64 | { 65 | if (enumerableUnderlying == t) 66 | { 67 | return 0; 68 | } 69 | return GetCollectionDimension(enumerableUnderlying) + 1; 70 | } 71 | else 72 | { 73 | return 0; 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | 6 | namespace TypeLitePlus.TsModels 7 | { 8 | /// 9 | /// Represents an enum in the code model. 10 | /// 11 | public class TsEnum : TsModuleMember 12 | { 13 | /// 14 | /// Gets or sets bool value indicating whether this enum will be ignored by TsGenerator. 15 | /// 16 | public bool IsIgnored { get; set; } 17 | 18 | /// 19 | /// Gets collection of properties of the class. 20 | /// 21 | public ICollection Values { get; private set; } 22 | 23 | /// 24 | /// Initializes a new instance of the TsEnum class with the specific CLR enum. 25 | /// 26 | /// The CLR enum represented by this instance of the TsEnum. 27 | public TsEnum(Type type) 28 | : base(type) 29 | { 30 | if (!this.Type.IsEnum) 31 | { 32 | throw new ArgumentException("ClrType isn't enum."); 33 | } 34 | 35 | this.Values = new List(this.GetEnumValues(type)); 36 | 37 | var attribute = this.Type.GetCustomAttribute(false); 38 | if (attribute != null) 39 | { 40 | if (!string.IsNullOrEmpty(attribute.Name)) 41 | { 42 | this.Name = attribute.Name; 43 | } 44 | 45 | if (!string.IsNullOrEmpty(attribute.Module)) 46 | { 47 | this.Module.Name = attribute.Module; 48 | } 49 | } 50 | } 51 | 52 | /// 53 | /// Retrieves a collection of possible value of the enum. 54 | /// 55 | /// The type of the enum. 56 | /// collection of all enum values. 57 | protected IEnumerable GetEnumValues(Type enumType) 58 | { 59 | return enumType.GetFields() 60 | .Where(fieldInfo => fieldInfo.IsLiteral && !string.IsNullOrEmpty(fieldInfo.Name)) 61 | .Select(fieldInfo => new TsEnumValue(fieldInfo)); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsEnumValue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace TypeLitePlus.TsModels 5 | { 6 | /// 7 | /// Represents a value of the enum 8 | /// 9 | public class TsEnumValue 10 | { 11 | /// 12 | /// Gets or sets name of the enum value 13 | /// 14 | public string Name { get; private set; } 15 | 16 | /// 17 | /// Gets or sets value of the enum 18 | /// 19 | public string Value { get; private set; } 20 | 21 | /// 22 | /// The Reflection API details about the Enum backing value. 23 | /// 24 | public FieldInfo Field { get; private set; } 25 | 26 | /// 27 | /// Initializes a new instance of the TsEnumValue class. 28 | /// 29 | public TsEnumValue() 30 | { 31 | } 32 | 33 | /// 34 | /// Initializes a new instance of the TsEnumValue class with the specific name and value. 35 | /// 36 | /// The name of the enum value. 37 | /// The value of the enum value. 38 | public TsEnumValue(FieldInfo field) 39 | { 40 | this.Field = field; 41 | this.Name = field.Name; 42 | 43 | var value = field.GetValue(null); 44 | 45 | var valueType = Enum.GetUnderlyingType(value.GetType()); 46 | if (valueType == typeof(byte)) 47 | { 48 | this.Value = ((byte)value).ToString(); 49 | } 50 | if (valueType == typeof(sbyte)) 51 | { 52 | this.Value = ((sbyte)value).ToString(); 53 | } 54 | if (valueType == typeof(short)) 55 | { 56 | this.Value = ((short)value).ToString(); 57 | } 58 | if (valueType == typeof(ushort)) 59 | { 60 | this.Value = ((ushort)value).ToString(); 61 | } 62 | if (valueType == typeof(int)) 63 | { 64 | this.Value = ((int)value).ToString(); 65 | } 66 | if (valueType == typeof(uint)) 67 | { 68 | this.Value = ((uint)value).ToString(); 69 | } 70 | if (valueType == typeof(long)) 71 | { 72 | this.Value = ((long)value).ToString(); 73 | } 74 | if (valueType == typeof(ulong)) 75 | { 76 | this.Value = ((ulong)value).ToString(); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsModule.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace TypeLitePlus.TsModels 5 | { 6 | /// 7 | /// Represents a module in the script model. 8 | /// 9 | public class TsModule 10 | { 11 | private ISet _members; 12 | 13 | /// 14 | /// Gets or sets name of the module. 15 | /// 16 | public string Name { get; set; } 17 | 18 | /// 19 | /// 20 | /// 21 | public int SortOrder { get; set; } = 100; 22 | 23 | /// 24 | /// Gets collection of classes in the module. 25 | /// 26 | public IEnumerable Classes 27 | { 28 | get 29 | { 30 | return _members.OfType(); 31 | } 32 | } 33 | 34 | /// 35 | /// Gets collection of enums in the module 36 | /// 37 | public IEnumerable Enums 38 | { 39 | get 40 | { 41 | return _members.OfType(); 42 | } 43 | } 44 | 45 | /// 46 | /// Gets collection of all members of the module 47 | /// 48 | public IEnumerable Members 49 | { 50 | get 51 | { 52 | return _members; 53 | } 54 | } 55 | 56 | /// 57 | /// Initializes a new instance of the TsModule class. 58 | /// 59 | public TsModule(string name) 60 | { 61 | _members = new HashSet(); 62 | this.Name = name; 63 | } 64 | 65 | /// 66 | /// Adds a member to this module. 67 | /// 68 | /// The member to add. 69 | internal void Add(TsModuleMember toAdd) 70 | { 71 | _members.Add(toAdd); 72 | 73 | } 74 | 75 | /// 76 | /// Removes a member from this module. 77 | /// 78 | /// The member to remove. 79 | internal void Remove(TsModuleMember toRemove) 80 | { 81 | _members.Remove(toRemove); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsModuleMember.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus.TsModels 4 | { 5 | /// 6 | /// Represents a type that can be places inside module 7 | /// 8 | public abstract class TsModuleMember : TsType 9 | { 10 | private TsModule _module; 11 | 12 | /// 13 | /// Gets or sets module, that contains this class. 14 | /// 15 | public TsModule Module 16 | { 17 | get 18 | { 19 | return _module; 20 | } 21 | set 22 | { 23 | if (_module != null) 24 | { 25 | _module.Remove(this); 26 | } 27 | _module = value; 28 | if (_module != null) 29 | { 30 | _module.Add(this); 31 | } 32 | } 33 | } 34 | 35 | /// 36 | /// Gets or sets the name of the module member. 37 | /// 38 | public string Name { get; set; } 39 | 40 | /// 41 | /// Initializes TsModuleMember class with the specific CLR type. 42 | /// 43 | /// The CLR type represented by this instance of the ModuleMember 44 | protected TsModuleMember(Type type) 45 | : base(type) 46 | { 47 | 48 | var moduleName = string.Empty; 49 | var declaringType = type.DeclaringType; 50 | while (declaringType != null) 51 | { 52 | moduleName = "." + declaringType.Name + moduleName; 53 | declaringType = declaringType.DeclaringType; 54 | } 55 | moduleName = type.Namespace + moduleName; 56 | 57 | this.Module = new TsModule(moduleName); 58 | this.Name = this.Type.Name; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsProperty.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using System.Linq; 4 | using System.Reflection; 5 | using TypeLitePlus.Extensions; 6 | 7 | namespace TypeLitePlus.TsModels 8 | { 9 | /// 10 | /// Represents a property of the class in the code model. 11 | /// 12 | [DebuggerDisplay("Name: {Name}")] 13 | public class TsProperty 14 | { 15 | public string Name { get; set; } 16 | 17 | /// 18 | /// Gets or sets type of the property. 19 | /// 20 | public TsType PropertyType { get; set; } 21 | 22 | /// 23 | /// Gets the CLR property represented by this TsProperty. 24 | /// 25 | public MemberInfo MemberInfo { get; set; } 26 | 27 | /// 28 | /// Gets or sets bool value indicating whether this property will be ignored by TsGenerator. 29 | /// 30 | public bool IsIgnored { get; set; } 31 | 32 | /// 33 | /// Gets or sets bool value indicating whether this property is optional in TypeScript interface. 34 | /// 35 | public bool IsOptional { get; set; } 36 | 37 | /// 38 | /// Gets the GenericArguments for this property. 39 | /// 40 | public IList GenericArguments { get; private set; } 41 | 42 | /// 43 | /// Gets or sets the constant value of this property. 44 | /// 45 | public object ConstantValue { get; set; } 46 | 47 | /// 48 | /// Initializes a new instance of the TsProperty class with the specific CLR property. 49 | /// 50 | /// The CLR property represented by this instance of the TsProperty. 51 | public TsProperty(PropertyInfo memberInfo) 52 | { 53 | this.MemberInfo = memberInfo; 54 | this.Name = memberInfo.Name; 55 | 56 | var propertyType = memberInfo.PropertyType; 57 | if (propertyType.IsNullable()) 58 | { 59 | propertyType = propertyType.GetNullableValueType(); 60 | } 61 | 62 | this.GenericArguments = propertyType.IsGenericType ? propertyType.GetGenericArguments().Select(o => new TsType(o)).ToArray() : new TsType[0]; 63 | 64 | this.PropertyType = propertyType.IsEnum ? new TsEnum(propertyType) : new TsType(propertyType); 65 | 66 | var attribute = memberInfo.GetCustomAttribute(false); 67 | if (attribute != null) 68 | { 69 | if (!string.IsNullOrEmpty(attribute.Name)) 70 | { 71 | this.Name = attribute.Name; 72 | } 73 | 74 | this.IsOptional = attribute.IsOptional; 75 | } 76 | 77 | this.IsIgnored = (memberInfo.GetCustomAttribute(false) != null); 78 | 79 | // Only fields can be constants. 80 | this.ConstantValue = null; 81 | } 82 | 83 | /// 84 | /// Initializes a new instance of the TsProperty class with the specific CLR field. 85 | /// 86 | /// The CLR field represented by this instance of the TsProperty. 87 | public TsProperty(FieldInfo memberInfo) 88 | { 89 | this.MemberInfo = memberInfo; 90 | this.Name = memberInfo.Name; 91 | 92 | if (memberInfo.ReflectedType.IsGenericType) 93 | { 94 | var definitionType = memberInfo.ReflectedType.GetGenericTypeDefinition(); 95 | var definitionTypeProperty = definitionType.GetProperty(memberInfo.Name); 96 | if (definitionTypeProperty.PropertyType.IsGenericParameter) 97 | { 98 | this.PropertyType = TsType.Any; 99 | } 100 | else 101 | { 102 | this.PropertyType = memberInfo.FieldType.IsEnum ? new TsEnum(memberInfo.FieldType) : new TsType(memberInfo.FieldType); 103 | } 104 | } 105 | else 106 | { 107 | var propertyType = memberInfo.FieldType; 108 | if (propertyType.IsNullable()) 109 | { 110 | propertyType = propertyType.GetNullableValueType(); 111 | } 112 | 113 | this.PropertyType = propertyType.IsEnum ? new TsEnum(propertyType) : new TsType(propertyType); 114 | } 115 | 116 | var attribute = memberInfo.GetCustomAttribute(false); 117 | if (attribute != null) 118 | { 119 | if (!string.IsNullOrEmpty(attribute.Name)) 120 | { 121 | this.Name = attribute.Name; 122 | } 123 | 124 | this.IsOptional = attribute.IsOptional; 125 | } 126 | 127 | this.IsIgnored = (memberInfo.GetCustomAttribute(false) != null); 128 | 129 | if (memberInfo.IsLiteral && !memberInfo.IsInitOnly) 130 | { 131 | // it's a constant 132 | this.ConstantValue = memberInfo.GetValue(null); 133 | } 134 | else 135 | { 136 | // not a constant 137 | this.ConstantValue = null; 138 | } 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsSystemType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus.TsModels 4 | { 5 | /// 6 | /// Represents a system type in the code model. 7 | /// 8 | public class TsSystemType : TsType 9 | { 10 | /// 11 | /// Gets kind of the system type. 12 | /// 13 | public SystemTypeKind Kind { get; private set; } 14 | 15 | /// 16 | /// Initializes a new instance of the TsSystemType with the specific CLR type. 17 | /// 18 | /// The CLR type represented by this instance of the TsSystemType. 19 | public TsSystemType(Type type) 20 | : base(type) 21 | { 22 | 23 | switch (this.Type.Name) 24 | { 25 | case "Boolean": this.Kind = SystemTypeKind.Bool; break; 26 | case "String": 27 | case "Char": 28 | this.Kind = SystemTypeKind.String; break; 29 | case "Byte": 30 | case "SByte": 31 | case "Int16": 32 | case "Int32": 33 | case "Int64": 34 | case "UInt16": 35 | case "UInt32": 36 | case "UInt64": 37 | case "Single": 38 | case "Double": 39 | case "Decimal": 40 | case "IntPtr": 41 | case "UIntPtr": 42 | this.Kind = SystemTypeKind.Number; break; 43 | case "DateTime": 44 | case "DateTimeOffset": 45 | this.Kind = SystemTypeKind.Date; break; 46 | default: 47 | throw new ArgumentException(string.Format("The type '{0}' is not supported system type.", type.FullName)); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using TypeLitePlus.Extensions; 6 | 7 | namespace TypeLitePlus.TsModels 8 | { 9 | /// 10 | /// Represents a type in the code model. 11 | /// 12 | [DebuggerDisplay("TsType - Type: {ClrType}")] 13 | public class TsType 14 | { 15 | /// 16 | /// Gets the CLR type represented by this instance of the TsType. 17 | /// 18 | public Type Type { get; private set; } 19 | 20 | /// 21 | /// Initializes a new instance of the TsType class with the specific CLR type. 22 | /// 23 | /// The CLR type represented by this instance of the TsType. 24 | public TsType(Type type) 25 | { 26 | if (type.IsNullable()) 27 | { 28 | type = type.GetNullableValueType(); 29 | } 30 | 31 | this.Type = type; 32 | } 33 | 34 | /// 35 | /// Represents the TsType for the object CLR type. 36 | /// 37 | public static readonly TsType Any = new TsType(typeof(object)); 38 | 39 | /// 40 | /// Returns true if this property is collection 41 | /// 42 | /// 43 | public bool IsCollection() 44 | { 45 | return GetTypeFamily(this.Type) == TsTypeFamily.Collection; 46 | } 47 | 48 | 49 | 50 | /// 51 | /// Gets TsTypeFamily of the CLR type. 52 | /// 53 | /// The CLR type to get TsTypeFamily of 54 | /// TsTypeFamily of the CLR type 55 | internal static TsTypeFamily GetTypeFamily(System.Type type) 56 | { 57 | if (type.IsNullable()) 58 | { 59 | return TsType.GetTypeFamily(type.GetNullableValueType()); 60 | } 61 | 62 | var isString = (type == typeof(string)); 63 | var isEnumerable = typeof(IEnumerable).IsAssignableFrom(type); 64 | 65 | // surprisingly Decimal isn't a primitive type 66 | if (isString || type.IsPrimitive || type.FullName == "System.Decimal" || type.FullName == "System.DateTime" || type.FullName == "System.DateTimeOffset" || type.FullName == "System.SByte") 67 | { 68 | return TsTypeFamily.System; 69 | } 70 | else if (isEnumerable) 71 | { 72 | return TsTypeFamily.Collection; 73 | } 74 | 75 | if (type.IsEnum) 76 | { 77 | return TsTypeFamily.Enum; 78 | } 79 | 80 | if ((type.IsClass && type.FullName != "System.Object") || type.IsValueType /* structures */ || type.IsInterface) 81 | { 82 | return TsTypeFamily.Class; 83 | } 84 | 85 | return TsTypeFamily.Type; 86 | } 87 | 88 | /// 89 | /// Factory method so that the correct TsType can be created for a given CLR type. 90 | /// 91 | /// 92 | /// 93 | internal static TsType Create(System.Type type) 94 | { 95 | var family = GetTypeFamily(type); 96 | switch (family) 97 | { 98 | case TsTypeFamily.System: 99 | return new TsSystemType(type); 100 | case TsTypeFamily.Collection: 101 | return new TsCollection(type); 102 | case TsTypeFamily.Class: 103 | return new TsClass(type); 104 | case TsTypeFamily.Enum: 105 | return new TsEnum(type); 106 | default: 107 | return new TsType(type); 108 | } 109 | } 110 | 111 | /// 112 | /// Gets type of items in generic version of IEnumerable. 113 | /// 114 | /// The IEnumerable type to get items type from 115 | /// The type of items in the generic IEnumerable or null if the type doesn't implement the generic version of IEnumerable. 116 | internal static Type GetEnumerableType(Type type) 117 | { 118 | if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) 119 | { 120 | return type.GetGenericArguments()[0]; 121 | } 122 | 123 | foreach (Type intType in type.GetInterfaces()) 124 | { 125 | if (intType.IsGenericType && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) 126 | { 127 | return intType.GetGenericArguments()[0]; 128 | } 129 | } 130 | return null; 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModels/TsTypeFamily.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.TsModels 2 | { 3 | /// 4 | /// Represents a type of the TsType 5 | /// 6 | internal enum TsTypeFamily 7 | { 8 | /// 9 | /// System type 10 | /// 11 | /// 12 | /// e.g. string, int, ... 13 | /// 14 | System, 15 | 16 | /// 17 | /// Collection 18 | /// 19 | Collection, 20 | 21 | /// 22 | /// Class 23 | /// 24 | Class, 25 | 26 | /// 27 | /// Enum 28 | /// 29 | Enum, 30 | 31 | /// 32 | /// Other type 33 | /// 34 | Type 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsModuleNameFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TypeLitePlus.TsModels; 3 | 4 | namespace TypeLitePlus 5 | { 6 | /// 7 | /// Formats a module name 8 | /// 9 | /// The module to be formatted 10 | /// The module name after formatting. 11 | public delegate string TsModuleNameFormatter(TsModule module); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsPropertyAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Configures properties of the property in the script model. 7 | /// 8 | [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] 9 | public sealed class TsPropertyAttribute : Attribute 10 | { 11 | /// 12 | /// Gets or sets name of the property in script model. 13 | /// 14 | public string Name { get; set; } 15 | 16 | /// 17 | /// Gets or sets bool value indicating whether the property is optional in the Typescript interface. 18 | /// 19 | public bool IsOptional { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsTypeFormatter.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.TsModels; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Defines a method used to format specific TsType to the string representation. 7 | /// 8 | /// The type to format. 9 | /// The formatter that can format other types. 10 | /// The string representation of the type. 11 | public delegate string TsTypeFormatter(TsType type, ITsTypeFormatter formatter); 12 | } 13 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsTypeFormatterCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using TypeLitePlus.TsModels; 4 | 5 | namespace TypeLitePlus 6 | { 7 | /// 8 | /// Manages collection of TsTypeFormatters 9 | /// 10 | public class TsTypeFormatterCollection : ITsTypeFormatter 11 | { 12 | internal Dictionary _formatters; 13 | 14 | /// 15 | /// Initializes a new instance of the TsTypeFormatterCollection class 16 | /// 17 | internal TsTypeFormatterCollection() 18 | { 19 | _formatters = new Dictionary(); 20 | } 21 | 22 | /// 23 | /// Converts the specific type to it's string representation using a formatter registered for the type 24 | /// 25 | /// The type to format. 26 | /// The string representation of the type. 27 | public string FormatType(TsType type) 28 | { 29 | if (_formatters.ContainsKey(type.GetType())) 30 | { 31 | return _formatters[type.GetType()](type, this); 32 | } 33 | else 34 | { 35 | return "any"; 36 | } 37 | } 38 | 39 | /// 40 | /// Registers the formatter for the specific TsType 41 | /// 42 | /// The type to register the formatter for. TFor is restricted to TsType and derived classes. 43 | /// The formatter to register 44 | public void RegisterTypeFormatter(TsTypeFormatter formatter) where TFor : TsType 45 | { 46 | _formatters[typeof(TFor)] = formatter; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TsTypeVisibilityFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TypeLitePlus.TsModels; 3 | 4 | namespace TypeLitePlus 5 | { 6 | /// 7 | /// Defines a method used to determine if a type should be marked with the keyword "export". 8 | /// 9 | /// The class model to format 10 | /// The type name to format 11 | /// A bool indicating if a member should be exported. 12 | public delegate bool TsTypeVisibilityFormatter(TsClass tsClass, string typeName); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TypeConvertor.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus 2 | { 3 | /// 4 | /// Defines a method used to convert specific Type to the string representation. 5 | /// 6 | /// The type to convert. 7 | /// The string representation of the type. 8 | public delegate string TypeConvertor(object type); 9 | } 10 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TypeConvertorCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace TypeLitePlus 5 | { 6 | /// 7 | /// Contains a collection of converters that provides a way to convert the specific type to custom string bypassing other rules. 8 | /// 9 | public class TypeConvertorCollection 10 | { 11 | internal Dictionary _convertors; 12 | 13 | /// 14 | /// Initializes a new instance of the TypeConvertorCollection class. 15 | /// 16 | public TypeConvertorCollection() 17 | { 18 | _convertors = new Dictionary(); 19 | } 20 | 21 | /// 22 | /// Registers the converter for the specific Type 23 | /// 24 | /// The type to register the converter for. 25 | /// The converter to register 26 | public void RegisterTypeConverter(TypeConvertor convertor) 27 | { 28 | _convertors[typeof(TFor)] = convertor; 29 | } 30 | 31 | /// 32 | /// Checks whether any converter is registered for the specific Type 33 | /// 34 | /// The type to check 35 | /// true if a converter is registered for the specific Type otherwise return false 36 | public bool IsConvertorRegistered(Type type) 37 | { 38 | return _convertors.ContainsKey(type); 39 | } 40 | 41 | /// 42 | /// Converts specific type to its string representation. 43 | /// 44 | /// The type to convert 45 | /// the string representation of the type if a converter of the type is registered otherwise return null 46 | public string ConvertType(Type type) 47 | { 48 | if (_convertors.ContainsKey(type)) 49 | { 50 | return _convertors[type](type); 51 | } 52 | 53 | return null; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TypeLitePlus.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0;net461 5 | 2.0.0 6 | Lukas Kabrt, Robert McLaws, and contributors. 7 | Generates TypeScript classes or interfaces from .Net Standard 2.0 classes. This package contains only binaries without T4 templates. 8 | Copyright &copy; 2018 Lukas Kabrt, Robert McLaws, and CloudNimble, Inc. 9 | TypeScript, TypeLite, d.ts 10 | true 11 | http://type.litesolutions.net 12 | https://github.com/CloudNimble/TypeLitePlus 13 | https://choosealicense.com/licenses/mit/ 14 | 15 | 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TypeResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using TypeLitePlus.TsModels; 4 | 5 | namespace TypeLitePlus 6 | { 7 | /// 8 | /// Resolves TsTypes to more specialized types 9 | /// 10 | /// 11 | /// When a class is added to the model by TsModelBuilder, TsType is used for all type references. The purpose of the TypeResolver is to visit references and resolve them to the specific types. 12 | /// 13 | internal class TypeResolver : TsModelVisitor 14 | { 15 | TsModel _model; 16 | Dictionary _knownTypes; 17 | Dictionary _modules; 18 | 19 | /// 20 | /// Initializes a new instance of the TypeResolver. 21 | /// 22 | /// The model to process. 23 | public TypeResolver(TsModel model) 24 | { 25 | _model = model; 26 | _modules = new Dictionary(); 27 | _knownTypes = new Dictionary(); 28 | 29 | foreach (var classModel in model.Classes) 30 | { 31 | _knownTypes[classModel.Type] = classModel; 32 | } 33 | 34 | foreach (var enumModel in model.Enums) 35 | { 36 | _knownTypes[enumModel.Type] = enumModel; 37 | } 38 | } 39 | 40 | /// 41 | /// Resolves references in the class. 42 | /// 43 | /// 44 | public override void VisitClass(TsClass classModel) 45 | { 46 | if (classModel.Module != null) 47 | { 48 | classModel.Module = this.ResolveModule(classModel.Module.Name); 49 | } 50 | 51 | if (classModel.BaseType != null && classModel.BaseType != TsType.Any) 52 | { 53 | classModel.BaseType = this.ResolveType(classModel.BaseType, false); 54 | } 55 | 56 | for (int i = 0; i < classModel.Interfaces.Count; i++) 57 | { 58 | classModel.Interfaces[i] = this.ResolveType(classModel.Interfaces[i], false); 59 | } 60 | } 61 | 62 | /// 63 | /// Resolves references in the enum. 64 | /// 65 | /// 66 | public override void VisitEnum(TsEnum enumModel) 67 | { 68 | if (enumModel.Module != null) 69 | { 70 | enumModel.Module = this.ResolveModule(enumModel.Module.Name); 71 | } 72 | } 73 | 74 | /// 75 | /// Resolves references in the property. 76 | /// 77 | /// 78 | public override void VisitProperty(TsProperty property) 79 | { 80 | if (property.IsIgnored) 81 | { 82 | return; 83 | } 84 | property.PropertyType = this.ResolveType(property.PropertyType); 85 | if (property.GenericArguments != null) 86 | { 87 | for (int i = 0; i < property.GenericArguments.Count; i++) 88 | { 89 | property.GenericArguments[i] = this.ResolveType(property.GenericArguments[i]); 90 | } 91 | } 92 | } 93 | 94 | /// 95 | /// Resolves TsType to the more specialized type. 96 | /// 97 | /// The type to resolve. 98 | /// 99 | private TsType ResolveType(TsType toResolve, bool useOpenGenericDefinition = true) 100 | { 101 | if (!(toResolve is TsType)) 102 | { 103 | return toResolve; 104 | } 105 | 106 | if (_knownTypes.ContainsKey(toResolve.Type)) 107 | { 108 | return _knownTypes[toResolve.Type]; 109 | } 110 | else if (toResolve.Type.IsGenericType && useOpenGenericDefinition) 111 | { 112 | // We stored its open type definition instead 113 | TsType openType = null; 114 | if (_knownTypes.TryGetValue(toResolve.Type.GetGenericTypeDefinition(), out openType)) 115 | { 116 | return openType; 117 | } 118 | } 119 | else if (toResolve.Type.IsGenericType) 120 | { 121 | var genericType = TsType.Create(toResolve.Type); 122 | _knownTypes[toResolve.Type] = genericType; 123 | return genericType; 124 | } 125 | 126 | var typeFamily = TsType.GetTypeFamily(toResolve.Type); 127 | TsType type = null; 128 | 129 | switch (typeFamily) 130 | { 131 | case TsTypeFamily.System: type = new TsSystemType(toResolve.Type); break; 132 | case TsTypeFamily.Collection: type = this.CreateCollectionType(toResolve); break; 133 | case TsTypeFamily.Enum: type = new TsEnum(toResolve.Type); break; 134 | default: type = TsType.Any; break; 135 | } 136 | 137 | _knownTypes[toResolve.Type] = type; 138 | return type; 139 | } 140 | 141 | /// 142 | /// Creates a TsCollection from TsType 143 | /// 144 | /// 145 | /// 146 | private TsCollection CreateCollectionType(TsType type) 147 | { 148 | var resolved = new TsCollection(type.Type); 149 | resolved.ItemsType = this.ResolveType(resolved.ItemsType, false); 150 | return resolved; 151 | } 152 | 153 | /// 154 | /// Resolves module instance from the module name. 155 | /// 156 | /// The name of the module 157 | /// 158 | private TsModule ResolveModule(string name) 159 | { 160 | name = name ?? string.Empty; 161 | 162 | if (_modules.ContainsKey(name)) 163 | { 164 | return _modules[name]; 165 | } 166 | 167 | var module = new TsModule(name); 168 | _modules[name] = module; 169 | _model.Modules.Add(module); 170 | return module; 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /TypeLitePlus.Core/TypeScript.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using TypeLitePlus.TsModels; 4 | 5 | namespace TypeLitePlus 6 | { 7 | /// 8 | /// Provides helper methods for generating TypeScript definition files. 9 | /// 10 | public static class TypeScript 11 | { 12 | /// 13 | /// Creates an instance of the FluentTsModelBuider for use in T4 templates. 14 | /// 15 | /// An instance of the FluentTsModelBuider 16 | public static TypeScriptFluent Definitions() 17 | { 18 | return new TypeScriptFluent(); 19 | } 20 | 21 | /// 22 | /// Creates an instance of the FluentTsModelBuider for use in T4 templates. 23 | /// 24 | /// The script generator you want it constructed with 25 | /// An instance of the FluentTsModelBuider 26 | public static TypeScriptFluent Definitions(TsGenerator scriptGenerator) 27 | { 28 | return new TypeScriptFluent(scriptGenerator); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /TypeLitePlus.Core/TypeScriptFluentModuleMember.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.TsModels; 2 | 3 | namespace TypeLitePlus 4 | { 5 | /// 6 | /// Represents a wrapper around TsModelBuilder and TsGenerator that simplify usage a enables fluent configuration for types. 7 | /// 8 | public class TypeScriptFluentModuleMember : TypeScriptFluent 9 | { 10 | /// 11 | /// Gets the class being configured. 12 | /// 13 | public TsModuleMember Member { get; protected set; } 14 | 15 | internal TypeScriptFluentModuleMember(TypeScriptFluent fluentConfigurator, TsModuleMember member) 16 | : base(fluentConfigurator) 17 | { 18 | this.Member = member; 19 | } 20 | 21 | /// 22 | /// Changes the name of the type being configured . 23 | /// 24 | /// The new name of the type 25 | /// Instance of the TypeScriptFluentModuleMember that enables fluent configuration. 26 | public TypeScriptFluentModuleMember Named(string name) 27 | { 28 | this.Member.Name = name; 29 | return this; 30 | } 31 | 32 | /// 33 | /// Maps the type being configured to the specific module 34 | /// 35 | /// The name of the module 36 | /// Instance of the TypeScriptFluentModuleMember that enables fluent configuration. 37 | public TypeScriptFluentModuleMember ToModule(string moduleName) 38 | { 39 | this.Member.Module = new TsModule(moduleName); 40 | return this; 41 | } 42 | 43 | /// 44 | /// Ignores this member when generating typescript 45 | /// 46 | /// Instance of the TypeScriptFluentModuleMember that enables fluent configuration. 47 | public TypeScriptFluentModuleMember Ignore() 48 | { 49 | if (Member is TsClass) 50 | { 51 | ((TsClass)Member).IsIgnored = true; 52 | } 53 | return this; 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /TypeLitePlus.Core/XmlDocumentationProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Xml.XPath; 6 | 7 | namespace TypeLitePlus 8 | { 9 | /// 10 | /// A custom that reads the API documentation from an XML documentation file. 11 | /// 12 | public class XmlDocumentationProvider 13 | { 14 | private XPathNavigator _documentNavigator; 15 | private const string TypeExpression = "/doc/members/member[@name='T:{0}']"; 16 | private const string MethodExpression = "/doc/members/member[@name='M:{0}']"; 17 | private const string PropertyExpression = "/doc/members/member[@name='P:{0}']"; 18 | private const string FieldExpression = "/doc/members/member[@name='F:{0}']"; 19 | private const string ParameterExpression = "param[@name='{0}']"; 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// The physical path to XML document. 25 | public XmlDocumentationProvider(string documentPath) 26 | { 27 | if (documentPath == null) 28 | { 29 | throw new ArgumentNullException("documentPath"); 30 | } 31 | XPathDocument xpath = new XPathDocument(documentPath); 32 | _documentNavigator = xpath.CreateNavigator(); 33 | } 34 | 35 | public string GetDocumentation(MemberInfo member) 36 | { 37 | string memberName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(member.DeclaringType), member.Name); 38 | string expression = member.MemberType == MemberTypes.Field ? FieldExpression : PropertyExpression; 39 | string selectExpression = String.Format(CultureInfo.InvariantCulture, expression, memberName); 40 | XPathNavigator propertyNode = _documentNavigator.SelectSingleNode(selectExpression); 41 | return GetTagValue(propertyNode, "summary"); 42 | } 43 | 44 | public string GetDocumentation(Type type) 45 | { 46 | XPathNavigator typeNode = GetTypeNode(type); 47 | return GetTagValue(typeNode, "summary"); 48 | } 49 | 50 | private static string GetMemberName(MethodInfo method) 51 | { 52 | string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(method.DeclaringType), method.Name); 53 | ParameterInfo[] parameters = method.GetParameters(); 54 | if (parameters.Length != 0) 55 | { 56 | string[] parameterTypeNames = parameters.Select(param => GetTypeName(param.ParameterType)).ToArray(); 57 | name += String.Format(CultureInfo.InvariantCulture, "({0})", String.Join(",", parameterTypeNames)); 58 | } 59 | 60 | return name; 61 | } 62 | 63 | private static string GetTagValue(XPathNavigator parentNode, string tagName) 64 | { 65 | if (parentNode != null) 66 | { 67 | XPathNavigator node = parentNode.SelectSingleNode(tagName); 68 | if (node != null) 69 | { 70 | return node.Value.Trim(); 71 | } 72 | } 73 | 74 | return null; 75 | } 76 | 77 | private XPathNavigator GetTypeNode(Type type) 78 | { 79 | string controllerTypeName = GetTypeName(type); 80 | string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, controllerTypeName); 81 | return _documentNavigator.SelectSingleNode(selectExpression); 82 | } 83 | 84 | private static string GetTypeName(Type type) 85 | { 86 | string name = type.FullName; 87 | if (type.IsGenericType) 88 | { 89 | // Format the generic type name to something like: Generic{System.Int32,System.String} 90 | Type genericType = type.GetGenericTypeDefinition(); 91 | Type[] genericArguments = type.GetGenericArguments(); 92 | string genericTypeName = genericType.FullName; 93 | 94 | // Trim the generic parameter counts from the name 95 | genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`')); 96 | string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray(); 97 | name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames)); 98 | } 99 | if (type.IsNested) 100 | { 101 | // Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax. 102 | if (name != null) name = name.Replace("+", "."); 103 | } 104 | 105 | return name; 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /TypeLitePlus.DotNetScript/TypeLite.csx: -------------------------------------------------------------------------------- 1 | #! "netcoreapp3.1" 2 | 3 | //INFO: Make sure you're getting the latest version here, Roslyn doesn't let you specify version ranges. 4 | // See https://github.com/dotnet/roslyn/issues/30823 5 | #r "nuget: TypeLitePlus.Core, 2.1.0" 6 | 7 | //INFO: The commented line below is an example of using a NuGet package right in the script. 8 | //#r "nuget: NodaTime, 2.4.0" 9 | 10 | //INFO: The commented line below is an example of referencing an assembly from your project. 11 | // Must be a relative reference. This example assumes the script is in the root of the project. 12 | //#r "bin/Debug/netcoreapp2.1/YourNamespace.YourApp.YourComponent.dll" 13 | 14 | using System.IO; 15 | using TypeLitePlus; 16 | //INFO: Don't forget to add your "usings" here. 17 | 18 | //INFO: Make the properties nullable if you want to be able to use anonymous signatures. 19 | var ts = TypeScript.Definitions() 20 | //INFO: Uncomment the line below if you'd like to generate exported classes instead of declared interfaces. 21 | //.WithMode(TsGenerationModes.Classes) 22 | .WithMemberFormatter((identifier) => 23 | identifier.Name + "?"); 24 | 25 | //INFO: It's usually a good idea to explicitly specify your types. 26 | ts.For(); 27 | 28 | File.WriteAllText("YOURFILENAME.ts", ts.Generate()); -------------------------------------------------------------------------------- /TypeLitePlus.DotNetScript/TypeLitePlus.DotNetScript.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Lukas Kabrt, Robert McLaws, and contributors. 6 | 2.0.0 7 | Generates TypeScript classes or interfaces from .Net Standard 2.0 classes. This package uses the DotNet.Script toolchain to run .csx files to generate your TypeScript classes in .NET Core apps. 8 | Copyright &copy; 2018 Lukas Kabrt, Robert McLaws, and CloudNimble, Inc. 9 | http://type.litesolutions.net 10 | https://github.com/CloudNimble/TypeLitePlus 11 | TypeScript, TypeLite, d.ts 12 | https://choosealicense.com/licenses/mit/ 13 | true 14 | false 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /TypeLitePlus.T4/Scripts/TypeLite.tt: -------------------------------------------------------------------------------- 1 | <#@ template debug="false" hostspecific="True" language="C#" #> 2 | <#@ assembly name="netstandard.dll" #> 3 | <#@ assembly name="$(TargetDir)TypeLitePlus.Core.dll" #> 4 | <#@ assembly name="$(TargetDir)$(TargetFileName)" #> 5 | 6 | <#@ import namespace="TypeLitePlus" #> 7 | <#@output extension=".d.ts"#> 8 | 9 | <#@include file="Manager.ttinclude"#> 10 | <# var manager = EntityFrameworkTemplateFileManager.Create(this); #> 11 | 12 | <# var ts = TypeScript.Definitions() 13 | .WithReference("Enums.ts"); 14 | #> 15 | 16 | <#= ts.Generate(TsGeneratorOutput.Properties) #> 17 | 18 | <# manager.StartNewFile("Enums.ts"); #> 19 | <#= ts.Generate(TsGeneratorOutput.Enums) #> 20 | <# 21 | manager.EndBlock(); 22 | manager.Process(true); 23 | #> -------------------------------------------------------------------------------- /TypeLitePlus.T4/TypeLitePlus.T4.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0;net461 5 | Lukas Kabrt, Robert McLaws, and contributors. 6 | 2.0.0 7 | Generates TypeScript classes or interfaces from .Net Standard 2.0 classes. This package uses the T4 toolchain to run .tt files to generate your TypeScript classes in .NET Standard apps. 8 | Copyright &copy; 2018 Lukas Kabrt, Robert McLaws, and CloudNimble, Inc. 9 | http://type.litesolutions.net 10 | https://github.com/CloudNimble/TypeLitePlus 11 | TypeScript, TypeLite, d.ts 12 | https://choosealicense.com/licenses/mit/ 13 | true 14 | false 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Always 25 | 26 | 27 | None 28 | TypeLite.d.ts 29 | Always 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.AssemblyWithEnum/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TypeLitePlus.Tests.AssemblyWithEnum")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TypeLitePlus.Tests.AssemblyWithEnum")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("99818a20-da2b-4ed4-a96d-e6fae2dbed48")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.AssemblyWithEnum/TestEnum.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.AssemblyWithEnum 2 | { 3 | [TsEnum] 4 | public enum TestEnum { 5 | One = 1, 6 | Two = 2, 7 | Three = 3 8 | } 9 | 10 | } 11 | 12 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.AssemblyWithEnum/TypeLitePlus.Tests.AssemblyWithEnum.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {99818A20-DA2B-4ED4-A96D-E6FAE2DBED48} 8 | Library 9 | Properties 10 | TypeLitePlus.Tests.AssemblyWithEnum 11 | TypeLitePlus.Tests.AssemblyWithEnum 12 | v4.7.2 13 | 512 14 | true 15 | 16 | false 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | true 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {1b55f4a6-e57c-4e5c-9186-85fcf4be0ff0} 53 | TypeLitePlus.Core 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/Extensions/TypeExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using TypeLitePlus.Extensions; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.Extensions 6 | { 7 | public class TypeExtensionsTests 8 | { 9 | 10 | #region IsNullable tests 11 | 12 | [Fact] 13 | public void WhenIsNullableIsCalledWithNullableType_TrueIsReturned() 14 | { 15 | var type = typeof(int?); 16 | 17 | Assert.True(type.IsNullable()); 18 | } 19 | 20 | [Fact] 21 | public void WhenIsNullableIsCalledWithValueType_FalseIsReturned() 22 | { 23 | var type = typeof(int); 24 | 25 | Assert.False(type.IsNullable()); 26 | } 27 | 28 | [Fact] 29 | public void WhenIsNullableIsCalledWithReferenceType_FalseIsReturned() 30 | { 31 | var type = typeof(string); 32 | 33 | Assert.False(type.IsNullable()); 34 | } 35 | 36 | #endregion 37 | 38 | #region GetNullableValueType tests 39 | 40 | [Fact] 41 | public void WhenGetNullableValueTypeWithNullableValueType_ValueTypeIsReturned() 42 | { 43 | var type = typeof(int?); 44 | 45 | Assert.Equal(typeof(int), type.GetNullableValueType()); 46 | } 47 | 48 | [Fact] 49 | public void WhenGetNullableValueTypeWithNonNullableType_ExceptionIsThrown() 50 | { 51 | var type = typeof(string); 52 | 53 | Assert.Throws(() => type.GetNullableValueType()); 54 | } 55 | 56 | #endregion 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/DateTimeTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 5 | { 6 | public class DateTimeTests 7 | { 8 | [Fact] 9 | public void WhenDateTimePropertyIsInModel_DateWithUppercaseDIsGenerated() 10 | { 11 | var builder = new TsModelBuilder(); 12 | builder.Add(); 13 | 14 | var generator = new TsGenerator(); 15 | var model = builder.Build(); 16 | var result = generator.Generate(model); 17 | 18 | Assert.Contains("Property: Date", result); 19 | } 20 | } 21 | 22 | public class ModelWithDateTime 23 | { 24 | public DateTime Property { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/DbGeometryIgnoreTests.cs: -------------------------------------------------------------------------------- 1 | #if !NETSTANDARD2_0 && !NETCOREAPP2_1 && !NETCOREAPP2_2 2 | 3 | using System.Data.Spatial; 4 | using Xunit; 5 | 6 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 7 | { 8 | public class DbGeometryIgnoreTests { 9 | [Fact] 10 | public void WhenPropertyWithDbGeometryTypeIsAnnotedWithTsIgnoreAttribute_GeneratorDoesntCrash() { 11 | var builder = new TsModelBuilder(); 12 | builder.Add(); 13 | 14 | var generator = new TsGenerator(); 15 | var model = builder.Build(); 16 | 17 | Assert.DoesNotThrow(() => generator.Generate(model)); 18 | } 19 | } 20 | 21 | public class DbGeometryTestClass { 22 | public int ID { get; set; } 23 | 24 | [TsIgnore] 25 | public DbGeometry Position { get; set; } 26 | } 27 | } 28 | #endif -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Generics0_8Tests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TypeLitePlus.Tests.NetCore.TestModels; 3 | using Xunit; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 6 | { 7 | public class Generics0_8Tests 8 | { 9 | [Fact] 10 | public void WhenClassHasGenericArguments_ValidTypescriptNameIsGenerated() 11 | { 12 | var builder = new TsModelBuilder(); 13 | builder.Add>(); 14 | 15 | var generator = new TsGenerator(); 16 | var model = builder.Build(); 17 | var result = generator.Generate(model); 18 | Console.WriteLine(result); 19 | 20 | Assert.Contains("interface ClassWithGenericArguments {", result); 21 | } 22 | 23 | [Fact] 24 | public void WhenClassHasGenericProperty_PropertyTypeIsResolvedToTypeOfGenericArgument() 25 | { 26 | var builder = new TsModelBuilder(); 27 | builder.Add>(); 28 | 29 | var generator = new TsGenerator(); 30 | var model = builder.Build(); 31 | var result = generator.Generate(model); 32 | 33 | Assert.Contains("Property: T", result); 34 | } 35 | } 36 | 37 | public class ClassWithGenericArguments 38 | { 39 | public T Property { get; set; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue103_GlobalizationTypes.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using Xunit; 3 | 4 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 5 | { 6 | public class Issue103_GlobalizationTypes 7 | { 8 | [Fact] 9 | public void GlobalizationTypesCreatedWhenNotUsed() 10 | { 11 | var ts = TypeScript.Definitions(); 12 | ts.WithConvertor(type => { return "string"; }).For().WithConvertor(type => { return "string"; }); 13 | var result = ts.Generate(TsGeneratorOutput.Properties); 14 | 15 | 16 | } 17 | 18 | class TestClass 19 | { 20 | public CultureInfo CultureInfo { get; set; } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue14_IgnoreAttributeIsNotWorking.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.Tests.NetCore.TestModels; 2 | using Xunit; 3 | 4 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 5 | { 6 | public class Issue14_IgnoreAttributeIsNotWorking 7 | { 8 | [Fact] 9 | public void WhenPropertyHastsIgnoreAttribute_TypeOfIgnoredPropertyIsExcludedFromModel() 10 | { 11 | var builder = new TsModelBuilder(); 12 | builder.Add(); 13 | 14 | var generator = new TsGenerator(); 15 | var model = builder.Build(); 16 | var script = generator.Generate(model); 17 | 18 | Assert.DoesNotContain("Person", script); 19 | } 20 | } 21 | 22 | public class Issue14Example 23 | { 24 | public string Name { get; set; } 25 | 26 | [TsIgnore] 27 | public Person Contact { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue15_ConvertSystemType.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 4 | { 5 | public class Issue15_ConvertSystemType 6 | { 7 | [Fact] 8 | public void WhenClassContainsPropertyOfSystemType_InvalidCastExceptionIsntThrown() 9 | { 10 | var builder = new TsModelBuilder(); 11 | builder.Add(); 12 | 13 | var generator = new TsGenerator(); 14 | var model = builder.Build(); 15 | 16 | var ex = Record.Exception(() => generator.Generate(model)); 17 | Assert.Null(ex); 18 | } 19 | } 20 | 21 | public class Issue15Example 22 | { 23 | public System.Type Type { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue24_NullableEnumProperty.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 4 | { 5 | public class Issue24_NullableEnumProperty 6 | { 7 | [Fact] 8 | public void WhenClassContainsNullableEnumProperty_ExceptionIsNotThrown() 9 | { 10 | var builder = new TsModelBuilder(); 11 | builder.Add(); 12 | 13 | var generator = new TsGenerator(); 14 | var model = builder.Build(); 15 | 16 | var ex = Record.Exception(() => generator.Generate(model)); 17 | Assert.Null(ex); 18 | } 19 | } 20 | 21 | public class Issue24Example 22 | { 23 | public Issue24Enum? EnumProperty { get; set; } 24 | } 25 | 26 | public enum Issue24Enum 27 | { 28 | A = 1, 29 | B = 2 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue32_DuplicateInterfacesForClosedGenericPropertyTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Xunit; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 6 | { 7 | public class Issue32_DuplicateInterfacesForClosedGenericPropertyTypes 8 | { 9 | [Fact] 10 | public void WhenClosedGenericTypeAppearsAsPropertyTypeMultipleTimes_OnlyOneInterfaceGenerated() 11 | { 12 | var builder = new TsModelBuilder(); 13 | builder.Add(); 14 | 15 | var generator = new TsGenerator(); 16 | var model = builder.Build(); 17 | 18 | var result = generator.Generate(model); 19 | 20 | Assert.True(result.IndexOf("interface KeyValuePair") > -1, "KeyValuePair interface missing"); 21 | Assert.True(result.IndexOf("interface KeyValuePair") == result.LastIndexOf("interface KeyValuePair"), "KeyValuePair interface generated too many times"); 22 | 23 | Assert.Contains("Test1: System.Collections.Generic.KeyValuePair", result); 24 | Assert.Contains("Test2: System.Collections.Generic.KeyValuePair", result); 25 | } 26 | 27 | [TsClass] 28 | public class GenericPropertiesBug 29 | { 30 | public KeyValuePair Test1 { get; set; } 31 | public KeyValuePair Test2 { get; set; } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue33_EnumCollectionTypePropertyFailsToGenerateEnum.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Xunit; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 6 | { 7 | public class Issue33_EnumCollectionTypePropertyFailsToGenerateEnum 8 | { 9 | [Fact] 10 | public void WhenEnumTypeAppearsOnlyInCollectionTypeProperty_EnumIsGenerated() 11 | { 12 | var builder = new TsModelBuilder(); 13 | builder.Add(); 14 | 15 | var generator = new TsGenerator(); 16 | var model = builder.Build(); 17 | var result = generator.Generate(model); 18 | 19 | Assert.True(model.Enums.Count == 1); 20 | Assert.True(model.Enums.Single().Type == typeof(AuthenticationError)); 21 | } 22 | 23 | [TsClass] 24 | public class AuthenticationResult 25 | { 26 | public IList Errors { get; set; } 27 | } 28 | 29 | public enum AuthenticationError 30 | { 31 | One, 32 | Two 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue41_EnumsInGenericClasses.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 4 | { 5 | public class Issue41_EnumsInGenericClasses 6 | { 7 | [Fact] 8 | public void DoesNotThrowNullReferenceException_WhenEnumPropertyInGenericClass() 9 | { 10 | 11 | var ex = Record.Exception(() => 12 | { 13 | var builder = new TsModelBuilder(); 14 | builder.Add>(); 15 | 16 | var generator = new TsGenerator(); 17 | var model = builder.Build(); 18 | var result = generator.Generate(model); 19 | }); 20 | Assert.Null(ex); 21 | } 22 | 23 | [TsClass] 24 | public class Bob 25 | { 26 | public MyTestEnum MyEnum { get; set; } 27 | public string TestString { get; set; } 28 | public string MyProperty { get; set; } 29 | } 30 | 31 | [TsEnum] 32 | public enum MyTestEnum 33 | { 34 | One, 35 | Two, 36 | Three 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue43_EnumsWithDeclare.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 5 | { 6 | public class Issue43_EnumsWithDeclare 7 | { 8 | [Fact] 9 | public void WhenModuleIsGeneratedWithEnumsOnlyOption_ModuleDoesntHaveDeclareKeyword() 10 | { 11 | var builder = new TsModelBuilder(); 12 | builder.Add(); 13 | 14 | var generator = new TsGenerator(); 15 | var model = builder.Build(); 16 | var result = generator.Generate(model, TsGeneratorOutput.Enums); 17 | 18 | Assert.DoesNotContain("declare", result); 19 | } 20 | 21 | [Fact] 22 | public void WhenModuleIsGeneratedWithConstantsOnlyOption_ModuleDoesntHaveDeclareKeyword() 23 | { 24 | var builder = new TsModelBuilder(); 25 | builder.Add(); 26 | 27 | var generator = new TsGenerator(); 28 | var model = builder.Build(); 29 | var result = generator.Generate(model, TsGeneratorOutput.Constants); 30 | 31 | Assert.DoesNotContain("declare", result); 32 | } 33 | 34 | [Fact] 35 | public void WhenModuleIsGeneratedWithConstantsAndProperties_ThrowsInvalidOperationException() 36 | { 37 | var builder = new TsModelBuilder(); 38 | builder.Add(); 39 | 40 | var generator = new TsGenerator(); 41 | var model = builder.Build(); 42 | Assert.Throws(() => 43 | { 44 | generator.Generate(model, TsGeneratorOutput.Constants | TsGeneratorOutput.Properties); 45 | }); 46 | } 47 | 48 | [Fact] 49 | public void WhenModuleIsGeneratedWithConstantsAndFields_ThrowsInvalidOperationException() 50 | { 51 | var builder = new TsModelBuilder(); 52 | builder.Add(); 53 | 54 | var generator = new TsGenerator(); 55 | var model = builder.Build(); 56 | Assert.Throws(() => 57 | { 58 | generator.Generate(model, TsGeneratorOutput.Constants | TsGeneratorOutput.Fields); 59 | }); 60 | } 61 | 62 | [Fact] 63 | public void WhenModuleIsGeneratedWithPropertiesOnlyOption_ModuleHasDeclareKeyword() 64 | { 65 | var builder = new TsModelBuilder(); 66 | builder.Add(); 67 | 68 | var generator = new TsGenerator(); 69 | var model = builder.Build(); 70 | var result = generator.Generate(model, TsGeneratorOutput.Properties); 71 | 72 | Assert.Contains("declare", result); 73 | } 74 | 75 | [Fact] 76 | public void WhenModuleIsGeneratedWithFieldsOnlyOption_ModuleHasDeclareKeyword() 77 | { 78 | var builder = new TsModelBuilder(); 79 | builder.Add(); 80 | 81 | var generator = new TsGenerator(); 82 | var model = builder.Build(); 83 | var result = generator.Generate(model, TsGeneratorOutput.Fields); 84 | 85 | Assert.Contains("declare", result); 86 | } 87 | 88 | public class MyTestClass 89 | { 90 | public int ID { get; set; } 91 | public MyTestEnum Enum { get; set; } 92 | } 93 | 94 | public enum MyTestEnum 95 | { 96 | One, 97 | Two, 98 | Three 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue44_EnumsWithExport.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 4 | { 5 | public class Issue44_EnumsWithExport 6 | { 7 | [Fact] 8 | public void WhenEnumIsGenerated_ItHasExportKeyword() 9 | { 10 | var builder = new TsModelBuilder(); 11 | builder.Add(); 12 | 13 | var generator = new TsGenerator(); 14 | var model = builder.Build(); 15 | var result = generator.Generate(model, TsGeneratorOutput.Enums); 16 | 17 | Assert.Contains("export", result); 18 | } 19 | 20 | public class MyTestClass 21 | { 22 | public int ID { get; set; } 23 | public MyTestEnum Enum { get; set; } 24 | } 25 | 26 | public enum MyTestEnum 27 | { 28 | One, 29 | Two, 30 | Three 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue45_EmptyNamespaceInEmuns.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 4 | { 5 | public class Issue45_EmptyNamespaceInEmuns 6 | { 7 | [Fact] 8 | public void WhenModuleDoesntContainsAnyEnums_ItIsntGeneratedWithEnumsOption() 9 | { 10 | var builder = new TsModelBuilder(); 11 | builder.Add(); 12 | 13 | var generator = new TsGenerator(); 14 | var model = builder.Build(); 15 | var result = generator.Generate(model, TsGeneratorOutput.Enums); 16 | 17 | Assert.DoesNotContain("MyTestModule", result); 18 | } 19 | 20 | [TsClass(Module = "MyTestModule")] 21 | public class MyTestClass 22 | { 23 | public int ID { get; set; } 24 | public MyTestEnum Enum { get; set; } 25 | } 26 | 27 | [TsEnum(Module = "EnumsModule")] 28 | public enum MyTestEnum 29 | { 30 | One, 31 | Two, 32 | Three 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue48_ToModuleForEnums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 5 | { 6 | public class Issue48_ToModuleForEnums 7 | { 8 | [Fact] 9 | public void WhenModuleContainsStandAloneEnumWithToModule_EnumIsGeneratedInTheSpecifiedModule() 10 | { 11 | var ts = TypeScript.Definitions() 12 | .For().ToModule("Foo") 13 | .Generate(); 14 | Console.WriteLine(ts); 15 | Assert.Contains("namespace Foo", ts); 16 | Assert.Contains("enum MyTestEnum", ts); 17 | } 18 | 19 | enum MyTestEnum 20 | { 21 | One, 22 | Two, 23 | Three 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue51_ArrayOfArrayOutput.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Xunit; 3 | 4 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 5 | { 6 | public class Issue51_ArrayOfArrayOutput 7 | { 8 | [Fact] 9 | public void WhenArrayOfArrayEncountered_ArrayOfArrayTypeScriptTypeGenerated() 10 | { 11 | var builder = new TsModelBuilder(); 12 | builder.Add(); 13 | 14 | var generator = new TsGenerator(); 15 | var model = builder.Build(); 16 | var result = generator.Generate(model); 17 | 18 | Assert.Contains("MyStringProperty: string;", result); 19 | Assert.Contains("MyArray: string[];", result); 20 | Assert.Contains("MyJaggedArray: string[][];", result); 21 | Assert.Contains("MyVeryJaggedArray: string[][][];", result); 22 | Assert.Contains("MyIEnumerableOfString: string[];", result); 23 | Assert.Contains("MyListOfString: string[];", result); 24 | 25 | Assert.Contains("MyListOfStringArrays: string[][];", result); 26 | Assert.Contains("MyListOfIEnumerableOfString: string[][];", result); 27 | Assert.Contains("MyListOfListOfStringArray: string[][][];", result); 28 | } 29 | 30 | class TestClass 31 | { 32 | public string MyStringProperty { get; set; } 33 | public string[] MyArray { get; set; } 34 | public string[][] MyJaggedArray { get; set; } 35 | public string[][][] MyVeryJaggedArray { get; set; } 36 | public IEnumerable MyIEnumerableOfString { get; set; } 37 | public List MyListOfString { get; set; } 38 | public List MyListOfStringArrays { get; set; } 39 | public List> MyListOfIEnumerableOfString { get; set; } 40 | public List> MyListOfListOfStringArray { get; set; } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue52_EnumsWithoutClass.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 4 | { 5 | public class Issue52_EnumsWithoutClass 6 | { 7 | 8 | [Fact] 9 | public void WhenAssemblyContainsEnumWithoutClass_EnumIsGeneratedInTheOutput() 10 | { 11 | var builder = new TsModelBuilder(); 12 | builder.Add(typeof(TypeLitePlus.Tests.AssemblyWithEnum.TestEnum).Assembly); 13 | 14 | var generator = new TsGenerator(); 15 | var model = builder.Build(); 16 | var result = generator.Generate(model, TsGeneratorOutput.Enums); 17 | 18 | Assert.Contains("TestEnum", result); 19 | } 20 | 21 | enum MyTestEnum 22 | { 23 | One, 24 | Two, 25 | Three 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue63_SelfReferencingEnumerable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using Xunit; 5 | 6 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 7 | { 8 | public class Issue63_SelfReferencingEnumerable 9 | { 10 | /// 11 | /// When a self-referencing enumerable is present but ignored, it shouldn't break the build. 12 | /// 13 | [Fact] 14 | public void WhenBuild_NoSelfReferencingEnumerableInfiniteLoop() 15 | { 16 | var target = new TsModelBuilder(); 17 | target.Add(typeof(IgnoredSelfReferencingEnumerableWrapper)); 18 | 19 | // May cause infinite loop or stack overflow, if not handled correctly. 20 | target.Build(); 21 | } 22 | 23 | /// 24 | /// A self-referencing enumerable should emit type "any". 25 | /// 26 | [Fact] 27 | public void SelfReferencingEnumerableGenerateAny() 28 | { 29 | string output = TypeScript.Definitions() 30 | .For() 31 | .Generate(TsGeneratorOutput.Properties); 32 | 33 | Assert.Contains("MyProperty: any;", output); 34 | } 35 | 36 | [Fact] 37 | public void SelfReferencingEnumerableInheritorGenerateAnyArray() 38 | { 39 | var ts = TypeScript.Definitions(); 40 | ts 41 | .WithMemberTypeFormatter((tsProperty, memberTypeName) => 42 | { 43 | // The following is a workaround proof-of-concept for the JSON.NET JObject class (among others). 44 | // Without this, it would be similar to a List (in the way that they both 45 | // implement IEnumerable) and emit type "any[]" instead of the desired type "any". 46 | // Example: tsProperty.PropertyType.Type.FullName == "Newtonsoft.Json.Linq.JObject" 47 | if (tsProperty.PropertyType.Type.Name == "SelfReferencingEnumerableInheritor") 48 | { 49 | // No "[]" emitted. 50 | return memberTypeName; 51 | } 52 | return ts.ScriptGenerator.DefaultMemberTypeFormatter(tsProperty, memberTypeName); 53 | }) 54 | .For(); 55 | string output = ts 56 | .Generate(TsGeneratorOutput.Properties); 57 | 58 | Assert.Contains("MyInheritorProperty: any;", output); 59 | Assert.Contains("MyArrayProperty: any[];", output); 60 | Assert.Contains("MyListProperty: any[];", output); 61 | } 62 | } 63 | 64 | public class IgnoredSelfReferencingEnumerableWrapper 65 | { 66 | [TsIgnore] 67 | public SelfReferencingEnumerable MyIgnoredProperty { get; set; } 68 | } 69 | 70 | public class SelfReferencingEnumerableWrapper 71 | { 72 | public SelfReferencingEnumerable MyProperty { get; set; } 73 | } 74 | 75 | public class SelfReferencingEnumerableInheritorWrapper 76 | { 77 | public SelfReferencingEnumerableInheritor MyInheritorProperty { get; set; } 78 | 79 | public SelfReferencingEnumerable[] MyArrayProperty { get; set; } 80 | 81 | public List MyListProperty { get; set; } 82 | } 83 | 84 | public class SelfReferencingEnumerable : IEnumerable 85 | { 86 | public IEnumerator GetEnumerator() 87 | { 88 | throw new NotImplementedException(); 89 | } 90 | 91 | IEnumerator IEnumerable.GetEnumerator() 92 | { 93 | throw new NotImplementedException(); 94 | } 95 | } 96 | 97 | public class SelfReferencingEnumerableInheritor : SelfReferencingEnumerable 98 | { 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue65_GenericReferencingContainingType.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Xunit; 3 | 4 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 5 | { 6 | public class Issue65_GenericReferencingContainingType 7 | { 8 | [Fact] 9 | public void WhenClassReferencesItself_ClassIsGenerated() 10 | { 11 | var builder = new TsModelBuilder(); 12 | builder.Add(); 13 | 14 | var generator = new TsGenerator(); 15 | var model = builder.Build(); 16 | var result = generator.Generate(model); 17 | 18 | Assert.Contains("Children: TypeLitePlus.Tests.NetCore.RegressionTests.GenericWithSelfReference[]", result); 19 | } 20 | 21 | } 22 | 23 | public class GenericWithSelfReference 24 | { 25 | public List Children { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue79_ModuleNameFormatterIsnNotUsed.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using TypeLitePlus.Tests.NetCore.TestModels; 3 | using Xunit; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 6 | { 7 | public class Issue79_ModuleNameFormatterIsnNotUsed 8 | { 9 | [Fact] 10 | public void WhenScriptGeneratorGenerateIsCalledModuleNameFormatterIsUsed() 11 | { 12 | 13 | var ts = TypeScript.Definitions(); 14 | ts.WithModuleNameFormatter(m => "XXX"); 15 | ts.ModelBuilder.Add(); 16 | 17 | var model = ts.ModelBuilder.Build(); 18 | var myType = model.Classes.First(); 19 | var name = ts.ScriptGenerator.GetFullyQualifiedTypeName(myType); 20 | 21 | Assert.Equal("XXX.Product", name); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue82_OrderingTests.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.Tests.NetCore.TestModels.Namespace1; 2 | using TypeLitePlus.Tests.NetCore.TestModels.Namespace2; 3 | using TypeLitePlus.TsModels; 4 | using Xunit; 5 | 6 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 7 | { 8 | public class Issue82_OrderingTests 9 | { 10 | [Fact] 11 | public void OrdersOutputByNamespace() 12 | { 13 | var builder = new TsModelBuilder(); 14 | builder.Add(); 15 | builder.Add(); 16 | builder.Add(); 17 | 18 | var generator = new TsGenerator(); 19 | var model = builder.Build(); 20 | 21 | var result = generator.Generate(model); 22 | 23 | Assert.True(result.IndexOf("TypeLitePlus.Tests.NetCore.TestModels.Namespace1") < result.IndexOf("TypeLitePlus.Tests.NetCore.TestModels.Namespace2"), "Didn't order namespaces"); 24 | } 25 | 26 | [Fact] 27 | public void RespectsModuleNameFormatterOverrides() 28 | { 29 | var builder = new TsModelBuilder(); 30 | builder.Add(); 31 | builder.Add(); 32 | 33 | var generator = new TsGenerator(); 34 | // Reverse the order of the modules 35 | generator.SetModuleNameFormatter(m => m.Name == "TypeLitePlus.Tests.NetCore.TestModels.Namespace1" ? "modz" : "moda"); 36 | var model = builder.Build(); 37 | 38 | var result = generator.Generate(model); 39 | 40 | Assert.True(result.IndexOf("moda") < result.IndexOf("modz"), "Didn't order namespaces when formatters involved"); 41 | } 42 | 43 | [Fact] 44 | public void OrdersClassesByName() 45 | { 46 | var builder = new TsModelBuilder(); 47 | builder.Add(); 48 | builder.Add(); 49 | 50 | var generator = new TsGenerator(); 51 | var model = builder.Build(); 52 | 53 | var result = generator.Generate(model); 54 | 55 | Assert.True(result.IndexOf("DifferentNamespaces_Class1") < result.IndexOf("DifferentNamespaces_Class2"), "Didn't order classes"); 56 | } 57 | 58 | [Fact] 59 | public void RespectsTypeNameFormatterOverrides() 60 | { 61 | var builder = new TsModelBuilder(); 62 | builder.Add(); 63 | builder.Add(); 64 | 65 | var generator = new TsGenerator(); 66 | // Reverse the order of the classes 67 | generator.RegisterTypeFormatter((t, f) => ((TsClass)t).Name == "DifferentNamespaces_Class1" ? "classz" : "classa"); 68 | var model = builder.Build(); 69 | 70 | var result = generator.Generate(model); 71 | 72 | Assert.True(result.IndexOf("classa") < result.IndexOf("classz"), "Didn't order classes when formatters involved"); 73 | } 74 | 75 | [Fact] 76 | public void OrdersPropertiesAndFieldsByName() 77 | { 78 | var builder = new TsModelBuilder(); 79 | builder.Add(); 80 | 81 | var generator = new TsGenerator(); 82 | var model = builder.Build(); 83 | 84 | var result = generator.Generate(model); 85 | 86 | Assert.True(result.IndexOf("Property1") < result.IndexOf("Property2"), "Didn't order properties"); 87 | } 88 | 89 | [Fact] 90 | public void RespectsFieldNameFormatterOverrides() 91 | { 92 | var builder = new TsModelBuilder(); 93 | builder.Add(); 94 | 95 | var generator = new TsGenerator(); 96 | // Reverse the order of the properties 97 | generator.SetIdentifierFormatter(x => x.Name == "Property1" ? "propz" : "propa"); 98 | var model = builder.Build(); 99 | 100 | var result = generator.Generate(model); 101 | 102 | Assert.True(result.IndexOf("propa") < result.IndexOf("propz"), "Didn't order properties when formatters involved"); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue85_ReUseTheModifiedTsEnum.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 4 | { 5 | public class Issue85_ReUseTheModifiedTsEnums 6 | { 7 | [Fact] 8 | public void WhenToModuleTheEnum() 9 | { 10 | var ts = TypeScript.Definitions() 11 | .For().ToModule("Foo") 12 | .For() 13 | .Generate(); 14 | Assert.Contains("MyTest: Foo.MyTestEnum;", ts); 15 | } 16 | 17 | enum MyTestEnum 18 | { 19 | One, 20 | Two, 21 | Three 22 | } 23 | 24 | class MyClass 25 | { 26 | public MyTestEnum MyTest { get; set; } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/Issue88_TypeformatterAppliedToOpenGenericsParameters.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Diagnostics; 3 | using Xunit; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 6 | { 7 | public class Issue88_TypeformatterAppliedToOpenGenericsParameters 8 | { 9 | 10 | [Fact(Skip = "Not fixed")] 11 | public void WhenTypeFormaterIsUsed_ItIsntAppliedToOpenGenericsParameters() 12 | { 13 | var ts = TypeScript.Definitions() 14 | .For() 15 | .WithTypeFormatter(((type, F) => "I" + ((TypeLitePlus.TsModels.TsClass)type).Name)) 16 | .Generate(); 17 | 18 | Debug.Write(ts); 19 | 20 | Assert.Contains("Key: TKey", ts); 21 | Assert.Contains("Value: TValue", ts); 22 | } 23 | 24 | 25 | public class UserPreference 26 | { 27 | public Dictionary Preferences { get; set; } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/JsDocTests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using TypeLitePlus; 3 | using System.Diagnostics; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 6 | { 7 | public class JsDocTests 8 | { 9 | [Fact] 10 | public void GenericClassWithTypeparam() 11 | { 12 | // Exception raised documenting generic class with typeparam. 13 | var ts = TypeScript.Definitions().WithJSDoc() 14 | .For(); 15 | string result; 16 | 17 | var ex = Record.Exception(() => result = ts.Generate(TsGeneratorOutput.Properties)); 18 | Assert.Null(ex); 19 | Debug.Write(ts); 20 | } 21 | 22 | /// 23 | /// User Preference 24 | /// 25 | public class UserPreference 26 | { 27 | /// 28 | /// Preferences's document. 29 | /// 30 | public GenericClass1 Preferences { get; set; } 31 | } 32 | 33 | /// 34 | /// GenericClass with T1 35 | /// 36 | /// typeparam T1 37 | public class GenericClass1 38 | { 39 | /// 40 | /// T1 Property 41 | /// 42 | public T1 Property1 { get; set; } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/ModuleNameFormatterTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using a_b; 3 | using a_b_c; 4 | using Xunit; 5 | 6 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 7 | { 8 | public class ModuleNameFormatterTests 9 | { 10 | [Fact] 11 | public void CanUseCustomFormatter() 12 | { 13 | var builder = new TsModelBuilder(); 14 | builder.Add(); 15 | 16 | var generator = new TsGenerator(); 17 | generator.SetModuleNameFormatter(_ => "custom");//everything should go into the 'custom' module 18 | var model = builder.Build(); 19 | var result = generator.Generate(model); 20 | 21 | var expectedOutput = @" 22 | declare namespace custom { 23 | interface Drink { 24 | } 25 | } 26 | "; 27 | 28 | Assert.Equal(expectedOutput, result); 29 | } 30 | 31 | [Fact] 32 | public void CanDealWithNestedNamespaces() 33 | { 34 | var builder = new TsModelBuilder(); 35 | builder.Add(); 36 | builder.Add(); 37 | 38 | var generator = new TsGenerator(); 39 | generator.SetModuleNameFormatter(_ => "custom");//everything should go into the 'custom' module 40 | var model = builder.Build(); 41 | var result = generator.Generate(model); 42 | 43 | var expectedOutput = @" 44 | declare namespace custom { 45 | interface Person { 46 | AllDrinks: custom.Drink[]; 47 | WhiteRussian: custom.Drink; 48 | } 49 | } 50 | declare namespace custom { 51 | interface Drink { 52 | } 53 | } 54 | "; 55 | 56 | Assert.Equal(expectedOutput, result); 57 | } 58 | } 59 | } 60 | 61 | namespace a_b 62 | { 63 | public class Person 64 | { 65 | public Drink WhiteRussian { get; set; } 66 | public List AllDrinks { get; set; } 67 | } 68 | } 69 | 70 | namespace a_b_c 71 | { 72 | public class Drink 73 | { 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/RegressionTests/NullablesTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Xunit; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.RegressionTests 6 | { 7 | public class NullablesTests 8 | { 9 | 10 | [Fact] 11 | public void WhenClassHasNullableStructure_StructureIsAddedToModel() 12 | { 13 | var builder = new TsModelBuilder(); 14 | builder.Add(); 15 | 16 | var generator = new TsGenerator(); 17 | var model = builder.Build(); 18 | var result = generator.Generate(model); 19 | 20 | Assert.Contains("NullableStructure: TypeLitePlus.Tests.NetCore.RegressionTests.Structure1;", result); 21 | Assert.Contains("NullableStructureCollection: TypeLitePlus.Tests.NetCore.RegressionTests.Structure2[];", result); 22 | Assert.Contains("NullableInt: number;", result); 23 | } 24 | 25 | [Fact] 26 | public void WhenClassContainsNullableAndNonNullableStruct_StructureIsIncludedInModelOnlyOnce() 27 | { 28 | var builder = new TsModelBuilder(); 29 | builder.Add(); 30 | 31 | var generator = new TsGenerator(); 32 | var model = builder.Build(); 33 | 34 | Assert.Single(model.Classes.Where(o => o.Type == typeof(Structure1))); 35 | } 36 | } 37 | 38 | public class NullableAndNonNullableContainer 39 | { 40 | public Structure1? NullableStructure { get; set; } 41 | public Structure1 Structure { get; set; } 42 | } 43 | 44 | public class NullableStructureContainer 45 | { 46 | public Structure1? NullableStructure { get; set; } 47 | public IEnumerable NullableStructureCollection { get; set; } 48 | public int? NullableInt { get; set; } 49 | } 50 | 51 | public struct Structure1 52 | { 53 | public int X { get; set; } 54 | } 55 | 56 | public struct Structure2 57 | { 58 | public int Y { get; set; } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/ScriptBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace TypeLitePlus.Tests.NetCore 4 | { 5 | public class ScriptBuilderTests 6 | { 7 | ScriptBuilder _sb; 8 | public ScriptBuilderTests() 9 | { 10 | _sb = new ScriptBuilder("\t"); 11 | } 12 | 13 | [Fact] 14 | public void WhenIncreaseIndentation_IndentationLevelIsIncreased() 15 | { 16 | _sb.IncreaseIndentation(); 17 | 18 | Assert.Equal(1, _sb.IndentationLevels); 19 | } 20 | 21 | [Fact] 22 | public void WhenIndentationLevelIsDisposed_IndentationLevelIsDecreased() 23 | { 24 | using (_sb.IncreaseIndentation()) 25 | { 26 | using (_sb.IncreaseIndentation()) 27 | { 28 | ; 29 | } 30 | 31 | Assert.Equal(1, _sb.IndentationLevels); 32 | } 33 | } 34 | 35 | [Fact] 36 | public void WhenAppendIndentation_IndentationCharactersAccordingToIndentationLevelsAreAppended() 37 | { 38 | _sb.IncreaseIndentation(); 39 | _sb.IncreaseIndentation(); 40 | 41 | _sb.AppendIndentation(); 42 | 43 | var script = _sb.ToString(); 44 | 45 | Assert.Equal("\t\t", script); 46 | } 47 | 48 | [Fact] 49 | public void WhenAppendString_StrignIsAppended() 50 | { 51 | _sb.Append("test"); 52 | 53 | var script = _sb.ToString(); 54 | 55 | Assert.Equal("test", script); 56 | } 57 | 58 | [Fact] 59 | public void WhenAppendFormatString_StrignIsAppended() 60 | { 61 | _sb.AppendFormat("test {0}", 1); 62 | 63 | var script = _sb.ToString(); 64 | 65 | Assert.Equal("test 1", script); 66 | } 67 | 68 | [Fact] 69 | public void WhenAppendIndentedString_IndentedStringIsAppended() 70 | { 71 | _sb.IncreaseIndentation(); 72 | _sb.AppendIndented("test"); 73 | 74 | var script = _sb.ToString(); 75 | 76 | Assert.Equal("\ttest", script); 77 | } 78 | 79 | [Fact] 80 | public void WhenAppendFormatIndented_IndentedStringIsAppended() 81 | { 82 | _sb.IncreaseIndentation(); 83 | _sb.AppendFormatIndented("test {0}", 1); 84 | 85 | var script = _sb.ToString(); 86 | 87 | Assert.Equal("\ttest 1", script); 88 | } 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/Address.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.TestModels 4 | { 5 | public class Address 6 | { 7 | public const int DefaultCountryId = 1; 8 | public const string DefaultPostalCode = ""; 9 | 10 | public Guid Id { get; set; } 11 | public Guid[] Ids { get; set; } 12 | public string Street { get; set; } 13 | public string Town { get; set; } 14 | 15 | // field 16 | public string PostalCode; 17 | 18 | public ContactType AddressType { get; set; } 19 | public ConsoleKey Shortkey { get; set; } 20 | 21 | [TsProperty(IsOptional = true)] 22 | public int CountryID { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/ContactType.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | public enum ContactType 4 | { 5 | Personal, 6 | Business 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/CustomClassName.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | [TsClass(Name = "MyClass", Module = "MyModule")] 4 | public class CustomClassName 5 | { 6 | [TsProperty(Name = "MyProperty")] 7 | public int CustomPorperty { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/CustomTypeCollectionReference.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.TestModels 4 | { 5 | public class CustomTypeCollectionReference 6 | { 7 | public Product[] Products { get; set; } 8 | public IEnumerable People { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/CustomerKind.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | public enum CustomerKind 4 | { 5 | Corporate = 1, 6 | Individual = 2 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/DifferentNamespaces.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels.Namespace2 2 | { 3 | [TsClass] 4 | public class DifferentNamespaces_Class2 5 | { 6 | public string Property2 { get; set; } 7 | public string Property1 { get; set; } 8 | } 9 | } 10 | 11 | namespace TypeLitePlus.Tests.NetCore.TestModels.Namespace1 12 | { 13 | [TsClass] 14 | public class DifferentNamespaces_Class3 15 | { 16 | 17 | } 18 | } 19 | 20 | namespace TypeLitePlus.Tests.NetCore.TestModels.Namespace2 21 | { 22 | [TsClass] 23 | public class DifferentNamespaces_Class1 24 | { 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/Employee.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | public class Employee : Person 4 | { 5 | public decimal Salary { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/IShippingService.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | public interface IShippingService 4 | { 5 | double Price { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/IgnoreTest.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | [TsIgnore] 4 | public class IgnoreTestBase { } 5 | public class IgnoreTest : IgnoreTestBase { } 6 | } 7 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/Item.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | [TsClass] 4 | public class Item 5 | { 6 | public int Id { get; set; } 7 | public ItemType Type { get; set; } 8 | public string Name { get; set; } 9 | 10 | public const int MaxItems = 100; 11 | } 12 | 13 | public enum ItemType 14 | { 15 | Book = 1, 16 | Music = 10, 17 | Clothing = 51 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/Outer.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | public class Outer 4 | { 5 | public class Inner 6 | { 7 | public class SecondLevelInner //Dto 8 | { 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/Person.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TypeLitePlus.Tests.NetCore.TestModels 4 | { 5 | public class Person 6 | { 7 | public const int MaxAddresses = 3; 8 | public const string DefaultPhoneNumber = "[None]"; 9 | 10 | public string Name { get; set; } 11 | public int YearOfBirth { get; set; } 12 | 13 | // field 14 | public string PhoneNumber; 15 | 16 | public Address PrimaryAddress { get; set; } 17 | public List
Addresses { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/PointStruct.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | public struct PointStruct 4 | { 5 | public double X { get; set; } 6 | public double Y { get; set; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/Product.cs: -------------------------------------------------------------------------------- 1 | namespace TypeLitePlus.Tests.NetCore.TestModels 2 | { 3 | [TsClass] 4 | public class Product 5 | { 6 | public string Name { get; set; } 7 | public double Price { get; set; } 8 | 9 | [TsIgnore] 10 | public double Ignored { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestModels/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.TestModels 6 | { 7 | public class User : Person 8 | { 9 | 10 | public string UserName { get; set; } 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestScripts/Enums.ts: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated from a template. 4 | // 5 | // Manual changes to this file may cause unexpected behavior in your application. 6 | // Manual changes to this file will be overwritten if the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace System { 11 | export const enum ConsoleKey { 12 | Backspace = 8, 13 | Tab = 9, 14 | Clear = 12, 15 | Enter = 13, 16 | Pause = 19, 17 | Escape = 27, 18 | Spacebar = 32, 19 | PageUp = 33, 20 | PageDown = 34, 21 | End = 35, 22 | Home = 36, 23 | LeftArrow = 37, 24 | UpArrow = 38, 25 | RightArrow = 39, 26 | DownArrow = 40, 27 | Select = 41, 28 | Print = 42, 29 | Execute = 43, 30 | PrintScreen = 44, 31 | Insert = 45, 32 | Delete = 46, 33 | Help = 47, 34 | D0 = 48, 35 | D1 = 49, 36 | D2 = 50, 37 | D3 = 51, 38 | D4 = 52, 39 | D5 = 53, 40 | D6 = 54, 41 | D7 = 55, 42 | D8 = 56, 43 | D9 = 57, 44 | A = 65, 45 | B = 66, 46 | C = 67, 47 | D = 68, 48 | E = 69, 49 | F = 70, 50 | G = 71, 51 | H = 72, 52 | I = 73, 53 | J = 74, 54 | K = 75, 55 | L = 76, 56 | M = 77, 57 | N = 78, 58 | O = 79, 59 | P = 80, 60 | Q = 81, 61 | R = 82, 62 | S = 83, 63 | T = 84, 64 | U = 85, 65 | V = 86, 66 | W = 87, 67 | X = 88, 68 | Y = 89, 69 | Z = 90, 70 | LeftWindows = 91, 71 | RightWindows = 92, 72 | Applications = 93, 73 | Sleep = 95, 74 | NumPad0 = 96, 75 | NumPad1 = 97, 76 | NumPad2 = 98, 77 | NumPad3 = 99, 78 | NumPad4 = 100, 79 | NumPad5 = 101, 80 | NumPad6 = 102, 81 | NumPad7 = 103, 82 | NumPad8 = 104, 83 | NumPad9 = 105, 84 | Multiply = 106, 85 | Add = 107, 86 | Separator = 108, 87 | Subtract = 109, 88 | Decimal = 110, 89 | Divide = 111, 90 | F1 = 112, 91 | F2 = 113, 92 | F3 = 114, 93 | F4 = 115, 94 | F5 = 116, 95 | F6 = 117, 96 | F7 = 118, 97 | F8 = 119, 98 | F9 = 120, 99 | F10 = 121, 100 | F11 = 122, 101 | F12 = 123, 102 | F13 = 124, 103 | F14 = 125, 104 | F15 = 126, 105 | F16 = 127, 106 | F17 = 128, 107 | F18 = 129, 108 | F19 = 130, 109 | F20 = 131, 110 | F21 = 132, 111 | F22 = 133, 112 | F23 = 134, 113 | F24 = 135, 114 | BrowserBack = 166, 115 | BrowserForward = 167, 116 | BrowserRefresh = 168, 117 | BrowserStop = 169, 118 | BrowserSearch = 170, 119 | BrowserFavorites = 171, 120 | BrowserHome = 172, 121 | VolumeMute = 173, 122 | VolumeDown = 174, 123 | VolumeUp = 175, 124 | MediaNext = 176, 125 | MediaPrevious = 177, 126 | MediaStop = 178, 127 | MediaPlay = 179, 128 | LaunchMail = 180, 129 | LaunchMediaSelect = 181, 130 | LaunchApp1 = 182, 131 | LaunchApp2 = 183, 132 | Oem1 = 186, 133 | OemPlus = 187, 134 | OemComma = 188, 135 | OemMinus = 189, 136 | OemPeriod = 190, 137 | Oem2 = 191, 138 | Oem3 = 192, 139 | Oem4 = 219, 140 | Oem5 = 220, 141 | Oem6 = 221, 142 | Oem7 = 222, 143 | Oem8 = 223, 144 | Oem102 = 226, 145 | Process = 229, 146 | Packet = 231, 147 | Attention = 246, 148 | CrSel = 247, 149 | ExSel = 248, 150 | EraseEndOfFile = 249, 151 | Play = 250, 152 | Zoom = 251, 153 | NoName = 252, 154 | Pa1 = 253, 155 | OemClear = 254 156 | } 157 | } 158 | namespace TypeLitePlus.Tests.NetCore.TestModels { 159 | export const enum ContactType { 160 | Personal = 0, 161 | Bussiness = 1 162 | } 163 | export namespace Address { 164 | export const DefaultCountryId: number = 1; 165 | export const DefaultPostalCode: string = ""; 166 | } 167 | export namespace Person { 168 | export const MaxAddresses: number = 3; 169 | export const DefaultPhoneNumber: string = "[None]"; 170 | } 171 | } 172 | 173 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestScripts/Knockout/Enums.ts: -------------------------------------------------------------------------------- 1 | namespace System { 2 | export const enum ConsoleKey { 3 | Backspace = 8, 4 | Tab = 9, 5 | Clear = 12, 6 | Enter = 13, 7 | Pause = 19, 8 | Escape = 27, 9 | Spacebar = 32, 10 | PageUp = 33, 11 | PageDown = 34, 12 | End = 35, 13 | Home = 36, 14 | LeftArrow = 37, 15 | UpArrow = 38, 16 | RightArrow = 39, 17 | DownArrow = 40, 18 | Select = 41, 19 | Print = 42, 20 | Execute = 43, 21 | PrintScreen = 44, 22 | Insert = 45, 23 | Delete = 46, 24 | Help = 47, 25 | D0 = 48, 26 | D1 = 49, 27 | D2 = 50, 28 | D3 = 51, 29 | D4 = 52, 30 | D5 = 53, 31 | D6 = 54, 32 | D7 = 55, 33 | D8 = 56, 34 | D9 = 57, 35 | A = 65, 36 | B = 66, 37 | C = 67, 38 | D = 68, 39 | E = 69, 40 | F = 70, 41 | G = 71, 42 | H = 72, 43 | I = 73, 44 | J = 74, 45 | K = 75, 46 | L = 76, 47 | M = 77, 48 | N = 78, 49 | O = 79, 50 | P = 80, 51 | Q = 81, 52 | R = 82, 53 | S = 83, 54 | T = 84, 55 | U = 85, 56 | V = 86, 57 | W = 87, 58 | X = 88, 59 | Y = 89, 60 | Z = 90, 61 | LeftWindows = 91, 62 | RightWindows = 92, 63 | Applications = 93, 64 | Sleep = 95, 65 | NumPad0 = 96, 66 | NumPad1 = 97, 67 | NumPad2 = 98, 68 | NumPad3 = 99, 69 | NumPad4 = 100, 70 | NumPad5 = 101, 71 | NumPad6 = 102, 72 | NumPad7 = 103, 73 | NumPad8 = 104, 74 | NumPad9 = 105, 75 | Multiply = 106, 76 | Add = 107, 77 | Separator = 108, 78 | Subtract = 109, 79 | Decimal = 110, 80 | Divide = 111, 81 | F1 = 112, 82 | F2 = 113, 83 | F3 = 114, 84 | F4 = 115, 85 | F5 = 116, 86 | F6 = 117, 87 | F7 = 118, 88 | F8 = 119, 89 | F9 = 120, 90 | F10 = 121, 91 | F11 = 122, 92 | F12 = 123, 93 | F13 = 124, 94 | F14 = 125, 95 | F15 = 126, 96 | F16 = 127, 97 | F17 = 128, 98 | F18 = 129, 99 | F19 = 130, 100 | F20 = 131, 101 | F21 = 132, 102 | F22 = 133, 103 | F23 = 134, 104 | F24 = 135, 105 | BrowserBack = 166, 106 | BrowserForward = 167, 107 | BrowserRefresh = 168, 108 | BrowserStop = 169, 109 | BrowserSearch = 170, 110 | BrowserFavorites = 171, 111 | BrowserHome = 172, 112 | VolumeMute = 173, 113 | VolumeDown = 174, 114 | VolumeUp = 175, 115 | MediaNext = 176, 116 | MediaPrevious = 177, 117 | MediaStop = 178, 118 | MediaPlay = 179, 119 | LaunchMail = 180, 120 | LaunchMediaSelect = 181, 121 | LaunchApp1 = 182, 122 | LaunchApp2 = 183, 123 | Oem1 = 186, 124 | OemPlus = 187, 125 | OemComma = 188, 126 | OemMinus = 189, 127 | OemPeriod = 190, 128 | Oem2 = 191, 129 | Oem3 = 192, 130 | Oem4 = 219, 131 | Oem5 = 220, 132 | Oem6 = 221, 133 | Oem7 = 222, 134 | Oem8 = 223, 135 | Oem102 = 226, 136 | Process = 229, 137 | Packet = 231, 138 | Attention = 246, 139 | CrSel = 247, 140 | ExSel = 248, 141 | EraseEndOfFile = 249, 142 | Play = 250, 143 | Zoom = 251, 144 | NoName = 252, 145 | Pa1 = 253, 146 | OemClear = 254 147 | } 148 | } 149 | namespace TypeLitePlus.Tests.NetCore.TestModels { 150 | export const enum ContactType { 151 | Personal = 0, 152 | Bussiness = 1 153 | } 154 | export namespace Address { 155 | export const DefaultCountryId: number = 1; 156 | export const DefaultPostalCode: string = ""; 157 | } 158 | export namespace Person { 159 | export const MaxAddresses: number = 3; 160 | export const DefaultPhoneNumber: string = "[None]"; 161 | } 162 | } 163 | 164 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestScripts/Knockout/TsKo.d.ts: -------------------------------------------------------------------------------- 1 | ErrorGeneratingOutput -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestScripts/Knockout/TsKo.tt: -------------------------------------------------------------------------------- 1 | <#@ template debug="true" hostspecific="true" language="C#" #> 2 | <#@ assembly name="netstandard.dll" #> 3 | <#@ assembly name="$(TargetDir)TypeLitePlus.Core.dll" #> 4 | <#@ assembly name="$(TargetDir)TypeLitePlus.Tests.NetCore.dll" #> 5 | 6 | <#@ import namespace="TypeLitePlus" #> 7 | <#@ import namespace="TypeLitePlus.Tests.NetCore.TestModels" #> 8 | <#@output extension=".d.ts"#> 9 | 10 | <#@include file="..\..\..\TypeLitePlus.T4Templates\ContentFiles\Scripts\Manager.ttinclude"#> 11 | <# 12 | var fileManager = EntityFrameworkTemplateFileManager.Create(this); 13 | 14 | var ts = TypeScript.Definitions(new TypeLitePlus.AlternateGenerators.TsKnockoutModelGenerator()) 15 | .WithReference("Enums.ts") 16 | .For(); 17 | #> 18 | 19 | <#= ts.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields) #> 20 | 21 | <# fileManager.StartNewFile("Enums.ts"); #> 22 | <#= ts.Generate(TsGeneratorOutput.Enums | TsGeneratorOutput.Constants) #> 23 | <# 24 | fileManager.EndBlock(); 25 | fileManager.Process(true); 26 | #> -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestScripts/TsUtils.d.ts: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | //------------------------------------------------------------------------------ 7 | // 8 | // This code was generated from a template. 9 | // 10 | // Manual changes to this file may cause unexpected behavior in your application. 11 | // Manual changes to this file will be overwritten if the code is regenerated. 12 | // 13 | //------------------------------------------------------------------------------ 14 | 15 | 16 | /// 17 | 18 | declare namespace System { 19 | interface Guid { 20 | Empty: System.Guid; 21 | } 22 | } 23 | declare namespace TypeLitePlus.Tests.NetCore.TestModels { 24 | interface Address { 25 | AddressType: TypeLitePlus.Tests.NetCore.TestModels.ContactType; 26 | CountryID?: number; 27 | Id: System.Guid; 28 | Ids: System.Guid[]; 29 | PostalCode: string; 30 | Shortkey: System.ConsoleKey; 31 | Street: string; 32 | Town: string; 33 | } 34 | interface Employee extends TypeLitePlus.Tests.NetCore.TestModels.Person { 35 | Salary: number; 36 | } 37 | interface Person { 38 | Addresses: TypeLitePlus.Tests.NetCore.TestModels.Address[]; 39 | Name: string; 40 | PhoneNumber: string; 41 | PrimaryAddress: TypeLitePlus.Tests.NetCore.TestModels.Address; 42 | YearOfBirth: number; 43 | } 44 | } 45 | 46 | 47 | namespace System { 48 | export const enum ConsoleKey { 49 | Backspace = 8, 50 | Tab = 9, 51 | Clear = 12, 52 | Enter = 13, 53 | Pause = 19, 54 | Escape = 27, 55 | Spacebar = 32, 56 | PageUp = 33, 57 | PageDown = 34, 58 | End = 35, 59 | Home = 36, 60 | LeftArrow = 37, 61 | UpArrow = 38, 62 | RightArrow = 39, 63 | DownArrow = 40, 64 | Select = 41, 65 | Print = 42, 66 | Execute = 43, 67 | PrintScreen = 44, 68 | Insert = 45, 69 | Delete = 46, 70 | Help = 47, 71 | D0 = 48, 72 | D1 = 49, 73 | D2 = 50, 74 | D3 = 51, 75 | D4 = 52, 76 | D5 = 53, 77 | D6 = 54, 78 | D7 = 55, 79 | D8 = 56, 80 | D9 = 57, 81 | A = 65, 82 | B = 66, 83 | C = 67, 84 | D = 68, 85 | E = 69, 86 | F = 70, 87 | G = 71, 88 | H = 72, 89 | I = 73, 90 | J = 74, 91 | K = 75, 92 | L = 76, 93 | M = 77, 94 | N = 78, 95 | O = 79, 96 | P = 80, 97 | Q = 81, 98 | R = 82, 99 | S = 83, 100 | T = 84, 101 | U = 85, 102 | V = 86, 103 | W = 87, 104 | X = 88, 105 | Y = 89, 106 | Z = 90, 107 | LeftWindows = 91, 108 | RightWindows = 92, 109 | Applications = 93, 110 | Sleep = 95, 111 | NumPad0 = 96, 112 | NumPad1 = 97, 113 | NumPad2 = 98, 114 | NumPad3 = 99, 115 | NumPad4 = 100, 116 | NumPad5 = 101, 117 | NumPad6 = 102, 118 | NumPad7 = 103, 119 | NumPad8 = 104, 120 | NumPad9 = 105, 121 | Multiply = 106, 122 | Add = 107, 123 | Separator = 108, 124 | Subtract = 109, 125 | Decimal = 110, 126 | Divide = 111, 127 | F1 = 112, 128 | F2 = 113, 129 | F3 = 114, 130 | F4 = 115, 131 | F5 = 116, 132 | F6 = 117, 133 | F7 = 118, 134 | F8 = 119, 135 | F9 = 120, 136 | F10 = 121, 137 | F11 = 122, 138 | F12 = 123, 139 | F13 = 124, 140 | F14 = 125, 141 | F15 = 126, 142 | F16 = 127, 143 | F17 = 128, 144 | F18 = 129, 145 | F19 = 130, 146 | F20 = 131, 147 | F21 = 132, 148 | F22 = 133, 149 | F23 = 134, 150 | F24 = 135, 151 | BrowserBack = 166, 152 | BrowserForward = 167, 153 | BrowserRefresh = 168, 154 | BrowserStop = 169, 155 | BrowserSearch = 170, 156 | BrowserFavorites = 171, 157 | BrowserHome = 172, 158 | VolumeMute = 173, 159 | VolumeDown = 174, 160 | VolumeUp = 175, 161 | MediaNext = 176, 162 | MediaPrevious = 177, 163 | MediaStop = 178, 164 | MediaPlay = 179, 165 | LaunchMail = 180, 166 | LaunchMediaSelect = 181, 167 | LaunchApp1 = 182, 168 | LaunchApp2 = 183, 169 | Oem1 = 186, 170 | OemPlus = 187, 171 | OemComma = 188, 172 | OemMinus = 189, 173 | OemPeriod = 190, 174 | Oem2 = 191, 175 | Oem3 = 192, 176 | Oem4 = 219, 177 | Oem5 = 220, 178 | Oem6 = 221, 179 | Oem7 = 222, 180 | Oem8 = 223, 181 | Oem102 = 226, 182 | Process = 229, 183 | Packet = 231, 184 | Attention = 246, 185 | CrSel = 247, 186 | ExSel = 248, 187 | EraseEndOfFile = 249, 188 | Play = 250, 189 | Zoom = 251, 190 | NoName = 252, 191 | Pa1 = 253, 192 | OemClear = 254 193 | } 194 | } 195 | namespace TypeLitePlus.Tests.NetCore.TestModels { 196 | export const enum ContactType { 197 | Personal = 0, 198 | Bussiness = 1 199 | } 200 | export namespace Address { 201 | export const DefaultCountryId: number = 1; 202 | export const DefaultPostalCode: string = ""; 203 | } 204 | export namespace Person { 205 | export const MaxAddresses: number = 3; 206 | export const DefaultPhoneNumber: string = "[None]"; 207 | } 208 | } 209 | 210 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TestScripts/TsUtils.tt: -------------------------------------------------------------------------------- 1 | <#@ template debug="true" hostspecific="false" language="C#" #> 2 | <#@ assembly name="netstandard.dll" #> 3 | <#@ assembly name="$(TargetDir)TypeLitePlus.Core.dll" #> 4 | <#@ assembly name="$(TargetDir)TypeLitePlus.Tests.NetCore.dll" #> 5 | 6 | <#@ import namespace="TypeLitePlus" #> 7 | <#@ import namespace="TypeLitePlus.Tests.NetCore.TestModels" #> 8 | <#@output extension=".d.ts"#> 9 | 10 | <#@include file="..\..\TypeLitePlus.T4Templates\ContentFiles\Scripts\Manager.ttinclude"#> 11 | <# 12 | var fileManager = EntityFrameworkTemplateFileManager.Create(this); 13 | WriteHeader(fileManager); 14 | 15 | var ts = TypeScript.Definitions() 16 | .WithReference("Enums.ts") 17 | .For(); 18 | #> 19 | 20 | <#= ts.Generate(TsGeneratorOutput.Properties | TsGeneratorOutput.Fields) #> 21 | 22 | <# fileManager.StartNewFile("Enums.ts"); #> 23 | <#= ts.Generate(TsGeneratorOutput.Enums | TsGeneratorOutput.Constants) #> 24 | <# 25 | fileManager.EndBlock(); 26 | fileManager.Process(true); 27 | #> 28 | <#+ 29 | void WriteHeader(EntityFrameworkTemplateFileManager fileManager) 30 | { 31 | fileManager.StartHeader(); 32 | #> 33 | //------------------------------------------------------------------------------ 34 | // 35 | // This code was generated from a template. 36 | // 37 | // Manual changes to this file may cause unexpected behavior in your application. 38 | // Manual changes to this file will be overwritten if the code is regenerated. 39 | // 40 | //------------------------------------------------------------------------------ 41 | 42 | <#+ 43 | fileManager.EndBlock(); 44 | } 45 | #> -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TsModelBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using TypeLitePlus.TsModels; 4 | using TypeLitePlus.Tests.NetCore.TestModels; 5 | 6 | using Xunit; 7 | 8 | namespace TypeLitePlus.Tests.NetCore 9 | { 10 | public class TsModelBuilderTests 11 | { 12 | 13 | #region Add tests 14 | 15 | [Fact] 16 | public void WhenAddTypeThatIsntClassStructOrEnum_ExceptionIsThrown() 17 | { 18 | var target = new TsModelBuilder(); 19 | 20 | Assert.Throws(() => target.Add(typeof(string))); 21 | } 22 | 23 | [Fact] 24 | public void WhenAddEnum_EnumIsAddedToModel() 25 | { 26 | var target = new TsModelBuilder(); 27 | target.Add(typeof(CustomerKind)); 28 | 29 | Assert.Single(target.Enums.Values.Where(o => o.Type == typeof(CustomerKind))); 30 | } 31 | 32 | [Fact] 33 | public void WhenAdd_ClassIsAddedToModel() 34 | { 35 | var target = new TsModelBuilder(); 36 | 37 | target.Add(typeof(Address), true); 38 | 39 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(Address))); 40 | } 41 | 42 | [Fact] 43 | public void WhenAddAndIncludeReferencesIsFalse_ReferencedClassesAreNotAddedToModel() 44 | { 45 | var target = new TsModelBuilder(); 46 | 47 | target.Add(typeof(Person), false); 48 | 49 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(Person))); 50 | Assert.Empty(target.Classes.Values.Where(o => o.Type == typeof(Address))); 51 | } 52 | 53 | [Fact] 54 | public void WhenAddAndIncludeReferencesIsTrue_ReferencedClassesAreAddedToModel() 55 | { 56 | var target = new TsModelBuilder(); 57 | 58 | target.Add(typeof(Person), true); 59 | 60 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(Person))); 61 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(Address))); 62 | } 63 | 64 | [Fact] 65 | public void WhenAddAndClassHasBaseClass_BaseClassIsAddedToModel() 66 | { 67 | var target = new TsModelBuilder(); 68 | 69 | target.Add(typeof(Employee), false); 70 | 71 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(Employee))); 72 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(Person))); 73 | } 74 | 75 | [Fact] 76 | public void WhenAddClassWithReferenceAndReferenceIsCollectionOfCustomType_CustomTypeIsAddedToModel() 77 | { 78 | var target = new TsModelBuilder(); 79 | 80 | target.Add(true); 81 | 82 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(CustomTypeCollectionReference))); 83 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(Product))); 84 | } 85 | 86 | [Fact] 87 | public void WhenAddClassWithReferenceAndReferenceIsIEnumerableOfCustomType_CustomTypeIsAddedToModel() 88 | { 89 | var target = new TsModelBuilder(); 90 | 91 | target.Add(true); 92 | 93 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(CustomTypeCollectionReference))); 94 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(Person))); 95 | } 96 | 97 | [Fact] 98 | public void WhenInterfaceIsAdded_InterfaceIsAddedAsClass() 99 | { 100 | var target = new TsModelBuilder(); 101 | 102 | target.Add(true); 103 | 104 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(IShippingService))); 105 | } 106 | 107 | #endregion 108 | 109 | #region Add(Assembly) tests 110 | 111 | [Fact] 112 | public void WhenAdd_AllClassesWithTsClassAttributeAreAdded() 113 | { 114 | var target = new TsModelBuilder(); 115 | target.Add(typeof(Product).Assembly); 116 | 117 | Assert.Single(target.Classes.Values.Where(o => o.Type == typeof(Product))); 118 | } 119 | 120 | #endregion 121 | 122 | #region Build tests 123 | 124 | [Fact] 125 | public void WhenBuild_ModelWithAddedClassesIsReturned() 126 | { 127 | var target = new TsModelBuilder(); 128 | target.Add(typeof(Person), true); 129 | 130 | var model = target.Build(); 131 | 132 | Assert.Equal(target.Classes.Values, model.Classes); 133 | } 134 | 135 | [Fact] 136 | public void WhenBuild_ModelWithModulesIsReturned() 137 | { 138 | var target = new TsModelBuilder(); 139 | target.Add(typeof(Person), true); 140 | 141 | var model = target.Build(); 142 | 143 | var module = model.Modules.Where(m => m.Name == "TypeLitePlus.Tests.NetCore.TestModels").Single(); 144 | var personClass = model.Classes.Where(o => o.Type == typeof(Person)).Single(); 145 | 146 | Assert.Same(personClass.Module, module); 147 | } 148 | 149 | [Fact] 150 | public void WhenBuild_TypeReferencesInModelAreResolved() 151 | { 152 | var target = new TsModelBuilder(); 153 | target.Add(typeof(Person), true); 154 | 155 | var model = target.Build(); 156 | 157 | var personClass = model.Classes.Where(o => o.Type == typeof(Person)).Single(); 158 | var addressClass = model.Classes.Where(o => o.Type == typeof(Address)).Single(); 159 | 160 | Assert.Same(addressClass, personClass.Properties.Where(p => p.Name == "PrimaryAddress").Single().PropertyType); 161 | Assert.IsType(personClass.Properties.Where(p => p.Name == "Name").Single().PropertyType); 162 | Assert.IsType(personClass.Properties.Where(p => p.Name == "Addresses").Single().PropertyType); 163 | 164 | Assert.IsType(personClass.Fields.Where(f => f.Name == "PhoneNumber").Single().PropertyType); 165 | 166 | Assert.IsType(personClass.Constants.Where(c => c.Name == "MaxAddresses").Single().PropertyType); 167 | } 168 | 169 | [Fact] 170 | public void WhenBuild_ModulesInModelAreResolved() 171 | { 172 | var target = new TsModelBuilder(); 173 | target.Add(typeof(Person)); 174 | 175 | var model = target.Build(); 176 | 177 | var personClass = model.Classes.Where(o => o.Type == typeof(Person)).Single(); 178 | var addressClass = model.Classes.Where(o => o.Type == typeof(Address)).Single(); 179 | 180 | Assert.Same(personClass.Module, addressClass.Module); 181 | } 182 | 183 | #endregion 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TsModelTests.cs: -------------------------------------------------------------------------------- 1 | using Moq; 2 | using TypeLitePlus.Tests.NetCore.TestModels; 3 | using TypeLitePlus.TsModels; 4 | using Xunit; 5 | 6 | namespace TypeLitePlus.Tests.NetCore 7 | { 8 | public class TsModelTests 9 | { 10 | [Fact] 11 | public void WhenInitialized_ClassesCollectionIsEmpty() 12 | { 13 | var target = new TsModel(); 14 | 15 | Assert.NotNull(target.Classes); 16 | Assert.Empty(target.Classes); 17 | } 18 | 19 | [Fact] 20 | public void WhenInitialized_ReferencesCollectionIsEmpty() 21 | { 22 | var target = new TsModel(); 23 | 24 | Assert.NotNull(target.References); 25 | Assert.Empty(target.References); 26 | } 27 | 28 | [Fact] 29 | public void WhenInitialized_ModulesCollectionIsEmpty() 30 | { 31 | var target = new TsModel(); 32 | 33 | Assert.NotNull(target.Modules); 34 | Assert.Empty(target.Modules); 35 | } 36 | 37 | [Fact] 38 | public void WhenInitializedWithCollectionOfClasses_ClassesAreAddedToModel() 39 | { 40 | var classes = new[] { new TsClass(typeof(Person)) }; 41 | 42 | var target = new TsModel(classes); 43 | 44 | Assert.Equal(classes, target.Classes); 45 | } 46 | 47 | #region RunVisitor tests 48 | 49 | [Fact] 50 | public void WhenRunVisitor_VisitModelIsCalledForModel() 51 | { 52 | var visitor = new Mock(); 53 | var builder = new TsModelBuilder(); 54 | builder.Add(typeof(Person), true); 55 | 56 | var target = builder.Build(); 57 | 58 | visitor.Setup(o => o.VisitModel(target)).Verifiable(); 59 | 60 | target.RunVisitor(visitor.Object); 61 | 62 | visitor.VerifyAll(); 63 | } 64 | 65 | [Fact] 66 | public void WhenRunVisitor_VisitModulIsCalledForModules() 67 | { 68 | var visitor = new Mock(); 69 | visitor.Setup(o => o.VisitModule(It.Is(m => m.Name == typeof(Person).Namespace))).Verifiable(); 70 | 71 | var builder = new TsModelBuilder(); 72 | builder.Add(typeof(Person), true); 73 | 74 | var target = builder.Build(); 75 | target.RunVisitor(visitor.Object); 76 | 77 | visitor.VerifyAll(); 78 | } 79 | 80 | [Fact] 81 | public void WhenRunVisitor_VisitClassIsCalledForClassesOfModel() 82 | { 83 | var visitor = new Mock(); 84 | visitor.Setup(o => o.VisitClass(It.Is(c => c.Type == typeof(Person)))).Verifiable(); 85 | visitor.Setup(o => o.VisitClass(It.Is(c => c.Type == typeof(Address)))).Verifiable(); 86 | 87 | var builder = new TsModelBuilder(); 88 | builder.Add(typeof(Person), true); 89 | 90 | var target = builder.Build(); 91 | target.RunVisitor(visitor.Object); 92 | 93 | visitor.VerifyAll(); 94 | } 95 | 96 | [Fact] 97 | public void WhenRunVisitor_VisitPropertyIsCalledForPropertiesOfModelClasses() 98 | { 99 | var visitor = new Mock(); 100 | visitor.Setup(o => o.VisitProperty(It.Is(p => p.Name == "Street"))).Verifiable(); 101 | visitor.Setup(o => o.VisitProperty(It.Is(p => p.Name == "Town"))).Verifiable(); 102 | 103 | var builder = new TsModelBuilder(); 104 | builder.Add(typeof(Address), true); 105 | 106 | var target = builder.Build(); 107 | target.RunVisitor(visitor.Object); 108 | 109 | visitor.VerifyAll(); 110 | } 111 | 112 | [Fact] 113 | public void WhenRunVisitor_VisitPropertyIsCalledForFieldsOfModelClasses() 114 | { 115 | var visitor = new Mock(); 116 | visitor.Setup(o => o.VisitProperty(It.Is(p => p.Name == "PostalCode"))).Verifiable(); 117 | 118 | var builder = new TsModelBuilder(); 119 | builder.Add(typeof(Address), true); 120 | 121 | var target = builder.Build(); 122 | target.RunVisitor(visitor.Object); 123 | 124 | visitor.VerifyAll(); 125 | } 126 | 127 | [Fact] 128 | public void WhenRunVisitor_VisitEnumIsCalledForEnumsOfModel() 129 | { 130 | var visitor = new Mock(); 131 | visitor.Setup(o => o.VisitEnum(It.Is(c => c.Type == typeof(ContactType)))).Verifiable(); 132 | 133 | var builder = new TsModelBuilder(); 134 | builder.Add(typeof(Address), true); 135 | 136 | var target = builder.Build(); 137 | target.RunVisitor(visitor.Object); 138 | 139 | visitor.VerifyAll(); 140 | } 141 | 142 | #endregion 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TsModels/TsCollectionTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using TypeLitePlus.Tests.NetCore.TestModels; 5 | using TypeLitePlus.TsModels; 6 | using Xunit; 7 | 8 | namespace TypeLitePlus.Tests.NetCore.TsModels 9 | { 10 | public class TsCollectionTests 11 | { 12 | 13 | [Fact] 14 | public void WhenInitializedWithTypedArray_ItemsTypeIsSetToGenericParameter() 15 | { 16 | var target = new TsCollection(typeof(Address[])); 17 | 18 | Assert.Equal(typeof(Address), target.ItemsType.Type); 19 | } 20 | 21 | [Fact] 22 | public void WhenInitializedWithTypedCollection_ItemsTypeIsSetToGenericParameter() 23 | { 24 | var target = new TsCollection(typeof(List
)); 25 | 26 | Assert.Equal(typeof(Address), target.ItemsType.Type); 27 | } 28 | 29 | [Fact] 30 | public void WhenInitializedWithUnyypedCollection_ItemsTypeIsSetToAny() 31 | { 32 | var target = new TsCollection(typeof(IList)); 33 | 34 | Assert.Equal(TsType.Any, target.ItemsType); 35 | } 36 | 37 | [Fact] 38 | public void WhenInitializedWithTypeNotImplementingIEnumerable_ArgumentExceptionIsThrown() 39 | { 40 | Assert.Throws(() => new TsCollection(typeof(Address))); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TsModels/TsEnumTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TypeLitePlus.Tests.NetCore.TestModels; 3 | using TypeLitePlus.TsModels; 4 | using Xunit; 5 | 6 | namespace TypeLitePlus.Tests.NetCore.TsModels 7 | { 8 | public class TsEnumTests 9 | { 10 | 11 | [Fact] 12 | public void WhenInitializedWithNonEnumType_ArgumentExceptionIsThrown() 13 | { 14 | Assert.Throws(() => new TsEnum(typeof(Address))); 15 | } 16 | 17 | [Fact] 18 | public void WhenInitialized_NameIsSet() 19 | { 20 | var target = new TsEnum(typeof(ContactType)); 21 | 22 | Assert.Equal("ContactType", target.Name); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TsModels/TsModuleTests.cs: -------------------------------------------------------------------------------- 1 |  2 | using Xunit; 3 | 4 | using TypeLitePlus.TsModels; 5 | 6 | namespace TypeLitePlus.Tests.NetCore.TsModels 7 | { 8 | public class TsModuleTests 9 | { 10 | 11 | [Fact] 12 | public void WhenInitialized_ClassesCollectionIsEmpty() 13 | { 14 | var target = new TsModule("Tests"); 15 | 16 | Assert.NotNull(target.Classes); 17 | Assert.Empty(target.Classes); 18 | } 19 | 20 | [Fact] 21 | public void WhenInitialized_NameIsSet() 22 | { 23 | var target = new TsModule("Tests"); 24 | 25 | Assert.Equal("Tests", target.Name); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TsModels/TsPropertyTests.cs: -------------------------------------------------------------------------------- 1 | using TypeLitePlus.Tests.NetCore.TestModels; 2 | using TypeLitePlus.TsModels; 3 | using Xunit; 4 | 5 | namespace TypeLitePlus.Tests.NetCore.TsModels 6 | { 7 | public class TsPropertyTests 8 | { 9 | [Fact] 10 | public void WhenInitialized_PropertyInfoIsSet() 11 | { 12 | var propertyInfo = typeof(Person).GetProperty("Name"); 13 | 14 | var target = new TsProperty(propertyInfo); 15 | 16 | Assert.Same(propertyInfo, target.MemberInfo); 17 | } 18 | 19 | [Fact] 20 | public void WhenInitialized_IsIgnoredIsFalse() 21 | { 22 | var propertyInfo = typeof(Person).GetProperty("Name"); 23 | 24 | var target = new TsProperty(propertyInfo); 25 | 26 | Assert.False(target.IsIgnored); 27 | } 28 | 29 | [Fact] 30 | public void WhenInitialized_IsOptionalIsFalse() 31 | { 32 | var propertyInfo = typeof(Person).GetProperty("Name"); 33 | 34 | var target = new TsProperty(propertyInfo); 35 | 36 | Assert.False(target.IsOptional); 37 | } 38 | 39 | [Fact] 40 | public void WhenInitialized_NameIsSet() 41 | { 42 | var propertyInfo = typeof(Person).GetProperty("Name"); 43 | 44 | var target = new TsProperty(propertyInfo); 45 | 46 | Assert.Equal("Name", target.Name); 47 | } 48 | 49 | [Fact] 50 | public void WhenInitialized_PropertyTypeIsSet() 51 | { 52 | var propertyInfo = typeof(Person).GetProperty("Name"); 53 | 54 | var target = new TsProperty(propertyInfo); 55 | 56 | Assert.Equal(propertyInfo.PropertyType, target.PropertyType.Type); 57 | } 58 | 59 | [Fact] 60 | public void WhenInitializedAndHasCustomNameInAttribute_CustomNameIsUsed() 61 | { 62 | var propertyInfo = typeof(CustomClassName).GetProperty("CustomPorperty"); 63 | 64 | var target = new TsProperty(propertyInfo); 65 | 66 | Assert.Equal("MyProperty", target.Name); 67 | } 68 | 69 | [Fact] 70 | public void WhenInitializedAndIsAnnotatedWithIgnoreAttribute_IsIgnoresIsSetToTrue() 71 | { 72 | var propertyInfo = typeof(Product).GetProperty("Ignored"); 73 | 74 | var target = new TsProperty(propertyInfo); 75 | 76 | Assert.True(target.IsIgnored); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TsModels/TsSystemTypeTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TypeLitePlus.Tests.NetCore.TestModels; 3 | using TypeLitePlus.TsModels; 4 | using Xunit; 5 | 6 | namespace TypeLitePlus.Tests.NetCore.TsModels 7 | { 8 | public class TsSystemTypeTests 9 | { 10 | 11 | [Fact] 12 | public void WhenInitializedWithBool_KindIsSetToBool() 13 | { 14 | var target = new TsSystemType(typeof(bool)); 15 | 16 | Assert.Equal(SystemTypeKind.Bool, target.Kind); 17 | } 18 | 19 | [Fact] 20 | public void WhenInitializedWithInt_KindIsSetToNumber() 21 | { 22 | var target = new TsSystemType(typeof(int)); 23 | 24 | Assert.Equal(SystemTypeKind.Number, target.Kind); 25 | } 26 | 27 | [Fact] 28 | public void WhenInitializedWithDouble_KindIsSetToNumber() 29 | { 30 | var target = new TsSystemType(typeof(double)); 31 | 32 | Assert.Equal(SystemTypeKind.Number, target.Kind); 33 | } 34 | 35 | [Fact] 36 | public void WhenInitializedWithDecimal_KindIsSetToNumber() 37 | { 38 | var target = new TsSystemType(typeof(decimal)); 39 | 40 | Assert.Equal(SystemTypeKind.Number, target.Kind); 41 | } 42 | 43 | [Fact] 44 | public void WhenInitializedWithString_KindIsSetToString() 45 | { 46 | var target = new TsSystemType(typeof(string)); 47 | 48 | Assert.Equal(SystemTypeKind.String, target.Kind); 49 | } 50 | 51 | [Fact] 52 | public void WhenInitializedWithDateTime_KindIsSetToDate() 53 | { 54 | var target = new TsSystemType(typeof(DateTime)); 55 | 56 | Assert.Equal(SystemTypeKind.Date, target.Kind); 57 | } 58 | 59 | [Fact] 60 | public void WhenInitializedWithNullableType_KindIsSetAccordingToUnderlayingType() 61 | { 62 | var target = new TsSystemType(typeof(int?)); 63 | 64 | Assert.Equal(SystemTypeKind.Number, target.Kind); 65 | } 66 | 67 | [Fact] 68 | public void WhenInitializedWithUnsupportedType_ExceptionIsThrown() 69 | { 70 | Assert.Throws(() => new TsSystemType(typeof(Address))); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TsModels/TsTypeTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using TypeLitePlus.Tests.NetCore.TestModels; 4 | using TypeLitePlus.TsModels; 5 | using Xunit; 6 | 7 | namespace TypeLitePlus.Tests.NetCore.TsModels 8 | { 9 | public class TsTypeTests 10 | { 11 | [Fact] 12 | public void WhenInitilized_ClrTypeIsSet() 13 | { 14 | var type = typeof(string); 15 | 16 | var target = new TsType(type); 17 | 18 | Assert.Equal(type, target.Type); 19 | } 20 | 21 | #region GetTypeFamily tests 22 | 23 | [Fact] 24 | public void WhenGetTypeFamilyForInt_SystemIsReturned() 25 | { 26 | var family = TsType.GetTypeFamily(typeof(int)); 27 | 28 | Assert.Equal(TsTypeFamily.System, family); 29 | } 30 | 31 | [Fact] 32 | public void WhenGetTypeFamilyForString_SystemIsReturned() 33 | { 34 | var family = TsType.GetTypeFamily(typeof(string)); 35 | 36 | Assert.Equal(TsTypeFamily.System, family); 37 | } 38 | 39 | [Fact] 40 | public void WhenGetTypeFamilyForDouble_SystemIsReturned() 41 | { 42 | var family = TsType.GetTypeFamily(typeof(double)); 43 | 44 | Assert.Equal(TsTypeFamily.System, family); 45 | } 46 | 47 | [Fact] 48 | public void WhenGetTypeFamilyForBool_SystemIsReturned() 49 | { 50 | var family = TsType.GetTypeFamily(typeof(bool)); 51 | 52 | Assert.Equal(TsTypeFamily.System, family); 53 | } 54 | 55 | [Fact] 56 | public void WhenGetTypeFamilyForDateTime_SystemIsReturned() 57 | { 58 | var family = TsType.GetTypeFamily(typeof(DateTime)); 59 | 60 | Assert.Equal(TsTypeFamily.System, family); 61 | } 62 | 63 | [Fact] 64 | public void WhenGetTypeFamilyForDecimal_SystemIsReturned() 65 | { 66 | var family = TsType.GetTypeFamily(typeof(decimal)); 67 | 68 | Assert.Equal(TsTypeFamily.System, family); 69 | } 70 | 71 | [Fact] 72 | public void WhenGetTypeFamilyForClass_ClassIsReturned() 73 | { 74 | var family = TsType.GetTypeFamily(typeof(Address)); 75 | 76 | Assert.Equal(TsTypeFamily.Class, family); 77 | } 78 | 79 | [Fact] 80 | public void WhenGetTypeFamilyForEnum_EnumIsReturned() 81 | { 82 | var family = TsType.GetTypeFamily(typeof(CustomerKind)); 83 | 84 | Assert.Equal(TsTypeFamily.Enum, family); 85 | } 86 | 87 | [Fact] 88 | public void WhenGetTypeFamilyForIEnumerable_ClassIsReturned() 89 | { 90 | var family = TsType.GetTypeFamily(typeof(List)); 91 | 92 | Assert.Equal(TsTypeFamily.Collection, family); 93 | } 94 | 95 | [Fact] 96 | public void WhenGetTypeFamilyForObject_TypeIsReturned() 97 | { 98 | var family = TsType.GetTypeFamily(typeof(object)); 99 | 100 | Assert.Equal(TsTypeFamily.Type, family); 101 | } 102 | 103 | [Fact] 104 | public void WhenGetTypeFamilyForStruct_ClassIsReturned() 105 | { 106 | var family = TsType.GetTypeFamily(typeof(PointStruct)); 107 | 108 | Assert.Equal(TsTypeFamily.Class, family); 109 | } 110 | 111 | [Fact] 112 | public void WhenGetTypeFamilyForNullableSystemType_SystemTypeIsReturned() 113 | { 114 | var family = TsType.GetTypeFamily(typeof(int?)); 115 | 116 | Assert.Equal(TsTypeFamily.System, family); 117 | } 118 | 119 | [Fact] 120 | public void WhenGetTypeFamilyForNullableStruct_ClassIsReturned() 121 | { 122 | var family = TsType.GetTypeFamily(typeof(PointStruct?)); 123 | 124 | Assert.Equal(TsTypeFamily.Class, family); 125 | } 126 | 127 | #endregion 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TypeConvertorCollectionTests.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | 3 | namespace TypeLitePlus.Tests.NetCore 4 | { 5 | public class TypeConvertorCollectionTests 6 | { 7 | [Fact] 8 | public void WhenConvertTypeAndNoConverterRegistered_NullIsReturned() 9 | { 10 | var target = new TypeConvertorCollection(); 11 | 12 | var result = target.ConvertType(typeof(string)); 13 | 14 | Assert.Null(result); 15 | } 16 | 17 | [Fact] 18 | public void WhenConvertType_ConvertedValueIsReturned() 19 | { 20 | var target = new TypeConvertorCollection(); 21 | target.RegisterTypeConverter(type => "KnockoutObservable"); 22 | 23 | var result = target.ConvertType(typeof(string)); 24 | 25 | Assert.Equal("KnockoutObservable", result); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TypeLitePlus.Tests.NetCore/TypeLitePlus.Tests.NetCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | false 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | all 15 | runtime; build; native; contentfiles; analyzers 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | True 27 | True 28 | TsKo.tt 29 | 30 | 31 | TextTemplatingFileGenerator 32 | TsKo.d.ts 33 | 34 | 35 | True 36 | True 37 | TsUtils.tt 38 | 39 | 40 | TextTemplatingFileGenerator 41 | TsUtils.d.ts 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /TypeLitePlus.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28124.53 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EEE2AFA0-BFF3-433C-B72C-E9BE1598D017}" 7 | ProjectSection(SolutionItems) = preProject 8 | readme.md = readme.md 9 | EndProjectSection 10 | EndProject 11 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TypeLitePlus.Core", "TypeLitePlus.Core\TypeLitePlus.Core.csproj", "{1B55F4A6-E57C-4E5C-9186-85FCF4BE0FF0}" 12 | EndProject 13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TypeLitePlus.T4", "TypeLitePlus.T4\TypeLitePlus.T4.csproj", "{BED54B17-3AE3-4F41-92BE-346AACB6E504}" 14 | EndProject 15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TypeLitePlus.Tests.NetCore", "TypeLitePlus.Tests.NetCore\TypeLitePlus.Tests.NetCore.csproj", "{F929AA37-6D8D-4D48-84D6-ED36F5929425}" 16 | EndProject 17 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{33ACD6E6-0ADF-4372-932C-0CEE767B3287}" 18 | EndProject 19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypeLitePlus.Tests.AssemblyWithEnum", "TypeLitePlus.Tests.AssemblyWithEnum\TypeLitePlus.Tests.AssemblyWithEnum.csproj", "{99818A20-DA2B-4ED4-A96D-E6FAE2DBED48}" 20 | EndProject 21 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TypeLitePlus", "TypeLitePlus\TypeLitePlus.csproj", "{CB386AF4-0417-4BE1-9724-B081582F895D}" 22 | EndProject 23 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TypeLitePlus.DotNetScript", "TypeLitePlus.DotNetScript\TypeLitePlus.DotNetScript.csproj", "{BB126D9A-2C0C-4F1A-95C5-7B1E42D813B9}" 24 | EndProject 25 | Global 26 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 27 | Debug|Any CPU = Debug|Any CPU 28 | Release|Any CPU = Release|Any CPU 29 | EndGlobalSection 30 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 31 | {1B55F4A6-E57C-4E5C-9186-85FCF4BE0FF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {1B55F4A6-E57C-4E5C-9186-85FCF4BE0FF0}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {1B55F4A6-E57C-4E5C-9186-85FCF4BE0FF0}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {1B55F4A6-E57C-4E5C-9186-85FCF4BE0FF0}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {BED54B17-3AE3-4F41-92BE-346AACB6E504}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {BED54B17-3AE3-4F41-92BE-346AACB6E504}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {BED54B17-3AE3-4F41-92BE-346AACB6E504}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {BED54B17-3AE3-4F41-92BE-346AACB6E504}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {F929AA37-6D8D-4D48-84D6-ED36F5929425}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 40 | {F929AA37-6D8D-4D48-84D6-ED36F5929425}.Debug|Any CPU.Build.0 = Debug|Any CPU 41 | {F929AA37-6D8D-4D48-84D6-ED36F5929425}.Release|Any CPU.ActiveCfg = Release|Any CPU 42 | {F929AA37-6D8D-4D48-84D6-ED36F5929425}.Release|Any CPU.Build.0 = Release|Any CPU 43 | {99818A20-DA2B-4ED4-A96D-E6FAE2DBED48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {99818A20-DA2B-4ED4-A96D-E6FAE2DBED48}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {99818A20-DA2B-4ED4-A96D-E6FAE2DBED48}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {99818A20-DA2B-4ED4-A96D-E6FAE2DBED48}.Release|Any CPU.Build.0 = Release|Any CPU 47 | {CB386AF4-0417-4BE1-9724-B081582F895D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 48 | {CB386AF4-0417-4BE1-9724-B081582F895D}.Debug|Any CPU.Build.0 = Debug|Any CPU 49 | {CB386AF4-0417-4BE1-9724-B081582F895D}.Release|Any CPU.ActiveCfg = Release|Any CPU 50 | {CB386AF4-0417-4BE1-9724-B081582F895D}.Release|Any CPU.Build.0 = Release|Any CPU 51 | {BB126D9A-2C0C-4F1A-95C5-7B1E42D813B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 52 | {BB126D9A-2C0C-4F1A-95C5-7B1E42D813B9}.Debug|Any CPU.Build.0 = Debug|Any CPU 53 | {BB126D9A-2C0C-4F1A-95C5-7B1E42D813B9}.Release|Any CPU.ActiveCfg = Release|Any CPU 54 | {BB126D9A-2C0C-4F1A-95C5-7B1E42D813B9}.Release|Any CPU.Build.0 = Release|Any CPU 55 | EndGlobalSection 56 | GlobalSection(SolutionProperties) = preSolution 57 | HideSolutionNode = FALSE 58 | EndGlobalSection 59 | GlobalSection(NestedProjects) = preSolution 60 | {F929AA37-6D8D-4D48-84D6-ED36F5929425} = {33ACD6E6-0ADF-4372-932C-0CEE767B3287} 61 | {99818A20-DA2B-4ED4-A96D-E6FAE2DBED48} = {33ACD6E6-0ADF-4372-932C-0CEE767B3287} 62 | EndGlobalSection 63 | GlobalSection(ExtensibilityGlobals) = postSolution 64 | SolutionGuid = {E275CC60-52C0-40CB-B007-DB9FDA3A34EB} 65 | EndGlobalSection 66 | EndGlobal 67 | -------------------------------------------------------------------------------- /TypeLitePlus/TypeLitePlus.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0;net461 5 | false 6 | 2.0.0 7 | Lukas Kabrt, Robert McLaws, and contributors. 8 | Generates TypeScript classes or interfaces from .Net Standard 2.0 classes. This metapackage references everything you need to get going. 9 | Copyright &copy; 2018 Robert McLaws, and CloudNimble, Inc. Copyright &copy 2013 Lukas Kabrt. 10 | TypeScript, TypeLite, d.ts 11 | true 12 | http://type.litesolutions.net 13 | https://github.com/CloudNimble/TypeLitePlus 14 | https://choosealicense.com/licenses/mit/ 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | Version 1.1.0.0 (12. 2. 2015) 2 | ===================================== 3 | Added Better extensibility of TsGenerator, better extensibility of formaters 4 | 5 | Version 1.0.2.0 (21. 1. 2015) 6 | ===================================== 7 | Fixed #47 Fixed problem with derived generics 8 | 9 | Version 1.0.1.0 (17. 11. 2014) 10 | ===================================== 11 | Fixed #64 Incorrect definition for KeyValuePair> 12 | Fixed #65 Generic porperty referencin containing type causes StackOverflowException 13 | Added #49 Better output formating 14 | 15 | Version 1.0.0.0 (29. 10. 2014) 16 | ===================================== 17 | Fixed #57 Support for generics 18 | 19 | Version 0.9.6.0 (20. 10. 2014) 20 | ===================================== 21 | Fixed #51 Support for multidimensional arrays 22 | 23 | Version 0.9.5.0 (5. 9. 2014) 24 | ===================================== 25 | Fixed #52 Support for using [TsEnum] without class 26 | Added #60 DateTimeOffset generated as Date 27 | Added #50 Support for generating TypeScript interfaces from .NET interfaces 28 | 29 | Version 0.9.4.1 (3. 9. 2014) 30 | ===================================== 31 | Fixed #59 Bug in tt files 32 | 33 | Version 0.9.4.0 (20. 8. 2014) 34 | ===================================== 35 | Added #57 Support public fields 36 | 37 | Version 0.9.3.0 (18. 6. 2014) 38 | ===================================== 39 | Fixed #48 For().ToModule() 40 | Added #46 Support for inner classes 41 | 42 | Version 0.9.2.0 (16. 6. 2014) 43 | ===================================== 44 | Fixed #43 Declare keyword on modules with enums 45 | Fixed #44 Export keyword on enums 46 | Fixed #45 Empty modules 47 | Added #27 Support for standalone enums 48 | 49 | Version 0.9.1.9 (10. 6. 2014) 50 | ===================================== 51 | Fixed #33: Enums not created when using list 52 | Fixed #41: Combination of generics and Enum throws an exception 53 | Fixed #42: Duplicate TS iterfaces for generic parameters 54 | 55 | Version 0.9.1.8 (8. 6. 2014) 56 | ===================================== 57 | Added Strong assembly names 58 | 59 | Version 0.9.1.7 (29. 5. 2014) 60 | ===================================== 61 | Added #17: Enums should go to .ts files 62 | 63 | Version 0.9.1.6 (17. 1. 2014) 64 | ===================================== 65 | Added MemberTypeFormatter 66 | Fixed #28: Fluent method for adding references 67 | 68 | Version 0.9.1.5 (10. 11. 2013) 69 | ===================================== 70 | Added Optional fields 71 | Fixed #24: Nullable enums 72 | 73 | Version 0.9.1.4 (14. 10. 2013) 74 | ===================================== 75 | Added Nuget package TypeLITE.Lib without T4 templates 76 | Fixed Empty modules when type convertor is used 77 | 78 | Version 0.9.1.3 (10. 10. 2013) 79 | ===================================== 80 | Fixed Incorrect output of type convertor if the module is specified 81 | 82 | Version 0.9.1.2 (9. 10. 2013) 83 | ===================================== 84 | Fixed #15: Problems with enum underlaying types 85 | Fixed #18: ModelVisitor visits enums 86 | Added #7: Type convertors 87 | Added #9: Fluent configuration for classes 88 | 89 | Version 0.9.1.1 (9. 8. 2013) 90 | ===================================== 91 | Added #12: Generation of enums 92 | 93 | Version 0.9.1beta (9. 8. 2013) 94 | ===================================== 95 | Fixed #13: TypeScript 0.9.1 uses boolean keyword instead of bool 96 | 97 | Version 0.9.0beta (27. 6. 2013) 98 | ===================================== 99 | Fixed #11: Typescript 0.9 requires declare keyword in the module definition 100 | Enhancement #10: Converted project to Portable class library 101 | 102 | Version 0.8.3 (22. 4. 2013) 103 | ===================================== 104 | Fixed #4: DateTime type conversion results in invalid type definition 105 | Fixed #5: Generic classes result in invalid interface definitions 106 | Fixed #6: Properties with System.Guid type result in invalid typescript code 107 | 108 | Version 0.8.2 (8. 4. 2013) 109 | ===================================== 110 | Fixed #2: TsIgnore-attribute doesn't work with properties 111 | Added Support for nullable value types 112 | Added Support for .NET 4 --------------------------------------------------------------------------------