private static IEnumerable <XRefSpec> GetXRefInfo(RestApiRootItemViewModel rootItem, string key) { yield return(new XRefSpec { Uid = rootItem.Uid, Name = rootItem.Name, Href = key, }); if (rootItem.Children != null) { foreach (var child in rootItem.Children) { yield return(new XRefSpec { Uid = child.Uid, Name = child.OperationId, Href = key, }); } } if (rootItem.Tags != null) { foreach (var tag in rootItem.Tags) { yield return(new XRefSpec { Uid = tag.Uid, Name = tag.Name, Href = key, }); } } }
public OperationGroupEntity Transform(SwaggerModel swaggerModel, RestApiRootItemViewModel viewModel, ConcurrentDictionary <string, ConcurrentBag <Operation> > groupOperations, string version) { var serviceId = swaggerModel.Metadata.GetValueFromMetaData <string>("x-internal-service-id"); var serviceName = swaggerModel.Metadata.GetValueFromMetaData <string>("x-internal-service-name"); var groupName = swaggerModel.Metadata.GetValueFromMetaData <string>("x-internal-toc-name"); var subgroupName = swaggerModel.Metadata.GetValueFromMetaData <string>("x-internal-sub-group-name"); var productUid = swaggerModel.Metadata.GetValueFromMetaData <string>("x-internal-product-uid"); var basePath = swaggerModel.BasePath; var apiVersion = swaggerModel.Info.Version; var groupId = Utility.TrimUId($"{Utility.GetHostWithBasePathUId(swaggerModel.Host, productUid, basePath)}.{serviceId}.{subgroupName}.{groupName}")?.ToLower(); ConcurrentBag <Operation> operations; var key = string.IsNullOrEmpty(version) ? groupId : $"{version}_{groupId}"; if (groupOperations.TryGetValue(key, out operations)) { if (operations.Count() > 0) { return(new OperationGroupEntity { Id = groupId, ApiVersion = apiVersion, Name = groupName, Operations = operations.OrderBy(p => p.Id).ToList(), Service = serviceName, Summary = GetSummary(swaggerModel, viewModel) }); } } return(null); }
private IEnumerable <RestApiChildItemViewModel> GetChildrenByTag(RestApiRootItemViewModel root, string tagName) { // Only group children into first tag, to keep cross reference unique var children = root.Children.Where(child => child.Tags != null && tagName == child.Tags.FirstOrDefault()); foreach (var child in children) { child.Tags = new List <string>(); yield return(child); } }
private TreeItem ConvertToTreeItem(RestApiRootItemViewModel root, string fileKey) { return(new TreeItem { Metadata = new Dictionary <string, object> { [Constants.PropertyName.Name] = root.Name, [Constants.PropertyName.TopicUid] = root.Uid } }); }
protected override string GetSummary(SwaggerModel swaggerModel, RestApiRootItemViewModel viewModel) { var groupName = swaggerModel.Metadata.GetValueFromMetaData <string>("x-internal-toc-name"); var tag = viewModel.Tags?.FirstOrDefault(t => t.Name == groupName); if (!string.IsNullOrEmpty(tag?.Description)) { return(tag?.Description); } return(Utility.GetSummary(viewModel.Summary, viewModel.Description)); }
private IEnumerable <string> CalculateUids(RestApiRootItemViewModel root) { if (!string.IsNullOrEmpty(root.Uid)) { yield return(root.Uid); } foreach (var child in root.Children ?? Enumerable.Empty <RestApiChildItemViewModel>()) { if (!string.IsNullOrEmpty(child.Uid)) { yield return(child.Uid); } } }
private Dictionary <string, object> MergeTagMetadata(RestApiRootItemViewModel root, RestApiTagViewModel tag) { var result = new Dictionary <string, object>(tag.Metadata); foreach (var pair in root.Metadata) { // Tag metadata wins for the same key if (!result.ContainsKey(pair.Key)) { result[pair.Key] = pair.Value; } } return(result); }
public override FileModel Load(FileAndType file, ImmutableDictionary <string, object> metadata) { switch (file.Type) { case DocumentType.Article: var filePath = Path.Combine(file.BaseDir, file.File); var swaggerContent = File.ReadAllText(filePath); var swagger = SwaggerJsonParser.Parse(swaggerContent); swagger.Metadata[DocumentTypeKey] = RestApiDocumentType; swagger.Raw = swaggerContent; var repoInfo = GitUtility.GetGitDetail(filePath); if (repoInfo != null) { swagger.Metadata["source"] = new SourceDetail() { Remote = repoInfo }; } swagger.Metadata = MergeMetadata(swagger.Metadata, metadata); var vm = RestApiRootItemViewModel.FromSwaggerModel(swagger); var displayLocalPath = repoInfo?.RelativePath ?? filePath.ToDisplayPath(); return(new FileModel(file, vm, serializer: new BinaryFormatter()) { Uids = new[] { new UidDefinition(vm.Uid, displayLocalPath) } .Concat(from item in vm.Children select new UidDefinition(item.Uid, displayLocalPath)) .Concat(from tag in vm.Tags select new UidDefinition(tag.Uid, displayLocalPath)).ToImmutableArray(), LocalPathFromRepoRoot = displayLocalPath, Properties = { LinkToFiles = new HashSet <string>(), LinkToUids = new HashSet <string>(), }, }); case DocumentType.Overwrite: // TODO: Refactor current behavior that overwrite file is read multiple times by multiple processors return(OverwriteDocumentReader.Read(file)); default: throw new NotSupportedException(); } }
private FileModel GenerateNewFileModel(FileModel model, RestApiRootItemViewModel tagModel) { var originalFile = model.FileAndType.File; var fileExtension = Path.GetExtension(originalFile); // When handling tags in petstore.swagger.json, the tag file path should be petstore/tag.json, to prevent tag name conflict var originalFileName = Path.GetFileName(originalFile); var subDirectory = originalFileName.Remove(originalFileName.IndexOf('.')); var directory = Path.GetDirectoryName(originalFile); var filePath = Path.Combine(directory, subDirectory, tagModel.Name + fileExtension).ToNormalizedPath(); var newFileAndType = new FileAndType(model.FileAndType.BaseDir, filePath, model.FileAndType.Type, model.FileAndType.SourceDir, model.FileAndType.DestinationDir); var newKey = "~/" + RelativePath.GetPathWithoutWorkingFolderChar(filePath); var newModel = new FileModel(newFileAndType, tagModel, model.OriginalFileAndType, model.Serializer, newKey) { LocalPathFromRoot = model.LocalPathFromRoot, Uids = CalculateUids(tagModel).Select(i => new UidDefinition(i, model.LocalPathFromRoot)).ToImmutableArray() }; return(newModel); }
private FileModel GenerateNewFileModel(FileModel model, RestApiRootItemViewModel operationModel) { var originalFile = model.FileAndType.File; var fileExtension = Path.GetExtension(originalFile); // When split into operation for petstore.swagger.json, the operation file path should be petstore/{operationName}.json, to prevent operation name confliction var originalFileName = Path.GetFileName(originalFile); var subDirectory = originalFileName.Remove(originalFileName.IndexOf('.')); var directory = Path.GetDirectoryName(originalFile); var filePath = Path.Combine(directory, subDirectory, operationModel.Name + fileExtension).ToNormalizedPath(); var newFileAndType = new FileAndType(model.FileAndType.BaseDir, filePath, model.FileAndType.Type, model.FileAndType.SourceDir, model.FileAndType.DestinationDir); var newKey = "~/" + RelativePath.GetPathWithoutWorkingFolderChar(filePath); var newModel = new FileModel(newFileAndType, operationModel, model.OriginalFileAndType, model.Serializer, newKey) { LocalPathFromRoot = model.LocalPathFromRoot, Uids = new[] { new UidDefinition(operationModel.Uid, model.LocalPathFromRoot) }.ToImmutableArray() }; return(newModel); }
private IEnumerable <RestApiRootItemViewModel> GenerateTagModels(RestApiRootItemViewModel root) { foreach (var tag in root.Tags) { var tagChildren = GetChildrenByTag(root, tag.Name).ToList(); if (tagChildren.Count > 0) { yield return(new RestApiRootItemViewModel { Uid = tag.Uid, HtmlId = tag.HtmlId, Name = tag.Name, Conceptual = tag.Conceptual, Description = tag.Description, Documentation = tag.Documentation, Children = tagChildren, Tags = new List <RestApiTagViewModel>(), Metadata = MergeTagMetadata(root, tag) }); } } }
private IEnumerable <RestApiRootItemViewModel> GenerateOperationModels(RestApiRootItemViewModel root) { foreach (var child in root.Children) { // Pop child's info into root model, include the uid var model = new RestApiRootItemViewModel { Uid = child.Uid, Name = child.OperationId, Conceptual = child.Conceptual, Description = child.Description, Summary = child.Summary, Remarks = child.Remarks, Documentation = child.Documentation, Children = new List <RestApiChildItemViewModel> { child }, Tags = new List <RestApiTagViewModel>(), Metadata = MergeChildMetadata(root, child) }; // Reset child's uid to "originalUid/operation", that is to say, overwrite of original Uid will show in operation page. child.Uid = string.Join("/", child.Uid, "operation"); // Reset html id, which is set by template child.HtmlId = null; // Reset child's additional content, which will show in operation page. child.Conceptual = null; child.Description = null; child.Summary = null; child.Remarks = null; child.Tags = new List <string>(); yield return(model); } }
public static RestApiRootItemViewModel FromSwaggerModel(SwaggerModel swagger) { var uid = GetUid(swagger); var vm = new RestApiRootItemViewModel { Name = swagger.Info.Title, Uid = uid, HtmlId = GetHtmlId(uid), Metadata = swagger.Metadata, Description = swagger.Description, Summary = swagger.Summary, Children = new List <RestApiChildItemViewModel>(), Raw = swagger.Raw, Tags = new List <RestApiTagViewModel>() }; if (swagger.Tags != null) { foreach (var tag in swagger.Tags) { vm.Tags.Add(new RestApiTagViewModel { Name = tag.Name, Description = tag.Description, HtmlId = string.IsNullOrEmpty(tag.BookmarkId) ? GetHtmlId(tag.Name) : tag.BookmarkId, // Fall back to tag name's html id Metadata = tag.Metadata, Uid = GetUidForTag(uid, tag) }); } } if (swagger.Paths != null) { foreach (var path in swagger.Paths) { var commonParameters = path.Value.Parameters; foreach (var op in path.Value.Metadata) { // fetch operations from metadata if (OperationNames.Contains(op.Key, StringComparer.OrdinalIgnoreCase)) { var opJObject = op.Value as JObject; if (opJObject == null) { throw new InvalidOperationException($"Value of {op.Key} should be JObject"); } // convert operation from JObject to OperationObject var operation = opJObject.ToObject <OperationObject>(); var parameters = GetParametersForOperation(operation.Parameters, commonParameters); var itemUid = GetUidForOperation(uid, operation); var itemVm = new RestApiChildItemViewModel { Path = path.Key, OperationName = op.Key, Tags = operation.Tags, OperationId = operation.OperationId, HtmlId = GetHtmlId(itemUid), Uid = itemUid, Metadata = operation.Metadata, Description = operation.Description, Summary = operation.Summary, Parameters = parameters?.Select(s => new RestApiParameterViewModel { Description = s.Description, Name = s.Name, Metadata = s.Metadata }).ToList(), Responses = operation.Responses?.Select(s => new RestApiResponseViewModel { Metadata = s.Value.Metadata, Description = s.Value.Description, Summary = s.Value.Summary, HttpStatusCode = s.Key, Examples = s.Value.Examples?.Select(example => new RestApiResponseExampleViewModel { MimeType = example.Key, Content = example.Value != null ? JsonUtility.Serialize(example.Value) : null, }).ToList(), }).ToList(), }; // TODO: line number if (swagger.Metadata.TryGetValue(Constants.PropertyName.Source, out object value)) { itemVm.Metadata[Constants.PropertyName.Source] = value; } else { itemVm.Metadata[Constants.PropertyName.Source] = null; } vm.Children.Add(itemVm); } } } } return(vm); }
private static void FillInBookmarks(FileModel model, RestApiRootItemViewModel restModel) { model.Bookmarks[restModel.Uid] = string.Empty; restModel.Children?.ForEach(c => model.Bookmarks[c.Uid] = c.HtmlId); restModel.Tags?.ForEach(t => model.Bookmarks[t.Uid] = t.HtmlId); }
protected override string GetSummary(SwaggerModel swaggerModel, RestApiRootItemViewModel viewModel) { return(Utility.GetSummary(viewModel.Summary, viewModel.Description)); }
private IEnumerable <string> CalculateUids(RestApiRootItemViewModel root) { return(new[] { root.Uid }.Concat(root.Children.Select(child => child.Uid))); }
protected abstract string GetSummary(SwaggerModel swaggerModel, RestApiRootItemViewModel viewModel);