├── .gitattributes
├── .gitignore
├── BanBrick.TypeScript.CodeGenerator.Annotations
├── BanBrick.TypeScript.CodeGenerator.Annotations.csproj
├── BanBrick.TypeScript.CodeGenerator.Annotations.nuspec
├── TypeScriptIgnoreAttribute.cs
├── TypeScriptObjectAttribute.cs
├── TypeScriptObjectType.cs
└── TypeScriptPropertyAttribute.cs
├── BanBrick.TypeScript.CodeGenerator.UnitTest
├── BanBrick.TypeScript.CodeGenerator.UnitTest.csproj
├── Convertors
│ └── ValueConvertorTest.cs
├── Generators
│ ├── ClassCodeGeneratorTest.cs
│ ├── EnumCodeGeneratorTest.cs
│ └── TypeDefinitionGeneratorTest.cs
├── Helpers
│ └── TypeHelperTest.cs
└── TestModels
│ ├── ITestInterface1.cs
│ ├── ITestInterface2.cs
│ ├── TestCollectionModel.cs
│ ├── TestDictionaryModel.cs
│ ├── TestEnum1.cs
│ ├── TestEnum2.cs
│ ├── TestInheritModel1.cs
│ ├── TestModel1.cs
│ ├── TestModel2.cs
│ ├── TestModel3.cs
│ ├── TestModel4.cs
│ ├── TestModel5.cs
│ └── TestPrimitiveModel.cs
├── BanBrick.TypeScript.CodeGenerator.sln
├── BanBrick.TypeScript.CodeGenerator
├── BanBrick.TypeScript.CodeGenerator.csproj
├── BanBrick.TypeScript.CodeGenerator.nuspec
├── Convertors
│ ├── ConfigConvertor.cs
│ ├── NameConvertor.cs
│ └── ValueConvertor.cs
├── Enums
│ ├── OutputType.cs
│ └── ProcessingCategory.cs
├── Extensions
│ ├── AddtionalStringExtensions.cs
│ ├── AddtionalTypeExtensions.cs
│ ├── TypeDefinitionExtension.cs
│ └── TypePropertyExtensions.cs
├── Generators
│ ├── ClassCodeGenerator.cs
│ ├── CodeGeneratorFactory.cs
│ ├── ConstCodeGenerator.cs
│ ├── EnumCodeGenerator.cs
│ ├── ICodeGenerator.cs
│ └── InterfaceCodeGenerator.cs
├── Helpers
│ ├── AssemblyHelper.cs
│ └── TypeHelper.cs
├── Models
│ ├── ProcessConfig.cs
│ ├── PropertyDefinition.cs
│ └── TypeDefinition.cs
├── ProjectInfo.cs
├── Resolvers
│ ├── ConfigResolver.cs
│ ├── DuplicationResolver.cs
│ ├── NameResolver.cs
│ └── RelationResolver.cs
├── TypeScriptProcesser.cs
└── TypeScriptSettings.cs
├── Code Generation Work Flow v3.png
├── LICENSE
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.Annotations/BanBrick.TypeScript.CodeGenerator.Annotations.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | 1.1.3
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.Annotations/BanBrick.TypeScript.CodeGenerator.Annotations.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BanBrick.TypeScript.CodeGenerator.Annotations
5 | 1.1.3
6 | jiarong.gu
7 | jiarong.gu
8 | false
9 | Annotations Liabrary for BanBrick.TypeScript.CodeGenerator
10 |
11 | 1. Added TypeScript Object Inherit for generation type
12 |
13 | Copyright 2018
14 | https://github.com/JiarongGu/BanBrick.TypeScript.CodeGenerator
15 |
16 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.Annotations/TypeScriptIgnoreAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.Annotations
6 | {
7 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
8 | public class TypeScriptIgnoreAttribute: Attribute
9 | {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.Annotations/TypeScriptObjectAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.Annotations
6 | {
7 | [AttributeUsage(AttributeTargets.Class| AttributeTargets.Enum, AllowMultiple = false)]
8 | public class TypeScriptObjectAttribute: Attribute
9 | {
10 | public TypeScriptObjectAttribute() { }
11 |
12 | public TypeScriptObjectAttribute(string name)
13 | => (Name) = name;
14 |
15 | public TypeScriptObjectAttribute(string name, TypeScriptObjectType type)
16 | => (Type, Name) = (type, name);
17 |
18 | public TypeScriptObjectAttribute(string name, TypeScriptObjectType type, bool inherit)
19 | => (Type, Name, Inherit) = (type, name, inherit);
20 |
21 | public string Name { get; set; }
22 |
23 | public TypeScriptObjectType Type { get; set; }
24 |
25 | public bool Inherit { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.Annotations/TypeScriptObjectType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.Annotations
6 | {
7 | public enum TypeScriptObjectType
8 | {
9 | Default,
10 | Class,
11 | Const,
12 | Enum,
13 | Interface
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.Annotations/TypeScriptPropertyAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.Annotations
6 | {
7 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
8 | public class TypeScriptPropertyAttribute : Attribute
9 | {
10 | public TypeScriptPropertyAttribute() { }
11 |
12 | public TypeScriptPropertyAttribute(string name)
13 | => (Name) = name;
14 |
15 | public TypeScriptPropertyAttribute(string name, string defaultValue)
16 | => (Name, DefaultValue) = (name, defaultValue);
17 |
18 | public TypeScriptPropertyAttribute(string name, string defaultValue, bool? allowedNull)
19 | => (Name, DefaultValue, AllowedNull) = (name, defaultValue, allowedNull);
20 |
21 | public string Name { get; set; }
22 |
23 | public string DefaultValue { get; set; }
24 |
25 | public bool? AllowedNull { get; set; }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/BanBrick.TypeScript.CodeGenerator.UnitTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 | false
7 |
8 | BanBrick.TypeScript.CodeGenerator.UnitTest
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/Convertors/ValueConvertorTest.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Convertors;
2 | using BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 | using Xunit;
7 |
8 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.Convertors
9 | {
10 | public class ValueConvertorTest
11 | {
12 | //private readonly ValueConvertor _convertor;
13 |
14 | //public ValueConvertorTest()
15 | //{
16 | // _convertor = new ValueConvertor();
17 | //}
18 |
19 | //[Fact]
20 | //public void GetPrimitiveValueCode_ShouldReturnCorrect() {
21 | // var instance = new TestPrimitiveModel()
22 | // {
23 | // Value1 = "Test value",
24 | // Value2 = 10,
25 | // Value3 = 20,
26 | // Value4 = 30,
27 | // Value5 = 40,
28 | // Value6 = 50,
29 | // Value7 = true,
30 | // Value8 = null,
31 | // Value9 = 70,
32 | // Value10 = null
33 | // };
34 |
35 | // var value1 = _convertor.GetPrimitiveValueCode(instance.Value1);
36 | // Assert.Equal("'Test value'", value1);
37 |
38 | // var value2 = _convertor.GetPrimitiveValueCode(instance.Value2);
39 | // Assert.Equal("10", value2);
40 |
41 | // var value3 = _convertor.GetPrimitiveValueCode(instance.Value3);
42 | // Assert.Equal("20", value3);
43 |
44 | // var value4 = _convertor.GetPrimitiveValueCode(instance.Value4);
45 | // Assert.Equal("30", value4);
46 |
47 | // var value5 = _convertor.GetPrimitiveValueCode(instance.Value5);
48 | // Assert.Equal("40", value5);
49 |
50 | // var value6 = _convertor.GetPrimitiveValueCode(instance.Value6);
51 | // Assert.Equal("50", value6);
52 |
53 | // var value7 = _convertor.GetPrimitiveValueCode(instance.Value7);
54 | // Assert.Equal("true", value7);
55 |
56 | // var value8 = _convertor.GetPrimitiveValueCode(instance.Value8);
57 | // Assert.Equal("null", value8);
58 |
59 | // var value9 = _convertor.GetPrimitiveValueCode(instance.Value9);
60 | // Assert.Equal("70", value9);
61 |
62 | // var value10 = _convertor.GetPrimitiveValueCode(instance.Value10);
63 | // Assert.Equal("null", value10);
64 | //}
65 |
66 |
67 | //[Fact]
68 | //public void GetValueCode_ShouldReturnNumberArrayCode()
69 | //{
70 | // var numberList = new List() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
71 | // var numberListCode = _convertor.GetValueCode(numberList.GetType(), numberList);
72 |
73 | // Assert.Equal("[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]", numberListCode);
74 | //}
75 |
76 | //[Fact]
77 | //public void GetValueCode_ShouldReturnNumberDictionaryCode()
78 | //{
79 | // var numberDisctionary = new Dictionary() {
80 | // { 1, "1" },
81 | // { 2, "2" },
82 | // { 3, "3" },
83 | // { 4, "4" },
84 | // { 5, "5" },
85 | // };
86 | // var numberListCode = _convertor.GetValueCode(numberDisctionary.GetType(), numberDisctionary);
87 | // Assert.Equal("{ 1: '1', 2: '2', 3: '3', 4: '4', 5: '5' }", numberListCode);
88 | //}
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/Generators/ClassCodeGeneratorTest.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Generators;
2 | using BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 | using Xunit;
7 |
8 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.Generators
9 | {
10 | public class ClassCodeGeneratorTest
11 | {
12 | private readonly ClassCodeGenerator _generator;
13 |
14 | public ClassCodeGeneratorTest()
15 | {
16 | //_generator = new ClassCodeGenerator();
17 | }
18 |
19 | [Fact]
20 | public void Generate_PrimitiveModel_ShouldReturnCorrect() {
21 | //var code = _generator.Generate(typeof(TestPrimitiveModel));
22 | //var expectedCode = "export class TestPrimitiveModel {\r\n constructor(\r\n public value1?: string,\r\n public value2: number = 0,\r\n public value3: number = 0,\r\n public value4: number = 0,\r\n public value5: number = 0,\r\n public value6: number = 0,\r\n public value7?: boolean,\r\n public value8?: number,\r\n public value9?: number,\r\n public value10?: number,\r\n public value11: string,\r\n public value12?: string,\r\n ) { }\r\n}\r\n";
23 | //Assert.Equal(expectedCode, code);
24 | }
25 |
26 | [Fact]
27 | public void Generate_ObjectModelWithDictionary_ShouldReturnCorrect() {
28 | //var code = _generator.Generate(typeof(TestDictionaryModel));
29 | //var expectedCode = "export class TestDictionaryModel {\r\n constructor(\r\n public value1: { [key: string] : string } = { 'value1': 'test_value1' },\r\n public value2: { [key: string] : string } = {},\r\n public value3: { [key: string] : string } = {},\r\n public value4: { [key: string] : string } = {},\r\n public value5: { [key: string] : string } = {},\r\n ) { }\r\n}\r\n";
30 | //Assert.Equal(expectedCode, code);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/Generators/EnumCodeGeneratorTest.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Generators;
2 | using BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 | using Xunit;
7 |
8 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.Generators
9 | {
10 | public class EnumCodeGeneratorTest
11 | {
12 | private readonly EnumCodeGenerator _generator;
13 |
14 | //public EnumCodeGeneratorTest() {
15 | // _generator = new EnumCodeGenerator();
16 | //}
17 |
18 | //[Fact]
19 | //public void GeneratorEnumCode_ReturnCorrectly() {
20 | // var generatedCode = _generator.Generate(typeof(TestEnum1));
21 | // var sampleCode = "export enum TestEnum1 {\r\n NSW = 0,\r\n ACT = 1,\r\n VIC = 2\r\n}\r\nexport const TestEnum1Array = [\r\n 'NSW',\r\n 'ACT',\r\n 'VIC',\r\n];\r\n";
22 |
23 | // Assert.Equal(sampleCode, generatedCode);
24 | //}
25 |
26 | //[Fact]
27 | //public void GeneratorEnumCode_ReturnCorrectlyWithTypeScriptName()
28 | //{
29 | // var generatedCode = _generator.Generate(typeof(TestEnum2));
30 | // var sampleCode = "export enum TestObject {\r\n NSW = 0,\r\n ACT = 1,\r\n VIC = 2\r\n}\r\nexport const TestObjectArray = [\r\n 'NSW',\r\n 'ACT',\r\n 'VIC',\r\n];\r\n";
31 |
32 | // Assert.Equal(sampleCode, generatedCode);
33 | //}
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/Generators/TypeDefinitionGeneratorTest.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Enums;
2 | using BanBrick.TypeScript.CodeGenerator.Resolvers;
3 | using BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Text;
8 | using Xunit;
9 |
10 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.Generators
11 | {
12 | public class TypeDefinitionGeneratorTest
13 | {
14 | [Fact]
15 | public void Get_Should_ReturnAllTypes()
16 | {
17 | var resolver = new RelationResolver();
18 | var types = new List()
19 | {
20 | typeof(TestModel1),
21 | typeof(TestModel2),
22 | typeof(ITestInterface1)
23 | };
24 | var processedTypes = resolver.Resolve(types);
25 | var duplicatedTypes = processedTypes.Select(x => x.Type).ToList().OrderBy(x => x.Name);
26 | var disitinctTypes = duplicatedTypes.Distinct();
27 |
28 | Assert.Equal(disitinctTypes.Count(), processedTypes.Count);
29 | Assert.Equal(2, processedTypes.Where(x => x.ProcessingCategory == ProcessingCategory.Enum).Count());
30 | Assert.Equal(5, processedTypes.Where(x => x.ProcessingCategory == ProcessingCategory.Object).Count());
31 | Assert.Equal(2, processedTypes.Where(x => x.ProcessingCategory == ProcessingCategory.Interface).Count());
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/Helpers/TypeHelperTest.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Enums;
2 | using BanBrick.TypeScript.CodeGenerator.Helpers;
3 | using BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Collections.ObjectModel;
7 | using Xunit;
8 |
9 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.Helpers
10 | {
11 | public class TypeHelperTest
12 | {
13 | private readonly TypeHelper _typeHelper;
14 |
15 | public TypeHelperTest() {
16 | _typeHelper = new TypeHelper();
17 | }
18 |
19 | [Fact]
20 | public void IsPrimitiveType_Should_ReturnTrue()
21 | {
22 | foreach (var prop in typeof(TestPrimitiveModel).GetProperties())
23 | {
24 | Assert.True(_typeHelper.IsPrimitiveType(prop.PropertyType), prop.Name);
25 | }
26 | }
27 |
28 | [Fact]
29 | public void IsPrimitiveType_Should_ReturnFalse()
30 | {
31 | foreach (var prop in typeof(TestCollectionModel).GetProperties())
32 | {
33 | Assert.False(_typeHelper.IsPrimitiveType(prop.PropertyType), prop.Name);
34 | }
35 |
36 | foreach (var prop in typeof(TestDictionaryModel).GetProperties())
37 | {
38 | Assert.False(_typeHelper.IsPrimitiveType(prop.PropertyType), prop.Name);
39 | }
40 | }
41 |
42 | [Fact]
43 | public void IsDictionaryType_Should_ReturnTrue()
44 | {
45 | foreach (var prop in typeof(TestDictionaryModel).GetProperties())
46 | {
47 | Assert.True(_typeHelper.IsDictionaryType(prop.PropertyType), prop.Name);
48 | }
49 | }
50 |
51 | [Fact]
52 | public void IsDictionaryType_Should_ReturnFalse()
53 | {
54 | foreach (var prop in typeof(TestPrimitiveModel).GetProperties())
55 | {
56 | Assert.False(_typeHelper.IsDictionaryType(prop.PropertyType), prop.Name);
57 | }
58 |
59 | foreach (var prop in typeof(TestCollectionModel).GetProperties())
60 | {
61 | Assert.False(_typeHelper.IsDictionaryType(prop.PropertyType), prop.Name);
62 | }
63 | }
64 |
65 | [Fact]
66 | public void IsCollectionType_Should_ReturnTrue()
67 | {
68 | foreach (var prop in typeof(TestCollectionModel).GetProperties())
69 | {
70 | Assert.True(_typeHelper.IsCollectionType(prop.PropertyType), prop.Name);
71 | }
72 | }
73 |
74 | [Fact]
75 | public void IsCollectionType_Should_ReturnFalse()
76 | {
77 | foreach (var prop in typeof(TestPrimitiveModel).GetProperties())
78 | {
79 | Assert.False(_typeHelper.IsCollectionType(prop.PropertyType), prop.Name);
80 | }
81 |
82 | foreach (var prop in typeof(TestDictionaryModel).GetProperties())
83 | {
84 | Assert.False(_typeHelper.IsCollectionType(prop.PropertyType), prop.Name);
85 | }
86 | }
87 |
88 | [Fact]
89 | public void GetTypeCategory_Should_ReturnObject()
90 | {
91 | Assert.Equal(ProcessingCategory.Object, _typeHelper.GetProcessingCategory(typeof(TestPrimitiveModel)));
92 | Assert.Equal(ProcessingCategory.Object, _typeHelper.GetProcessingCategory(typeof(TestCollectionModel)));
93 | Assert.Equal(ProcessingCategory.Object, _typeHelper.GetProcessingCategory(typeof(TestDictionaryModel)));
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/ITestInterface1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
6 | {
7 | public interface ITestInterface1
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/ITestInterface2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
6 | {
7 | public interface ITestInterface2
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestCollectionModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 | using System.Text;
6 |
7 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
8 | {
9 | public class TestCollectionModel
10 | {
11 | public Collection Value1 { get; set; }
12 | public ICollection Value2 { get; set; }
13 | public List Value3 { get; set; }
14 | public IList Value4 { get; set; }
15 | public IEnumerable Value5 { get; set; }
16 | public ConcurrentQueue Value6 { get; set; }
17 | public Queue Value7 { get; set; }
18 | public IReadOnlyCollection Value8 { get; set; }
19 | public string[] Value9 { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestDictionaryModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
7 | {
8 | public class TestDictionaryModel
9 | {
10 | public Dictionary Value1 => new Dictionary()
11 | {
12 | { "value1", "test_value1" }
13 | };
14 |
15 | public IDictionary Value2 { get; set; }
16 | public Dictionary Value3 { get; set; }
17 | public ConcurrentDictionary Value4 { get; set; }
18 | public IReadOnlyDictionary Value5 { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestEnum1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
6 | {
7 | public enum TestEnum1
8 | {
9 | NSW,
10 | ACT,
11 | VIC,
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestEnum2.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
7 | {
8 | [TypeScriptObject("TestObject")]
9 | public enum TestEnum2
10 | {
11 | NSW,
12 | ACT,
13 | VIC,
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestInheritModel1.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
7 | {
8 | [TypeScriptObject(Type = TypeScriptObjectType.Interface, Inherit = true)]
9 | public class TestInheritModel1
10 | {
11 | public TestModel1 TestModel1 { get; set; }
12 | public TestModel2 TestModel2 { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestModel1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 | using System.Text;
6 |
7 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
8 | {
9 | public class TestModel1
10 | {
11 | public TestModel2 Value1 { get; set; }
12 | public ICollection Value2 { get; set; }
13 | public List Value3 { get; set; }
14 | public IList Value4 { get; set; }
15 | public IDictionary Value5 { get; set; }
16 | public Dictionary Value6 { get; set; }
17 | public ITestInterface2 value7 { get; set; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestModel2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
7 | {
8 | public class TestModel2
9 | {
10 | public IEnumerable Value1 { get; set; }
11 | public ConcurrentQueue Value2 { get; set; }
12 | public Queue Value3 { get; set; }
13 | public IReadOnlyCollection Value4 { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestModel3.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
6 | {
7 | public class TestModel3
8 | {
9 | public ITestInterface1 Value1 { get; set; }
10 | public Dictionary Value2 { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestModel4.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
6 | {
7 | public class TestModel4
8 | {
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestModel5.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
6 | {
7 | public class TestModel5
8 | {
9 | public decimal Value1 { get; set; }
10 | public bool? Value2 { get; set; }
11 | public int? Value3 { get; set; }
12 | public TestEnum1 Value4 { get; set; }
13 | public TestModel1 Value5 { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.UnitTest/TestModels/TestPrimitiveModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.UnitTest.TestModels
6 | {
7 | public class TestPrimitiveModel
8 | {
9 | public string Value1 { get; set; }
10 | public int Value2 { get; set; }
11 | public double Value3 { get; set; }
12 | public short Value4 { get; set; }
13 | public long Value5 { get; set; }
14 | public decimal Value6 { get; set; }
15 | public bool? Value7 { get; set; }
16 | public int? Value8 { get; set; }
17 | public decimal? Value9 { get; set; }
18 | public int? Value10 { get; set; }
19 | public DateTime Value11 { get; set; }
20 | public DateTime? Value12 { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28010.2036
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BanBrick.TypeScript.CodeGenerator", "BanBrick.TypeScript.CodeGenerator\BanBrick.TypeScript.CodeGenerator.csproj", "{AB2930A7-1B41-45FF-8B74-8049D5C0DD90}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BanBrick.TypeScript.CodeGenerator.Annotations", "BanBrick.TypeScript.CodeGenerator.Annotations\BanBrick.TypeScript.CodeGenerator.Annotations.csproj", "{45253583-55F3-4B77-A19E-8CC23EDAA900}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BanBrick.TypeScript.CodeGenerator.UnitTest", "BanBrick.TypeScript.CodeGenerator.UnitTest\BanBrick.TypeScript.CodeGenerator.UnitTest.csproj", "{8AD4071E-7EF6-4EB0-A4D8-C096CC5E976A}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {AB2930A7-1B41-45FF-8B74-8049D5C0DD90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {AB2930A7-1B41-45FF-8B74-8049D5C0DD90}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {AB2930A7-1B41-45FF-8B74-8049D5C0DD90}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {AB2930A7-1B41-45FF-8B74-8049D5C0DD90}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {45253583-55F3-4B77-A19E-8CC23EDAA900}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {45253583-55F3-4B77-A19E-8CC23EDAA900}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {45253583-55F3-4B77-A19E-8CC23EDAA900}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {45253583-55F3-4B77-A19E-8CC23EDAA900}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {8AD4071E-7EF6-4EB0-A4D8-C096CC5E976A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {8AD4071E-7EF6-4EB0-A4D8-C096CC5E976A}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {8AD4071E-7EF6-4EB0-A4D8-C096CC5E976A}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {8AD4071E-7EF6-4EB0-A4D8-C096CC5E976A}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {C904C73A-7808-435A-8A7E-D63415F708A5}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/BanBrick.TypeScript.CodeGenerator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | 1.2.4
6 | 1.2.4.0
7 | Jiarong Gu
8 | 1. Added TimeSpan type to primitive type
9 | 2. Fix bug when inner type is same as outer type cause config resolver uncompleted
10 | 3. Fix config resolver not resolver inherit dependency with collection and dictionary
11 | C# to TypeScript Code Generator Library for .Net Core Web APIs Request/Response models
12 | true
13 | false
14 | https://github.com/JiarongGu/BanBrick.TypeScript.CodeGenerator/blob/master/LICENSE
15 | https://github.com/JiarongGu/BanBrick.TypeScript.CodeGenerator
16 | Github
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/BanBrick.TypeScript.CodeGenerator.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BanBrick.TypeScript.CodeGenerator
5 | 1.2.4
6 | jiarong.gu
7 | jiarong.gu
8 | false
9 | C# to TypeScript Code Generator Library for .Net Core Web APIs Request/Response models
10 |
11 | Added TimeSpan type to primitive type
12 | Fix bug when inner type is same as outer type cause config resolver uncompleted
13 | Fix config resolver not resolver inherit dependency with collection and dictionary
14 |
15 | Copyright 2018
16 | https://github.com/JiarongGu/BanBrick.TypeScript.CodeGenerator
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Convertors/ConfigConvertor.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using BanBrick.TypeScript.CodeGenerator.Enums;
3 | using BanBrick.TypeScript.CodeGenerator.Models;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Reflection;
8 | using System.Text;
9 |
10 | namespace BanBrick.TypeScript.CodeGenerator.Convertors
11 | {
12 | ///
13 | /// convert attributes to configs
14 | ///
15 | internal static class ConfigConvertor
16 | {
17 | public static IEnumerable GetProcessConfigs(IEnumerable types)
18 | {
19 | return types.Select(x => GetProcessConfig(x));
20 | }
21 |
22 | public static IEnumerable GetProcessConfigs(IEnumerable typeDefinitions)
23 | {
24 | return GetProcessConfigs(typeDefinitions.Select(x => x.Type));
25 | }
26 |
27 | public static ProcessConfig GetProcessConfig(Type type)
28 | {
29 | var attribute = type.GetCustomAttribute();
30 |
31 | if (attribute == null) return null;
32 |
33 | return new ProcessConfig()
34 | {
35 | OutputType = Parse(attribute.Type),
36 | Name = attribute.Name,
37 | Inherit = attribute.Inherit
38 | };
39 | }
40 |
41 | public static ProcessConfig GetProcessConfig(ProcessingCategory category)
42 | {
43 | return new ProcessConfig()
44 | {
45 | OutputType = Parse(category)
46 | };
47 | }
48 |
49 | public static OutputType Parse(TypeScriptObjectType objectType)
50 | {
51 | switch (objectType)
52 | {
53 | case TypeScriptObjectType.Class:
54 | return OutputType.Class;
55 | case TypeScriptObjectType.Const:
56 | return OutputType.Const;
57 | case TypeScriptObjectType.Enum:
58 | return OutputType.Enum;
59 | case TypeScriptObjectType.Interface:
60 | return OutputType.Interface;
61 | default:
62 | return OutputType.Default;
63 | }
64 | }
65 |
66 | public static OutputType Parse(ProcessingCategory category)
67 | {
68 | switch (category)
69 | {
70 | case ProcessingCategory.Enum:
71 | return OutputType.Enum;
72 | case ProcessingCategory.Object:
73 | return OutputType.Class;
74 | case ProcessingCategory.Interface:
75 | return OutputType.Interface;
76 | default:
77 | return OutputType.None;
78 | }
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Convertors/NameConvertor.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using BanBrick.TypeScript.CodeGenerator.Helpers;
3 | using BanBrick.TypeScript.CodeGenerator.Models;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Reflection;
8 | using System.Text;
9 |
10 | namespace BanBrick.TypeScript.CodeGenerator.Convertors
11 | {
12 | internal interface INameConvertor {
13 | string GetName(Type type);
14 | }
15 |
16 | internal sealed class NameConvertor: INameConvertor
17 | {
18 | private readonly IDictionary _nameDictionary;
19 |
20 | public NameConvertor(IEnumerable typeDefinitions)
21 | {
22 | _nameDictionary = typeDefinitions.ToDictionary(x => x.Type, x => x.ProcessConfig.Name);
23 | }
24 |
25 | public string GetName(Type type)
26 | {
27 | return _nameDictionary[type];
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Convertors/ValueConvertor.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Enums;
2 | using BanBrick.TypeScript.CodeGenerator.Extensions;
3 | using BanBrick.TypeScript.CodeGenerator.Helpers;
4 | using BanBrick.TypeScript.CodeGenerator.Models;
5 | using System;
6 | using System.Collections;
7 | using System.Collections.Generic;
8 | using System.Globalization;
9 | using System.Linq;
10 | using System.Reflection;
11 | using System.Text;
12 |
13 | namespace BanBrick.TypeScript.CodeGenerator.Convertors
14 | {
15 | internal interface IValueConvertor
16 | {
17 | string GetValue(Type type, object value, int indentation = 0);
18 | }
19 |
20 | internal sealed class ValueConvertor: IValueConvertor
21 | {
22 | private readonly INameConvertor _nameConvertor;
23 | private readonly IDictionary _typeDictionary;
24 |
25 | public ValueConvertor(IEnumerable typeDefinitions, INameConvertor nameConvertor)
26 | {
27 | _nameConvertor = nameConvertor;
28 | _typeDictionary = typeDefinitions.ToDictionary(x => x.Type, x => x);
29 | }
30 |
31 | ///
32 | /// Generate value code for typescript in including value check
33 | ///
34 | ///
35 | ///
36 | ///
37 | public string GetValue(Type type, object value, int indentation = 0)
38 | {
39 | var category = _typeDictionary[type].ProcessingCategory;
40 |
41 | if (category == ProcessingCategory.Primitive)
42 | {
43 | if (value == null) return null;
44 | return GetPrimitive(value);
45 | }
46 |
47 | if (category == ProcessingCategory.Enum)
48 | {
49 | return GetEnumValue(_nameConvertor.GetName(type), value);
50 | }
51 |
52 | if (category == ProcessingCategory.Collection)
53 | {
54 | return GenerateArray(value);
55 | }
56 |
57 | if (category == ProcessingCategory.Dictionary)
58 | {
59 | return GenerateDictionary(value, indentation);
60 | }
61 |
62 | if (category == ProcessingCategory.Object)
63 | {
64 | return GenerateObject(value, indentation);
65 | }
66 |
67 | return "";
68 | }
69 |
70 | private string GetPrimitive(object value)
71 | {
72 | if (value == null) return "null";
73 |
74 | var type = value.GetType();
75 | var typeDefinition = _typeDictionary[type];
76 |
77 | if (type == typeof(bool))
78 | return (bool)value ? "true" : "false";
79 |
80 | if (typeDefinition.IsNumeric)
81 | return value.ToString();
82 |
83 | if (type == typeof(string))
84 | return ((string)value).ToTypeScript();
85 |
86 | if (type == typeof(DateTime) && ((DateTime)value).Ticks > 0 )
87 | return ((DateTime)value).ToUniversalTime().ToString("o", CultureInfo.InvariantCulture).ToTypeScript();
88 |
89 | if (type == typeof(DateTime))
90 | return "''";
91 |
92 | if (type == typeof(TimeSpan))
93 | return $"{((TimeSpan)value).TotalMilliseconds}";
94 |
95 | if (type == typeof(Guid))
96 | return "''";
97 |
98 | return null;
99 | }
100 |
101 | private string GenerateArray(object value)
102 | {
103 | if (value == null)
104 | return "[]";
105 |
106 | var arrayValues = value as IEnumerable;
107 | var arrayValuesCode = new List();
108 |
109 | foreach (var arrayValue in arrayValues)
110 | {
111 | arrayValuesCode.Add(GetValue(arrayValue.GetType(), arrayValue));
112 | }
113 |
114 | return $"[ {string.Join(", ", arrayValuesCode)} ]";
115 | }
116 |
117 | private string GenerateDictionary(object value, int indentation = 0)
118 | {
119 | if (value == null)
120 | return "{}";
121 |
122 | var dictionaryValue = value as IDictionary;
123 | var dictionaryValuesCode = new List();
124 |
125 | foreach (var key in dictionaryValue.Keys)
126 | {
127 | var keyValue = dictionaryValue[key];
128 | var keyType = key.GetType();
129 | var keyValueType = keyValue.GetType();
130 |
131 | dictionaryValuesCode.Add($"\n{new string(' ', indentation + 2)}{GetValue(keyType, key)}: {GetValue(keyValueType, keyValue, indentation + 2)}");
132 | }
133 | var code = string.Join($",", dictionaryValuesCode);
134 |
135 | if (string.IsNullOrEmpty(code))
136 | {
137 | return "{}";
138 | }
139 | return $"{{{code}\n{new string(' ', indentation)}}}";
140 | }
141 |
142 | private string GenerateObject(object value, int indentation = 0)
143 | {
144 | if (value == null)
145 | return "";
146 |
147 | var objectType = value.GetType();
148 | var properties = TypeExtensions.GetProperties(objectType);
149 | var objectPropertiesCode = new List();
150 |
151 | foreach (var property in properties)
152 | {
153 | if (property.IsTypeScriptIgnored())
154 | continue;
155 |
156 | var propertyType = property.PropertyType;
157 | var propertyName = _nameConvertor.GetName(propertyType);
158 | var valueCode = GetValue(propertyType, property.GetValue(value), indentation + 2);
159 |
160 | objectPropertiesCode.Add($"\n{new string(' ', indentation + 2)}{property.Name.ToCamelCase()}: {valueCode}");
161 | }
162 | var code = string.Join($",", objectPropertiesCode);
163 |
164 | if (string.IsNullOrEmpty(code))
165 | {
166 | return "{}";
167 | }
168 |
169 | return $"{{{code}\n{new string(' ', indentation)}}}";
170 | }
171 |
172 | private string GetEnumValue(string enumName, object value)
173 | {
174 | return $"{enumName}.{value.ToString()}";
175 | }
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Enums/OutputType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.Enums
6 | {
7 | public enum OutputType
8 | {
9 | None,
10 | Default,
11 | Enum,
12 | Interface,
13 | Class,
14 | Const,
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Enums/ProcessingCategory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.CompilerServices;
4 | using System.Text;
5 |
6 | namespace BanBrick.TypeScript.CodeGenerator.Enums
7 | {
8 | internal enum ProcessingCategory
9 | {
10 | Dictionary,
11 | Collection,
12 | Primitive,
13 | Enum,
14 | Generic,
15 | Object,
16 | Interface
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Extensions/AddtionalStringExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.Extensions
6 | {
7 | internal static class AddtionalStringExtensions
8 | {
9 | public static string ToCamelCase(this string value)
10 | {
11 | if (string.IsNullOrEmpty(value))
12 | return value;
13 |
14 | return value[0].ToString().ToLower() + value.Substring(1);
15 | }
16 |
17 | public static string ToTypeScript(this string value)
18 | {
19 | return "'" + (value?.Replace("'", "\'") ?? "") + "'";
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Extensions/AddtionalTypeExtensions.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 |
8 | namespace BanBrick.TypeScript.CodeGenerator.Extensions
9 | {
10 | internal static class AddtionalTypeExtensions
11 | {
12 | public static (Type key, Type value) GetDictionaryTypes(this Type type)
13 | {
14 | var keyValuetypes = type.GenericTypeArguments;
15 | return (key: keyValuetypes[0], value: keyValuetypes[1]);
16 | }
17 |
18 | public static Type GetCollectionType(this Type type)
19 | {
20 | return type.IsArray ? type.GetElementType() : type.GenericTypeArguments.First();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Extensions/TypeDefinitionExtension.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using BanBrick.TypeScript.CodeGenerator.Enums;
3 | using BanBrick.TypeScript.CodeGenerator.Models;
4 | using BanBrick.TypeScript.CodeGenerator.Resolvers;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 |
10 | namespace BanBrick.TypeScript.CodeGenerator.Extensions
11 | {
12 | internal static class TypeDefinitionExtension
13 | {
14 | public static IEnumerable ResolveRelations(this IEnumerable types)
15 | {
16 | return new RelationResolver().Resolve(types);
17 | }
18 |
19 | public static IEnumerable ResolveNames(this IEnumerable typeDefinitions)
20 | {
21 | return new NameResolver().Resolve(typeDefinitions);
22 | }
23 |
24 | public static IEnumerable ResolveDuplications(this IEnumerable typeDefinitions)
25 | {
26 | return new DuplicationResolver().Resolve(typeDefinitions);
27 | }
28 |
29 | public static IEnumerable ResolveConfigs(this IEnumerable typeDefinitions)
30 | {
31 | return new ConfigResolver().Resolve(typeDefinitions);
32 | }
33 |
34 | public static List GetProcessingTypes(this IEnumerable typeDefinitions, OutputType outputType)
35 | {
36 | return typeDefinitions
37 | .Where(x => x.ProcessConfig.OutputType == outputType)
38 | .OrderBy(x => x.ProcessConfig.Name)
39 | .Select(x => x.Type)
40 | .ToList();
41 | }
42 |
43 | public static bool IsInheritable(this TypeDefinition typeDefinition)
44 | {
45 | switch (typeDefinition.ProcessingCategory)
46 | {
47 | case ProcessingCategory.Interface:
48 | case ProcessingCategory.Object:
49 | return true;
50 | default: return false;
51 | }
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Extensions/TypePropertyExtensions.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 |
8 | namespace BanBrick.TypeScript.CodeGenerator.Extensions
9 | {
10 | internal static class TypePropertyExtensions
11 | {
12 | public static bool IsTypeScriptIgnored(this PropertyInfo propertyInfo)
13 | {
14 | return propertyInfo.GetCustomAttributes(true).OfType().Any();
15 | }
16 |
17 | public static object TryGetValue(this PropertyInfo propertyInfo, object obj)
18 | {
19 | try {
20 | return propertyInfo.GetValue(obj);
21 | }
22 | catch {
23 | return null;
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Generators/ClassCodeGenerator.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Convertors;
2 | using BanBrick.TypeScript.CodeGenerator.Enums;
3 | using BanBrick.TypeScript.CodeGenerator.Extensions;
4 | using BanBrick.TypeScript.CodeGenerator.Helpers;
5 | using BanBrick.TypeScript.CodeGenerator.Models;
6 | using System;
7 | using System.Collections;
8 | using System.Collections.Generic;
9 | using System.Linq;
10 | using System.Reflection;
11 | using System.Text;
12 |
13 | namespace BanBrick.TypeScript.CodeGenerator.Generators
14 | {
15 | internal class ClassCodeGenerator: ICodeGenerator
16 | {
17 | private readonly TypeHelper _typeHelper;
18 |
19 | private readonly IValueConvertor _valueConvertor;
20 | private readonly INameConvertor _nameConvertor;
21 |
22 | public ClassCodeGenerator(INameConvertor nameConvertor, IValueConvertor valueConvertor)
23 | {
24 | _typeHelper = new TypeHelper();
25 |
26 | _valueConvertor = valueConvertor;
27 | _nameConvertor = nameConvertor;
28 | }
29 |
30 | public string Generate(Type type)
31 | {
32 | var stringBuilder = new StringBuilder();
33 |
34 | var typeScriptType = _nameConvertor.GetName(type);
35 |
36 | stringBuilder.AppendLine($"export class {typeScriptType} {{");
37 | stringBuilder.AppendLine(" constructor(");
38 |
39 | object instance = null;
40 |
41 | // create new instance if type contains parameterless constractor
42 | if (type.GetConstructor(Type.EmptyTypes) != null)
43 | {
44 | instance = Activator.CreateInstance(type);
45 | }
46 |
47 | var properties = TypeExtensions.GetProperties(type).ToList().OrderBy(x => x.Name);
48 |
49 | foreach (var property in properties)
50 | {
51 | if (property.IsTypeScriptIgnored())
52 | continue;
53 |
54 | var propertyType = property.PropertyType;
55 | var propertyName = _nameConvertor.GetName(propertyType);
56 | var propertyValue = instance == null ? null : property.GetValue(instance);
57 |
58 | var valueCode = _valueConvertor.GetValue(propertyType, propertyValue);
59 |
60 | var noValueCode = string.IsNullOrEmpty(valueCode);
61 |
62 | var nullableCode = _typeHelper.IsNullable(propertyType) && noValueCode ? "?" : "";
63 | stringBuilder.Append($" public {property.Name.ToCamelCase()}{nullableCode}: ");
64 |
65 | if (!noValueCode)
66 | {
67 | stringBuilder.AppendLine($"{ propertyName} = {valueCode},");
68 | }
69 | else
70 | {
71 | stringBuilder.AppendLine($"{ propertyName},");
72 | }
73 | }
74 |
75 | stringBuilder.AppendLine(" ) { }");
76 | stringBuilder.AppendLine("}");
77 |
78 | return stringBuilder.ToString();
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Generators/CodeGeneratorFactory.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Convertors;
2 | using BanBrick.TypeScript.CodeGenerator.Enums;
3 | using BanBrick.TypeScript.CodeGenerator.Models;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace BanBrick.TypeScript.CodeGenerator.Generators
9 | {
10 | internal class CodeGeneratorFactory
11 | {
12 | private readonly IValueConvertor _valueConvertor;
13 | private readonly INameConvertor _nameConvertor;
14 |
15 | private readonly Dictionary _typeCodeGenerators;
16 |
17 | public CodeGeneratorFactory(INameConvertor nameConvertor, IValueConvertor valueConvertor)
18 | {
19 | _valueConvertor = valueConvertor;
20 | _nameConvertor = nameConvertor;
21 |
22 | _typeCodeGenerators = new Dictionary();
23 | _typeCodeGenerators[OutputType.Enum] = new EnumCodeGenerator(_nameConvertor);
24 | _typeCodeGenerators[OutputType.Interface] = new InterfaceCodeGenerator(_nameConvertor);
25 | _typeCodeGenerators[OutputType.Class] = new ClassCodeGenerator(_nameConvertor, _valueConvertor);
26 | _typeCodeGenerators[OutputType.Const] = new ConstCodeGenerator(_nameConvertor, _valueConvertor);
27 | }
28 |
29 | public ICodeGenerator GetInstance(OutputType outputType)
30 | {
31 | if (outputType == OutputType.None || outputType == OutputType.Default)
32 | return null;
33 | return _typeCodeGenerators[outputType];
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Generators/ConstCodeGenerator.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Convertors;
2 | using BanBrick.TypeScript.CodeGenerator.Extensions;
3 | using BanBrick.TypeScript.CodeGenerator.Helpers;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Reflection;
7 | using System.Text;
8 |
9 | namespace BanBrick.TypeScript.CodeGenerator.Generators
10 | {
11 | internal class ConstCodeGenerator : ICodeGenerator
12 | {
13 | private readonly TypeHelper _typeHelper;
14 |
15 | private readonly IValueConvertor _valueConvertor;
16 | private readonly INameConvertor _nameConvertor;
17 |
18 | public ConstCodeGenerator(INameConvertor nameConvertor, IValueConvertor valueConvertor)
19 | {
20 | _typeHelper = new TypeHelper();
21 |
22 | _valueConvertor = valueConvertor;
23 | _nameConvertor = nameConvertor;
24 | }
25 |
26 | public string Generate(Type type)
27 | {
28 | var stringBuilder = new StringBuilder();
29 |
30 | var name = _nameConvertor.GetName(type).ToCamelCase();
31 |
32 | stringBuilder.AppendLine($"export const {name} = {{");
33 |
34 | object instance = null;
35 |
36 | // create new instance if type contains parameterless constractor
37 | if (type.GetConstructor(Type.EmptyTypes) != null)
38 | {
39 | instance = Activator.CreateInstance(type);
40 | }
41 |
42 | var properties = TypeExtensions.GetProperties(type);
43 | foreach (var property in properties)
44 | {
45 | if (property.IsTypeScriptIgnored())
46 | continue;
47 |
48 | var propertyName = property.Name.ToCamelCase();
49 | var propertyType = property.PropertyType;
50 | var propertyValue = instance == null ? null : property.GetValue(instance);
51 |
52 | var valueCode = _valueConvertor.GetValue(propertyType, propertyValue, 2);
53 |
54 | if (!string.IsNullOrEmpty(valueCode))
55 | {
56 | stringBuilder.AppendLine($" {propertyName}: {valueCode},");
57 | }
58 | }
59 |
60 | stringBuilder.AppendLine("}");
61 |
62 | return stringBuilder.ToString();
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Generators/EnumCodeGenerator.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Convertors;
2 | using BanBrick.TypeScript.CodeGenerator.Extensions;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 |
8 | namespace BanBrick.TypeScript.CodeGenerator.Generators
9 | {
10 | internal sealed class EnumCodeGenerator : ICodeGenerator
11 | {
12 | private readonly INameConvertor _nameConvertor;
13 |
14 | public EnumCodeGenerator(INameConvertor nameConvertor) {
15 | _nameConvertor = nameConvertor;
16 | }
17 |
18 | public string Generate(Type type)
19 | {
20 | var stringBuilder = new StringBuilder();
21 |
22 | var names = Enum.GetNames(type);
23 | var values = Enum.GetValues(type).Cast().ToArray();
24 |
25 | // add typescript enum
26 | stringBuilder.AppendLine($"export enum {_nameConvertor.GetName(type)} {{");
27 |
28 | for (int i = 0; i < names.Length; i++)
29 | stringBuilder.AppendLine($" {names[i]} = {values[i]}{(i == names.Length - 1 ? string.Empty : ",")}");
30 |
31 | stringBuilder.AppendLine("}");
32 |
33 | // add typescript enum array
34 | stringBuilder.AppendLine($"export const {_nameConvertor.GetName(type)}Array = [");
35 |
36 | for (int i = 0; i < names.Length; i++)
37 | stringBuilder.AppendLine($" {names[i].ToTypeScript()},");
38 | stringBuilder.AppendLine("];");
39 |
40 | return stringBuilder.ToString(); ;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Generators/ICodeGenerator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator.Generators
6 | {
7 | interface ICodeGenerator
8 | {
9 | string Generate(Type type);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Generators/InterfaceCodeGenerator.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Convertors;
2 | using BanBrick.TypeScript.CodeGenerator.Extensions;
3 | using BanBrick.TypeScript.CodeGenerator.Helpers;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Reflection;
8 | using System.Text;
9 |
10 | namespace BanBrick.TypeScript.CodeGenerator.Generators
11 | {
12 | internal class InterfaceCodeGenerator : ICodeGenerator
13 | {
14 | private readonly TypeHelper _typeHelper;
15 | private readonly INameConvertor _nameConvertor;
16 |
17 | public InterfaceCodeGenerator(INameConvertor nameConvertor)
18 | {
19 | _typeHelper = new TypeHelper();
20 | _nameConvertor = nameConvertor;
21 | }
22 |
23 | public string Generate(Type type)
24 | {
25 | var stringBuilder = new StringBuilder();
26 |
27 | var typeScriptType = _nameConvertor.GetName(type);
28 |
29 | stringBuilder.AppendLine($"export interface {typeScriptType} {{");
30 |
31 | object instance = null;
32 |
33 | // create new instance if type contains parameterless constractor
34 | if (type.GetConstructor(Type.EmptyTypes) != null)
35 | {
36 | instance = Activator.CreateInstance(type);
37 | }
38 |
39 | var properties = TypeExtensions.GetProperties(type).ToList().OrderBy(x => x.Name);
40 |
41 | foreach (var property in properties)
42 | {
43 | if (property.IsTypeScriptIgnored())
44 | continue;
45 |
46 | var propertyType = property.PropertyType;
47 | var propertyName = _nameConvertor.GetName(propertyType);
48 | var nullableCode = _typeHelper.IsNullable(propertyType) ? "?" : "";
49 |
50 | stringBuilder.AppendLine($" {property.Name.ToCamelCase()}{nullableCode}: {propertyName};");
51 | }
52 |
53 | stringBuilder.AppendLine("}");
54 |
55 | return stringBuilder.ToString();
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Helpers/AssemblyHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using System.Text;
5 |
6 | namespace BanBrick.TypeScript.CodeGenerator.Helpers
7 | {
8 | internal class AssemblyHelper
9 | {
10 | public string GetSectionSeparator(string sectionName)
11 | {
12 | var stringBuilder = new StringBuilder();
13 |
14 | stringBuilder.AppendLine();
15 | stringBuilder.AppendLine($"// {sectionName} ---------------------------------------------");
16 |
17 | return stringBuilder.ToString();
18 | }
19 |
20 | public string GetAssemblyContent()
21 | {
22 | var stringBuilder = new StringBuilder();
23 |
24 | stringBuilder.AppendLine($"// Code Generated on {DateTime.Now} using {Assembly.GetEntryAssembly().FullName}");
25 | stringBuilder.AppendLine("// Do not change this file manually");
26 | stringBuilder.AppendLine("// ---------------------------------------------");
27 |
28 | stringBuilder.AppendLine();
29 |
30 | return stringBuilder.ToString();
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Helpers/TypeHelper.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using BanBrick.TypeScript.CodeGenerator.Enums;
3 | using BanBrick.TypeScript.CodeGenerator.Extensions;
4 | using BanBrick.TypeScript.CodeGenerator.Models;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Reflection;
9 | using System.Runtime.CompilerServices;
10 | using System.Text;
11 |
12 | namespace BanBrick.TypeScript.CodeGenerator.Helpers
13 | {
14 | internal class TypeHelper
15 | {
16 | public bool IsDictionaryType(Type type)
17 | {
18 | if (GetGenericTypeDefinition(type) == typeof(IDictionary<,>))
19 | return true;
20 |
21 | if (GetGenericTypeDefinition(type) == typeof(IReadOnlyDictionary<,>))
22 | return true;
23 |
24 | if (type.GetInterfaces().Any(x => GetGenericTypeDefinition(x) == typeof(IDictionary<,>)))
25 | return true;
26 |
27 | return false;
28 | }
29 |
30 | ///
31 | /// check whether the type is a collection type, ICollection, IEnumerable, Array ...
32 | ///
33 | ///
34 | /// any type
35 | ///
36 | ///
37 | /// true if the type is belong to a collection type
38 | ///
39 | public bool IsCollectionType(Type type)
40 | {
41 | if (type.IsArray)
42 | return true;
43 |
44 | // collection type only has 1 generic argument
45 | if (!(type.IsGenericType && type.GetGenericArguments().Count() == 1))
46 | return false;
47 |
48 | if (GetGenericTypeDefinition(type) == typeof(IEnumerable<>))
49 | return true;
50 |
51 | if (type.GetInterfaces().Any(x => GetGenericTypeDefinition(x) == typeof(IEnumerable<>)))
52 | return true;
53 |
54 | return false;
55 | }
56 |
57 | ///
58 | /// check whether the type is a c# primitive type, string, double, int ...
59 | ///
60 | ///
61 | /// any type
62 | ///
63 | ///
64 | /// if the type is matched to any primitive type return ture.
65 | /// otherwise return false.
66 | ///
67 | public bool IsPrimitiveType(Type type)
68 | {
69 | if (IsPurePrimitiveType(type))
70 | return true;
71 |
72 | if (IsNullAblePrimitiveType(type))
73 | return true;
74 |
75 | return false;
76 | }
77 |
78 | public bool IsNumericType(Type type)
79 | {
80 | if (type == typeof(TimeSpan))
81 | return true;
82 |
83 | switch (Type.GetTypeCode(type))
84 | {
85 | case TypeCode.Byte:
86 | case TypeCode.SByte:
87 | case TypeCode.UInt16:
88 | case TypeCode.UInt32:
89 | case TypeCode.UInt64:
90 | case TypeCode.Int16:
91 | case TypeCode.Int32:
92 | case TypeCode.Int64:
93 | case TypeCode.Decimal:
94 | case TypeCode.Double:
95 | case TypeCode.Single:
96 | return true;
97 | default:
98 | return false;
99 | }
100 | }
101 |
102 | public bool IsStringType(Type type)
103 | {
104 | if (type == typeof(string))
105 | return true;
106 |
107 | if (type == typeof(DateTime))
108 | return true;
109 |
110 | if (type == typeof(Guid) || type == typeof(Guid?))
111 | return true;
112 |
113 | if (type == typeof(char) || type == typeof(char?))
114 | return true;
115 |
116 | return false;
117 | }
118 |
119 | public bool IsNullable(Type type)
120 | {
121 | return !type.IsValueType || IsNullAblePrimitiveType(type);
122 | }
123 |
124 | ///
125 | /// Get TypeCategory for Type
126 | ///
127 | ///
128 | ///
129 | public ProcessingCategory GetProcessingCategory(Type type)
130 | {
131 | if (IsPrimitiveType(type))
132 | return ProcessingCategory.Primitive;
133 |
134 | if (IsDictionaryType(type))
135 | return ProcessingCategory.Dictionary;
136 |
137 | if (IsCollectionType(type))
138 | return ProcessingCategory.Collection;
139 |
140 | if (type.IsEnum)
141 | return ProcessingCategory.Enum;
142 |
143 | if (type.IsGenericType)
144 | return ProcessingCategory.Generic;
145 |
146 | if (type.IsInterface)
147 | return ProcessingCategory.Interface;
148 |
149 | return ProcessingCategory.Object;
150 | }
151 |
152 | ///
153 | /// convert type to typescript processing type
154 | ///
155 | ///
156 | /// any type
157 | ///
158 | ///
159 | /// processing type with typescript object name and typescript object type
160 | ///
161 | public TypeDefinition ToTypeDefinition(Type type)
162 | {
163 | var nullable = IsNullable(type);
164 | var category = GetProcessingCategory(type);
165 | var actualType = GetActualType(type, category, nullable);
166 |
167 | return new TypeDefinition()
168 | {
169 | Type = type,
170 | ActualType = actualType,
171 | ProcessingCategory = category,
172 | IsNullable = nullable,
173 | IsNumeric = IsNumericType(type),
174 | IsString = IsStringType(type)
175 | };
176 | }
177 |
178 | private TypeScriptObjectType GetProcessType(Type type, ProcessingCategory category) {
179 | var info = type.GetCustomAttribute();
180 | if (info == null || info.Type == TypeScriptObjectType.Default)
181 | {
182 | switch (category)
183 | {
184 | case ProcessingCategory.Enum:
185 | return TypeScriptObjectType.Enum;
186 | case ProcessingCategory.Object:
187 | return TypeScriptObjectType.Class;
188 | case ProcessingCategory.Interface:
189 | return TypeScriptObjectType.Interface;
190 | default:
191 | return TypeScriptObjectType.Default;
192 | }
193 | }
194 | else {
195 | return info.Type;
196 | }
197 | }
198 |
199 | private Type GetActualType(Type type, ProcessingCategory category, bool nullable ) {
200 | if (category == ProcessingCategory.Primitive && nullable && type.IsGenericType)
201 | return type.GenericTypeArguments.First();
202 | return type;
203 | }
204 |
205 | public Type GetGenericTypeDefinition(Type type)
206 | {
207 | if (type.IsGenericType)
208 | return type.GetGenericTypeDefinition();
209 | return null;
210 | }
211 |
212 | private bool IsNullAblePrimitiveType(Type type)
213 | {
214 | if (!type.IsValueType)
215 | return false;
216 |
217 | if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
218 | return true;
219 |
220 | return false;
221 | }
222 |
223 | private bool IsPurePrimitiveType(Type type)
224 | {
225 | if (type.IsPrimitive || IsSpecialPrimitiveType(type))
226 | {
227 | return true;
228 | }
229 | return false;
230 | }
231 |
232 | private bool IsSpecialPrimitiveType(Type type)
233 | {
234 | if (type == typeof(decimal) || IsStringType(type))
235 | {
236 | return true;
237 | }
238 |
239 | if (type == typeof(TimeSpan))
240 | return true;
241 |
242 | return false;
243 | }
244 | }
245 | }
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Models/ProcessConfig.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Enums;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace BanBrick.TypeScript.CodeGenerator.Models
7 | {
8 | public class ProcessConfig
9 | {
10 | public OutputType OutputType { get; set; }
11 |
12 | public string Name { get; set; }
13 |
14 | public bool Inherit { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Models/PropertyDefinition.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using System.Text;
5 |
6 | namespace BanBrick.TypeScript.CodeGenerator.Models
7 | {
8 | public class PropertyDefinition
9 | {
10 | public PropertyInfo PropertyInfo { get; set; }
11 |
12 | public Type Type { get; set; }
13 |
14 | public bool IsNullable { get; set; }
15 |
16 | public object DefaultValue { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Models/TypeDefinition.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using BanBrick.TypeScript.CodeGenerator.Enums;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace BanBrick.TypeScript.CodeGenerator.Models
8 | {
9 | internal class TypeDefinition
10 | {
11 | public Type Type { get; set; }
12 |
13 | public Type ActualType { get; set; }
14 |
15 | public ProcessingCategory ProcessingCategory { get; set; }
16 |
17 | public ProcessConfig ProcessConfig { get; set; }
18 |
19 | public bool IsNullable { get; set; }
20 |
21 | public bool IsNumeric { get; set; }
22 |
23 | public bool IsString { get; set; }
24 |
25 | public bool IsFirstLevel { get; set; }
26 |
27 | public List Properties { get; set; } = new List();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/ProjectInfo.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.Runtime.CompilerServices;
3 |
4 | [assembly: InternalsVisibleTo("BanBrick.TypeScript.CodeGenerator.UnitTest")]
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Resolvers/ConfigResolver.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Convertors;
2 | using BanBrick.TypeScript.CodeGenerator.Enums;
3 | using BanBrick.TypeScript.CodeGenerator.Extensions;
4 | using BanBrick.TypeScript.CodeGenerator.Models;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 |
10 | namespace BanBrick.TypeScript.CodeGenerator.Resolvers
11 | {
12 | internal class ConfigResolver
13 | {
14 | public IEnumerable Resolve(IEnumerable definitions)
15 | {
16 | var unprocessedDefinitions = definitions.Where(x => x.IsFirstLevel)
17 | .Select(x => { x.ProcessConfig = ConfigConvertor.GetProcessConfig(x.Type); return x; })
18 | .OrderBy(x => x.ProcessConfig.OutputType)
19 | .ToList();
20 |
21 | var processedDictionary = definitions.ToDictionary(x => x.Type, x => x);
22 |
23 | while (unprocessedDefinitions.Any())
24 | {
25 | var processingDefinition = unprocessedDefinitions.First();
26 | unprocessedDefinitions.RemoveAt(0);
27 |
28 | processingDefinition.ProcessConfig =
29 | processingDefinition.ProcessConfig ?? ConfigConvertor.GetProcessConfig(processingDefinition.Type);
30 |
31 | processedDictionary[processingDefinition.Type] = processingDefinition;
32 |
33 | var innerTypes = new List();
34 |
35 | if (processingDefinition.ProcessingCategory == ProcessingCategory.Collection)
36 | {
37 | innerTypes.Add(processingDefinition.Type.GetCollectionType());
38 | }
39 |
40 | if (processingDefinition.ProcessingCategory == ProcessingCategory.Dictionary)
41 | {
42 | var dicTypes = processingDefinition.Type.GetDictionaryTypes();
43 | innerTypes.Add(dicTypes.key);
44 | innerTypes.Add(dicTypes.value);
45 | }
46 |
47 | if (processingDefinition.ProcessingCategory == ProcessingCategory.Generic)
48 | {
49 | innerTypes.AddRange(processingDefinition.Type.GetGenericArguments());
50 | }
51 |
52 | if (processingDefinition.ProcessingCategory == ProcessingCategory.Object)
53 | {
54 | innerTypes.AddRange(processingDefinition.Properties.Select(x => x.Type));
55 | }
56 |
57 | foreach (var innerType in innerTypes)
58 | {
59 | var propertyDefinition = processedDictionary[innerType];
60 |
61 | // ignore property definition that's the same as processing definition
62 | if (propertyDefinition == processingDefinition)
63 | continue;
64 |
65 | if (propertyDefinition.ProcessConfig == null)
66 | {
67 | if (processingDefinition.ProcessConfig?.Inherit ?? false) {
68 | propertyDefinition.ProcessConfig = new ProcessConfig() {
69 | OutputType = processingDefinition.ProcessConfig.OutputType,
70 | Inherit = true
71 | };
72 | }
73 |
74 | if (processingDefinition.ProcessConfig?.OutputType == OutputType.Const) {
75 | propertyDefinition.ProcessConfig = new ProcessConfig() {
76 | OutputType = OutputType.None,
77 | Inherit = true
78 | };
79 | }
80 | }
81 |
82 | unprocessedDefinitions.Add(propertyDefinition);
83 | }
84 | }
85 |
86 | var processedDefinitions = processedDictionary.Select(x => x.Value);
87 |
88 | // remove config from inherited non heritable types
89 | processedDefinitions.Where(x => !x.IsInheritable() && (x.ProcessConfig?.Inherit ?? false)).ToList()
90 | .ForEach(x =>
91 | x.ProcessConfig = null
92 | );
93 |
94 | processedDefinitions.Where(x => x.ProcessConfig == null).ToList().ForEach(x =>
95 | {
96 | x.ProcessConfig = ConfigConvertor.GetProcessConfig(x.ProcessingCategory);
97 | });
98 |
99 | processedDefinitions.Where(x => x.ProcessConfig.OutputType == OutputType.Default).ToList().ForEach(x =>
100 | {
101 | x.ProcessConfig.OutputType = ConfigConvertor.Parse(x.ProcessingCategory);
102 | });
103 |
104 | return processedDefinitions;
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Resolvers/DuplicationResolver.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Annotations;
2 | using BanBrick.TypeScript.CodeGenerator.Convertors;
3 | using BanBrick.TypeScript.CodeGenerator.Enums;
4 | using BanBrick.TypeScript.CodeGenerator.Generators;
5 | using BanBrick.TypeScript.CodeGenerator.Models;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Text;
10 |
11 | namespace BanBrick.TypeScript.CodeGenerator.Resolvers
12 | {
13 | internal class DuplicationResolver
14 | {
15 | public IEnumerable Resolve(IEnumerable definitions)
16 | {
17 | var nameConvertor = new NameConvertor(definitions);
18 | var valueConvertor = new ValueConvertor(definitions, nameConvertor);
19 |
20 | var codeGeneratorFactory = new CodeGeneratorFactory(nameConvertor, valueConvertor);
21 |
22 | var typeDefinitions = definitions.ToList();
23 |
24 | var duplicationGroups = typeDefinitions
25 | .Where(x => x.ProcessConfig.OutputType != OutputType.None)
26 | .GroupBy(x => x.ProcessConfig.Name)
27 | .Where(x => x.ToList().Count > 1)
28 | .ToList();
29 |
30 | if (duplicationGroups.Count > 0)
31 | {
32 | foreach (var duplicationGroup in duplicationGroups)
33 | {
34 | var commonName = duplicationGroup.Key;
35 | var duplicateDefinitions = duplicationGroup.ToList();
36 |
37 | var codeGroups = duplicateDefinitions
38 | .Select(x => (
39 | code: codeGeneratorFactory.GetInstance(x.ProcessConfig.OutputType)?.Generate(x.ActualType),
40 | definition: x)
41 | )
42 | .GroupBy(x => x.code)
43 | .ToList();
44 |
45 | // keep the same code of first group, flag others to NoGeneration
46 | codeGroups.ForEach(x => {
47 | var outputType = x.First().definition.ProcessConfig.OutputType;
48 |
49 | x.ToList().ForEach(y =>
50 | {
51 | y.definition.ProcessConfig.OutputType = OutputType.None;
52 | });
53 |
54 | x.First().definition.ProcessConfig.OutputType = outputType;
55 | });
56 |
57 | if (codeGroups.Count() > 1)
58 | {
59 | // rename if multiple version of code, rename need to apply
60 | for (int i = 0; i < codeGroups.Count; i++)
61 | {
62 | codeGroups[i].ToList().ForEach(x =>
63 | {
64 | var name = x.definition.ProcessConfig.Name;
65 | var indexOfMarker = name.IndexOfAny(new char[]{ '[', '<'});
66 | x.definition.ProcessConfig.Name =
67 | indexOfMarker < 0 ? $"{name}_{i}" : $"{name.Substring(0, indexOfMarker)}_{i}{name.Substring(indexOfMarker)}";
68 | });
69 | }
70 | }
71 | }
72 | }
73 |
74 | return typeDefinitions;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Resolvers/NameResolver.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Enums;
2 | using BanBrick.TypeScript.CodeGenerator.Extensions;
3 | using BanBrick.TypeScript.CodeGenerator.Models;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Reflection;
8 | using System.Text;
9 |
10 | namespace BanBrick.TypeScript.CodeGenerator.Resolvers
11 | {
12 | internal class NameResolver
13 | {
14 | public IEnumerable Resolve(IEnumerable definitions)
15 | {
16 | var unprocessedDefinitions = definitions.ToList();
17 | var processedDefinitions = new List();
18 |
19 | while (unprocessedDefinitions.Any())
20 | {
21 | // pop first type
22 | var processingDefinition = unprocessedDefinitions.First();
23 | unprocessedDefinitions.RemoveAt(0);
24 |
25 | var type = processingDefinition.Type;
26 | var processConfig = processingDefinition.ProcessConfig;
27 | var category = processingDefinition.ProcessingCategory;
28 |
29 | if (category == ProcessingCategory.Primitive)
30 | processConfig.Name = GetPrimitiveName(processingDefinition);
31 |
32 | if (category == ProcessingCategory.Enum)
33 | processConfig.Name = GetDefaultName(processConfig, type);
34 |
35 | if (category == ProcessingCategory.Dictionary)
36 | {
37 | var (key, value) = type.GetDictionaryTypes();
38 | if (TypeDefinitionContains(processedDefinitions, key, value))
39 | {
40 | var keyName = $"[key: {GetName(processedDefinitions, key)}]";
41 | var valueName = $"{GetName(processedDefinitions, value)}";
42 | processConfig.Name = $"{{ {keyName} : {valueName} }}";
43 | }
44 | }
45 |
46 | if (category == ProcessingCategory.Collection)
47 | {
48 | var value = type.GetCollectionType();
49 | if (TypeDefinitionContains(processedDefinitions, value))
50 | {
51 | processConfig.Name = $"{GetName(processedDefinitions, value)}[]";
52 | }
53 | }
54 |
55 | if (category == ProcessingCategory.Object)
56 | {
57 | processConfig.Name = GetDefaultName(processConfig, type);
58 | }
59 |
60 | if (category == ProcessingCategory.Interface)
61 | {
62 | processConfig.Name = GetDefaultName(processConfig, type);
63 | }
64 |
65 | if (category == ProcessingCategory.Generic)
66 | {
67 | var genericTypes = type.GetGenericArguments();
68 | if (TypeDefinitionContains(processedDefinitions, genericTypes))
69 | {
70 | var genericNames = genericTypes.Select(x => GetName(processedDefinitions, x));
71 | processConfig.Name = $"{GetDefaultName(processConfig, type)}<{string.Join(", ", genericNames)}>";
72 | }
73 | }
74 |
75 |
76 | // if cannot process add to last of queue else add to completed list
77 | if (processingDefinition.ProcessConfig.Name == null)
78 | {
79 | unprocessedDefinitions.Add(processingDefinition);
80 | }
81 | else
82 | {
83 | processedDefinitions.Add(processingDefinition);
84 | }
85 | }
86 |
87 | return processedDefinitions;
88 | }
89 |
90 | private string GetDefaultName(ProcessConfig processConfig, Type type) {
91 | var typeName = type.Name;
92 | var genericCharIndex = typeName.IndexOf('`');
93 |
94 | return processConfig.Name ?? (genericCharIndex > 0 ? typeName.Substring(0, genericCharIndex) : typeName);
95 | }
96 |
97 | private string GetName(IEnumerable typeDefinitions, Type type)
98 | {
99 | return typeDefinitions.First(x => x.Type == type).ProcessConfig.Name;
100 | }
101 |
102 | private bool TypeDefinitionContains(IEnumerable typeDefinitions, params Type[] types)
103 | {
104 | return types.All(t => typeDefinitions.Any(x => x.Type == t));
105 | }
106 |
107 | public string GetPrimitiveName(TypeDefinition typeDefinition)
108 | {
109 | var type = typeDefinition.ActualType;
110 |
111 | if (typeDefinition.IsNumeric)
112 | return "number";
113 |
114 | if (typeDefinition.IsString)
115 | return "string";
116 |
117 | if (type == typeof(bool))
118 | return "boolean";
119 |
120 | return "any";
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/Resolvers/RelationResolver.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Enums;
2 | using BanBrick.TypeScript.CodeGenerator.Extensions;
3 | using BanBrick.TypeScript.CodeGenerator.Helpers;
4 | using BanBrick.TypeScript.CodeGenerator.Models;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Reflection;
9 | using System.Runtime.CompilerServices;
10 | using System.Text;
11 |
12 | namespace BanBrick.TypeScript.CodeGenerator.Resolvers
13 | {
14 | internal class RelationResolver
15 | {
16 | private readonly TypeHelper _typeHelper;
17 |
18 | public RelationResolver() {
19 | _typeHelper = new TypeHelper();
20 | }
21 |
22 | public ICollection Resolve(IEnumerable types)
23 | {
24 | var unProcessedTypes = types.ToList();
25 | var typeDefinitions = new List();
26 |
27 | while (unProcessedTypes.Any())
28 | {
29 | // pop last type
30 | var processingType = unProcessedTypes.Last();
31 | unProcessedTypes.RemoveAt(unProcessedTypes.Count - 1);
32 |
33 | // already in category type;
34 | if (typeDefinitions.Any(x => x.Type == processingType))
35 | continue;
36 |
37 | // add type to category types
38 | var processingTypeCategory = _typeHelper.GetProcessingCategory(processingType);
39 | var currentDefinition = _typeHelper.ToTypeDefinition(processingType);
40 |
41 | object instance = null;
42 |
43 | // create new instance if type contains parameterless constractor
44 | if (processingType.GetConstructor(Type.EmptyTypes) != null)
45 | instance = Activator.CreateInstance(processingType);
46 |
47 | // process all properties
48 | foreach (var property in TypeExtensions.GetProperties(processingType))
49 | {
50 | if (property.IsTypeScriptIgnored())
51 | continue;
52 |
53 | var propertyType = property.PropertyType;
54 | var category = _typeHelper.GetProcessingCategory(propertyType);
55 |
56 | unProcessedTypes.Add(propertyType);
57 |
58 | switch (category)
59 | {
60 | case ProcessingCategory.Collection:
61 | unProcessedTypes.Add(propertyType.GetCollectionType());
62 | break;
63 | case ProcessingCategory.Dictionary:
64 | var (key, value) = propertyType.GetDictionaryTypes();
65 | unProcessedTypes.Add(key);
66 | unProcessedTypes.Add(value);
67 | break;
68 | case ProcessingCategory.Generic:
69 | unProcessedTypes.AddRange(propertyType.GetGenericArguments());
70 | break;
71 | }
72 |
73 | currentDefinition.Properties.Add(new PropertyDefinition()
74 | {
75 | PropertyInfo = property,
76 | Type = propertyType,
77 | IsNullable = _typeHelper.IsNullable(propertyType),
78 | DefaultValue = property.TryGetValue(instance)
79 | });
80 | }
81 |
82 | if (types.Contains(currentDefinition.Type))
83 | currentDefinition.IsFirstLevel = true;
84 |
85 | typeDefinitions.Add(currentDefinition);
86 | }
87 |
88 | return typeDefinitions;
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/TypeScriptProcesser.cs:
--------------------------------------------------------------------------------
1 | using BanBrick.TypeScript.CodeGenerator.Convertors;
2 | using BanBrick.TypeScript.CodeGenerator.Generators;
3 | using BanBrick.TypeScript.CodeGenerator.Helpers;
4 | using BanBrick.TypeScript.CodeGenerator.Extensions;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using BanBrick.TypeScript.CodeGenerator.Models;
10 | using BanBrick.TypeScript.CodeGenerator.Enums;
11 | using BanBrick.TypeScript.CodeGenerator.Annotations;
12 | using PluralizationService;
13 | using PluralizationService.English;
14 | using System.Globalization;
15 |
16 | namespace BanBrick.TypeScript.CodeGenerator
17 | {
18 | public class TypeScriptProcesser
19 | {
20 | private readonly AssemblyHelper _assemblyHelper;
21 |
22 | public TypeScriptProcesser()
23 | {
24 | _assemblyHelper = new AssemblyHelper();
25 | }
26 |
27 | public string GenerateTypeScript(IEnumerable types) {
28 | var typeDefinitions = types
29 | .ResolveRelations()
30 | .ResolveConfigs()
31 | .ResolveNames()
32 | .ResolveDuplications();
33 |
34 | var processDefinitions = typeDefinitions.Where(x => x.ProcessConfig?.OutputType != OutputType.None);
35 |
36 | var nameConvertor = new NameConvertor(typeDefinitions);
37 | var valueConvertor = new ValueConvertor(typeDefinitions, nameConvertor);
38 |
39 | var codeGeneratorFactory = new CodeGeneratorFactory(nameConvertor, valueConvertor);
40 | var codeBuilder = new StringBuilder();
41 |
42 | var pluralizationBuilder = new PluralizationApiBuilder();
43 | pluralizationBuilder.AddEnglishProvider();
44 |
45 | var pluralizationApi = pluralizationBuilder.Build();
46 | var cultureInfo = new CultureInfo("en-US");
47 |
48 | codeBuilder.Append(_assemblyHelper.GetAssemblyContent());
49 |
50 | Enum.GetValues(typeof(OutputType)).Cast().ToList()
51 | .ForEach(x =>
52 | {
53 | var codeGenerator = codeGeneratorFactory.GetInstance(x);
54 | if (codeGenerator != null)
55 | {
56 | var sectionName = pluralizationApi.Pluralize(x.ToString(), cultureInfo);
57 | codeBuilder.Append(_assemblyHelper.GetSectionSeparator(sectionName));
58 |
59 | processDefinitions.GetProcessingTypes(x).ForEach(t =>
60 | codeBuilder.AppendLine(codeGenerator.Generate(t))
61 | );
62 | }
63 | });
64 |
65 | return codeBuilder.ToString();
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/BanBrick.TypeScript.CodeGenerator/TypeScriptSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BanBrick.TypeScript.CodeGenerator
6 | {
7 | public class TypeScriptSettings
8 | {
9 | public TypeScriptSettings() => Indentation = " ";
10 | public TypeScriptSettings(string indentation) => Indentation = indentation;
11 |
12 | public string Indentation { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Code Generation Work Flow v3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiarongGu/BanBrick.TypeScript.CodeGenerator/f91859b456b468e2c9c22861522f10d8de65a0db/Code Generation Work Flow v3.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Jiarong Gu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BanBrick.TypeScript.CodeGenerator
2 | C# to TypeScript Code Generator Libarary for WebApi Request/Response Model
3 |
4 | ## Getting Started
5 |
6 | https://www.nuget.org/packages/BanBrick.TypeScript.CodeGenerator/
7 |
8 | PM > Install-Package BanBrick.TypeScript.CodeGenerator -Version 1.2.3
9 |
10 |
11 | ### Prerequisites
12 |
13 | ```
14 | .net standard
15 | ```
16 |
17 |
18 | ## How To Use
19 |
20 | #### Generate typescript code from list of types.
21 |
22 | ```
23 | using BanBrick.TypeScript.CodeGenerator;
24 |
25 | var types = new List() { type1, type2, type3, ...};
26 | var codeProcesser = new TypeScriptProcesser();
27 | var code = codeProcesser.GenerateTypeScript(types);
28 | ```
29 |
30 | #### Generate typescript types from annotation configs.
31 |
32 | current support typescript enum, interface, class, count generation using annotation
33 |
34 | #### Output type inherit use annotation
35 |
36 | ```
37 | using BanBrick.TypeScript.CodeGenerator.Annotation;
38 |
39 | [TypeScriptObject(Type = TypeScriptObjectType.Interface, Inherit = true)]
40 | public class Request
41 | {
42 | public RequestDetail Details { get; set; }
43 | }
44 |
45 | public class RequestDetail
46 | {
47 | public string Name { get; set; }
48 | }
49 | ```
50 |
51 | this will output both Request and RequestDetail in Interface format of Typescript
52 |
53 | ## Roadmap
54 |
55 | - [x] Generate const value output instead of class
56 | - [x] Support for Interface generation
57 | - [x] Auto-Indenting to multiple-layered tree structure values
58 | - [x] Support Auto-Resolve for Type Name Duplication
59 | - [x] Support for Inherit of Generation Types
60 | - [x] Auto-Indenting to multiple-layered tree structure types
61 | - [ ] Support for external config instead of only annotation
62 | - [ ] Support for Generictypes generation
63 |
64 |
65 |
66 | ## Code Generation Workflow
67 | 
68 |
--------------------------------------------------------------------------------