Skip to content

Commit 8b5def6

Browse files
committed
Add views generation first pass
1 parent a64ea02 commit 8b5def6

File tree

5 files changed

+174
-14
lines changed

5 files changed

+174
-14
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace WebApiToTypeScript.Views
2+
{
3+
public class ViewEntry
4+
{
5+
public string Name { get; set; }
6+
public string Path { get; set; }
7+
}
8+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Collections.Generic;
2+
3+
namespace WebApiToTypeScript.Views
4+
{
5+
public class ViewNode
6+
{
7+
public string Name { get; set; }
8+
9+
public List<ViewEntry> ViewEntries { get; }
10+
= new List<ViewEntry>();
11+
12+
public List<ViewNode> ChildViews { get; }
13+
= new List<ViewNode>();
14+
}
15+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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+
}

src/WebApiToTypeScript/WebApiToTypeScript.cs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using WebApiToTypeScript.Enums;
1111
using WebApiToTypeScript.Interfaces;
1212
using WebApiToTypeScript.Types;
13+
using WebApiToTypeScript.Views;
1314
using WebApiToTypeScript.WebApi;
1415

1516
namespace WebApiToTypeScript
@@ -29,6 +30,8 @@ public class WebApiToTypeScript : AppDomainIsolatedTask
2930
public static EndpointsService EndpointsService { get; private set; }
3031
public static AngularEndpointsService AngularEndpointsService { get; private set; }
3132

33+
public static ViewsService ViewsService { get; private set; }
34+
3235
[Required]
3336
public string ConfigFilePath { get; set; }
3437

@@ -41,6 +44,20 @@ public override bool Execute()
4144
var endpointBlock = EndpointsService.CreateEndpointBlock();
4245
var serviceBlock = AngularEndpointsService.CreateServiceBlock();
4346

47+
if (Config.GenerateViews)
48+
{
49+
StartAnalysis("views");
50+
51+
var viewsBlock = ViewsService.CreateViewsBlock();
52+
ViewsService.WriteViewsToBlock(viewsBlock);
53+
54+
CreateFileForBlock(viewsBlock, Config.ViewsOutputDirectory, Config.ViewsFileName);
55+
56+
StopAnalysis();
57+
}
58+
59+
return true;
60+
4461
StartAnalysis("controllers and actions");
4562

4663
foreach (var apiController in apiControllers)
@@ -57,12 +74,12 @@ public override bool Execute()
5774
CreateFileForBlock(serviceBlock, Config.ServiceOutputDirectory, Config.ServiceFileName);
5875

5976
var enumsBlock = EnumsService.CreateEnumsBlock();
60-
var interfacesBlock = InterfaceService.CreateInterfacesBlock();
6177

6278
if (Config.GenerateInterfaces)
6379
{
6480
StartAnalysis("interfaces");
6581

82+
var interfacesBlock = InterfaceService.CreateInterfacesBlock();
6683
InterfaceService.AddMatchingInterfaces();
6784
InterfaceService.WriteInterfacesToBlock(interfacesBlock);
6885

@@ -97,6 +114,8 @@ private void InitializeServices()
97114

98115
EndpointsService = new EndpointsService();
99116
AngularEndpointsService = new AngularEndpointsService();
117+
118+
ViewsService = new ViewsService();
100119
}
101120

102121
private Config.Config GetConfig(string configFilePath)
@@ -112,30 +131,17 @@ private void CreateFileForBlock(TypeScriptBlock typeScriptBlock, string outputDi
112131

113132
var filePath = Path.Combine(outputDirectory, fileName);
114133

115-
//LogMessage($"Writing file [{filePath}]...");
116-
117-
//stopwatch = Stopwatch.StartNew();
118-
119134
using (var endpointFileWriter = new StreamWriter(filePath, false))
120135
{
121136
endpointFileWriter.Write(typeScriptBlock.ToString());
122137
}
123-
124-
//LogMessage($"File [{filePath}] saved! Took {stopwatch.ElapsedMilliseconds}ms.");
125138
}
126139

127140
private void CreateOuputDirectory(string directory)
128141
{
129-
//LogMessage($"Creating directory [{directory}]...");
130-
131142
if (!Directory.Exists(directory))
132143
{
133144
Directory.CreateDirectory(directory);
134-
//LogMessage($"Directory [{directory}] created!");
135-
}
136-
else
137-
{
138-
//LogMessage($"Directory [{directory}] already exists!");
139145
}
140146
}
141147

src/WebApiToTypeScript/WebApiToTypeScript.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@
7979
<Compile Include="Block\TypeScriptBlock.cs" />
8080
<Compile Include="Types\TypeScriptType.cs" />
8181
<Compile Include="Types\TypeService.cs" />
82+
<Compile Include="Views\ViewEntry.cs" />
83+
<Compile Include="Views\ViewNode.cs" />
84+
<Compile Include="Views\ViewsService.cs" />
8285
<Compile Include="WebApi\WebApiAction.cs" />
8386
<Compile Include="WebApi\WebApiController.cs" />
8487
<Compile Include="WebApi\WebApiHttpVerb.cs" />

0 commit comments

Comments
 (0)