/// <summary> /// /// </summary> /// <param name="codeGenParameters"></param> /// <remarks>The client data types should better be generated through SvcUtil.exe with the DC option. The client namespace will then be the original namespace plus suffix ".client". </remarks> public ControllersClientApiGen(Settings settings) { this.settings = settings; codeCompileUnit = new CodeCompileUnit(); sharedContext = new SharedContext(); nameComposer = new NameComposer(settings); }
public void TestComposeActionNameWithParameters() { OpenApiPathItem pathItem = doc.Paths["/api/Entities/link"]; string actionName = NameComposer.ComposeActionName(pathItem.Operations[OperationType.Put], OperationType.Put.ToString()); Assert.Equal("EntitiesPutByIdAndRelationship", actionName); }
public CodeMemberMethod CreateApiFunction(Settings settings, string relativePath, OperationType httpMethod, OpenApiOperation apiOperation, ComponentsToCsTypes coms2CsTypes, bool forAsync, bool useEnsureSuccessStatusCodeEx) { if (!(new OperationType[] { OperationType.Get, OperationType.Post, OperationType.Put, OperationType.Delete, OperationType.Patch }).Any(d => d == httpMethod)) { Trace.TraceWarning("This HTTP method {0} is not yet supported", httpMethod); return(null); } this.settings = settings; this.nameComposer = new NameComposer(settings); this.apiOperation = apiOperation; statementOfEnsureSuccessStatusCode = useEnsureSuccessStatusCodeEx ? "EnsureSuccessStatusCodeEx" : "EnsureSuccessStatusCode"; this.actionName = nameComposer.GetActionName(apiOperation, httpMethod.ToString(), relativePath); this.coms2CsTypes = coms2CsTypes; this.forAsync = forAsync; this.RelativePath = RemovePrefixSlash(relativePath); this.RelativePath = RegexFunctions.RefineUrlWithHyphenInParameters(RelativePath); if (actionName.EndsWith("Async")) { actionName = actionName[0..^ 5];
public void TestComposeActionName() { OpenApiPathItem pathItem = doc.Paths["/api/Values"]; string actionName = NameComposer.ComposeActionName(pathItem.Operations[OperationType.Get], OperationType.Get.ToString()); Assert.Equal("ValuesGet", actionName); }
public DocFixture() { using FileStream stream = new FileStream("SwagMock\\myswagger.json", FileMode.Open, FileAccess.Read); Doc = new OpenApiStreamReader().Read(stream, out OpenApiDiagnostic diagnostic); Composer = new NameComposer(new Settings { PathPrefixToRemove = "/api", }); }
void CreateDocComments() { StringBuilder builder = new StringBuilder(); string[] linesNoIndent = Fonlow.DocComment.StringFunctions.TrimIndentedMultiLineTextToArray( apiOperation.Summary + ((String.IsNullOrEmpty(apiOperation.Summary) || string.IsNullOrEmpty(apiOperation.Description)) ? String.Empty : "\n") + apiOperation.Description); if (linesNoIndent != null) { foreach (string line in linesNoIndent) { bool funky = line.Contains("*/"); var lineComment = funky ? line.Replace("*/", "") : line; builder.AppendLine(lineComment); if (funky) { Trace.TraceWarning("Doc comments contain '*/' which is invalid in JSDoc. Please remove it in the definition."); } } } builder.AppendLine(HttpMethod + " " + RelativePath); foreach (ParameterDescriptionEx item in ParameterDescriptions) { CodeTypeReference tsParameterType = item.ParameterTypeReference; // Poco2TsGen.TranslateToClientTypeReference(item.ParameterDescriptor.ParameterType); if (!String.IsNullOrEmpty(item.Documentation)) { var funky = item.Documentation.Contains("*/"); var docComment = funky ? item.Documentation.Replace("*/", "") : item.Documentation; builder.AppendLine($"@param {{{TypeMapper.MapCodeTypeReferenceToTsText(tsParameterType)}}} {item.Name} {docComment}"); if (funky) { Trace.TraceWarning($"param {TypeMapper.MapCodeTypeReferenceToTsText(tsParameterType)} {item.Name} has Doc comments containing '*/' which is invalid in JSDoc. Please remove it in the definition."); } } } if (!String.IsNullOrEmpty(requestBodyComment)) { var funky = requestBodyComment.Contains("*/"); var docComment = funky ? requestBodyComment.Replace("*/", "") : requestBodyComment; builder.AppendLine($"@param {{{TypeMapper.MapCodeTypeReferenceToTsText(RequestBodyCodeTypeReference)}}} requestBody {docComment}"); if (funky) { Trace.TraceWarning($"param {TypeMapper.MapCodeTypeReferenceToTsText(RequestBodyCodeTypeReference)} requestBody has Doc comments containing '*/' which is invalid in JSDoc. Please remove it in the definition."); } } string returnTypeOfResponse = ReturnTypeReference == null ? "void" : TypeMapper.MapCodeTypeReferenceToTsText(ReturnTypeReference); builder.AppendLine($"@return {{{returnTypeOfResponse}}} {NameComposer.GetOperationReturnComment(apiOperation)}"); Method.Comments.Add(new CodeCommentStatement(builder.ToString(), true)); }
readonly Func <ClientApiTsFunctionGenAbstract> apiFunctionGenFactory; //to be injected in ctor of derived class. /// <summary> /// /// </summary> /// <param name="jsOutput"></param> /// <param name="apiFunctionGen"></param> /// <remarks>The client data types should better be generated through SvcUtil.exe with the DC option. The client namespace will then be the original namespace plus suffix ".client". </remarks> protected ControllersTsClientApiGenBase(Settings settings, JSOutput jsOutput, Func <ClientApiTsFunctionGenAbstract> apiFunctionGenFactory) { this.settings = settings; this.jsOutput = jsOutput; this.apiFunctionGenFactory = apiFunctionGenFactory; CodeCompileUnit = new CodeCompileUnit(); nameComposer = new NameComposer(settings); TsCodeGenerationOptions options = TsCodeGenerationOptions.Instance; options.BracingStyle = "JS"; options.IndentString = "\t"; options.CamelCase = true; var versionInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location); ProductName = versionInfo.ProductName; }
public CodeMemberMethod CreateApiFunction(Settings settings, string relativePath, OperationType httpMethod, OpenApiOperation apiOperation, ComponentsToTsTypes com2TsTypes) { if (!(new OperationType[] { OperationType.Get, OperationType.Post, OperationType.Put, OperationType.Delete, OperationType.Patch }).Any(d => d == httpMethod)) { Trace.TraceWarning("This HTTP method {0} is not yet supported", httpMethod); return(null); } this.nameComposer = new NameComposer(settings); this.apiOperation = apiOperation; this.HttpMethod = httpMethod; this.ActionName = nameComposer.GetActionName(apiOperation, httpMethod.ToString(), relativePath); this.bodyContentRefBuilder = new BodyContentRefBuilder(com2TsTypes, ActionName); this.parametersRefBuilder = new ParametersRefBuilder(com2TsTypes, ActionName); this.ParameterDescriptions = parametersRefBuilder.OpenApiParametersToParameterDescriptions(apiOperation.Parameters); if (httpMethod == OperationType.Post || httpMethod == OperationType.Put || httpMethod == OperationType.Patch) { Tuple <CodeTypeReference, string, bool> kc = bodyContentRefBuilder.GetBodyContent(apiOperation, httpMethod.ToString(), relativePath); if (kc != null) { this.RequestBodyCodeTypeReference = kc.Item1; this.requestBodyComment = kc.Item2; if (!kc.Item3) { return(null); // not to generate for unsupported POST content type. } } } this.RelativePath = RemovePrefixSlash(relativePath); this.RelativePath = RegexFunctions.RefineUrlWithHyphenInParameters(RelativePath); Tuple <CodeTypeReference, bool> r; try { var returnRefBuilder = new ReturnRefBuilder(com2TsTypes, ActionName); r = returnRefBuilder.GetOperationReturnTypeReference(apiOperation); } catch (CodeGenException ex) { if (ex.Pending) { throw new CodeGenException($"When generating TS scripts, definition {relativePath}=>{httpMethod} triggers error {ex.Message}"); } throw; } ReturnTypeReference = r.Item1; //create method Method = CreateMethodName(); CreateDocComments(); switch (HttpMethod) { case OperationType.Get: case OperationType.Delete: case OperationType.Post: case OperationType.Put: case OperationType.Patch: RenderImplementation(); break; default: Trace.TraceWarning("This HTTP method {0} is not yet supported in TS gen", HttpMethod); break; } return(Method); }