From b1cbdd507b8463b8650234c7896178f4c5dc504c Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Thu, 30 Jun 2022 23:53:00 -0700 Subject: [PATCH 01/33] Store --- openapi.json | 41 ++++++++++++++++++++++++++++ src/OpenApi/CodeGenerator/Program.cs | 16 ++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 openapi.json diff --git a/openapi.json b/openapi.json new file mode 100644 index 00000000..38f0494a --- /dev/null +++ b/openapi.json @@ -0,0 +1,41 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Swagger Students", + "license": { + "name": "MIT" + } + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1" + } + ], + "paths": { + "/students": { + "get": { + "summary": "List all the students in the school", + "operationId": "listStudents", + "tags": [ + "students" + ], + "responses": { + "200": { + "description": "An array of student names", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/OpenApi/CodeGenerator/Program.cs b/src/OpenApi/CodeGenerator/Program.cs index b4bf8512..714d82ea 100644 --- a/src/OpenApi/CodeGenerator/Program.cs +++ b/src/OpenApi/CodeGenerator/Program.cs @@ -1 +1,15 @@ -// TODO: Write code to open and read a JSON file with an OpenAPI schema in it +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Readers; + +class App +{ + public static void Main(string[] args) + { + OpenApiDiagnostic diagnostic = new OpenApiDiagnostic(); + var reader = new OpenApiStreamReader(); + + Stream stream = File.OpenRead(args[0]); + var newDocument = reader.Read(stream, out diagnostic); + Console.WriteLine("File Read Successful"); + } +} From ddeeb7d0ecea66e0dfd2f21947beecf0e9d85ad7 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Thu, 21 Jul 2022 13:38:01 -0700 Subject: [PATCH 02/33] OpenApi first draft --- src/OpenApi/CodeGenerator/Class1.cs | 138 +++++++ .../CodeGenerator/RuntimeTextTemplate2.cs | 361 ++++++++++++++++++ .../CodeGenerator/RuntimeTextTemplate2.tt | 25 ++ 3 files changed, 524 insertions(+) create mode 100644 src/OpenApi/CodeGenerator/Class1.cs create mode 100644 src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs create mode 100644 src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt diff --git a/src/OpenApi/CodeGenerator/Class1.cs b/src/OpenApi/CodeGenerator/Class1.cs new file mode 100644 index 00000000..a79dd610 --- /dev/null +++ b/src/OpenApi/CodeGenerator/Class1.cs @@ -0,0 +1,138 @@ +namespace CodeGenerator +{ + using Microsoft.OpenApi.Models; + using Microsoft.OpenApi.Readers; + public class App + { + public static void Main(string[] args) + { + var document = new App().ReadJson(""); + var paths = document.Paths; + //var operation = paths.Values.FirstOrDefault().Operations[0]; + //var responseDescription = operation.Responses["200"]; + + RuntimeTextTemplate2 page; + String pageContent; + + foreach (var path in paths) + { + var operations = path.Value.Operations; + foreach (var operation in operations) + { + var method = operation.Key.ToString().ToLower(); + + switch(method) + { + case "get": + page = new RuntimeTextTemplate2 + { + apiPath = path.Key.ToString(), + apiMethod = "MapGet" + }; + pageContent = page.TransformText(); + File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); + break; + + case "post": + page = new RuntimeTextTemplate2 + { + apiPath = path.Key.ToString(), + apiMethod = "MapPost" + }; + pageContent = page.TransformText(); + File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); + break; + + case "put": + page = new RuntimeTextTemplate2 + { + apiPath = path.Key.ToString(), + apiMethod = "MapPut" + }; + pageContent = page.TransformText(); + File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); + break; + + case "delete": + page = new RuntimeTextTemplate2 + { + apiPath = path.Key.ToString(), + apiMethod = "MapDelete" + }; + pageContent = page.TransformText(); + File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); + break; + } + } + } + + //RuntimeTextTemplate2 page = new RuntimeTextTemplate2 + //{ + // path = "\"/students\"" + //}; + //String pageContent = page.TransformText(); + //System.IO.File.WriteAllText(args[1], pageContent); + } + + private OpenApiDocument ReadJson(string args) + { + string inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; + + + + if (!Path.IsPathRooted(inputPath)) + { + Console.WriteLine("The file path you entered does not have a root"); + return new OpenApiDocument(); + } + + OpenApiStreamReader reader = new OpenApiStreamReader(); + var diagnostic = new OpenApiDiagnostic(); + + try + { + string path = Path.GetFullPath(inputPath); + Stream stream = File.OpenRead(path); + OpenApiDocument newDocument = reader.Read(stream, out diagnostic); + return newDocument; + } + catch (FileNotFoundException e) + { + Console.WriteLine("Check to make sure you entered a correct file path because the file was not found."); + Console.Error.WriteLine(e.Message); + return new OpenApiDocument(); + } + catch (Exception e) + { + Console.WriteLine("Check the file path you entered for errors."); + Console.Error.WriteLine(e.Message); + return new OpenApiDocument(); + } + finally + { + if (diagnostic.Errors.Count == 0) + { + Console.WriteLine("Read File Successfully"); + } + else + { + foreach (OpenApiError error in diagnostic.Errors) + { + Console.WriteLine($"There was an error reading in the file at {error.Pointer}"); + Console.Error.WriteLine(error.Message); + } + } + } + } + + + + // public OpenApiOperation CreateOperation(OpenApiDocument document) + // { + // OpenApiOperation operation = new OpenApiOperation(); + // OpenApiPathItem key = new OpenApiPathItem() + // operation = document.Paths.Values; + // } + } + +} diff --git a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs new file mode 100644 index 00000000..1b9e2c89 --- /dev/null +++ b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs @@ -0,0 +1,361 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version: 17.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +namespace CodeGenerator +{ + using System.Linq; + using System.Text; + using System.Collections.Generic; + using System.Reflection; + using Microsoft.VisualStudio.TextTemplating; + using System; + + /// + /// Class to produce the template output + /// + + #line 1 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] + public partial class RuntimeTextTemplate2 : RuntimeTextTemplate2Base + { +#line hidden + /// + /// Create the template output + /// + public virtual string TransformText() + { + + #line 10 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + if (shouldCreateWebApp) { + + + #line default + #line hidden + this.Write("var builder = WebApplication.CreateBuilder(args);\r\nvar app = builder.Build();\r\n"); + + #line 14 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + +} + + + #line default + #line hidden + this.Write("\r\napp."); + + #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(method)); + + #line default + #line hidden + this.Write("(\""); + + #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(path)); + + #line default + #line hidden + this.Write("\", () => "); + + #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(response)); + + #line default + #line hidden + this.Write(");\r\n"); + return this.GenerationEnvironment.ToString(); + } + + #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + + public string path { get; set; } + public string method { get; set; } + public string apiResponse { get; set; } + public bool shouldCreateWebApp { get; set; } + public string response { get; set; } + + + #line default + #line hidden + } + + #line default + #line hidden + #region Base class + /// + /// Base class for this transformation + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] + public class RuntimeTextTemplate2Base + { + #region Fields + private global::System.Text.StringBuilder generationEnvironmentField; + private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; + private global::System.Collections.Generic.List indentLengthsField; + private string currentIndentField = ""; + private bool endsWithNewline; + private global::System.Collections.Generic.IDictionary sessionField; + #endregion + #region Properties + /// + /// The string builder that generation-time code is using to assemble generated output + /// + protected System.Text.StringBuilder GenerationEnvironment + { + get + { + if ((this.generationEnvironmentField == null)) + { + this.generationEnvironmentField = new global::System.Text.StringBuilder(); + } + return this.generationEnvironmentField; + } + set + { + this.generationEnvironmentField = value; + } + } + /// + /// The error collection for the generation process + /// + public System.CodeDom.Compiler.CompilerErrorCollection Errors + { + get + { + if ((this.errorsField == null)) + { + this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); + } + return this.errorsField; + } + } + /// + /// A list of the lengths of each indent that was added with PushIndent + /// + private System.Collections.Generic.List indentLengths + { + get + { + if ((this.indentLengthsField == null)) + { + this.indentLengthsField = new global::System.Collections.Generic.List(); + } + return this.indentLengthsField; + } + } + /// + /// Gets the current indent we use when adding lines to the output + /// + public string CurrentIndent + { + get + { + return this.currentIndentField; + } + } + /// + /// Current transformation session + /// + public virtual global::System.Collections.Generic.IDictionary Session + { + get + { + return this.sessionField; + } + set + { + this.sessionField = value; + } + } + #endregion + #region Transform-time helpers + /// + /// Write text directly into the generated output + /// + public void Write(string textToAppend) + { + if (string.IsNullOrEmpty(textToAppend)) + { + return; + } + // If we're starting off, or if the previous text ended with a newline, + // we have to append the current indent first. + if (((this.GenerationEnvironment.Length == 0) + || this.endsWithNewline)) + { + this.GenerationEnvironment.Append(this.currentIndentField); + this.endsWithNewline = false; + } + // Check if the current text ends with a newline + if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) + { + this.endsWithNewline = true; + } + // This is an optimization. If the current indent is "", then we don't have to do any + // of the more complex stuff further down. + if ((this.currentIndentField.Length == 0)) + { + this.GenerationEnvironment.Append(textToAppend); + return; + } + // Everywhere there is a newline in the text, add an indent after it + textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); + // If the text ends with a newline, then we should strip off the indent added at the very end + // because the appropriate indent will be added when the next time Write() is called + if (this.endsWithNewline) + { + this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); + } + else + { + this.GenerationEnvironment.Append(textToAppend); + } + } + /// + /// Write text directly into the generated output + /// + public void WriteLine(string textToAppend) + { + this.Write(textToAppend); + this.GenerationEnvironment.AppendLine(); + this.endsWithNewline = true; + } + /// + /// Write formatted text directly into the generated output + /// + public void Write(string format, params object[] args) + { + this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); + } + /// + /// Write formatted text directly into the generated output + /// + public void WriteLine(string format, params object[] args) + { + this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); + } + /// + /// Raise an error + /// + public void Error(string message) + { + System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); + error.ErrorText = message; + this.Errors.Add(error); + } + /// + /// Raise a warning + /// + public void Warning(string message) + { + System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); + error.ErrorText = message; + error.IsWarning = true; + this.Errors.Add(error); + } + /// + /// Increase the indent + /// + public void PushIndent(string indent) + { + if ((indent == null)) + { + throw new global::System.ArgumentNullException("indent"); + } + this.currentIndentField = (this.currentIndentField + indent); + this.indentLengths.Add(indent.Length); + } + /// + /// Remove the last indent that was added with PushIndent + /// + public string PopIndent() + { + string returnValue = ""; + if ((this.indentLengths.Count > 0)) + { + int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; + this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); + if ((indentLength > 0)) + { + returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); + this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); + } + } + return returnValue; + } + /// + /// Remove any indentation + /// + public void ClearIndent() + { + this.indentLengths.Clear(); + this.currentIndentField = ""; + } + #endregion + #region ToString Helpers + /// + /// Utility class to produce culture-oriented representation of an object as a string. + /// + public class ToStringInstanceHelper + { + private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; + /// + /// Gets or sets format provider to be used by ToStringWithCulture method. + /// + public System.IFormatProvider FormatProvider + { + get + { + return this.formatProviderField ; + } + set + { + if ((value != null)) + { + this.formatProviderField = value; + } + } + } + /// + /// This is called from the compile/run appdomain to convert objects within an expression block to a string + /// + public string ToStringWithCulture(object objectToConvert) + { + if ((objectToConvert == null)) + { + throw new global::System.ArgumentNullException("objectToConvert"); + } + System.Type t = objectToConvert.GetType(); + System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { + typeof(System.IFormatProvider)}); + if ((method == null)) + { + return objectToConvert.ToString(); + } + else + { + return ((string)(method.Invoke(objectToConvert, new object[] { + this.formatProviderField }))); + } + } + } + private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); + /// + /// Helper to produce culture-oriented representation of an object as a string + /// + public ToStringInstanceHelper ToStringHelper + { + get + { + return this.toStringHelperField; + } + } + #endregion + } + #endregion +} diff --git a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt new file mode 100644 index 00000000..7418b2bb --- /dev/null +++ b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt @@ -0,0 +1,25 @@ +<#@ template language="C#" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Reflection" #> +<#@ assembly name="mscorlib" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> +<# if (shouldCreateWebApp) { +#> +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); +<# +} +#> + +app.<#=method #>("<#=path #>", () => <#=response #>); +<#+ + public string path { get; set; } + public string method { get; set; } + public string apiResponse { get; set; } + public bool shouldCreateWebApp { get; set; } + public string response { get; set; } +#> From b644adf6c904c3a1f7e7d3424e14ad0442dbf531 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Fri, 22 Jul 2022 14:38:41 -0700 Subject: [PATCH 03/33] draft --- src/OpenApi/OutputFile/Program.cs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/OpenApi/OutputFile/Program.cs diff --git a/src/OpenApi/OutputFile/Program.cs b/src/OpenApi/OutputFile/Program.cs new file mode 100644 index 00000000..3b1a71fd --- /dev/null +++ b/src/OpenApi/OutputFile/Program.cs @@ -0,0 +1,6 @@ +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); + +app.MapGet("/students", () => ""); + +app.MapPost("/students/{id}", () => new string[][] {}); From edaa6340d18201843e9fc0dc6015aff43bce700e Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Fri, 22 Jul 2022 14:41:49 -0700 Subject: [PATCH 04/33] draft --- src/OpenApi/CodeGenerator/Class1.cs | 144 ++++++++++++------ .../CodeGenerator/RuntimeTextTemplate2.cs | 14 +- .../CodeGenerator/RuntimeTextTemplate2.tt | 5 +- 3 files changed, 104 insertions(+), 59 deletions(-) diff --git a/src/OpenApi/CodeGenerator/Class1.cs b/src/OpenApi/CodeGenerator/Class1.cs index a79dd610..395f80b3 100644 --- a/src/OpenApi/CodeGenerator/Class1.cs +++ b/src/OpenApi/CodeGenerator/Class1.cs @@ -13,72 +13,116 @@ namespace CodeGenerator RuntimeTextTemplate2 page; String pageContent; + int count = 0; + bool shouldCreateWebApp = true; foreach (var path in paths) { + if (count > 0) + { + shouldCreateWebApp = false; + } var operations = path.Value.Operations; foreach (var operation in operations) { var method = operation.Key.ToString().ToLower(); + var response = operation.Value.Responses.FirstOrDefault().Value; + var schema = response.Content.Values.FirstOrDefault()?.Schema; - switch(method) + string returnValue; + if (schema?.Type.ToLower() == "array") { - case "get": - page = new RuntimeTextTemplate2 - { - apiPath = path.Key.ToString(), - apiMethod = "MapGet" - }; - pageContent = page.TransformText(); - File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); - break; - - case "post": - page = new RuntimeTextTemplate2 - { - apiPath = path.Key.ToString(), - apiMethod = "MapPost" - }; - pageContent = page.TransformText(); - File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); - break; - - case "put": - page = new RuntimeTextTemplate2 - { - apiPath = path.Key.ToString(), - apiMethod = "MapPut" - }; - pageContent = page.TransformText(); - File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); - break; - - case "delete": - page = new RuntimeTextTemplate2 - { - apiPath = path.Key.ToString(), - apiMethod = "MapDelete" - }; - pageContent = page.TransformText(); - File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); - break; + returnValue = new App().GetArraySchema(schema); + returnValue = "new " + returnValue + " {}"; } + else + { + returnValue = new App().GetPrimitiveType(schema); + } + + page = new RuntimeTextTemplate2 + { + path = path.Key.ToString(), + method = new App().GetHttpMethod(method), + shouldCreateWebApp = shouldCreateWebApp, + returnValue = returnValue + }; + pageContent = page.TransformText(); + File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); } + count++; } - //RuntimeTextTemplate2 page = new RuntimeTextTemplate2 - //{ - // path = "\"/students\"" - //}; - //String pageContent = page.TransformText(); - //System.IO.File.WriteAllText(args[1], pageContent); - } + // //RuntimeTextTemplate2 page = new RuntimeTextTemplate2 + // //{ + // // path = "\"/students\"" + // //}; + // //String pageContent = page.TransformText(); + // //System.IO.File.WriteAllText(args[1], pageContent); + } + private string GetHttpMethod(string method) + { + switch (method) + { + case "get": + return "MapGet"; + + case "post": + return "MapPost"; + + case "put": + return "MapPut"; + + case "delete": + return "MapDelete"; + + default: + return ""; + } + } + private string GetArraySchema(OpenApiSchema? schema) + { + var type = schema?.Type; + + switch (type) + { + case "string": + return "string"; + + case "integer": + return "int"; + + case "boolean": + return "bool"; + + case "array": + return new App().GetArraySchema(schema?.Items) + "[]"; + } + return ""; + } + private string GetPrimitiveType(OpenApiSchema? schema) + { + var type = schema?.Type; + + switch (type) + { + case "string": + return "\"\""; + + case "integer": + return "0"; + //draft + + case "boolean": + return "false"; + } + return ""; + } private OpenApiDocument ReadJson(string args) { - string inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; - - + var inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; + //var inputPath = "C:\\Users\\Anh Thi Dao\\Downloads\\petstore.json"; if (!Path.IsPathRooted(inputPath)) { diff --git a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs index 1b9e2c89..30e0d5a5 100644 --- a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs +++ b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs @@ -46,24 +46,24 @@ namespace CodeGenerator #line default #line hidden - this.Write("\r\napp."); + this.Write("draft\r\n\r\napp."); - #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" this.Write(this.ToStringHelper.ToStringWithCulture(method)); #line default #line hidden this.Write("(\""); - #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" this.Write(this.ToStringHelper.ToStringWithCulture(path)); #line default #line hidden this.Write("\", () => "); - #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(response)); + #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(returnValue)); #line default #line hidden @@ -71,13 +71,13 @@ namespace CodeGenerator return this.GenerationEnvironment.ToString(); } - #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + #line 20 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" public string path { get; set; } public string method { get; set; } public string apiResponse { get; set; } public bool shouldCreateWebApp { get; set; } - public string response { get; set; } + public string returnValue { get; set; } #line default diff --git a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt index 7418b2bb..3b078553 100644 --- a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt +++ b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt @@ -14,12 +14,13 @@ var app = builder.Build(); <# } #> +draft -app.<#=method #>("<#=path #>", () => <#=response #>); +app.<#=method #>("<#=path #>", () => <#=returnValue #>); <#+ public string path { get; set; } public string method { get; set; } public string apiResponse { get; set; } public bool shouldCreateWebApp { get; set; } - public string response { get; set; } + public string returnValue { get; set; } #> From fb2b14815ea05c6632eac032512603f0860c916c Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Fri, 22 Jul 2022 14:43:01 -0700 Subject: [PATCH 05/33] update parse data type --- src/OpenApi/CodeGenerator/Class1.cs | 1 - src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs | 10 +++++----- src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt | 1 - 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/OpenApi/CodeGenerator/Class1.cs b/src/OpenApi/CodeGenerator/Class1.cs index 395f80b3..5a5f2b54 100644 --- a/src/OpenApi/CodeGenerator/Class1.cs +++ b/src/OpenApi/CodeGenerator/Class1.cs @@ -112,7 +112,6 @@ namespace CodeGenerator case "integer": return "0"; - //draft case "boolean": return "false"; diff --git a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs index 30e0d5a5..884df133 100644 --- a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs +++ b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs @@ -46,23 +46,23 @@ namespace CodeGenerator #line default #line hidden - this.Write("draft\r\n\r\napp."); + this.Write("\r\napp."); - #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" this.Write(this.ToStringHelper.ToStringWithCulture(method)); #line default #line hidden this.Write("(\""); - #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" this.Write(this.ToStringHelper.ToStringWithCulture(path)); #line default #line hidden this.Write("\", () => "); - #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" this.Write(this.ToStringHelper.ToStringWithCulture(returnValue)); #line default @@ -71,7 +71,7 @@ namespace CodeGenerator return this.GenerationEnvironment.ToString(); } - #line 20 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" + #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" public string path { get; set; } public string method { get; set; } diff --git a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt index 3b078553..86ce0e9c 100644 --- a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt +++ b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt @@ -14,7 +14,6 @@ var app = builder.Build(); <# } #> -draft app.<#=method #>("<#=path #>", () => <#=returnValue #>); <#+ From 1d4c5981cb657cedf7c14d5c8f1c5d6c1ad64f66 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Mon, 25 Jul 2022 14:13:41 -0700 Subject: [PATCH 06/33] update --- src/OpenApi/CodeGenerator/Class1.cs | 61 ++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/src/OpenApi/CodeGenerator/Class1.cs b/src/OpenApi/CodeGenerator/Class1.cs index 5a5f2b54..777c71cb 100644 --- a/src/OpenApi/CodeGenerator/Class1.cs +++ b/src/OpenApi/CodeGenerator/Class1.cs @@ -13,31 +13,48 @@ namespace CodeGenerator RuntimeTextTemplate2 page; String pageContent; - int count = 0; + int countPaths = 0; bool shouldCreateWebApp = true; foreach (var path in paths) { - if (count > 0) - { - shouldCreateWebApp = false; - } var operations = path.Value.Operations; foreach (var operation in operations) { + if (countPaths > 0) + { + shouldCreateWebApp = false; + } + var method = operation.Key.ToString().ToLower(); var response = operation.Value.Responses.FirstOrDefault().Value; var schema = response.Content.Values.FirstOrDefault()?.Schema; + var parameters = operation.Value.Parameters; + string parametersList = ""; + int countParam = 1; + + foreach (var parameter in parameters) + { + parametersList += new App().GetDataTypeKeyword(parameter.Schema) + " " + parameter.Name; + + if (countParam < parameters.Count) + { + parametersList += ", "; + } + + countParam++; + } + string returnValue; if (schema?.Type.ToLower() == "array") { - returnValue = new App().GetArraySchema(schema); + returnValue = new App().GetDataTypeKeyword(schema); returnValue = "new " + returnValue + " {}"; } else { - returnValue = new App().GetPrimitiveType(schema); + returnValue = new App().GetPrimitiveValue(schema); } page = new RuntimeTextTemplate2 @@ -45,12 +62,14 @@ namespace CodeGenerator path = path.Key.ToString(), method = new App().GetHttpMethod(method), shouldCreateWebApp = shouldCreateWebApp, - returnValue = returnValue + returnValue = returnValue, + parametersList = parametersList }; pageContent = page.TransformText(); - File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs", pageContent); + File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenApi\\OutputFile\\Program.cs", pageContent); + + countPaths++; } - count++; } // //RuntimeTextTemplate2 page = new RuntimeTextTemplate2 @@ -81,7 +100,7 @@ namespace CodeGenerator return ""; } } - private string GetArraySchema(OpenApiSchema? schema) + private string GetDataTypeKeyword(OpenApiSchema? schema) { var type = schema?.Type; @@ -96,12 +115,18 @@ namespace CodeGenerator case "boolean": return "bool"; + case "float": + return "float"; + + case "double": + return "double"; + case "array": - return new App().GetArraySchema(schema?.Items) + "[]"; + return new App().GetDataTypeKeyword(schema?.Items) + "[]"; } return ""; } - private string GetPrimitiveType(OpenApiSchema? schema) + private string GetPrimitiveValue(OpenApiSchema? schema) { var type = schema?.Type; @@ -115,13 +140,19 @@ namespace CodeGenerator case "boolean": return "false"; + + case "float": + return "0.0f"; + + case "double": + return "0.0d"; } return ""; } private OpenApiDocument ReadJson(string args) { - var inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; - //var inputPath = "C:\\Users\\Anh Thi Dao\\Downloads\\petstore.json"; + //var inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; + var inputPath = "C:\\Users\\Anh Thi Dao\\Downloads\\petstore.json"; if (!Path.IsPathRooted(inputPath)) { From cc67e777c4547270b6b54a748482917eecb728e8 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Tue, 26 Jul 2022 11:15:30 -0700 Subject: [PATCH 07/33] update after receiving feedback --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 174 +++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/OpenApi/CodeGenerator/CodeGenerator.cs diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs new file mode 100644 index 00000000..55025934 --- /dev/null +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -0,0 +1,174 @@ +using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Readers; + +namespace CodeGenerator; + +public class App +{ + public static void Main(string[] args) + { + var document = ReadJson(""); + var paths = document.Paths; + + if (paths is null || paths.Count == 0) + { + Console.WriteLine("No path was found!"); + return; + } + + RuntimeTextTemplate2 page; + String pageContent; + + int countPaths = 0; + bool shouldCreateWebApp = true; + + foreach (var path in paths) + { + var operations = path.Value.Operations; + if (operations is null || operations.Count == 0) + { + Console.WriteLine("No path was found!"); + return; + } + foreach (var operation in operations) + { + if (countPaths > 0) + { + shouldCreateWebApp = false; + } + + var method = operation.Key.ToString().ToLower(); + var response = operation.Value.Responses.FirstOrDefault().Value; + var schema = response.Content.Values.FirstOrDefault()?.Schema; + + var parameters = operation.Value.Parameters; + string parametersList = ""; + + for (int i = 0; i < parameters.Count; i++) + { + var parameter = parameters[i]; + parametersList += GetDataTypeKeyword(parameter.Schema) + " " + parameter.Name; + + if (i < parameters.Count - 1) + { + parametersList += ", "; + } + } + + string returnValue; + + if (schema?.Type.ToLower() == "array") + { + returnValue = GetArrayKeyword(schema); + } + else + { + returnValue = GetPrimitiveValue(schema); + } + + page = new RuntimeTextTemplate2 + { + Path = path.Key.ToString(), + Method = GetHttpMethod(method), + ShouldCreateWebApp = shouldCreateWebApp, + ReturnValue = returnValue, + ParametersList = parametersList + }; + pageContent = page.TransformText(); + File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenApi\\OutputFile\\Program.cs", pageContent); + + countPaths++; + } + } + } + private static string GetHttpMethod(string method) => method switch + { + "get" => "MapGet", + "post" => "MapPost", + "put" => "MapPut", + "delete" => "MapDelete", + _ => String.Empty + }; + private static string GetDataTypeKeyword(OpenApiSchema? schema) => schema?.Type switch + { + "string" => "string", + "integer" => "int", + "float" => "float", + "boolean" => "bool", + "double" => "double", + _ => "" + }; + private static string GetArrayKeyword(OpenApiSchema? schema) + { + if (schema == null) + { + return String.Empty; + } + string returnValue = "["; + while (schema.Items.Type == "array") + { + returnValue += ","; + schema = schema.Items; + } + returnValue = "new " + GetDataTypeKeyword(schema.Items) + returnValue + "] {}"; + return returnValue; + } + private static string GetPrimitiveValue(OpenApiSchema? schema) => schema?.Type switch + { + "string" => "\"\"", + "integer" => "0", + "boolean" => "false", + "float" => "0.0f", + "double" => "0.0d", + _ => String.Empty, + }; + private static OpenApiDocument ReadJson(string args) + { + var inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; + //var inputPath = "C:\\Users\\Anh Thi Dao\\Downloads\\petstore.json"; + + if (!Path.IsPathRooted(inputPath)) + { + Console.WriteLine("The file path you entered does not have a root"); + return new OpenApiDocument(); + } + + OpenApiStreamReader reader = new OpenApiStreamReader(); + var diagnostic = new OpenApiDiagnostic(); + + try + { + string path = Path.GetFullPath(inputPath); + Stream stream = File.OpenRead(path); + OpenApiDocument newDocument = reader.Read(stream, out diagnostic); + return newDocument; + } + catch (FileNotFoundException e) + { + Console.WriteLine("Check to make sure you entered a correct file path because the file was not found."); + Console.Error.WriteLine(e.Message); + return new OpenApiDocument(); + } + catch (Exception e) + { + Console.WriteLine("Check the file path you entered for errors."); + Console.Error.WriteLine(e.Message); + return new OpenApiDocument(); + } + finally + { + if (diagnostic.Errors.Count == 0) + { + Console.WriteLine("Read File Successfully"); + } + else + { + foreach (OpenApiError error in diagnostic.Errors) + { + Console.WriteLine($"There was an error reading in the file at {error.Pointer}"); + Console.Error.WriteLine(error.Message); + } + } + } + } +} From a273cce57f05832a8002f44f69c13edf6cf55eb8 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Tue, 26 Jul 2022 14:59:15 -0700 Subject: [PATCH 08/33] update again --- src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt index 86ce0e9c..a12477be 100644 --- a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt +++ b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt @@ -7,7 +7,7 @@ <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Reflection" #> <#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> -<# if (shouldCreateWebApp) { +<# if (ShouldCreateWebApp) { #> var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); @@ -15,11 +15,11 @@ var app = builder.Build(); } #> -app.<#=method #>("<#=path #>", () => <#=returnValue #>); +app.<#=Method #>("<#=Path #>", (<#=ParametersList #>) => <#=ReturnValue #>); <#+ - public string path { get; set; } - public string method { get; set; } - public string apiResponse { get; set; } - public bool shouldCreateWebApp { get; set; } - public string returnValue { get; set; } + public string Path { get; set; } + public string Method { get; set; } + public bool ShouldCreateWebApp { get; set; } + public string ReturnValue { get; set; } + public string ParametersList { get; set; } #> From d5d3f5c35500a6020f6e93e2c69ed4a5302b302d Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Wed, 27 Jul 2022 15:50:52 -0700 Subject: [PATCH 09/33] update to handle invalid operations --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 46 +++++++++++++++------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs index 55025934..c974c99d 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.cs +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -7,12 +7,17 @@ public class App { public static void Main(string[] args) { - var document = ReadJson(""); + if (args.Length == 0) + { + Console.WriteLine("No file path was found!"); + return; + } + var document = ReadJson(args[0]); var paths = document.Paths; if (paths is null || paths.Count == 0) { - Console.WriteLine("No path was found!"); + Console.WriteLine("No path was found in the schema!"); return; } @@ -28,7 +33,7 @@ public class App if (operations is null || operations.Count == 0) { Console.WriteLine("No path was found!"); - return; + Environment.Exit(0); } foreach (var operation in operations) { @@ -38,6 +43,14 @@ public class App } var method = operation.Key.ToString().ToLower(); + method = GetHttpMethod(method); + + if (method == String.Empty) + { + Console.WriteLine("Invalid operation found!"); + Environment.Exit(0); + } + var response = operation.Value.Responses.FirstOrDefault().Value; var schema = response.Content.Values.FirstOrDefault()?.Schema; @@ -69,13 +82,13 @@ public class App page = new RuntimeTextTemplate2 { Path = path.Key.ToString(), - Method = GetHttpMethod(method), + Method = method, ShouldCreateWebApp = shouldCreateWebApp, ReturnValue = returnValue, ParametersList = parametersList }; pageContent = page.TransformText(); - File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenApi\\OutputFile\\Program.cs", pageContent); + File.AppendAllText(args[1], pageContent); countPaths++; } @@ -96,7 +109,7 @@ public class App "float" => "float", "boolean" => "bool", "double" => "double", - _ => "" + _ => String.Empty }; private static string GetArrayKeyword(OpenApiSchema? schema) { @@ -122,15 +135,15 @@ public class App "double" => "0.0d", _ => String.Empty, }; - private static OpenApiDocument ReadJson(string args) + private static OpenApiDocument? ReadJson(string args) { - var inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; - //var inputPath = "C:\\Users\\Anh Thi Dao\\Downloads\\petstore.json"; + //var inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; + var inputPath = "C:\\Users\\Anh Thi Dao\\Downloads\\petstore.json"; - if (!Path.IsPathRooted(inputPath)) + if (!Path.IsPathRooted(args)) { Console.WriteLine("The file path you entered does not have a root"); - return new OpenApiDocument(); + return null; } OpenApiStreamReader reader = new OpenApiStreamReader(); @@ -138,7 +151,7 @@ public class App try { - string path = Path.GetFullPath(inputPath); + string path = Path.GetFullPath(args); Stream stream = File.OpenRead(path); OpenApiDocument newDocument = reader.Read(stream, out diagnostic); return newDocument; @@ -147,13 +160,15 @@ public class App { Console.WriteLine("Check to make sure you entered a correct file path because the file was not found."); Console.Error.WriteLine(e.Message); - return new OpenApiDocument(); + Environment.Exit(0); + return null; } catch (Exception e) { Console.WriteLine("Check the file path you entered for errors."); Console.Error.WriteLine(e.Message); - return new OpenApiDocument(); + Environment.Exit(0); + return null; } finally { @@ -165,8 +180,9 @@ public class App { foreach (OpenApiError error in diagnostic.Errors) { - Console.WriteLine($"There was an error reading in the file at {error.Pointer}"); + Console.WriteLine($"There was an error reading in the file: {error.Pointer}"); Console.Error.WriteLine(error.Message); + Environment.Exit(0); } } } From 774962be26ace0b23cee4452666b37fd796cd6a5 Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 27 Jul 2022 15:52:33 -0700 Subject: [PATCH 10/33] Delete Class1.cs --- src/OpenApi/CodeGenerator/Class1.cs | 212 ---------------------------- 1 file changed, 212 deletions(-) delete mode 100644 src/OpenApi/CodeGenerator/Class1.cs diff --git a/src/OpenApi/CodeGenerator/Class1.cs b/src/OpenApi/CodeGenerator/Class1.cs deleted file mode 100644 index 777c71cb..00000000 --- a/src/OpenApi/CodeGenerator/Class1.cs +++ /dev/null @@ -1,212 +0,0 @@ -namespace CodeGenerator -{ - using Microsoft.OpenApi.Models; - using Microsoft.OpenApi.Readers; - public class App - { - public static void Main(string[] args) - { - var document = new App().ReadJson(""); - var paths = document.Paths; - //var operation = paths.Values.FirstOrDefault().Operations[0]; - //var responseDescription = operation.Responses["200"]; - - RuntimeTextTemplate2 page; - String pageContent; - int countPaths = 0; - bool shouldCreateWebApp = true; - - foreach (var path in paths) - { - var operations = path.Value.Operations; - foreach (var operation in operations) - { - if (countPaths > 0) - { - shouldCreateWebApp = false; - } - - var method = operation.Key.ToString().ToLower(); - var response = operation.Value.Responses.FirstOrDefault().Value; - var schema = response.Content.Values.FirstOrDefault()?.Schema; - - var parameters = operation.Value.Parameters; - string parametersList = ""; - int countParam = 1; - - foreach (var parameter in parameters) - { - parametersList += new App().GetDataTypeKeyword(parameter.Schema) + " " + parameter.Name; - - if (countParam < parameters.Count) - { - parametersList += ", "; - } - - countParam++; - } - - string returnValue; - if (schema?.Type.ToLower() == "array") - { - returnValue = new App().GetDataTypeKeyword(schema); - returnValue = "new " + returnValue + " {}"; - } - else - { - returnValue = new App().GetPrimitiveValue(schema); - } - - page = new RuntimeTextTemplate2 - { - path = path.Key.ToString(), - method = new App().GetHttpMethod(method), - shouldCreateWebApp = shouldCreateWebApp, - returnValue = returnValue, - parametersList = parametersList - }; - pageContent = page.TransformText(); - File.AppendAllText("C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenApi\\OutputFile\\Program.cs", pageContent); - - countPaths++; - } - } - - // //RuntimeTextTemplate2 page = new RuntimeTextTemplate2 - // //{ - // // path = "\"/students\"" - // //}; - // //String pageContent = page.TransformText(); - // //System.IO.File.WriteAllText(args[1], pageContent); - - } - private string GetHttpMethod(string method) - { - switch (method) - { - case "get": - return "MapGet"; - - case "post": - return "MapPost"; - - case "put": - return "MapPut"; - - case "delete": - return "MapDelete"; - - default: - return ""; - } - } - private string GetDataTypeKeyword(OpenApiSchema? schema) - { - var type = schema?.Type; - - switch (type) - { - case "string": - return "string"; - - case "integer": - return "int"; - - case "boolean": - return "bool"; - - case "float": - return "float"; - - case "double": - return "double"; - - case "array": - return new App().GetDataTypeKeyword(schema?.Items) + "[]"; - } - return ""; - } - private string GetPrimitiveValue(OpenApiSchema? schema) - { - var type = schema?.Type; - - switch (type) - { - case "string": - return "\"\""; - - case "integer": - return "0"; - - case "boolean": - return "false"; - - case "float": - return "0.0f"; - - case "double": - return "0.0d"; - } - return ""; - } - private OpenApiDocument ReadJson(string args) - { - //var inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; - var inputPath = "C:\\Users\\Anh Thi Dao\\Downloads\\petstore.json"; - - if (!Path.IsPathRooted(inputPath)) - { - Console.WriteLine("The file path you entered does not have a root"); - return new OpenApiDocument(); - } - - OpenApiStreamReader reader = new OpenApiStreamReader(); - var diagnostic = new OpenApiDiagnostic(); - - try - { - string path = Path.GetFullPath(inputPath); - Stream stream = File.OpenRead(path); - OpenApiDocument newDocument = reader.Read(stream, out diagnostic); - return newDocument; - } - catch (FileNotFoundException e) - { - Console.WriteLine("Check to make sure you entered a correct file path because the file was not found."); - Console.Error.WriteLine(e.Message); - return new OpenApiDocument(); - } - catch (Exception e) - { - Console.WriteLine("Check the file path you entered for errors."); - Console.Error.WriteLine(e.Message); - return new OpenApiDocument(); - } - finally - { - if (diagnostic.Errors.Count == 0) - { - Console.WriteLine("Read File Successfully"); - } - else - { - foreach (OpenApiError error in diagnostic.Errors) - { - Console.WriteLine($"There was an error reading in the file at {error.Pointer}"); - Console.Error.WriteLine(error.Message); - } - } - } - } - - - - // public OpenApiOperation CreateOperation(OpenApiDocument document) - // { - // OpenApiOperation operation = new OpenApiOperation(); - // OpenApiPathItem key = new OpenApiPathItem() - // operation = document.Paths.Values; - // } - } - -} From 3810d8cdf8a59f483f52c4a2052cb944ef424b1b Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Wed, 27 Jul 2022 18:14:19 -0700 Subject: [PATCH 11/33] update implementation to only open and write to output file once --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 103 ++--- .../CodeGenerator/MinimalApiTemplate.cs | 387 ++++++++++++++++++ .../CodeGenerator/MinimalApiTemplate.tt | 44 ++ 3 files changed, 485 insertions(+), 49 deletions(-) create mode 100644 src/OpenApi/CodeGenerator/MinimalApiTemplate.cs create mode 100644 src/OpenApi/CodeGenerator/MinimalApiTemplate.tt diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs index c974c99d..8821a365 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.cs +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -7,52 +7,47 @@ public class App { public static void Main(string[] args) { - if (args.Length == 0) + + if (args.Length != 2) { - Console.WriteLine("No file path was found!"); - return; + Console.Error.WriteLine("Please enter two arguments: an input file path and an output file path."); + Environment.Exit(1); } + var document = ReadJson(args[0]); - var paths = document.Paths; + var paths = document?.Paths; if (paths is null || paths.Count == 0) { - Console.WriteLine("No path was found in the schema!"); - return; + Console.Error.WriteLine("No path was found in the schema."); + Environment.Exit(3); } - RuntimeTextTemplate2 page; - String pageContent; - - int countPaths = 0; - bool shouldCreateWebApp = true; + var fileProperties = new Dictionary>>(); foreach (var path in paths) { var operations = path.Value.Operations; if (operations is null || operations.Count == 0) { - Console.WriteLine("No path was found!"); - Environment.Exit(0); + Console.Error.WriteLine("No operation was found in path."); + Environment.Exit(4); } + var pathString = path.Key.ToString(); + fileProperties.Add(pathString, new Dictionary> { }); + foreach (var operation in operations) { - if (countPaths > 0) - { - shouldCreateWebApp = false; - } - var method = operation.Key.ToString().ToLower(); method = GetHttpMethod(method); if (method == String.Empty) { - Console.WriteLine("Invalid operation found!"); - Environment.Exit(0); + Console.Error.WriteLine($"Unsupported HTTP method found: '{operation.Key}'"); + Environment.Exit(4); } - var response = operation.Value.Responses.FirstOrDefault().Value; - var schema = response.Content.Values.FirstOrDefault()?.Schema; + fileProperties[pathString].Add(method, new Dictionary { }); var parameters = operation.Value.Parameters; string parametersList = ""; @@ -68,31 +63,44 @@ public class App } } - string returnValue; + fileProperties[pathString][method].Add("parameters", parametersList); - if (schema?.Type.ToLower() == "array") + var responses = operation.Value.Responses; + + foreach (var response in responses) { - returnValue = GetArrayKeyword(schema); + string returnValue; + + // for responses that doesn't have "content" property + // but a description is always required so we will return that + if (response.Value.Content == null || response.Value.Content.Count == 0) + { + returnValue = $"\"{response.Value.Description}\""; + fileProperties[pathString][method].Add(response.Key, returnValue); + continue; + } + var schema = response.Value.Content.First().Value.Schema; + + if (schema?.Type.ToLower() == "array") + { + returnValue = GetArrayKeyword(schema); + } + else + { + returnValue = GetPrimitiveValue(schema); + } + + fileProperties[pathString][method].Add(response.Key, returnValue); } - else - { - returnValue = GetPrimitiveValue(schema); - } - - page = new RuntimeTextTemplate2 - { - Path = path.Key.ToString(), - Method = method, - ShouldCreateWebApp = shouldCreateWebApp, - ReturnValue = returnValue, - ParametersList = parametersList - }; - pageContent = page.TransformText(); - File.AppendAllText(args[1], pageContent); - - countPaths++; } } + + var page = new MinimalApiTemplate + { + FileProperties = fileProperties + }; + var pageContent = page.TransformText(); + File.AppendAllText(args[1], pageContent); } private static string GetHttpMethod(string method) => method switch { @@ -137,12 +145,9 @@ public class App }; private static OpenApiDocument? ReadJson(string args) { - //var inputPath = "C:\\Users\\AnhThiDao\\openapi.json"; - var inputPath = "C:\\Users\\Anh Thi Dao\\Downloads\\petstore.json"; - if (!Path.IsPathRooted(args)) { - Console.WriteLine("The file path you entered does not have a root"); + Console.Error.WriteLine("The file path you entered does not have a root"); return null; } @@ -160,14 +165,14 @@ public class App { Console.WriteLine("Check to make sure you entered a correct file path because the file was not found."); Console.Error.WriteLine(e.Message); - Environment.Exit(0); + Environment.Exit(2); return null; } catch (Exception e) { Console.WriteLine("Check the file path you entered for errors."); Console.Error.WriteLine(e.Message); - Environment.Exit(0); + Environment.Exit(2); return null; } finally @@ -182,7 +187,7 @@ public class App { Console.WriteLine($"There was an error reading in the file: {error.Pointer}"); Console.Error.WriteLine(error.Message); - Environment.Exit(0); + Environment.Exit(2); } } } diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs new file mode 100644 index 00000000..9cdb2938 --- /dev/null +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs @@ -0,0 +1,387 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version: 17.0.0.0 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +namespace CodeGenerator +{ + using System.Linq; + using System.Text; + using System.Collections.Generic; + using System.Reflection; + using Microsoft.VisualStudio.TextTemplating; + using System; + + /// + /// Class to produce the template output + /// + + #line 1 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] + public partial class MinimalApiTemplate : MinimalApiTemplateBase + { +#line hidden + /// + /// Create the template output + /// + public virtual string TransformText() + { + this.Write("var builder = WebApplication.CreateBuilder(args);\r\nvar app = builder.Build();\r\n\r\n" + + ""); + + #line 13 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + foreach (var path in FileProperties) { + Path = path.Key; + foreach (var operation in FileProperties[Path]) { + Method = operation.Key; + + // currently, the code doesn't handle multiple status code + // so it will return the response for code "200" if there is + // if not, it will return the first response in the list + // this will be changed after we figure out how to handle different status code + if (operation.Value.ContainsKey("200")) { + ReturnValue = operation.Value["200"]; + } + else { + ReturnValue = operation.Value.ElementAt(1).Value; + } + ParametersList = operation.Value["parameters"]; + + + #line default + #line hidden + this.Write("app."); + + #line 31 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(Method)); + + #line default + #line hidden + this.Write("(\""); + + #line 31 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(Path)); + + #line default + #line hidden + this.Write("\", ("); + + #line 31 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(ParametersList)); + + #line default + #line hidden + this.Write(") => "); + + #line 31 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(ReturnValue)); + + #line default + #line hidden + this.Write(");\r\n\r\n"); + + #line 33 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + } + } + + + #line default + #line hidden + this.Write("\r\n"); + return this.GenerationEnvironment.ToString(); + } + + #line 38 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + public Dictionary>> FileProperties { get; set; } + public string Path { get; set; } + public string Method { get; set; } + public string ReturnValue { get; set; } + public string ParametersList { get; set; } + + + #line default + #line hidden + } + + #line default + #line hidden + #region Base class + /// + /// Base class for this transformation + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] + public class MinimalApiTemplateBase + { + #region Fields + private global::System.Text.StringBuilder generationEnvironmentField; + private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; + private global::System.Collections.Generic.List indentLengthsField; + private string currentIndentField = ""; + private bool endsWithNewline; + private global::System.Collections.Generic.IDictionary sessionField; + #endregion + #region Properties + /// + /// The string builder that generation-time code is using to assemble generated output + /// + protected System.Text.StringBuilder GenerationEnvironment + { + get + { + if ((this.generationEnvironmentField == null)) + { + this.generationEnvironmentField = new global::System.Text.StringBuilder(); + } + return this.generationEnvironmentField; + } + set + { + this.generationEnvironmentField = value; + } + } + /// + /// The error collection for the generation process + /// + public System.CodeDom.Compiler.CompilerErrorCollection Errors + { + get + { + if ((this.errorsField == null)) + { + this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); + } + return this.errorsField; + } + } + /// + /// A list of the lengths of each indent that was added with PushIndent + /// + private System.Collections.Generic.List indentLengths + { + get + { + if ((this.indentLengthsField == null)) + { + this.indentLengthsField = new global::System.Collections.Generic.List(); + } + return this.indentLengthsField; + } + } + /// + /// Gets the current indent we use when adding lines to the output + /// + public string CurrentIndent + { + get + { + return this.currentIndentField; + } + } + /// + /// Current transformation session + /// + public virtual global::System.Collections.Generic.IDictionary Session + { + get + { + return this.sessionField; + } + set + { + this.sessionField = value; + } + } + #endregion + #region Transform-time helpers + /// + /// Write text directly into the generated output + /// + public void Write(string textToAppend) + { + if (string.IsNullOrEmpty(textToAppend)) + { + return; + } + // If we're starting off, or if the previous text ended with a newline, + // we have to append the current indent first. + if (((this.GenerationEnvironment.Length == 0) + || this.endsWithNewline)) + { + this.GenerationEnvironment.Append(this.currentIndentField); + this.endsWithNewline = false; + } + // Check if the current text ends with a newline + if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) + { + this.endsWithNewline = true; + } + // This is an optimization. If the current indent is "", then we don't have to do any + // of the more complex stuff further down. + if ((this.currentIndentField.Length == 0)) + { + this.GenerationEnvironment.Append(textToAppend); + return; + } + // Everywhere there is a newline in the text, add an indent after it + textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); + // If the text ends with a newline, then we should strip off the indent added at the very end + // because the appropriate indent will be added when the next time Write() is called + if (this.endsWithNewline) + { + this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); + } + else + { + this.GenerationEnvironment.Append(textToAppend); + } + } + /// + /// Write text directly into the generated output + /// + public void WriteLine(string textToAppend) + { + this.Write(textToAppend); + this.GenerationEnvironment.AppendLine(); + this.endsWithNewline = true; + } + /// + /// Write formatted text directly into the generated output + /// + public void Write(string format, params object[] args) + { + this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); + } + /// + /// Write formatted text directly into the generated output + /// + public void WriteLine(string format, params object[] args) + { + this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); + } + /// + /// Raise an error + /// + public void Error(string message) + { + System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); + error.ErrorText = message; + this.Errors.Add(error); + } + /// + /// Raise a warning + /// + public void Warning(string message) + { + System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); + error.ErrorText = message; + error.IsWarning = true; + this.Errors.Add(error); + } + /// + /// Increase the indent + /// + public void PushIndent(string indent) + { + if ((indent == null)) + { + throw new global::System.ArgumentNullException("indent"); + } + this.currentIndentField = (this.currentIndentField + indent); + this.indentLengths.Add(indent.Length); + } + /// + /// Remove the last indent that was added with PushIndent + /// + public string PopIndent() + { + string returnValue = ""; + if ((this.indentLengths.Count > 0)) + { + int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; + this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); + if ((indentLength > 0)) + { + returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); + this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); + } + } + return returnValue; + } + /// + /// Remove any indentation + /// + public void ClearIndent() + { + this.indentLengths.Clear(); + this.currentIndentField = ""; + } + #endregion + #region ToString Helpers + /// + /// Utility class to produce culture-oriented representation of an object as a string. + /// + public class ToStringInstanceHelper + { + private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; + /// + /// Gets or sets format provider to be used by ToStringWithCulture method. + /// + public System.IFormatProvider FormatProvider + { + get + { + return this.formatProviderField ; + } + set + { + if ((value != null)) + { + this.formatProviderField = value; + } + } + } + /// + /// This is called from the compile/run appdomain to convert objects within an expression block to a string + /// + public string ToStringWithCulture(object objectToConvert) + { + if ((objectToConvert == null)) + { + throw new global::System.ArgumentNullException("objectToConvert"); + } + System.Type t = objectToConvert.GetType(); + System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { + typeof(System.IFormatProvider)}); + if ((method == null)) + { + return objectToConvert.ToString(); + } + else + { + return ((string)(method.Invoke(objectToConvert, new object[] { + this.formatProviderField }))); + } + } + } + private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); + /// + /// Helper to produce culture-oriented representation of an object as a string + /// + public ToStringInstanceHelper ToStringHelper + { + get + { + return this.toStringHelperField; + } + } + #endregion + } + #endregion +} diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt new file mode 100644 index 00000000..dbc0fd56 --- /dev/null +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt @@ -0,0 +1,44 @@ +<#@ template language="C#" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Reflection" #> +<#@ assembly name="mscorlib" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); + +<# + foreach (var path in FileProperties) { + Path = path.Key; + foreach (var operation in FileProperties[Path]) { + Method = operation.Key; + + // currently, the code doesn't handle multiple status code + // so it will return the response for code "200" if there is + // if not, it will return the first response in the list + // this will be changed after we figure out how to handle different status code + if (operation.Value.ContainsKey("200")) { + ReturnValue = operation.Value["200"]; + } + else { + ReturnValue = operation.Value.ElementAt(1).Value; + } + ParametersList = operation.Value["parameters"]; +#> +app.<#=Method #>("<#=Path #>", (<#=ParametersList #>) => <#=ReturnValue #>); + +<# + } + } +#> + +<#+ + public Dictionary>> FileProperties { get; set; } + public string Path { get; set; } + public string Method { get; set; } + public string ReturnValue { get; set; } + public string ParametersList { get; set; } +#> From 582d43f105ce32e25a4d447657b67920eedfe11d Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 27 Jul 2022 18:15:45 -0700 Subject: [PATCH 12/33] Delete RuntimeTextTemplate2.cs --- .../CodeGenerator/RuntimeTextTemplate2.cs | 361 ------------------ 1 file changed, 361 deletions(-) delete mode 100644 src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs diff --git a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs deleted file mode 100644 index 884df133..00000000 --- a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.cs +++ /dev/null @@ -1,361 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version: 17.0.0.0 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -// ------------------------------------------------------------------------------ -namespace CodeGenerator -{ - using System.Linq; - using System.Text; - using System.Collections.Generic; - using System.Reflection; - using Microsoft.VisualStudio.TextTemplating; - using System; - - /// - /// Class to produce the template output - /// - - #line 1 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] - public partial class RuntimeTextTemplate2 : RuntimeTextTemplate2Base - { -#line hidden - /// - /// Create the template output - /// - public virtual string TransformText() - { - - #line 10 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" - if (shouldCreateWebApp) { - - - #line default - #line hidden - this.Write("var builder = WebApplication.CreateBuilder(args);\r\nvar app = builder.Build();\r\n"); - - #line 14 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" - -} - - - #line default - #line hidden - this.Write("\r\napp."); - - #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(method)); - - #line default - #line hidden - this.Write("(\""); - - #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(path)); - - #line default - #line hidden - this.Write("\", () => "); - - #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(returnValue)); - - #line default - #line hidden - this.Write(");\r\n"); - return this.GenerationEnvironment.ToString(); - } - - #line 19 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\RuntimeTextTemplate2.tt" - - public string path { get; set; } - public string method { get; set; } - public string apiResponse { get; set; } - public bool shouldCreateWebApp { get; set; } - public string returnValue { get; set; } - - - #line default - #line hidden - } - - #line default - #line hidden - #region Base class - /// - /// Base class for this transformation - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] - public class RuntimeTextTemplate2Base - { - #region Fields - private global::System.Text.StringBuilder generationEnvironmentField; - private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; - private global::System.Collections.Generic.List indentLengthsField; - private string currentIndentField = ""; - private bool endsWithNewline; - private global::System.Collections.Generic.IDictionary sessionField; - #endregion - #region Properties - /// - /// The string builder that generation-time code is using to assemble generated output - /// - protected System.Text.StringBuilder GenerationEnvironment - { - get - { - if ((this.generationEnvironmentField == null)) - { - this.generationEnvironmentField = new global::System.Text.StringBuilder(); - } - return this.generationEnvironmentField; - } - set - { - this.generationEnvironmentField = value; - } - } - /// - /// The error collection for the generation process - /// - public System.CodeDom.Compiler.CompilerErrorCollection Errors - { - get - { - if ((this.errorsField == null)) - { - this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); - } - return this.errorsField; - } - } - /// - /// A list of the lengths of each indent that was added with PushIndent - /// - private System.Collections.Generic.List indentLengths - { - get - { - if ((this.indentLengthsField == null)) - { - this.indentLengthsField = new global::System.Collections.Generic.List(); - } - return this.indentLengthsField; - } - } - /// - /// Gets the current indent we use when adding lines to the output - /// - public string CurrentIndent - { - get - { - return this.currentIndentField; - } - } - /// - /// Current transformation session - /// - public virtual global::System.Collections.Generic.IDictionary Session - { - get - { - return this.sessionField; - } - set - { - this.sessionField = value; - } - } - #endregion - #region Transform-time helpers - /// - /// Write text directly into the generated output - /// - public void Write(string textToAppend) - { - if (string.IsNullOrEmpty(textToAppend)) - { - return; - } - // If we're starting off, or if the previous text ended with a newline, - // we have to append the current indent first. - if (((this.GenerationEnvironment.Length == 0) - || this.endsWithNewline)) - { - this.GenerationEnvironment.Append(this.currentIndentField); - this.endsWithNewline = false; - } - // Check if the current text ends with a newline - if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) - { - this.endsWithNewline = true; - } - // This is an optimization. If the current indent is "", then we don't have to do any - // of the more complex stuff further down. - if ((this.currentIndentField.Length == 0)) - { - this.GenerationEnvironment.Append(textToAppend); - return; - } - // Everywhere there is a newline in the text, add an indent after it - textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); - // If the text ends with a newline, then we should strip off the indent added at the very end - // because the appropriate indent will be added when the next time Write() is called - if (this.endsWithNewline) - { - this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); - } - else - { - this.GenerationEnvironment.Append(textToAppend); - } - } - /// - /// Write text directly into the generated output - /// - public void WriteLine(string textToAppend) - { - this.Write(textToAppend); - this.GenerationEnvironment.AppendLine(); - this.endsWithNewline = true; - } - /// - /// Write formatted text directly into the generated output - /// - public void Write(string format, params object[] args) - { - this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Write formatted text directly into the generated output - /// - public void WriteLine(string format, params object[] args) - { - this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Raise an error - /// - public void Error(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - this.Errors.Add(error); - } - /// - /// Raise a warning - /// - public void Warning(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - error.IsWarning = true; - this.Errors.Add(error); - } - /// - /// Increase the indent - /// - public void PushIndent(string indent) - { - if ((indent == null)) - { - throw new global::System.ArgumentNullException("indent"); - } - this.currentIndentField = (this.currentIndentField + indent); - this.indentLengths.Add(indent.Length); - } - /// - /// Remove the last indent that was added with PushIndent - /// - public string PopIndent() - { - string returnValue = ""; - if ((this.indentLengths.Count > 0)) - { - int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; - this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); - if ((indentLength > 0)) - { - returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); - this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); - } - } - return returnValue; - } - /// - /// Remove any indentation - /// - public void ClearIndent() - { - this.indentLengths.Clear(); - this.currentIndentField = ""; - } - #endregion - #region ToString Helpers - /// - /// Utility class to produce culture-oriented representation of an object as a string. - /// - public class ToStringInstanceHelper - { - private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; - /// - /// Gets or sets format provider to be used by ToStringWithCulture method. - /// - public System.IFormatProvider FormatProvider - { - get - { - return this.formatProviderField ; - } - set - { - if ((value != null)) - { - this.formatProviderField = value; - } - } - } - /// - /// This is called from the compile/run appdomain to convert objects within an expression block to a string - /// - public string ToStringWithCulture(object objectToConvert) - { - if ((objectToConvert == null)) - { - throw new global::System.ArgumentNullException("objectToConvert"); - } - System.Type t = objectToConvert.GetType(); - System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { - typeof(System.IFormatProvider)}); - if ((method == null)) - { - return objectToConvert.ToString(); - } - else - { - return ((string)(method.Invoke(objectToConvert, new object[] { - this.formatProviderField }))); - } - } - } - private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); - /// - /// Helper to produce culture-oriented representation of an object as a string - /// - public ToStringInstanceHelper ToStringHelper - { - get - { - return this.toStringHelperField; - } - } - #endregion - } - #endregion -} From 791e35d35792e8087a731d0df813b382fdd2f9b1 Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 27 Jul 2022 18:15:55 -0700 Subject: [PATCH 13/33] Delete RuntimeTextTemplate2.tt --- .../CodeGenerator/RuntimeTextTemplate2.tt | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt diff --git a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt b/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt deleted file mode 100644 index a12477be..00000000 --- a/src/OpenApi/CodeGenerator/RuntimeTextTemplate2.tt +++ /dev/null @@ -1,25 +0,0 @@ -<#@ template language="C#" #> -<#@ assembly name="System.Core" #> -<#@ assembly name="System.Reflection" #> -<#@ assembly name="mscorlib" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ import namespace="System.Reflection" #> -<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> -<# if (ShouldCreateWebApp) { -#> -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); -<# -} -#> - -app.<#=Method #>("<#=Path #>", (<#=ParametersList #>) => <#=ReturnValue #>); -<#+ - public string Path { get; set; } - public string Method { get; set; } - public bool ShouldCreateWebApp { get; set; } - public string ReturnValue { get; set; } - public string ParametersList { get; set; } -#> From 6bb8708889a4a5ec53419ab5da2b012a3309e062 Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 27 Jul 2022 18:18:04 -0700 Subject: [PATCH 14/33] Delete Program.cs --- src/OpenApi/OutputFile/Program.cs | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 src/OpenApi/OutputFile/Program.cs diff --git a/src/OpenApi/OutputFile/Program.cs b/src/OpenApi/OutputFile/Program.cs deleted file mode 100644 index 3b1a71fd..00000000 --- a/src/OpenApi/OutputFile/Program.cs +++ /dev/null @@ -1,6 +0,0 @@ -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -app.MapGet("/students", () => ""); - -app.MapPost("/students/{id}", () => new string[][] {}); From 69a1c7b8ff5b357257eb49c480ecd6b28c1d9ceb Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 27 Jul 2022 18:20:00 -0700 Subject: [PATCH 15/33] Delete openapi.json --- openapi.json | 41 ----------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 openapi.json diff --git a/openapi.json b/openapi.json deleted file mode 100644 index 38f0494a..00000000 --- a/openapi.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "version": "1.0.0", - "title": "Swagger Students", - "license": { - "name": "MIT" - } - }, - "servers": [ - { - "url": "http://petstore.swagger.io/v1" - } - ], - "paths": { - "/students": { - "get": { - "summary": "List all the students in the school", - "operationId": "listStudents", - "tags": [ - "students" - ], - "responses": { - "200": { - "description": "An array of student names", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - } - } - } - } - } -} \ No newline at end of file From f456271cb7607cefa1300effafddd742c9709be5 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Wed, 27 Jul 2022 18:28:08 -0700 Subject: [PATCH 16/33] make changes about exit codes --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs index 8821a365..2431e6e5 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.cs +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -11,7 +11,7 @@ public class App if (args.Length != 2) { Console.Error.WriteLine("Please enter two arguments: an input file path and an output file path."); - Environment.Exit(1); + Environment.Exit(1); // Code 1 is for problems with passed in file paths } var document = ReadJson(args[0]); @@ -20,7 +20,7 @@ public class App if (paths is null || paths.Count == 0) { Console.Error.WriteLine("No path was found in the schema."); - Environment.Exit(3); + Environment.Exit(2); // Code 2 is for problems with paths in schema } var fileProperties = new Dictionary>>(); @@ -31,7 +31,7 @@ public class App if (operations is null || operations.Count == 0) { Console.Error.WriteLine("No operation was found in path."); - Environment.Exit(4); + Environment.Exit(3); // Code 3 is for problems with operations } var pathString = path.Key.ToString(); fileProperties.Add(pathString, new Dictionary> { }); @@ -44,7 +44,7 @@ public class App if (method == String.Empty) { Console.Error.WriteLine($"Unsupported HTTP method found: '{operation.Key}'"); - Environment.Exit(4); + Environment.Exit(3); } fileProperties[pathString].Add(method, new Dictionary { }); @@ -165,14 +165,14 @@ public class App { Console.WriteLine("Check to make sure you entered a correct file path because the file was not found."); Console.Error.WriteLine(e.Message); - Environment.Exit(2); + Environment.Exit(1); return null; } catch (Exception e) { Console.WriteLine("Check the file path you entered for errors."); Console.Error.WriteLine(e.Message); - Environment.Exit(2); + Environment.Exit(1); return null; } finally @@ -187,7 +187,7 @@ public class App { Console.WriteLine($"There was an error reading in the file: {error.Pointer}"); Console.Error.WriteLine(error.Message); - Environment.Exit(2); + Environment.Exit(1); } } } From 5b6f7763607cdad78a126d13ff2f7d7c246ea5cd Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Mon, 1 Aug 2022 09:32:25 -0700 Subject: [PATCH 17/33] update code to handle objects --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 122 ++++++++-- .../CodeGenerator/MinimalApiTemplate.cs | 215 ++++++++++++++++-- .../CodeGenerator/MinimalApiTemplate.tt | 111 ++++++++- 3 files changed, 405 insertions(+), 43 deletions(-) diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs index 2431e6e5..c7e3302b 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.cs +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -1,3 +1,4 @@ +using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Readers; @@ -7,7 +8,10 @@ public class App { public static void Main(string[] args) { - + args = new string[] { "C:\\Users\\AnhThiDao\\AspLabs\\mockFiles\\petstore.json", "C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs" }; + //C:\\Users\\Anh Thi Dao\\Downloads\\openapi (1).json + //C:\\Users\\Anh Thi Dao\\Downloads\\Movies.json + //C:\\Users\\AnhThiDao\\AspLabs\\mockFiles\\petstore.json if (args.Length != 2) { Console.Error.WriteLine("Please enter two arguments: an input file path and an output file path."); @@ -19,7 +23,7 @@ public class App if (paths is null || paths.Count == 0) { - Console.Error.WriteLine("No path was found in the schema."); + Console.Error.WriteLine("No path were found in the schema."); Environment.Exit(2); // Code 2 is for problems with paths in schema } @@ -50,12 +54,23 @@ public class App fileProperties[pathString].Add(method, new Dictionary { }); var parameters = operation.Value.Parameters; - string parametersList = ""; + string parametersList = String.Empty; for (int i = 0; i < parameters.Count; i++) { var parameter = parameters[i]; - parametersList += GetDataTypeKeyword(parameter.Schema) + " " + parameter.Name; + if (parameter.Schema.Type.ToLower() == "array") + { + parametersList += GetArrayKeyword(parameter.Schema) + " " + parameter.Name; + } + else if (parameter.Schema.Type.ToLower() == "object") + { + parametersList += parameter.Schema.Reference?.Id + $" user{parameter.Schema.Reference?.Id}"; + } + else + { + parametersList += GetDataTypeKeyword(parameter.Schema) + " " + parameter.Name; + } if (i < parameters.Count - 1) { @@ -71,37 +86,110 @@ public class App { string returnValue; - // for responses that doesn't have "content" property - // but a description is always required so we will return that + // some responses doesn't have "content" property + // so these would later return a default value if (response.Value.Content == null || response.Value.Content.Count == 0) { - returnValue = $"\"{response.Value.Description}\""; + returnValue = "Default"; fileProperties[pathString][method].Add(response.Key, returnValue); continue; } - var schema = response.Value.Content.First().Value.Schema; + var content = response.Value.Content.First().Value; + var schema = content.Schema; if (schema?.Type.ToLower() == "array") { - returnValue = GetArrayKeyword(schema); + returnValue = "new " + GetArrayKeyword(schema) + " {}"; + } + else if (schema?.Type.ToLower() == "object") + { + returnValue = "new " + schema?.Reference?.Id + "()"; } else { returnValue = GetPrimitiveValue(schema); } + // this code below is for parsing sample values + // this is used for demoing the project + if (content.Example != null) + { + + returnValue = GetSampleValue(content.Example, schema); + } + + if (content.Examples != null && content.Examples.Count > 0) + { + returnValue = GetSampleValue(content.Examples.First().Value.Value, schema); + } + fileProperties[pathString][method].Add(response.Key, returnValue); } } } + var schemas = document?.Components?.Schemas; + + Dictionary> schemaDict = new Dictionary> (); + if (schemas != null && schemas.Count > 0) + { + foreach (var schema in schemas) + { + schemaDict.Add(schema.Key, new Dictionary()); + foreach (var property in schema.Value.Properties) + { + string propertyType; + if (property.Value.Type.ToLower() == "array") + { + propertyType = GetArrayKeyword(property.Value); + } + else if (property.Value.Reference?.Id != null) + { + propertyType = property.Value.Reference.Id; + } + else + { + propertyType = GetDataTypeKeyword(property.Value); + } + schemaDict[schema.Key].Add(property.Key, propertyType); + } + } + } + var page = new MinimalApiTemplate { - FileProperties = fileProperties + FileProperties = fileProperties, + Schemas = schemaDict }; var pageContent = page.TransformText(); File.AppendAllText(args[1], pageContent); } + private static string GetSampleValue(IOpenApiAny example, OpenApiSchema? schema) => example switch + { + OpenApiString castedExample => $"\"{castedExample.Value}\"", + OpenApiInteger castedExample => castedExample.Value.ToString(), + OpenApiBoolean castedExample => castedExample.Value.ToString(), + OpenApiFloat castedExample => castedExample.Value.ToString(), + OpenApiDouble castedExample => castedExample.Value.ToString(), + OpenApiArray castedExample => "new " + GetDataTypeKeyword(schema) + $"[] {{{GetArrayValues(castedExample)}}}", + _ => string.Empty + }; + private static string GetArrayValues(OpenApiArray example) + { + int count = example.Count; + string returnValue = string.Empty; + foreach (var value in example) + { + returnValue += GetSampleValue(value,null); + if (count > 1) + { + returnValue += ", "; + } + count--; + } + return returnValue; + } + private static string GetHttpMethod(string method) => method switch { "get" => "MapGet", @@ -131,9 +219,16 @@ public class App returnValue += ","; schema = schema.Items; } - returnValue = "new " + GetDataTypeKeyword(schema.Items) + returnValue + "] {}"; + if (schema.Items.Type.ToLower() == "object") + { + returnValue = schema?.Items.Reference?.Id + returnValue + "]"; + } + else + { + returnValue = GetDataTypeKeyword(schema?.Items) + returnValue + "]"; + } return returnValue; - } + } private static string GetPrimitiveValue(OpenApiSchema? schema) => schema?.Type switch { "string" => "\"\"", @@ -183,13 +278,14 @@ public class App } else { - foreach (OpenApiError error in diagnostic.Errors) + foreach (var error in diagnostic.Errors) { Console.WriteLine($"There was an error reading in the file: {error.Pointer}"); Console.Error.WriteLine(error.Message); Environment.Exit(1); } } + } } } diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs index 9cdb2938..e815e94b 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs @@ -40,70 +40,247 @@ namespace CodeGenerator foreach (var operation in FileProperties[Path]) { Method = operation.Key; - // currently, the code doesn't handle multiple status code - // so it will return the response for code "200" if there is - // if not, it will return the first response in the list - // this will be changed after we figure out how to handle different status code - if (operation.Value.ContainsKey("200")) { - ReturnValue = operation.Value["200"]; - } - else { - ReturnValue = operation.Value.ElementAt(1).Value; - } ParametersList = operation.Value["parameters"]; + if (ParametersList != String.Empty) { + ParametersList = ", " + ParametersList; + } + #line default #line hidden this.Write("app."); - #line 31 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(Method)); #line default #line hidden this.Write("(\""); - #line 31 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(Path)); #line default #line hidden - this.Write("\", ("); + this.Write("\", (HttpContext context"); - #line 31 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ParametersList)); #line default #line hidden - this.Write(") => "); + this.Write(") =>\r\n{\r\n"); - #line 31 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 27 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + foreach (var response in operation.Value) { + + if (response.Key != "parameters") { + StatusCode = response.Key; + if (response.Value == "Default") { + var statusMethod = StatusCode switch { + "202" => "Accepted()", + "400" => "BadRequest()", + "409" => "Conflict()", + "204" => "NoContent()", + "404" => "NotFound()", + "200" => "Ok()", + "401" => "Unauthorized()", + "422" => "UnprocessableEntity()", + _ => $"StatusCode({response.Key})" + }; + ReturnValue = $"Results.{statusMethod}"; + } + else { + var statusMethod = StatusCode switch { + "202" => $"Accepted(_, {response.Value})", + "400" => $"BadRequest({response.Value})", + "409" => $"Conflict({response.Value})", + "204" => "NoContent()", + "404" => $"NotFound({response.Value})", + "200" => $"Ok({response.Value})", + "401" => "Unauthorized()", + "422" => $"UnprocessableEntity({response.Value})", + _ => $"StatusCode({response.Key})" + }; + ReturnValue = $"Results.{statusMethod}"; + } + + } + + else { + continue; + } + + + #line default + #line hidden + this.Write(" if (context.Request.Headers[\"AcceptStatusCode\"] == \""); + + #line 67 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(StatusCode)); + + #line default + #line hidden + this.Write("\")\r\n {\r\n return "); + + #line 69 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ReturnValue)); #line default #line hidden - this.Write(");\r\n\r\n"); + this.Write(";\r\n }\r\n\r\n"); - #line 33 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 72 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + } + + + #line default + #line hidden + this.Write(" return null;\r\n});\r\n\r\n"); + + #line 78 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } } + #line default + #line hidden + this.Write("\r\n"); + + #line 83 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + foreach (var schema in Schemas) { + UserObject = schema.Key; + + + #line default + #line hidden + this.Write("public class "); + + #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); + + #line default + #line hidden + this.Write(" {\r\n"); + + #line 88 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + string constructorParameters = string.Empty; + string constructorBody = string.Empty; + foreach (var property in schema.Value) { + PropertyName = property.Key; + PropertyType = property.Value; + constructorParameters += PropertyType + "? " + PropertyName + ", "; + constructorBody += $"this.{PropertyName} = {PropertyName}\n"; + + + #line default + #line hidden + this.Write(" public "); + + #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(PropertyType)); + + #line default + #line hidden + this.Write("? "); + + #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(PropertyName)); + + #line default + #line hidden + this.Write(" { get; set; }\r\n"); + + #line 98 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + } + ConstructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); + constructorBody = constructorBody.Substring(0, constructorBody.Length - 1); + + + #line default + #line hidden + this.Write(" public "); + + #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); + + #line default + #line hidden + this.Write("("); + + #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorParameters)); + + #line default + #line hidden + this.Write(") {\r\n"); + + #line 104 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + var statements = constructorBody.Split("\n"); + foreach (var statement in statements) { + ConstructorBody = statement; + + + #line default + #line hidden + this.Write(" "); + + #line 109 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorBody)); + + #line default + #line hidden + this.Write(";\r\n"); + + #line 110 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + } + + + #line default + #line hidden + this.Write(" }\r\n public "); + + #line 114 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); + + #line default + #line hidden + this.Write("() {}\r\n}\r\n"); + + #line 116 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + + } + + #line default #line hidden this.Write("\r\n"); return this.GenerationEnvironment.ToString(); } - #line 38 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 120 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" public Dictionary>> FileProperties { get; set; } public string Path { get; set; } public string Method { get; set; } public string ReturnValue { get; set; } public string ParametersList { get; set; } + public string StatusCode { get; set; } + public Dictionary> Schemas { get; set; } + public string UserObject { get; set; } + public string PropertyName { get; set; } + public string PropertyType { get; set; } + public string ConstructorParameters { get; set; } + public string ConstructorBody { get; set; } #line default diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt index dbc0fd56..f35f869c 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt @@ -16,29 +16,118 @@ var app = builder.Build(); foreach (var operation in FileProperties[Path]) { Method = operation.Key; - // currently, the code doesn't handle multiple status code - // so it will return the response for code "200" if there is - // if not, it will return the first response in the list - // this will be changed after we figure out how to handle different status code - if (operation.Value.ContainsKey("200")) { - ReturnValue = operation.Value["200"]; - } - else { - ReturnValue = operation.Value.ElementAt(1).Value; - } ParametersList = operation.Value["parameters"]; + + if (ParametersList != String.Empty) { + ParametersList = ", " + ParametersList; + } #> -app.<#=Method #>("<#=Path #>", (<#=ParametersList #>) => <#=ReturnValue #>); +app.<#=Method #>("<#=Path #>", (HttpContext context<#=ParametersList #>) => +{ +<# + foreach (var response in operation.Value) { + + if (response.Key != "parameters") { + StatusCode = response.Key; + if (response.Value == "Default") { + var statusMethod = StatusCode switch { + "202" => "Accepted()", + "400" => "BadRequest()", + "409" => "Conflict()", + "204" => "NoContent()", + "404" => "NotFound()", + "200" => "Ok()", + "401" => "Unauthorized()", + "422" => "UnprocessableEntity()", + _ => $"StatusCode({response.Key})" + }; + ReturnValue = $"Results.{statusMethod}"; + } + else { + var statusMethod = StatusCode switch { + "202" => $"Accepted(_, {response.Value})", + "400" => $"BadRequest({response.Value})", + "409" => $"Conflict({response.Value})", + "204" => "NoContent()", + "404" => $"NotFound({response.Value})", + "200" => $"Ok({response.Value})", + "401" => "Unauthorized()", + "422" => $"UnprocessableEntity({response.Value})", + _ => $"StatusCode({response.Key})" + }; + ReturnValue = $"Results.{statusMethod}"; + } + + } + + else { + continue; + } +#> + if (context.Request.Headers["AcceptStatusCode"] == "<#=StatusCode #>") + { + return <#=ReturnValue #>; + } + +<# + } +#> + return null; +}); <# } } #> +<# + foreach (var schema in Schemas) { + UserObject = schema.Key; +#> +public class <#=UserObject #> { +<# + string constructorParameters = string.Empty; + string constructorBody = string.Empty; + foreach (var property in schema.Value) { + PropertyName = property.Key; + PropertyType = property.Value; + constructorParameters += PropertyType + "? " + PropertyName + ", "; + constructorBody += $"this.{PropertyName} = {PropertyName}\n"; +#> + public <#=PropertyType #>? <#=PropertyName #> { get; set; } +<# + } + ConstructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); + constructorBody = constructorBody.Substring(0, constructorBody.Length - 1); +#> + public <#=UserObject #>(<#=ConstructorParameters #>) { +<# + var statements = constructorBody.Split("\n"); + foreach (var statement in statements) { + ConstructorBody = statement; +#> + <#=ConstructorBody #>; +<# + } +#> + } + public <#=UserObject #>() {} +} +<# + } +#> + <#+ public Dictionary>> FileProperties { get; set; } public string Path { get; set; } public string Method { get; set; } public string ReturnValue { get; set; } public string ParametersList { get; set; } + public string StatusCode { get; set; } + public Dictionary> Schemas { get; set; } + public string UserObject { get; set; } + public string PropertyName { get; set; } + public string PropertyType { get; set; } + public string ConstructorParameters { get; set; } + public string ConstructorBody { get; set; } #> From 7bfa22622b6c533dd48852b937f2e574138dcc47 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Wed, 3 Aug 2022 10:58:54 -0700 Subject: [PATCH 18/33] update code to handle values' details --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 26 ++++++++++--- .../CodeGenerator/MinimalApiTemplate.cs | 37 +++++++++---------- .../CodeGenerator/MinimalApiTemplate.tt | 1 - 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs index c7e3302b..a7951ed1 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.cs +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -8,10 +8,6 @@ public class App { public static void Main(string[] args) { - args = new string[] { "C:\\Users\\AnhThiDao\\AspLabs\\mockFiles\\petstore.json", "C:\\Users\\AnhThiDao\\AspLabs\\src\\OpenAPI\\OutputFile\\Program.cs" }; - //C:\\Users\\Anh Thi Dao\\Downloads\\openapi (1).json - //C:\\Users\\Anh Thi Dao\\Downloads\\Movies.json - //C:\\Users\\AnhThiDao\\AspLabs\\mockFiles\\petstore.json if (args.Length != 2) { Console.Error.WriteLine("Please enter two arguments: an input file path and an output file path."); @@ -114,7 +110,6 @@ public class App // this is used for demoing the project if (content.Example != null) { - returnValue = GetSampleValue(content.Example, schema); } @@ -161,8 +156,9 @@ public class App FileProperties = fileProperties, Schemas = schemaDict }; + var pageContent = page.TransformText(); - File.AppendAllText(args[1], pageContent); + File.WriteAllText(args[1], pageContent); } private static string GetSampleValue(IOpenApiAny example, OpenApiSchema? schema) => example switch { @@ -172,6 +168,8 @@ public class App OpenApiFloat castedExample => castedExample.Value.ToString(), OpenApiDouble castedExample => castedExample.Value.ToString(), OpenApiArray castedExample => "new " + GetDataTypeKeyword(schema) + $"[] {{{GetArrayValues(castedExample)}}}", + OpenApiObject castedExample => GetObjectArguments(castedExample, schema), + OpenApiNull castedExample => "null", _ => string.Empty }; private static string GetArrayValues(OpenApiArray example) @@ -189,6 +187,22 @@ public class App } return returnValue; } + private static string GetObjectArguments(OpenApiObject example, OpenApiSchema? schema) + { + string arguments = $"new {schema?.Reference?.Id}("; + for (int i = 0; i < example.Values.Count; i++) + { + if (schema?.Properties?.Values.Count > i) + { + arguments += $"{GetSampleValue(example.Values.ElementAt(i), schema?.Properties?.Values?.ElementAt(i))}, "; + } + else + { + arguments += $"{GetSampleValue(example.Values.ElementAt(i), null)}, "; + } + } + return arguments.Substring(0, arguments.Length - 2) + ")"; + } private static string GetHttpMethod(string method) => method switch { diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs index e815e94b..7e20bcb8 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs @@ -108,7 +108,6 @@ namespace CodeGenerator } } - else { continue; } @@ -118,21 +117,21 @@ namespace CodeGenerator #line hidden this.Write(" if (context.Request.Headers[\"AcceptStatusCode\"] == \""); - #line 67 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 66 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(StatusCode)); #line default #line hidden this.Write("\")\r\n {\r\n return "); - #line 69 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 68 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ReturnValue)); #line default #line hidden this.Write(";\r\n }\r\n\r\n"); - #line 72 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 71 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -141,7 +140,7 @@ namespace CodeGenerator #line hidden this.Write(" return null;\r\n});\r\n\r\n"); - #line 78 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 77 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } } @@ -151,7 +150,7 @@ namespace CodeGenerator #line hidden this.Write("\r\n"); - #line 83 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 82 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var schema in Schemas) { UserObject = schema.Key; @@ -161,14 +160,14 @@ namespace CodeGenerator #line hidden this.Write("public class "); - #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 86 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); #line default #line hidden this.Write(" {\r\n"); - #line 88 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" string constructorParameters = string.Empty; string constructorBody = string.Empty; @@ -183,21 +182,21 @@ namespace CodeGenerator #line hidden this.Write(" public "); - #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(PropertyType)); #line default #line hidden this.Write("? "); - #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(PropertyName)); #line default #line hidden this.Write(" { get; set; }\r\n"); - #line 98 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } ConstructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); @@ -208,21 +207,21 @@ namespace CodeGenerator #line hidden this.Write(" public "); - #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); #line default #line hidden this.Write("("); - #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorParameters)); #line default #line hidden this.Write(") {\r\n"); - #line 104 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" var statements = constructorBody.Split("\n"); foreach (var statement in statements) { @@ -233,14 +232,14 @@ namespace CodeGenerator #line hidden this.Write(" "); - #line 109 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 108 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorBody)); #line default #line hidden this.Write(";\r\n"); - #line 110 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 109 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -249,14 +248,14 @@ namespace CodeGenerator #line hidden this.Write(" }\r\n public "); - #line 114 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 113 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); #line default #line hidden this.Write("() {}\r\n}\r\n"); - #line 116 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 115 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -267,7 +266,7 @@ namespace CodeGenerator return this.GenerationEnvironment.ToString(); } - #line 120 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 119 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" public Dictionary>> FileProperties { get; set; } public string Path { get; set; } diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt index f35f869c..96b21801 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt @@ -59,7 +59,6 @@ app.<#=Method #>("<#=Path #>", (HttpContext context<#=ParametersList #>) => } } - else { continue; } From fa3dc93d537316557d8a9e3e4cc46ceafb34288d Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Mon, 8 Aug 2022 08:51:06 -0700 Subject: [PATCH 19/33] draft --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 1 + .../CodeGenerator/MinimalApiTemplate.cs | 48 +++++++++---------- .../CodeGenerator/MinimalApiTemplate.tt | 1 + 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs index a7951ed1..a7e6d602 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.cs +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -160,6 +160,7 @@ public class App var pageContent = page.TransformText(); File.WriteAllText(args[1], pageContent); } + private static string GetSampleValue(IOpenApiAny example, OpenApiSchema? schema) => example switch { OpenApiString castedExample => $"\"{castedExample.Value}\"", diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs index 7e20bcb8..260be4a6 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs @@ -31,9 +31,9 @@ namespace CodeGenerator public virtual string TransformText() { this.Write("var builder = WebApplication.CreateBuilder(args);\r\nvar app = builder.Build();\r\n\r\n" + - ""); + "\r\n"); - #line 13 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 14 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var path in FileProperties) { Path = path.Key; @@ -51,28 +51,28 @@ namespace CodeGenerator #line hidden this.Write("app."); - #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 26 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(Method)); #line default #line hidden this.Write("(\""); - #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 26 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(Path)); #line default #line hidden this.Write("\", (HttpContext context"); - #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 26 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ParametersList)); #line default #line hidden this.Write(") =>\r\n{\r\n"); - #line 27 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 28 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var response in operation.Value) { @@ -117,21 +117,21 @@ namespace CodeGenerator #line hidden this.Write(" if (context.Request.Headers[\"AcceptStatusCode\"] == \""); - #line 66 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 67 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(StatusCode)); #line default #line hidden this.Write("\")\r\n {\r\n return "); - #line 68 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 69 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ReturnValue)); #line default #line hidden this.Write(";\r\n }\r\n\r\n"); - #line 71 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 72 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -140,7 +140,7 @@ namespace CodeGenerator #line hidden this.Write(" return null;\r\n});\r\n\r\n"); - #line 77 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 78 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } } @@ -150,7 +150,7 @@ namespace CodeGenerator #line hidden this.Write("\r\n"); - #line 82 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 83 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var schema in Schemas) { UserObject = schema.Key; @@ -160,14 +160,14 @@ namespace CodeGenerator #line hidden this.Write("public class "); - #line 86 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); #line default #line hidden this.Write(" {\r\n"); - #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 88 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" string constructorParameters = string.Empty; string constructorBody = string.Empty; @@ -182,21 +182,21 @@ namespace CodeGenerator #line hidden this.Write(" public "); - #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(PropertyType)); #line default #line hidden this.Write("? "); - #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(PropertyName)); #line default #line hidden this.Write(" { get; set; }\r\n"); - #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 98 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } ConstructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); @@ -207,21 +207,21 @@ namespace CodeGenerator #line hidden this.Write(" public "); - #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); #line default #line hidden this.Write("("); - #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorParameters)); #line default #line hidden this.Write(") {\r\n"); - #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 104 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" var statements = constructorBody.Split("\n"); foreach (var statement in statements) { @@ -232,14 +232,14 @@ namespace CodeGenerator #line hidden this.Write(" "); - #line 108 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 109 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorBody)); #line default #line hidden this.Write(";\r\n"); - #line 109 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 110 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -248,14 +248,14 @@ namespace CodeGenerator #line hidden this.Write(" }\r\n public "); - #line 113 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 114 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); #line default #line hidden this.Write("() {}\r\n}\r\n"); - #line 115 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 116 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -266,7 +266,7 @@ namespace CodeGenerator return this.GenerationEnvironment.ToString(); } - #line 119 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 120 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" public Dictionary>> FileProperties { get; set; } public string Path { get; set; } diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt index 96b21801..10685f33 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt @@ -10,6 +10,7 @@ var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); + <# foreach (var path in FileProperties) { Path = path.Key; From 9adc2f371206f5a25fbac4578bec5500c24b1183 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Mon, 8 Aug 2022 08:51:54 -0700 Subject: [PATCH 20/33] update on 8/8/22 --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 1 - .../CodeGenerator/MinimalApiTemplate.cs | 48 +++++++++---------- .../CodeGenerator/MinimalApiTemplate.tt | 1 - 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs index a7e6d602..a7951ed1 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.cs +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -160,7 +160,6 @@ public class App var pageContent = page.TransformText(); File.WriteAllText(args[1], pageContent); } - private static string GetSampleValue(IOpenApiAny example, OpenApiSchema? schema) => example switch { OpenApiString castedExample => $"\"{castedExample.Value}\"", diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs index 260be4a6..7e20bcb8 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs @@ -31,9 +31,9 @@ namespace CodeGenerator public virtual string TransformText() { this.Write("var builder = WebApplication.CreateBuilder(args);\r\nvar app = builder.Build();\r\n\r\n" + - "\r\n"); + ""); - #line 14 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 13 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var path in FileProperties) { Path = path.Key; @@ -51,28 +51,28 @@ namespace CodeGenerator #line hidden this.Write("app."); - #line 26 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(Method)); #line default #line hidden this.Write("(\""); - #line 26 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(Path)); #line default #line hidden this.Write("\", (HttpContext context"); - #line 26 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ParametersList)); #line default #line hidden this.Write(") =>\r\n{\r\n"); - #line 28 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 27 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var response in operation.Value) { @@ -117,21 +117,21 @@ namespace CodeGenerator #line hidden this.Write(" if (context.Request.Headers[\"AcceptStatusCode\"] == \""); - #line 67 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 66 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(StatusCode)); #line default #line hidden this.Write("\")\r\n {\r\n return "); - #line 69 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 68 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ReturnValue)); #line default #line hidden this.Write(";\r\n }\r\n\r\n"); - #line 72 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 71 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -140,7 +140,7 @@ namespace CodeGenerator #line hidden this.Write(" return null;\r\n});\r\n\r\n"); - #line 78 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 77 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } } @@ -150,7 +150,7 @@ namespace CodeGenerator #line hidden this.Write("\r\n"); - #line 83 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 82 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var schema in Schemas) { UserObject = schema.Key; @@ -160,14 +160,14 @@ namespace CodeGenerator #line hidden this.Write("public class "); - #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 86 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); #line default #line hidden this.Write(" {\r\n"); - #line 88 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" string constructorParameters = string.Empty; string constructorBody = string.Empty; @@ -182,21 +182,21 @@ namespace CodeGenerator #line hidden this.Write(" public "); - #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(PropertyType)); #line default #line hidden this.Write("? "); - #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(PropertyName)); #line default #line hidden this.Write(" { get; set; }\r\n"); - #line 98 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } ConstructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); @@ -207,21 +207,21 @@ namespace CodeGenerator #line hidden this.Write(" public "); - #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); #line default #line hidden this.Write("("); - #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorParameters)); #line default #line hidden this.Write(") {\r\n"); - #line 104 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" var statements = constructorBody.Split("\n"); foreach (var statement in statements) { @@ -232,14 +232,14 @@ namespace CodeGenerator #line hidden this.Write(" "); - #line 109 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 108 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorBody)); #line default #line hidden this.Write(";\r\n"); - #line 110 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 109 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -248,14 +248,14 @@ namespace CodeGenerator #line hidden this.Write(" }\r\n public "); - #line 114 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 113 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); #line default #line hidden this.Write("() {}\r\n}\r\n"); - #line 116 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 115 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -266,7 +266,7 @@ namespace CodeGenerator return this.GenerationEnvironment.ToString(); } - #line 120 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 119 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" public Dictionary>> FileProperties { get; set; } public string Path { get; set; } diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt index 10685f33..96b21801 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt @@ -10,7 +10,6 @@ var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); - <# foreach (var path in FileProperties) { Path = path.Key; From 30f327bd64607ae9e3c19a353cb39b66fe446069 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Mon, 8 Aug 2022 13:54:47 -0700 Subject: [PATCH 21/33] update to address comments --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 34 +++++++++++++------ .../CodeGenerator/MinimalApiTemplate.cs | 30 ++++++++-------- .../CodeGenerator/MinimalApiTemplate.tt | 30 ++++++++-------- 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs index a7951ed1..908445bc 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.cs +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -41,7 +41,7 @@ public class App var method = operation.Key.ToString().ToLower(); method = GetHttpMethod(method); - if (method == String.Empty) + if (method == string.Empty) { Console.Error.WriteLine($"Unsupported HTTP method found: '{operation.Key}'"); Environment.Exit(3); @@ -50,7 +50,7 @@ public class App fileProperties[pathString].Add(method, new Dictionary { }); var parameters = operation.Value.Parameters; - string parametersList = String.Empty; + string parametersList = string.Empty; for (int i = 0; i < parameters.Count; i++) { @@ -86,18 +86,23 @@ public class App // so these would later return a default value if (response.Value.Content == null || response.Value.Content.Count == 0) { - returnValue = "Default"; - fileProperties[pathString][method].Add(response.Key, returnValue); + fileProperties[pathString][method].Add(response.Key, null); continue; } var content = response.Value.Content.First().Value; var schema = content.Schema; - if (schema?.Type.ToLower() == "array") + if (schema == null) + { + Console.Error.WriteLine("No schema was found for the response."); + Environment.Exit(3); + } + + if (schema.Type.ToLower() == "array") { returnValue = "new " + GetArrayKeyword(schema) + " {}"; } - else if (schema?.Type.ToLower() == "object") + else if (schema.Type.ToLower() == "object") { returnValue = "new " + schema?.Reference?.Id + "()"; } @@ -160,6 +165,7 @@ public class App var pageContent = page.TransformText(); File.WriteAllText(args[1], pageContent); } + private static string GetSampleValue(IOpenApiAny example, OpenApiSchema? schema) => example switch { OpenApiString castedExample => $"\"{castedExample.Value}\"", @@ -172,6 +178,7 @@ public class App OpenApiNull castedExample => "null", _ => string.Empty }; + private static string GetArrayValues(OpenApiArray example) { int count = example.Count; @@ -187,6 +194,7 @@ public class App } return returnValue; } + private static string GetObjectArguments(OpenApiObject example, OpenApiSchema? schema) { string arguments = $"new {schema?.Reference?.Id}("; @@ -210,8 +218,9 @@ public class App "post" => "MapPost", "put" => "MapPut", "delete" => "MapDelete", - _ => String.Empty + _ => string.Empty }; + private static string GetDataTypeKeyword(OpenApiSchema? schema) => schema?.Type switch { "string" => "string", @@ -219,13 +228,14 @@ public class App "float" => "float", "boolean" => "bool", "double" => "double", - _ => String.Empty + _ => string.Empty }; + private static string GetArrayKeyword(OpenApiSchema? schema) { if (schema == null) { - return String.Empty; + return string.Empty; } string returnValue = "["; while (schema.Items.Type == "array") @@ -239,10 +249,11 @@ public class App } else { - returnValue = GetDataTypeKeyword(schema?.Items) + returnValue + "]"; + returnValue = GetDataTypeKeyword(schema.Items) + returnValue + "]"; } return returnValue; } + private static string GetPrimitiveValue(OpenApiSchema? schema) => schema?.Type switch { "string" => "\"\"", @@ -250,8 +261,9 @@ public class App "boolean" => "false", "float" => "0.0f", "double" => "0.0d", - _ => String.Empty, + _ => string.Empty, }; + private static OpenApiDocument? ReadJson(string args) { if (!Path.IsPathRooted(args)) diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs index 7e20bcb8..1fa0db53 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs @@ -78,7 +78,7 @@ namespace CodeGenerator if (response.Key != "parameters") { StatusCode = response.Key; - if (response.Value == "Default") { + if (response.Value == null) { var statusMethod = StatusCode switch { "202" => "Accepted()", "400" => "BadRequest()", @@ -153,7 +153,7 @@ namespace CodeGenerator #line 82 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var schema in Schemas) { - UserObject = schema.Key; + CustomObject = schema.Key; #line default @@ -161,7 +161,7 @@ namespace CodeGenerator this.Write("public class "); #line 86 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); + this.Write(this.ToStringHelper.ToStringWithCulture(CustomObject)); #line default #line hidden @@ -208,7 +208,7 @@ namespace CodeGenerator this.Write(" public "); #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); + this.Write(this.ToStringHelper.ToStringWithCulture(CustomObject)); #line default #line hidden @@ -249,7 +249,7 @@ namespace CodeGenerator this.Write(" }\r\n public "); #line 113 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(UserObject)); + this.Write(this.ToStringHelper.ToStringWithCulture(CustomObject)); #line default #line hidden @@ -269,17 +269,17 @@ namespace CodeGenerator #line 119 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" public Dictionary>> FileProperties { get; set; } - public string Path { get; set; } - public string Method { get; set; } - public string ReturnValue { get; set; } - public string ParametersList { get; set; } - public string StatusCode { get; set; } + private string Path { get; set; } + private string Method { get; set; } + private string ReturnValue { get; set; } + private string ParametersList { get; set; } + private string StatusCode { get; set; } public Dictionary> Schemas { get; set; } - public string UserObject { get; set; } - public string PropertyName { get; set; } - public string PropertyType { get; set; } - public string ConstructorParameters { get; set; } - public string ConstructorBody { get; set; } + private string CustomObject { get; set; } + private string PropertyName { get; set; } + private string PropertyType { get; set; } + private string ConstructorParameters { get; set; } + private string ConstructorBody { get; set; } #line default diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt index 96b21801..548c89c4 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt @@ -29,7 +29,7 @@ app.<#=Method #>("<#=Path #>", (HttpContext context<#=ParametersList #>) => if (response.Key != "parameters") { StatusCode = response.Key; - if (response.Value == "Default") { + if (response.Value == null) { var statusMethod = StatusCode switch { "202" => "Accepted()", "400" => "BadRequest()", @@ -81,9 +81,9 @@ app.<#=Method #>("<#=Path #>", (HttpContext context<#=ParametersList #>) => <# foreach (var schema in Schemas) { - UserObject = schema.Key; + CustomObject = schema.Key; #> -public class <#=UserObject #> { +public class <#=CustomObject #> { <# string constructorParameters = string.Empty; string constructorBody = string.Empty; @@ -99,7 +99,7 @@ public class <#=UserObject #> { ConstructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); constructorBody = constructorBody.Substring(0, constructorBody.Length - 1); #> - public <#=UserObject #>(<#=ConstructorParameters #>) { + public <#=CustomObject #>(<#=ConstructorParameters #>) { <# var statements = constructorBody.Split("\n"); foreach (var statement in statements) { @@ -110,7 +110,7 @@ public class <#=UserObject #> { } #> } - public <#=UserObject #>() {} + public <#=CustomObject #>() {} } <# } @@ -118,15 +118,15 @@ public class <#=UserObject #> { <#+ public Dictionary>> FileProperties { get; set; } - public string Path { get; set; } - public string Method { get; set; } - public string ReturnValue { get; set; } - public string ParametersList { get; set; } - public string StatusCode { get; set; } + private string Path { get; set; } + private string Method { get; set; } + private string ReturnValue { get; set; } + private string ParametersList { get; set; } + private string StatusCode { get; set; } public Dictionary> Schemas { get; set; } - public string UserObject { get; set; } - public string PropertyName { get; set; } - public string PropertyType { get; set; } - public string ConstructorParameters { get; set; } - public string ConstructorBody { get; set; } + private string CustomObject { get; set; } + private string PropertyName { get; set; } + private string PropertyType { get; set; } + private string ConstructorParameters { get; set; } + private string ConstructorBody { get; set; } #> From 8efa5c952921933216726c874c89e7c6164b6332 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Mon, 8 Aug 2022 14:29:07 -0700 Subject: [PATCH 22/33] changing properties to local variables in T4 template --- .../CodeGenerator/MinimalApiTemplate.cs | 98 +++++++++---------- .../CodeGenerator/MinimalApiTemplate.tt | 62 +++++------- 2 files changed, 70 insertions(+), 90 deletions(-) diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs index 1fa0db53..b19f6b2d 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs @@ -36,14 +36,14 @@ namespace CodeGenerator #line 13 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var path in FileProperties) { - Path = path.Key; - foreach (var operation in FileProperties[Path]) { - Method = operation.Key; + var pathValue = path.Key; + foreach (var operation in FileProperties[pathValue]) { + var method = operation.Key; - ParametersList = operation.Value["parameters"]; + var parameterList = operation.Value["parameters"]; - if (ParametersList != String.Empty) { - ParametersList = ", " + ParametersList; + if (parameterList != String.Empty) { + parameterList = ", " + parameterList; } @@ -52,21 +52,21 @@ namespace CodeGenerator this.Write("app."); #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(Method)); + this.Write(this.ToStringHelper.ToStringWithCulture(method)); #line default #line hidden this.Write("(\""); #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(Path)); + this.Write(this.ToStringHelper.ToStringWithCulture(pathValue)); #line default #line hidden this.Write("\", (HttpContext context"); #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ParametersList)); + this.Write(this.ToStringHelper.ToStringWithCulture(parameterList)); #line default #line hidden @@ -75,11 +75,12 @@ namespace CodeGenerator #line 27 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var response in operation.Value) { - + string returnValue; + string statusCode; if (response.Key != "parameters") { - StatusCode = response.Key; + statusCode = response.Key; if (response.Value == null) { - var statusMethod = StatusCode switch { + var statusMethod = statusCode switch { "202" => "Accepted()", "400" => "BadRequest()", "409" => "Conflict()", @@ -90,10 +91,10 @@ namespace CodeGenerator "422" => "UnprocessableEntity()", _ => $"StatusCode({response.Key})" }; - ReturnValue = $"Results.{statusMethod}"; + returnValue = $"Results.{statusMethod}"; } else { - var statusMethod = StatusCode switch { + var statusMethod = statusCode switch { "202" => $"Accepted(_, {response.Value})", "400" => $"BadRequest({response.Value})", "409" => $"Conflict({response.Value})", @@ -104,7 +105,7 @@ namespace CodeGenerator "422" => $"UnprocessableEntity({response.Value})", _ => $"StatusCode({response.Key})" }; - ReturnValue = $"Results.{statusMethod}"; + returnValue = $"Results.{statusMethod}"; } } @@ -117,21 +118,21 @@ namespace CodeGenerator #line hidden this.Write(" if (context.Request.Headers[\"AcceptStatusCode\"] == \""); - #line 66 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(StatusCode)); + #line 67 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(statusCode)); #line default #line hidden this.Write("\")\r\n {\r\n return "); - #line 68 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ReturnValue)); + #line 69 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(returnValue)); #line default #line hidden this.Write(";\r\n }\r\n\r\n"); - #line 71 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 72 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -140,7 +141,7 @@ namespace CodeGenerator #line hidden this.Write(" return null;\r\n});\r\n\r\n"); - #line 77 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 78 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } } @@ -150,56 +151,56 @@ namespace CodeGenerator #line hidden this.Write("\r\n"); - #line 82 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 83 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var schema in Schemas) { - CustomObject = schema.Key; + var customObject = schema.Key; #line default #line hidden this.Write("public class "); - #line 86 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(CustomObject)); + #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(customObject)); #line default #line hidden this.Write(" {\r\n"); - #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 88 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" string constructorParameters = string.Empty; string constructorBody = string.Empty; foreach (var property in schema.Value) { - PropertyName = property.Key; - PropertyType = property.Value; - constructorParameters += PropertyType + "? " + PropertyName + ", "; - constructorBody += $"this.{PropertyName} = {PropertyName}\n"; + var propertyName = property.Key; + var propertyType = property.Value; + constructorParameters += propertyType + "? " + propertyName + ", "; + constructorBody += $"this.{propertyName} = {propertyName}\n"; #line default #line hidden this.Write(" public "); - #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(PropertyType)); + #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(propertyType)); #line default #line hidden this.Write("? "); - #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(PropertyName)); + #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); #line default #line hidden this.Write(" { get; set; }\r\n"); - #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 98 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } - ConstructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); + constructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); constructorBody = constructorBody.Substring(0, constructorBody.Length - 1); @@ -207,25 +208,24 @@ namespace CodeGenerator #line hidden this.Write(" public "); - #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(CustomObject)); + #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(customObject)); #line default #line hidden this.Write("("); - #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorParameters)); + #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + this.Write(this.ToStringHelper.ToStringWithCulture(constructorParameters)); #line default #line hidden this.Write(") {\r\n"); - #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 104 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" var statements = constructorBody.Split("\n"); foreach (var statement in statements) { - ConstructorBody = statement; #line default @@ -233,7 +233,7 @@ namespace CodeGenerator this.Write(" "); #line 108 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ConstructorBody)); + this.Write(this.ToStringHelper.ToStringWithCulture(statement)); #line default #line hidden @@ -249,7 +249,7 @@ namespace CodeGenerator this.Write(" }\r\n public "); #line 113 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(CustomObject)); + this.Write(this.ToStringHelper.ToStringWithCulture(customObject)); #line default #line hidden @@ -269,17 +269,7 @@ namespace CodeGenerator #line 119 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" public Dictionary>> FileProperties { get; set; } - private string Path { get; set; } - private string Method { get; set; } - private string ReturnValue { get; set; } - private string ParametersList { get; set; } - private string StatusCode { get; set; } public Dictionary> Schemas { get; set; } - private string CustomObject { get; set; } - private string PropertyName { get; set; } - private string PropertyType { get; set; } - private string ConstructorParameters { get; set; } - private string ConstructorBody { get; set; } #line default diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt index 548c89c4..259d4e40 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt @@ -12,25 +12,26 @@ var app = builder.Build(); <# foreach (var path in FileProperties) { - Path = path.Key; - foreach (var operation in FileProperties[Path]) { - Method = operation.Key; + var pathValue = path.Key; + foreach (var operation in FileProperties[pathValue]) { + var method = operation.Key; - ParametersList = operation.Value["parameters"]; + var parameterList = operation.Value["parameters"]; - if (ParametersList != String.Empty) { - ParametersList = ", " + ParametersList; + if (parameterList != String.Empty) { + parameterList = ", " + parameterList; } #> -app.<#=Method #>("<#=Path #>", (HttpContext context<#=ParametersList #>) => +app.<#=method #>("<#=pathValue #>", (HttpContext context<#=parameterList #>) => { <# foreach (var response in operation.Value) { if (response.Key != "parameters") { - StatusCode = response.Key; + var statusCode = response.Key; + string returnValue; if (response.Value == null) { - var statusMethod = StatusCode switch { + var statusMethod = statusCode switch { "202" => "Accepted()", "400" => "BadRequest()", "409" => "Conflict()", @@ -41,10 +42,10 @@ app.<#=Method #>("<#=Path #>", (HttpContext context<#=ParametersList #>) => "422" => "UnprocessableEntity()", _ => $"StatusCode({response.Key})" }; - ReturnValue = $"Results.{statusMethod}"; + returnValue = $"Results.{statusMethod}"; } else { - var statusMethod = StatusCode switch { + var statusMethod = statusCode switch { "202" => $"Accepted(_, {response.Value})", "400" => $"BadRequest({response.Value})", "409" => $"Conflict({response.Value})", @@ -55,7 +56,7 @@ app.<#=Method #>("<#=Path #>", (HttpContext context<#=ParametersList #>) => "422" => $"UnprocessableEntity({response.Value})", _ => $"StatusCode({response.Key})" }; - ReturnValue = $"Results.{statusMethod}"; + returnValue = $"Results.{statusMethod}"; } } @@ -63,9 +64,9 @@ app.<#=Method #>("<#=Path #>", (HttpContext context<#=ParametersList #>) => continue; } #> - if (context.Request.Headers["AcceptStatusCode"] == "<#=StatusCode #>") + if (context.Request.Headers["AcceptStatusCode"] == "<#=statusCode #>") { - return <#=ReturnValue #>; + return <#=returnValue #>; } <# @@ -81,36 +82,35 @@ app.<#=Method #>("<#=Path #>", (HttpContext context<#=ParametersList #>) => <# foreach (var schema in Schemas) { - CustomObject = schema.Key; + var customObject = schema.Key; #> -public class <#=CustomObject #> { +public class <#=customObject #> { <# string constructorParameters = string.Empty; string constructorBody = string.Empty; foreach (var property in schema.Value) { - PropertyName = property.Key; - PropertyType = property.Value; - constructorParameters += PropertyType + "? " + PropertyName + ", "; - constructorBody += $"this.{PropertyName} = {PropertyName}\n"; + var propertyName = property.Key; + var propertyType = property.Value; + constructorParameters += propertyType + "? " + propertyName + ", "; + constructorBody += $"this.{propertyName} = {propertyName}\n"; #> - public <#=PropertyType #>? <#=PropertyName #> { get; set; } + public <#=propertyType #>? <#=propertyName #> { get; set; } <# } - ConstructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); + constructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); constructorBody = constructorBody.Substring(0, constructorBody.Length - 1); #> - public <#=CustomObject #>(<#=ConstructorParameters #>) { + public <#=customObject #>(<#=constructorParameters #>) { <# var statements = constructorBody.Split("\n"); foreach (var statement in statements) { - ConstructorBody = statement; #> - <#=ConstructorBody #>; + <#=statement #>; <# } #> } - public <#=CustomObject #>() {} + public <#=customObject #>() {} } <# } @@ -118,15 +118,5 @@ public class <#=CustomObject #> { <#+ public Dictionary>> FileProperties { get; set; } - private string Path { get; set; } - private string Method { get; set; } - private string ReturnValue { get; set; } - private string ParametersList { get; set; } - private string StatusCode { get; set; } public Dictionary> Schemas { get; set; } - private string CustomObject { get; set; } - private string PropertyName { get; set; } - private string PropertyType { get; set; } - private string ConstructorParameters { get; set; } - private string ConstructorBody { get; set; } #> From b608b49e5a74203a16ba79fc3c48ac5cc2b29f92 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Tue, 9 Aug 2022 11:06:44 -0700 Subject: [PATCH 23/33] remove unused namespaces --- .../CodeGenerator/MinimalApiTemplate.cs | 53 +++++++++---------- .../CodeGenerator/MinimalApiTemplate.tt | 13 ++--- 2 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs index b19f6b2d..89141189 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs @@ -9,11 +9,6 @@ // ------------------------------------------------------------------------------ namespace CodeGenerator { - using System.Linq; - using System.Text; - using System.Collections.Generic; - using System.Reflection; - using Microsoft.VisualStudio.TextTemplating; using System; /// @@ -33,7 +28,7 @@ namespace CodeGenerator this.Write("var builder = WebApplication.CreateBuilder(args);\r\nvar app = builder.Build();\r\n\r\n" + ""); - #line 13 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 6 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var path in FileProperties) { var pathValue = path.Key; @@ -51,32 +46,32 @@ namespace CodeGenerator #line hidden this.Write("app."); - #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(method)); #line default #line hidden this.Write("(\""); - #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(pathValue)); #line default #line hidden this.Write("\", (HttpContext context"); - #line 25 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parameterList)); #line default #line hidden this.Write(") =>\r\n{\r\n"); - #line 27 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 20 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var response in operation.Value) { - string returnValue; string statusCode; + string returnValue; if (response.Key != "parameters") { statusCode = response.Key; if (response.Value == null) { @@ -118,21 +113,21 @@ namespace CodeGenerator #line hidden this.Write(" if (context.Request.Headers[\"AcceptStatusCode\"] == \""); - #line 67 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 60 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(statusCode)); #line default #line hidden this.Write("\")\r\n {\r\n return "); - #line 69 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 62 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(returnValue)); #line default #line hidden this.Write(";\r\n }\r\n\r\n"); - #line 72 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 65 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -141,7 +136,7 @@ namespace CodeGenerator #line hidden this.Write(" return null;\r\n});\r\n\r\n"); - #line 78 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 71 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } } @@ -151,7 +146,7 @@ namespace CodeGenerator #line hidden this.Write("\r\n"); - #line 83 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 76 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" foreach (var schema in Schemas) { var customObject = schema.Key; @@ -161,14 +156,14 @@ namespace CodeGenerator #line hidden this.Write("public class "); - #line 87 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 80 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(customObject)); #line default #line hidden this.Write(" {\r\n"); - #line 88 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 81 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" string constructorParameters = string.Empty; string constructorBody = string.Empty; @@ -183,21 +178,21 @@ namespace CodeGenerator #line hidden this.Write(" public "); - #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 90 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(propertyType)); #line default #line hidden this.Write("? "); - #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 90 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); #line default #line hidden this.Write(" { get; set; }\r\n"); - #line 98 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 91 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } constructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); @@ -208,21 +203,21 @@ namespace CodeGenerator #line hidden this.Write(" public "); - #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(customObject)); #line default #line hidden this.Write("("); - #line 103 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(constructorParameters)); #line default #line hidden this.Write(") {\r\n"); - #line 104 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" var statements = constructorBody.Split("\n"); foreach (var statement in statements) { @@ -232,14 +227,14 @@ namespace CodeGenerator #line hidden this.Write(" "); - #line 108 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 101 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(statement)); #line default #line hidden this.Write(";\r\n"); - #line 109 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -248,14 +243,14 @@ namespace CodeGenerator #line hidden this.Write(" }\r\n public "); - #line 113 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 106 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" this.Write(this.ToStringHelper.ToStringWithCulture(customObject)); #line default #line hidden this.Write("() {}\r\n}\r\n"); - #line 115 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 108 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" } @@ -266,7 +261,7 @@ namespace CodeGenerator return this.GenerationEnvironment.ToString(); } - #line 119 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" + #line 112 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" public Dictionary>> FileProperties { get; set; } public Dictionary> Schemas { get; set; } diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt index 259d4e40..c9487482 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt @@ -1,12 +1,5 @@ <#@ template language="C#" #> -<#@ assembly name="System.Core" #> -<#@ assembly name="System.Reflection" #> <#@ assembly name="mscorlib" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ import namespace="System.Reflection" #> -<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); @@ -26,10 +19,10 @@ app.<#=method #>("<#=pathValue #>", (HttpContext context<#=parameterList #>) => { <# foreach (var response in operation.Value) { - + string statusCode; + string returnValue; if (response.Key != "parameters") { - var statusCode = response.Key; - string returnValue; + statusCode = response.Key; if (response.Value == null) { var statusMethod = statusCode switch { "202" => "Accepted()", From 4429f6df1e13c89c663ff86f3eb84d7a0ad415f8 Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Tue, 9 Aug 2022 14:26:33 -0700 Subject: [PATCH 24/33] update to have nullable dictionary --- src/OpenApi/CodeGenerator/CodeGenerator.cs | 7 ++++--- src/OpenApi/CodeGenerator/MinimalApiTemplate.cs | 4 +++- src/OpenApi/CodeGenerator/MinimalApiTemplate.tt | 4 +++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.cs b/src/OpenApi/CodeGenerator/CodeGenerator.cs index 908445bc..678a176d 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.cs +++ b/src/OpenApi/CodeGenerator/CodeGenerator.cs @@ -23,7 +23,7 @@ public class App Environment.Exit(2); // Code 2 is for problems with paths in schema } - var fileProperties = new Dictionary>>(); + var fileProperties = new Dictionary>>(); foreach (var path in paths) { @@ -34,8 +34,9 @@ public class App Environment.Exit(3); // Code 3 is for problems with operations } var pathString = path.Key.ToString(); - fileProperties.Add(pathString, new Dictionary> { }); + fileProperties.Add(pathString, new Dictionary> ()); + var dict = new Dictionary> (); foreach (var operation in operations) { var method = operation.Key.ToString().ToLower(); @@ -47,7 +48,7 @@ public class App Environment.Exit(3); } - fileProperties[pathString].Add(method, new Dictionary { }); + fileProperties[pathString].Add(method, new Dictionary ()); var parameters = operation.Value.Parameters; string parametersList = string.Empty; diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs index 89141189..35d7d2cc 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs @@ -263,7 +263,9 @@ namespace CodeGenerator #line 112 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - public Dictionary>> FileProperties { get; set; } +#nullable enable + public Dictionary>>? FileProperties { get; set; } +#nullable disable public Dictionary> Schemas { get; set; } diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt index c9487482..dca6d64a 100644 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt +++ b/src/OpenApi/CodeGenerator/MinimalApiTemplate.tt @@ -110,6 +110,8 @@ public class <#=customObject #> { #> <#+ - public Dictionary>> FileProperties { get; set; } +#nullable enable + public Dictionary>>? FileProperties { get; set; } +#nullable disable public Dictionary> Schemas { get; set; } #> From 6e6257e0e62832aafc154c2311632515c0e7ab0d Mon Sep 17 00:00:00 2001 From: Anh Thi Dao Date: Wed, 10 Aug 2022 10:23:12 -0700 Subject: [PATCH 25/33] include dependencies --- .../CodeGenerator/CodeGenerator.csproj | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/OpenApi/CodeGenerator/CodeGenerator.csproj b/src/OpenApi/CodeGenerator/CodeGenerator.csproj index 5999668e..c4f64ab7 100644 --- a/src/OpenApi/CodeGenerator/CodeGenerator.csproj +++ b/src/OpenApi/CodeGenerator/CodeGenerator.csproj @@ -1,4 +1,4 @@ - + Exe @@ -7,9 +7,30 @@ enable + + + TextTemplatingFilePreprocessor + MinimalApiTemplate.cs + + + + + + + + + + + + + + True + True + MinimalApiTemplate.tt + From 52f828e26c039d0a5653491e0ec98840d9c55848 Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 10 Aug 2022 10:25:09 -0700 Subject: [PATCH 26/33] Delete MinimalApiTemplate.cs --- .../CodeGenerator/MinimalApiTemplate.cs | 550 ------------------ 1 file changed, 550 deletions(-) delete mode 100644 src/OpenApi/CodeGenerator/MinimalApiTemplate.cs diff --git a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs b/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs deleted file mode 100644 index 35d7d2cc..00000000 --- a/src/OpenApi/CodeGenerator/MinimalApiTemplate.cs +++ /dev/null @@ -1,550 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version: 17.0.0.0 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -// ------------------------------------------------------------------------------ -namespace CodeGenerator -{ - using System; - - /// - /// Class to produce the template output - /// - - #line 1 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] - public partial class MinimalApiTemplate : MinimalApiTemplateBase - { -#line hidden - /// - /// Create the template output - /// - public virtual string TransformText() - { - this.Write("var builder = WebApplication.CreateBuilder(args);\r\nvar app = builder.Build();\r\n\r\n" + - ""); - - #line 6 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - foreach (var path in FileProperties) { - var pathValue = path.Key; - foreach (var operation in FileProperties[pathValue]) { - var method = operation.Key; - - var parameterList = operation.Value["parameters"]; - - if (parameterList != String.Empty) { - parameterList = ", " + parameterList; - } - - - #line default - #line hidden - this.Write("app."); - - #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(method)); - - #line default - #line hidden - this.Write("(\""); - - #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(pathValue)); - - #line default - #line hidden - this.Write("\", (HttpContext context"); - - #line 18 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(parameterList)); - - #line default - #line hidden - this.Write(") =>\r\n{\r\n"); - - #line 20 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - foreach (var response in operation.Value) { - string statusCode; - string returnValue; - if (response.Key != "parameters") { - statusCode = response.Key; - if (response.Value == null) { - var statusMethod = statusCode switch { - "202" => "Accepted()", - "400" => "BadRequest()", - "409" => "Conflict()", - "204" => "NoContent()", - "404" => "NotFound()", - "200" => "Ok()", - "401" => "Unauthorized()", - "422" => "UnprocessableEntity()", - _ => $"StatusCode({response.Key})" - }; - returnValue = $"Results.{statusMethod}"; - } - else { - var statusMethod = statusCode switch { - "202" => $"Accepted(_, {response.Value})", - "400" => $"BadRequest({response.Value})", - "409" => $"Conflict({response.Value})", - "204" => "NoContent()", - "404" => $"NotFound({response.Value})", - "200" => $"Ok({response.Value})", - "401" => "Unauthorized()", - "422" => $"UnprocessableEntity({response.Value})", - _ => $"StatusCode({response.Key})" - }; - returnValue = $"Results.{statusMethod}"; - } - - } - else { - continue; - } - - - #line default - #line hidden - this.Write(" if (context.Request.Headers[\"AcceptStatusCode\"] == \""); - - #line 60 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(statusCode)); - - #line default - #line hidden - this.Write("\")\r\n {\r\n return "); - - #line 62 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(returnValue)); - - #line default - #line hidden - this.Write(";\r\n }\r\n\r\n"); - - #line 65 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - } - - - #line default - #line hidden - this.Write(" return null;\r\n});\r\n\r\n"); - - #line 71 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - } - } - - - #line default - #line hidden - this.Write("\r\n"); - - #line 76 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - foreach (var schema in Schemas) { - var customObject = schema.Key; - - - #line default - #line hidden - this.Write("public class "); - - #line 80 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(customObject)); - - #line default - #line hidden - this.Write(" {\r\n"); - - #line 81 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - string constructorParameters = string.Empty; - string constructorBody = string.Empty; - foreach (var property in schema.Value) { - var propertyName = property.Key; - var propertyType = property.Value; - constructorParameters += propertyType + "? " + propertyName + ", "; - constructorBody += $"this.{propertyName} = {propertyName}\n"; - - - #line default - #line hidden - this.Write(" public "); - - #line 90 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(propertyType)); - - #line default - #line hidden - this.Write("? "); - - #line 90 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(propertyName)); - - #line default - #line hidden - this.Write(" { get; set; }\r\n"); - - #line 91 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - } - constructorParameters = constructorParameters.Substring(0, constructorParameters.Length - 2); - constructorBody = constructorBody.Substring(0, constructorBody.Length - 1); - - - #line default - #line hidden - this.Write(" public "); - - #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(customObject)); - - #line default - #line hidden - this.Write("("); - - #line 96 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(constructorParameters)); - - #line default - #line hidden - this.Write(") {\r\n"); - - #line 97 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - var statements = constructorBody.Split("\n"); - foreach (var statement in statements) { - - - #line default - #line hidden - this.Write(" "); - - #line 101 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(statement)); - - #line default - #line hidden - this.Write(";\r\n"); - - #line 102 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - } - - - #line default - #line hidden - this.Write(" }\r\n public "); - - #line 106 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(customObject)); - - #line default - #line hidden - this.Write("() {}\r\n}\r\n"); - - #line 108 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - - } - - - #line default - #line hidden - this.Write("\r\n"); - return this.GenerationEnvironment.ToString(); - } - - #line 112 "C:\Users\AnhThiDao\AspLabs\src\OpenAPI\CodeGenerator\MinimalApiTemplate.tt" - -#nullable enable - public Dictionary>>? FileProperties { get; set; } -#nullable disable - public Dictionary> Schemas { get; set; } - - - #line default - #line hidden - } - - #line default - #line hidden - #region Base class - /// - /// Base class for this transformation - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "17.0.0.0")] - public class MinimalApiTemplateBase - { - #region Fields - private global::System.Text.StringBuilder generationEnvironmentField; - private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; - private global::System.Collections.Generic.List indentLengthsField; - private string currentIndentField = ""; - private bool endsWithNewline; - private global::System.Collections.Generic.IDictionary sessionField; - #endregion - #region Properties - /// - /// The string builder that generation-time code is using to assemble generated output - /// - protected System.Text.StringBuilder GenerationEnvironment - { - get - { - if ((this.generationEnvironmentField == null)) - { - this.generationEnvironmentField = new global::System.Text.StringBuilder(); - } - return this.generationEnvironmentField; - } - set - { - this.generationEnvironmentField = value; - } - } - /// - /// The error collection for the generation process - /// - public System.CodeDom.Compiler.CompilerErrorCollection Errors - { - get - { - if ((this.errorsField == null)) - { - this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); - } - return this.errorsField; - } - } - /// - /// A list of the lengths of each indent that was added with PushIndent - /// - private System.Collections.Generic.List indentLengths - { - get - { - if ((this.indentLengthsField == null)) - { - this.indentLengthsField = new global::System.Collections.Generic.List(); - } - return this.indentLengthsField; - } - } - /// - /// Gets the current indent we use when adding lines to the output - /// - public string CurrentIndent - { - get - { - return this.currentIndentField; - } - } - /// - /// Current transformation session - /// - public virtual global::System.Collections.Generic.IDictionary Session - { - get - { - return this.sessionField; - } - set - { - this.sessionField = value; - } - } - #endregion - #region Transform-time helpers - /// - /// Write text directly into the generated output - /// - public void Write(string textToAppend) - { - if (string.IsNullOrEmpty(textToAppend)) - { - return; - } - // If we're starting off, or if the previous text ended with a newline, - // we have to append the current indent first. - if (((this.GenerationEnvironment.Length == 0) - || this.endsWithNewline)) - { - this.GenerationEnvironment.Append(this.currentIndentField); - this.endsWithNewline = false; - } - // Check if the current text ends with a newline - if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) - { - this.endsWithNewline = true; - } - // This is an optimization. If the current indent is "", then we don't have to do any - // of the more complex stuff further down. - if ((this.currentIndentField.Length == 0)) - { - this.GenerationEnvironment.Append(textToAppend); - return; - } - // Everywhere there is a newline in the text, add an indent after it - textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); - // If the text ends with a newline, then we should strip off the indent added at the very end - // because the appropriate indent will be added when the next time Write() is called - if (this.endsWithNewline) - { - this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); - } - else - { - this.GenerationEnvironment.Append(textToAppend); - } - } - /// - /// Write text directly into the generated output - /// - public void WriteLine(string textToAppend) - { - this.Write(textToAppend); - this.GenerationEnvironment.AppendLine(); - this.endsWithNewline = true; - } - /// - /// Write formatted text directly into the generated output - /// - public void Write(string format, params object[] args) - { - this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Write formatted text directly into the generated output - /// - public void WriteLine(string format, params object[] args) - { - this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Raise an error - /// - public void Error(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - this.Errors.Add(error); - } - /// - /// Raise a warning - /// - public void Warning(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - error.IsWarning = true; - this.Errors.Add(error); - } - /// - /// Increase the indent - /// - public void PushIndent(string indent) - { - if ((indent == null)) - { - throw new global::System.ArgumentNullException("indent"); - } - this.currentIndentField = (this.currentIndentField + indent); - this.indentLengths.Add(indent.Length); - } - /// - /// Remove the last indent that was added with PushIndent - /// - public string PopIndent() - { - string returnValue = ""; - if ((this.indentLengths.Count > 0)) - { - int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; - this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); - if ((indentLength > 0)) - { - returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); - this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); - } - } - return returnValue; - } - /// - /// Remove any indentation - /// - public void ClearIndent() - { - this.indentLengths.Clear(); - this.currentIndentField = ""; - } - #endregion - #region ToString Helpers - /// - /// Utility class to produce culture-oriented representation of an object as a string. - /// - public class ToStringInstanceHelper - { - private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; - /// - /// Gets or sets format provider to be used by ToStringWithCulture method. - /// - public System.IFormatProvider FormatProvider - { - get - { - return this.formatProviderField ; - } - set - { - if ((value != null)) - { - this.formatProviderField = value; - } - } - } - /// - /// This is called from the compile/run appdomain to convert objects within an expression block to a string - /// - public string ToStringWithCulture(object objectToConvert) - { - if ((objectToConvert == null)) - { - throw new global::System.ArgumentNullException("objectToConvert"); - } - System.Type t = objectToConvert.GetType(); - System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { - typeof(System.IFormatProvider)}); - if ((method == null)) - { - return objectToConvert.ToString(); - } - else - { - return ((string)(method.Invoke(objectToConvert, new object[] { - this.formatProviderField }))); - } - } - } - private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); - /// - /// Helper to produce culture-oriented representation of an object as a string - /// - public ToStringInstanceHelper ToStringHelper - { - get - { - return this.toStringHelperField; - } - } - #endregion - } - #endregion -} From 8faba87352845265ffc9260bf7851935bc549ff3 Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 10 Aug 2022 10:27:58 -0700 Subject: [PATCH 27/33] Delete Program.cs --- src/OpenApi/CodeGenerator/Program.cs | 57 ---------------------------- 1 file changed, 57 deletions(-) delete mode 100644 src/OpenApi/CodeGenerator/Program.cs diff --git a/src/OpenApi/CodeGenerator/Program.cs b/src/OpenApi/CodeGenerator/Program.cs deleted file mode 100644 index 7aaedb4e..00000000 --- a/src/OpenApi/CodeGenerator/Program.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Microsoft.OpenApi.Models; -using Microsoft.OpenApi.Readers; - -public class App -{ - public static void Main(string[] args) - { - new App().ReadJson(args); - } - - private void ReadJson(string[] args) - { - string inputPath = args[0]; - - if (!Path.IsPathRooted(inputPath)) - { - Console.WriteLine("The file path you entered does not have a root"); - return; - } - - OpenApiStreamReader reader = new OpenApiStreamReader(); - var diagnostic = new OpenApiDiagnostic(); - - try - { - string path = Path.GetFullPath(inputPath); - Stream stream = File.OpenRead(path); - OpenApiDocument newDocument = reader.Read(stream, out diagnostic); - } - catch (FileNotFoundException e) - { - Console.WriteLine("Check to make sure you entered a correct file path because the file was not found."); - Console.Error.WriteLine(e.Message); - return; - } - catch(Exception e) - { - Console.WriteLine("Check the file path you entered for errors."); - Console.Error.WriteLine(e.Message); - return; - } - - if (diagnostic.Errors.Count == 0) - { - Console.WriteLine("Read File Successfully"); - } - else - { - foreach (OpenApiError error in diagnostic.Errors) - { - Console.WriteLine($"There was an error reading in the file at {error.Pointer}"); - Console.Error.WriteLine(error.Message); - } - } - } - -} From 7613597e487d4d7f0b21e65128b8f868297e8470 Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 10 Aug 2022 10:35:49 -0700 Subject: [PATCH 28/33] Add files via upload --- ...or doc 1adc13dd00724365a43994e106be4eba.md | 234 ++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 src/OpenApi/Code Generator doc 1adc13dd00724365a43994e106be4eba.md diff --git a/src/OpenApi/Code Generator doc 1adc13dd00724365a43994e106be4eba.md b/src/OpenApi/Code Generator doc 1adc13dd00724365a43994e106be4eba.md new file mode 100644 index 00000000..52aa55fe --- /dev/null +++ b/src/OpenApi/Code Generator doc 1adc13dd00724365a43994e106be4eba.md @@ -0,0 +1,234 @@ +# Code Generator doc + +Created: August 9, 2022 10:23 AM +Last Edited Time: August 10, 2022 10:30 AM + +# Overview 🖥️ + +This is a CLI tool that generates the server side API route handler code in Minimal API from an Open API spec. + +Some possible use cases for this tool are testing and validating API contracts, including mocking for a single service and performing UI integration tests with the generated mock server. This tool can also be used to facilitate decoupled development. + +# How to use the tool 🔨 + +In order for the tool to work, there are a couple of steps we must take to properly set up the environment. + +We must create the `MinimalApiTemplate.cs` file which will be created in design time by the `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` file. In order to do this: + +1. Open the `OpenApi.sln` file on VS. +2. Right click on the `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` and select `Properties` . +3. Change the `Build Action` property to `Content` and the `Custom Tool` property to `TextTemplatingFilePreprocessor` . +4. After doing this you should be able to right click the `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` file and select `Run Custom Tool` . +5. This will generate the `MinimalApiTemplate.cs` file which will be responsible for writing the code to the output file. + +At this point, the tool is ready for use, and can be executed with the following command: + +`dotnet run ` + +### Arguments + +`` corresponds to the file path of the json file containing the Open API documentation. + +`` is the path where the output file will be created. + +## Constraints + +`` has to be a valid path to .json file. + +`` has to be a valid path to .cs file. If a file path for an existing file is passed, the existing file will be overwritten. + +# Implementation ⚙️ + +## Logic + +Inside of the `CodeGenerator.cs` file, the `OpenApi.Reader` package is used to read the Open Api spec into an `OpenApiDocument` . + +Then , parse the properties of `OpenApiDocument` (paths, HTTP methods, arguments, schemas, etc) into two dictionaries- `fileProperties` and `schemaDict` . + +Both of these dictionaries are passed onto `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` , which is the T4 template with the code generation pattern. + +The T4 template iterates through the dictionaries and uses the values to write the code pattern for the route handlers. The `MinimalApiTemplate.cs` file generated by + +the T4 template during design time contains the method `TranformText()` that is used to produce the output code as a string value. + +## Dependencies + +- Microsoft.OpenApi (1.3.2) +- Microsoft.OpenApi.Reader (1.3.2) +- System.CodeDom (6.0.0) +- Microsoft.VisualStudio.TextTemplating.15.0 + +# Sample + +## Input + +```json +"openapi": "3.0.2", + "info": { + "title": "Swagger Petstore - OpenAPI 3.0", + "description": "This is a sample server", + "version": "1.0.11" + }, + "externalDocs": { + "description": "Find out more about Swagger", + "url": "http://swagger.io" + }, + "servers": [ + { + "url": "/api/v3" + } + ], + "tags": [ + { + "name": "pet", + "description": "Everything about your Pets", + "externalDocs": { + "description": "Find out more", + "url": "http://swagger.io" + } + }, + { + "name": "store", + "description": "Access to Petstore orders", + "externalDocs": { + "description": "Find out more about our store", + "url": "http://swagger.io" + } + }, + { + "name": "user", + "description": "Operations about user" + } + ], + "paths": { + "/": { + "get": { + "tags": [ + "store" + ], + "summary": "Welcome message", + "description": "Write the welcome message", + "operationId": "welcomeUser", + "responses": { + "200": { + "description": "Successful operation", + "content": { + "text/plain": { + "schema": { + "type": "string" + }, + "example": "Welcome to the store!" + } + } + } + } + } + }, + "/pet": { + "put": { + "tags": [ + "pet" + ], + "summary": "Update an existing pet", + "description": "Update an existing pet by Id", + "operationId": "updatePet", + "requestBody": { + "description": "Update an existent pet in the store", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pet" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pet" + }, + "example": { + "id": 56, + "name": "Max", + "category": { + "id": 56, + "name": "Max" + }, + "photoUrls": [ + "http://samplelink.com/image1", + "http://samplelink.com/image2" + ], + "tags": null, + "status": "available" + } + } + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + }, + "405": { + "description": "Validation exception" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } +``` + +## Output + +```csharp +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); + +app.MapGet("/", (HttpContext context) => +{ + if (context.Request.Headers["AcceptStatusCode"] == "200") + { + return Results.Ok("Welcome to the store!"); + } + + return null; +}); + +app.MapPut("/pet", (HttpContext context) => +{ + if (context.Request.Headers["AcceptStatusCode"] == "200") + { + return Results.Ok(new Pet(56, "Max", new Category(56, "Max"), new [] {"http://samplelink.com/image1", "http://samplelink.com/image2"}, null, "available")); + } + + if (context.Request.Headers["AcceptStatusCode"] == "400") + { + return Results.BadRequest(); + } + + if (context.Request.Headers["AcceptStatusCode"] == "404") + { + return Results.NotFound(); + } + + if (context.Request.Headers["AcceptStatusCode"] == "405") + { + return Results.StatusCode(405); + } + + return null; +}); +``` + +# Additional Notes 📒 \ No newline at end of file From f36b8526124fb719095e1a3aa4ba243396b624dd Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 10 Aug 2022 10:36:42 -0700 Subject: [PATCH 29/33] Rename Code Generator doc 1adc13dd00724365a43994e106be4eba.md to Code Generator Doc --- ...c 1adc13dd00724365a43994e106be4eba.md => Code Generator Doc} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/OpenApi/{Code Generator doc 1adc13dd00724365a43994e106be4eba.md => Code Generator Doc} (99%) diff --git a/src/OpenApi/Code Generator doc 1adc13dd00724365a43994e106be4eba.md b/src/OpenApi/Code Generator Doc similarity index 99% rename from src/OpenApi/Code Generator doc 1adc13dd00724365a43994e106be4eba.md rename to src/OpenApi/Code Generator Doc index 52aa55fe..7ec77025 100644 --- a/src/OpenApi/Code Generator doc 1adc13dd00724365a43994e106be4eba.md +++ b/src/OpenApi/Code Generator Doc @@ -231,4 +231,4 @@ app.MapPut("/pet", (HttpContext context) => }); ``` -# Additional Notes 📒 \ No newline at end of file +# Additional Notes 📒 From 98a208c5758e40215f69cb12a9194931fe7a017e Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 10 Aug 2022 10:37:12 -0700 Subject: [PATCH 30/33] Delete Code Generator Doc --- src/OpenApi/Code Generator Doc | 234 --------------------------------- 1 file changed, 234 deletions(-) delete mode 100644 src/OpenApi/Code Generator Doc diff --git a/src/OpenApi/Code Generator Doc b/src/OpenApi/Code Generator Doc deleted file mode 100644 index 7ec77025..00000000 --- a/src/OpenApi/Code Generator Doc +++ /dev/null @@ -1,234 +0,0 @@ -# Code Generator doc - -Created: August 9, 2022 10:23 AM -Last Edited Time: August 10, 2022 10:30 AM - -# Overview 🖥️ - -This is a CLI tool that generates the server side API route handler code in Minimal API from an Open API spec. - -Some possible use cases for this tool are testing and validating API contracts, including mocking for a single service and performing UI integration tests with the generated mock server. This tool can also be used to facilitate decoupled development. - -# How to use the tool 🔨 - -In order for the tool to work, there are a couple of steps we must take to properly set up the environment. - -We must create the `MinimalApiTemplate.cs` file which will be created in design time by the `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` file. In order to do this: - -1. Open the `OpenApi.sln` file on VS. -2. Right click on the `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` and select `Properties` . -3. Change the `Build Action` property to `Content` and the `Custom Tool` property to `TextTemplatingFilePreprocessor` . -4. After doing this you should be able to right click the `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` file and select `Run Custom Tool` . -5. This will generate the `MinimalApiTemplate.cs` file which will be responsible for writing the code to the output file. - -At this point, the tool is ready for use, and can be executed with the following command: - -`dotnet run ` - -### Arguments - -`` corresponds to the file path of the json file containing the Open API documentation. - -`` is the path where the output file will be created. - -## Constraints - -`` has to be a valid path to .json file. - -`` has to be a valid path to .cs file. If a file path for an existing file is passed, the existing file will be overwritten. - -# Implementation ⚙️ - -## Logic - -Inside of the `CodeGenerator.cs` file, the `OpenApi.Reader` package is used to read the Open Api spec into an `OpenApiDocument` . - -Then , parse the properties of `OpenApiDocument` (paths, HTTP methods, arguments, schemas, etc) into two dictionaries- `fileProperties` and `schemaDict` . - -Both of these dictionaries are passed onto `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` , which is the T4 template with the code generation pattern. - -The T4 template iterates through the dictionaries and uses the values to write the code pattern for the route handlers. The `MinimalApiTemplate.cs` file generated by - -the T4 template during design time contains the method `TranformText()` that is used to produce the output code as a string value. - -## Dependencies - -- Microsoft.OpenApi (1.3.2) -- Microsoft.OpenApi.Reader (1.3.2) -- System.CodeDom (6.0.0) -- Microsoft.VisualStudio.TextTemplating.15.0 - -# Sample - -## Input - -```json -"openapi": "3.0.2", - "info": { - "title": "Swagger Petstore - OpenAPI 3.0", - "description": "This is a sample server", - "version": "1.0.11" - }, - "externalDocs": { - "description": "Find out more about Swagger", - "url": "http://swagger.io" - }, - "servers": [ - { - "url": "/api/v3" - } - ], - "tags": [ - { - "name": "pet", - "description": "Everything about your Pets", - "externalDocs": { - "description": "Find out more", - "url": "http://swagger.io" - } - }, - { - "name": "store", - "description": "Access to Petstore orders", - "externalDocs": { - "description": "Find out more about our store", - "url": "http://swagger.io" - } - }, - { - "name": "user", - "description": "Operations about user" - } - ], - "paths": { - "/": { - "get": { - "tags": [ - "store" - ], - "summary": "Welcome message", - "description": "Write the welcome message", - "operationId": "welcomeUser", - "responses": { - "200": { - "description": "Successful operation", - "content": { - "text/plain": { - "schema": { - "type": "string" - }, - "example": "Welcome to the store!" - } - } - } - } - } - }, - "/pet": { - "put": { - "tags": [ - "pet" - ], - "summary": "Update an existing pet", - "description": "Update an existing pet by Id", - "operationId": "updatePet", - "requestBody": { - "description": "Update an existent pet in the store", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful operation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Pet" - }, - "example": { - "id": 56, - "name": "Max", - "category": { - "id": 56, - "name": "Max" - }, - "photoUrls": [ - "http://samplelink.com/image1", - "http://samplelink.com/image2" - ], - "tags": null, - "status": "available" - } - } - } - }, - "400": { - "description": "Invalid ID supplied" - }, - "404": { - "description": "Pet not found" - }, - "405": { - "description": "Validation exception" - } - }, - "security": [ - { - "petstore_auth": [ - "write:pets", - "read:pets" - ] - } - ] - } -``` - -## Output - -```csharp -var builder = WebApplication.CreateBuilder(args); -var app = builder.Build(); - -app.MapGet("/", (HttpContext context) => -{ - if (context.Request.Headers["AcceptStatusCode"] == "200") - { - return Results.Ok("Welcome to the store!"); - } - - return null; -}); - -app.MapPut("/pet", (HttpContext context) => -{ - if (context.Request.Headers["AcceptStatusCode"] == "200") - { - return Results.Ok(new Pet(56, "Max", new Category(56, "Max"), new [] {"http://samplelink.com/image1", "http://samplelink.com/image2"}, null, "available")); - } - - if (context.Request.Headers["AcceptStatusCode"] == "400") - { - return Results.BadRequest(); - } - - if (context.Request.Headers["AcceptStatusCode"] == "404") - { - return Results.NotFound(); - } - - if (context.Request.Headers["AcceptStatusCode"] == "405") - { - return Results.StatusCode(405); - } - - return null; -}); -``` - -# Additional Notes 📒 From 8c41b18f2bfc8e8c0b0c99c9e7d3fb68117aae42 Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 10 Aug 2022 10:38:43 -0700 Subject: [PATCH 31/33] Add files via upload --- src/OpenApi/Code Generator Doc.md | 234 ++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 src/OpenApi/Code Generator Doc.md diff --git a/src/OpenApi/Code Generator Doc.md b/src/OpenApi/Code Generator Doc.md new file mode 100644 index 00000000..52aa55fe --- /dev/null +++ b/src/OpenApi/Code Generator Doc.md @@ -0,0 +1,234 @@ +# Code Generator doc + +Created: August 9, 2022 10:23 AM +Last Edited Time: August 10, 2022 10:30 AM + +# Overview 🖥️ + +This is a CLI tool that generates the server side API route handler code in Minimal API from an Open API spec. + +Some possible use cases for this tool are testing and validating API contracts, including mocking for a single service and performing UI integration tests with the generated mock server. This tool can also be used to facilitate decoupled development. + +# How to use the tool 🔨 + +In order for the tool to work, there are a couple of steps we must take to properly set up the environment. + +We must create the `MinimalApiTemplate.cs` file which will be created in design time by the `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` file. In order to do this: + +1. Open the `OpenApi.sln` file on VS. +2. Right click on the `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` and select `Properties` . +3. Change the `Build Action` property to `Content` and the `Custom Tool` property to `TextTemplatingFilePreprocessor` . +4. After doing this you should be able to right click the `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` file and select `Run Custom Tool` . +5. This will generate the `MinimalApiTemplate.cs` file which will be responsible for writing the code to the output file. + +At this point, the tool is ready for use, and can be executed with the following command: + +`dotnet run ` + +### Arguments + +`` corresponds to the file path of the json file containing the Open API documentation. + +`` is the path where the output file will be created. + +## Constraints + +`` has to be a valid path to .json file. + +`` has to be a valid path to .cs file. If a file path for an existing file is passed, the existing file will be overwritten. + +# Implementation ⚙️ + +## Logic + +Inside of the `CodeGenerator.cs` file, the `OpenApi.Reader` package is used to read the Open Api spec into an `OpenApiDocument` . + +Then , parse the properties of `OpenApiDocument` (paths, HTTP methods, arguments, schemas, etc) into two dictionaries- `fileProperties` and `schemaDict` . + +Both of these dictionaries are passed onto `[MinimalApiTemplate.tt](http://MinimalApiTemplate.tt)` , which is the T4 template with the code generation pattern. + +The T4 template iterates through the dictionaries and uses the values to write the code pattern for the route handlers. The `MinimalApiTemplate.cs` file generated by + +the T4 template during design time contains the method `TranformText()` that is used to produce the output code as a string value. + +## Dependencies + +- Microsoft.OpenApi (1.3.2) +- Microsoft.OpenApi.Reader (1.3.2) +- System.CodeDom (6.0.0) +- Microsoft.VisualStudio.TextTemplating.15.0 + +# Sample + +## Input + +```json +"openapi": "3.0.2", + "info": { + "title": "Swagger Petstore - OpenAPI 3.0", + "description": "This is a sample server", + "version": "1.0.11" + }, + "externalDocs": { + "description": "Find out more about Swagger", + "url": "http://swagger.io" + }, + "servers": [ + { + "url": "/api/v3" + } + ], + "tags": [ + { + "name": "pet", + "description": "Everything about your Pets", + "externalDocs": { + "description": "Find out more", + "url": "http://swagger.io" + } + }, + { + "name": "store", + "description": "Access to Petstore orders", + "externalDocs": { + "description": "Find out more about our store", + "url": "http://swagger.io" + } + }, + { + "name": "user", + "description": "Operations about user" + } + ], + "paths": { + "/": { + "get": { + "tags": [ + "store" + ], + "summary": "Welcome message", + "description": "Write the welcome message", + "operationId": "welcomeUser", + "responses": { + "200": { + "description": "Successful operation", + "content": { + "text/plain": { + "schema": { + "type": "string" + }, + "example": "Welcome to the store!" + } + } + } + } + } + }, + "/pet": { + "put": { + "tags": [ + "pet" + ], + "summary": "Update an existing pet", + "description": "Update an existing pet by Id", + "operationId": "updatePet", + "requestBody": { + "description": "Update an existent pet in the store", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pet" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pet" + }, + "example": { + "id": 56, + "name": "Max", + "category": { + "id": 56, + "name": "Max" + }, + "photoUrls": [ + "http://samplelink.com/image1", + "http://samplelink.com/image2" + ], + "tags": null, + "status": "available" + } + } + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + }, + "405": { + "description": "Validation exception" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } +``` + +## Output + +```csharp +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); + +app.MapGet("/", (HttpContext context) => +{ + if (context.Request.Headers["AcceptStatusCode"] == "200") + { + return Results.Ok("Welcome to the store!"); + } + + return null; +}); + +app.MapPut("/pet", (HttpContext context) => +{ + if (context.Request.Headers["AcceptStatusCode"] == "200") + { + return Results.Ok(new Pet(56, "Max", new Category(56, "Max"), new [] {"http://samplelink.com/image1", "http://samplelink.com/image2"}, null, "available")); + } + + if (context.Request.Headers["AcceptStatusCode"] == "400") + { + return Results.BadRequest(); + } + + if (context.Request.Headers["AcceptStatusCode"] == "404") + { + return Results.NotFound(); + } + + if (context.Request.Headers["AcceptStatusCode"] == "405") + { + return Results.StatusCode(405); + } + + return null; +}); +``` + +# Additional Notes 📒 \ No newline at end of file From dbc52794c10f61c915d68fc8e6cae5ad4c228f30 Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 10 Aug 2022 10:39:54 -0700 Subject: [PATCH 32/33] Update and rename Code Generator Doc.md to CodeGeneratorDoc.md --- src/OpenApi/{Code Generator Doc.md => CodeGeneratorDoc.md} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename src/OpenApi/{Code Generator Doc.md => CodeGeneratorDoc.md} (99%) diff --git a/src/OpenApi/Code Generator Doc.md b/src/OpenApi/CodeGeneratorDoc.md similarity index 99% rename from src/OpenApi/Code Generator Doc.md rename to src/OpenApi/CodeGeneratorDoc.md index 52aa55fe..5c3d6a5d 100644 --- a/src/OpenApi/Code Generator Doc.md +++ b/src/OpenApi/CodeGeneratorDoc.md @@ -1,5 +1,6 @@ # Code Generator doc + Created: August 9, 2022 10:23 AM Last Edited Time: August 10, 2022 10:30 AM @@ -231,4 +232,4 @@ app.MapPut("/pet", (HttpContext context) => }); ``` -# Additional Notes 📒 \ No newline at end of file +# Additional Notes 📒 From 13c958f6addd9b2d1fe5362e59eb05a8b9fc4681 Mon Sep 17 00:00:00 2001 From: anhthidao <107068384+anhthidao@users.noreply.github.com> Date: Wed, 10 Aug 2022 10:40:08 -0700 Subject: [PATCH 33/33] Update CodeGeneratorDoc.md --- src/OpenApi/CodeGeneratorDoc.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OpenApi/CodeGeneratorDoc.md b/src/OpenApi/CodeGeneratorDoc.md index 5c3d6a5d..7ec77025 100644 --- a/src/OpenApi/CodeGeneratorDoc.md +++ b/src/OpenApi/CodeGeneratorDoc.md @@ -1,6 +1,5 @@ # Code Generator doc - Created: August 9, 2022 10:23 AM Last Edited Time: August 10, 2022 10:30 AM