private string GenerateApiClient(ApplicationType type, Domain domain) { var adapter = new ClientApiAdapter(type, domain); foreach (var operation in adapter.Operations) { Log.Debug("Api Client operation will be generated for {OperationName}", operation.Name); } try { return(GenerateFromTemplate(adapter, TemplateNames.ApiClient)); } catch (Exception ex) { Log.Error(ex, "Unexpected error generating API client for {TypeName}", type.Name); throw; } }
public List <CodeFile> GenerateClientModels(Domain domain) { Util.RegisterHelpers(domain.TypeProvider); var files = new List <CodeFile>(); foreach (var type in domain.FilteredTypes) { if (type.GenerateUI) { var adapter = new ClientApiAdapter(type, domain); if (adapter.Operations.Any()) { var path = GetRelativePathFromTypeName(type.Name); foreach (var op in adapter.ApiOperations) { // generate the request model if there is one if (op.HasCustomType) { var file = new CodeFile { Name = Util.CSharpNameFromName(op.CustomType.Name) + ".ts", Contents = GenerateClientApiModel(op), RelativePath = path, Template = TemplateNames.ApiClientModel }; files.Add(file); } // generate the response if there is one // TODO - re-use of models causes the same files to be generated multiple times var resultType = op.SimpleReturnType as ResultType; if (!op.NoResult && !op.IsSingular && (resultType == null || resultType.RelatedType == type) && op.SimpleReturnType != null) { var file = new CodeFile { Name = Util.CSharpNameFromName(op.SimpleReturnType.Name) + ".ts", Contents = GenerateClientApiResultType(op.SimpleReturnType), RelativePath = path, Template = TemplateNames.ApiClientResult }; files.Add(file); } } } } } return(files); }
public List <CodeFile> GenerateComponents(Domain domain) { Util.RegisterHelpers(domain.TypeProvider); var files = new List <CodeFile>(); var all = new CodeFile { Name = "all-types.tsx", Contents = GenerateAllPage(domain) }; files.Add(all); var regUserHome = new CodeFile { Name = "RegularUserHome.tsx", Contents = GenerateRegularUserHomepage(domain) }; files.Add(regUserHome); foreach (var type in domain.FilteredTypes.OrderBy(t => t.Name)) { if (type.GenerateUI) { var namestart = Util.TypescriptFileName(type.Name); var path = GetRelativePathFromTypeName(type.Name); var adapter = new ClientApiAdapter(type, domain); files.Add(new CodeFile { Name = namestart + "Select.tsx", Contents = GenerateFromTemplate(adapter, TemplateNames.ReactSelectControl), RelativePath = path, Template = TemplateNames.ReactSelectControl }); files.Add(new CodeFile { Name = namestart + "Component.tsx", Contents = GenerateFromTemplate(adapter, TemplateNames.ReactComponent), RelativePath = path, Template = TemplateNames.ReactComponent }); if (adapter.HasDetails) { var detailAdapter = new ClientDetailAdapter(type, domain); files.Add(new CodeFile { Name = namestart + "Detail.tsx", Contents = GenerateFromTemplate(detailAdapter, TemplateNames.ReactDetailPage), RelativePath = path, Template = TemplateNames.ReactDetailPage }); } foreach (var operation in adapter.ApiOperations.Where(op => op.ChangesData && op.GenerateUI)) { var changeDataAdapter = new ClientApiInsertUpdateAdapter(type, domain, operation); files.Add(new CodeFile { Name = namestart + operation.FriendlyName + ".tsx", Contents = GenerateFromTemplate(changeDataAdapter, TemplateNames.ReactAddEditPage), RelativePath = path, Template = TemplateNames.ReactAddEditPage }); files.Add(new CodeFile { Name = namestart + operation.FriendlyName + "Rendering.tsx", Contents = GenerateFromTemplate(changeDataAdapter, TemplateNames.ReactAddEditPageRendering), RelativePath = path, Template = TemplateNames.ReactAddEditPageRendering }); } if (adapter.Operations.Any(op => op.ChangesData && op.GenerateUI)) { files.Add(new CodeFile { Name = namestart + "Validate.tsx", Contents = GenerateFromTemplate(adapter, TemplateNames.ModelValidator), RelativePath = path, Template = TemplateNames.ModelValidator }); } if (adapter.CanDelete) { files.Add(new CodeFile { Name = namestart + "ConfirmDelete.tsx", Contents = GenerateFromTemplate(adapter, TemplateNames.ReactConfirmDeletePage), RelativePath = path, Template = TemplateNames.ReactConfirmDeletePage }); } } } // build 'list' UIs from return types foreach (var rt in domain.Operations.Where(o => o.GenerateUI && o.RelatedType?.GenerateUI == true && (o.Returns != null && o.Returns.ReturnType == ReturnType.ApplicationType || o.Returns != null && o.Returns.ReturnType == ReturnType.CustomType)) .Select(o => new { o.Returns.SimpleReturnType, RelatedType = o.Returns.SimpleReturnType is ApplicationType ? o.RelatedType : ((ResultType)o.Returns.SimpleReturnType).RelatedType }) // get the related type from the result type if it is a custom type, or from the operation if the operation returns an application type - allows OpenApi operations to re-use types across application types. .Distinct() .OrderBy(rt => rt.RelatedType.Name)) { if (rt.RelatedType == null || domain.FilteredTypes.Contains(rt.RelatedType)) { var listAdapter = new ListViewAdapter(rt.SimpleReturnType, domain, rt.RelatedType); var listPath = GetRelativePathFromTypeName(rt.RelatedType.Name) + "list\\"; var nameStart = Util.TypescriptFileName(rt.SimpleReturnType.Name); files.Add(new CodeFile { Name = nameStart + "List.tsx", Contents = GenerateFromTemplate(listAdapter, TemplateNames.ReactListPage), RelativePath = listPath, Template = TemplateNames.ReactListPage }); files.Add(new CodeFile { Name = nameStart + "Header.tsx", Contents = GenerateFromTemplate(listAdapter, TemplateNames.ReactListHeader), RelativePath = listPath, Template = TemplateNames.ReactListHeader }); files.Add(new CodeFile { Name = nameStart + "Row.tsx", Contents = GenerateFromTemplate(listAdapter, TemplateNames.ReactListRow), RelativePath = listPath, Template = TemplateNames.ReactListRow }); files.Add(new CodeFile { Name = nameStart + "ListRendering.tsx", Contents = GenerateFromTemplate(listAdapter, TemplateNames.ReactListRendering), RelativePath = listPath, Template = TemplateNames.ReactListRendering }); } } foreach (var srchOp in domain.Operations.Where(o => o.RelatedType != null).Select(o => new ClientApiOperationAdapter(o, domain, o.RelatedType)).Where(o => o.RelatedType?.GenerateUI == true && o.IsSearch)) { if (srchOp.RelatedType != null && domain.FilteredTypes.Contains(srchOp.RelatedType)) { var search = new CodeFile { Name = Util.TypescriptFileName(srchOp.Name) + ".tsx", Contents = GenerateFromTemplate(srchOp, TemplateNames.ReactSearchControl), RelativePath = GetRelativePathFromTypeName(srchOp.RelatedType.Name), Template = TemplateNames.ReactSearchControl }; files.Add(search); } } var appImports = new CodeFile { Name = "../App.tsx", Contents = GenerateFromTemplate(new DomainAdapter(domain), "AppImports"), IsFragment = true }; files.Add(appImports); var appRoutes = new CodeFile { Name = "../App.tsx", Contents = GenerateFromTemplate(new DomainAdapter(domain), "AppRoutes"), IsFragment = true }; files.Add(appRoutes); return(files); }