1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . IO ;
4+ using System . Linq ;
5+ using System . Text . RegularExpressions ;
6+ using WebApiToTypeScript . Block ;
7+
8+ namespace WebApiToTypeScript . Views
9+ {
10+ public class ViewsService : ServiceAware
11+ {
12+ private string ViewsSourceDirectory { get ; set ; }
13+
14+ private List < ViewNode > FeatureViews { get ; }
15+ = new List < ViewNode > ( ) ;
16+
17+ public TypeScriptBlock CreateViewsBlock ( )
18+ {
19+ return new TypeScriptBlock ( $ "{ Config . NamespaceOrModuleName } { Config . ViewsNamespace } ") ;
20+ }
21+
22+ public TypeScriptBlock WriteViewsToBlock ( TypeScriptBlock viewsBlock )
23+ {
24+ ViewsSourceDirectory = Path . GetFullPath ( Config . ViewsSourceDirectory ) ;
25+
26+ var viewFiles = Directory . GetFiles ( ViewsSourceDirectory , "*.view.*" , SearchOption . AllDirectories ) ;
27+
28+ foreach ( var viewFile in viewFiles )
29+ {
30+ var featureViewPath = Path . GetFullPath ( viewFile )
31+ . Split ( new [ ] { $@ "{ ViewsSourceDirectory } \" } , StringSplitOptions . RemoveEmptyEntries )
32+ . Last ( ) ;
33+
34+ var parts = featureViewPath
35+ . Split ( new [ ] { @"\" } , StringSplitOptions . RemoveEmptyEntries ) ;
36+
37+ var namespaces = parts
38+ . Take ( parts . Length - 1 )
39+ . Select ( Helpers . ToPascalCaseFromCamelCase )
40+ . ToList ( ) ;
41+
42+ var featureNamespace = namespaces . First ( ) ;
43+
44+ if ( FeatureViews . All ( v => v . Name != featureNamespace ) )
45+ {
46+ FeatureViews . Add ( new ViewNode
47+ {
48+ Name = featureNamespace
49+ } ) ;
50+ }
51+
52+ var subFeatures = namespaces
53+ . Skip ( 1 )
54+ . ToList ( ) ;
55+
56+ var viewNode = FeatureViews . Single ( v => v . Name == featureNamespace ) ;
57+ var nameThusFar = subFeatures . Count == 0 // instead should i skip last or first or something
58+ ? featureNamespace
59+ : string . Empty ;
60+
61+ foreach ( var subFeature in subFeatures )
62+ {
63+ var doesViewNodeHasSubFeature = viewNode . ChildViews
64+ . Any ( v => v . Name == subFeature ) ;
65+
66+ if ( ! doesViewNodeHasSubFeature )
67+ {
68+ var subFeatureNode = new ViewNode
69+ {
70+ Name = subFeature
71+ } ;
72+
73+ viewNode . ChildViews . Add ( subFeatureNode ) ;
74+ }
75+
76+ viewNode = viewNode . ChildViews
77+ . Single ( v => v . Name == subFeature ) ;
78+
79+ nameThusFar += viewNode . Name ;
80+ }
81+
82+ var fullViewNameInKebabCase = parts
83+ . Last ( )
84+ . Split ( new [ ] { ".view." } , StringSplitOptions . RemoveEmptyEntries )
85+ . First ( ) ;
86+
87+ var fullViewNameInPascalCase = Helpers . ToPascalCaseFromKebabCase ( fullViewNameInKebabCase ) ;
88+
89+ var viewName = fullViewNameInPascalCase != nameThusFar
90+ ? Regex . Replace ( fullViewNameInPascalCase , $ "^{ nameThusFar } ", string . Empty )
91+ : fullViewNameInPascalCase ;
92+
93+ viewNode . ViewEntries . Add ( new ViewEntry {
94+ Name = viewName ,
95+ Path = featureViewPath . Replace ( @"\" , "/" )
96+ } ) ;
97+ }
98+
99+ foreach ( var featureView in FeatureViews )
100+ {
101+ WriteViewEntry ( viewsBlock , featureView ) ;
102+ }
103+
104+ return viewsBlock ;
105+ }
106+
107+ private void WriteViewEntry ( TypeScriptBlock viewsBlock , ViewNode featureViewNode , bool isChild = false )
108+ {
109+ var viewNamespace = isChild
110+ ? string . Empty
111+ : ".Views" ;
112+
113+ var featureBlock = viewsBlock
114+ . AddAndUseBlock ( $ "export namespace { featureViewNode . Name } { viewNamespace } ") ;
115+
116+ foreach ( var viewEntry in featureViewNode . ViewEntries )
117+ {
118+ featureBlock
119+ . AddStatement ( $ "export const { viewEntry . Name } = '{ viewEntry . Path } ';") ;
120+ }
121+
122+ foreach ( var childView in featureViewNode . ChildViews )
123+ {
124+ WriteViewEntry ( featureBlock , childView , isChild : true ) ;
125+ }
126+ }
127+ }
128+ }
0 commit comments