Ejemplo n.º 1
0
        /// <summary>
        /// Generate CodeDom of the client API for ApiDescriptions.
        /// </summary>
        /// <param name="descriptions">Web Api descriptions exposed by Configuration.Services.GetApiExplorer().ApiDescriptions</param>
        public void CreateCodeDom(OpenApiPaths paths, OpenApiComponents components)
        {
            if (paths == null && components == null)
            {
                return;
            }

            clientNamespace = new CodeNamespace(settings.ClientNamespace);
            CodeCompileUnit.Namespaces.Add(clientNamespace);            //namespace added to Dom

            ComponentsToTsTypes componentsToTsTypes = new ComponentsToTsTypes(settings, CodeCompileUnit, clientNamespace);

            componentsToTsTypes.CreateCodeDom(components);

            if (paths == null)
            {
                return;
            }

            AddBasicReferences();

            string[] containerClassNames = GetContainerClassNames(paths);

            CodeTypeDeclaration[] newClassesCreated = containerClassNames.Select(d => CreateControllerClientClass(clientNamespace, d)).ToArray();

            foreach (KeyValuePair <string, OpenApiPathItem> p in paths)
            {
                string relativePath = p.Key;
                foreach (KeyValuePair <OperationType, OpenApiOperation> op in p.Value.Operations)
                {
                    ClientApiTsFunctionGenAbstract apiFunctionGen = apiFunctionGenFactory();
                    CodeMemberMethod apiFunction = apiFunctionGen.CreateApiFunction(settings, relativePath, op.Key, op.Value, componentsToTsTypes);
                    if (apiFunction == null)
                    {
                        System.Diagnostics.Trace.TraceWarning($"Not to generate TS for {p.Key} {op.Key}.");
                        continue;
                    }

                    string containerClassName         = nameComposer.GetContainerName(op.Value, p.Key);
                    CodeTypeDeclaration existingClass = LookupExistingClass(containerClassName);
                    existingClass.Members.Add(apiFunction);
                }
            }


            foreach (CodeTypeDeclaration c in newClassesCreated)
            {
                AddHelperFunctionsInClass(c);
            }
        }
        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);
        }