private static ListApis GetListApis()

in tools/code/extractor/Api.cs [84:186]


    private static ListApis GetListApis(IServiceProvider provider)
    {
        var findConfigurationNamesFactory = provider.GetRequiredService<FindConfigurationNamesFactory>();
        var defaultApiSpecification = provider.GetRequiredService<DefaultApiSpecification>();
        var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
        var pipeline = provider.GetRequiredService<HttpPipeline>();

        var findConfigurationApis = findConfigurationNamesFactory.Create<ApiName>();
        var findConfigurationVersionSets = findConfigurationNamesFactory.Create<VersionSetName>();

        return cancellationToken =>
            list(cancellationToken)
                .Where(api => shouldExtractApiDto(api.Dto))
                .SelectAwait(async api =>
                {
                    var (name, dto) = api;
                    var specificationContentsOption = await tryGetSpecificationContents(name, dto, cancellationToken);
                    return (name, dto, specificationContentsOption);
                });

        IAsyncEnumerable<(ApiName Name, ApiDto Dto)> list(CancellationToken cancellationToken) =>
            findConfigurationApis()
                .Map(names => listFromSet(names, cancellationToken))
                .IfNone(() => listAll(cancellationToken));

        IAsyncEnumerable<(ApiName, ApiDto)> listFromSet(IEnumerable<ApiName> names, CancellationToken cancellationToken) =>
            names.ToAsyncEnumerable()
                 // Ensure API exists
                 .WhereAwait(async name =>
                 {
                     var uri = ApiUri.From(name, serviceUri);
                     var dtoOption = await uri.TryGetDto(pipeline, cancellationToken);
                     return dtoOption.IsSome;
                 })
                 // Get all API revisions
                 .SelectMany(name => listAllRevisions(name, cancellationToken));

        IAsyncEnumerable<(ApiName, ApiDto)> listAllRevisions(ApiName name, CancellationToken cancellationToken)
        {
            var rootName = ApiName.GetRootName(name);
            var rootNameUri = ApiUri.From(name, serviceUri);
            var revisionsUri = rootNameUri.ToUri().AppendPathSegment("revisions").ToUri();

            return pipeline.ListJsonObjects(revisionsUri, cancellationToken)
                           // Get name for each revision. If the revision is current, use the root name.
                           .Select(jsonObject =>
                           {
                               var revisionNumberInt = jsonObject.GetIntProperty("apiRevision");
                               var revisionNumber = ApiRevisionNumber.From(revisionNumberInt);

                               var isCurrent = jsonObject.GetBoolProperty("isCurrent");

                               return isCurrent ? name : ApiName.GetRevisionedName(rootName, revisionNumber);
                           })
                           // Get DTO for each revision
                           .SelectAwait(async name =>
                           {
                               var uri = ApiUri.From(name, serviceUri);
                               var dto = await uri.GetDto(pipeline, cancellationToken);

                               return (name, dto);
                           });
        }

        IAsyncEnumerable<(ApiName, ApiDto)> listAll(CancellationToken cancellationToken) =>
            ApisUri.From(serviceUri)
                   .List(pipeline, cancellationToken);

        bool shouldExtractApiDto(ApiDto dto) =>
            // Don't extract if its version set should not be extracted
            common.ApiModule.TryGetVersionSetName(dto)
                            .Map(shouldExtractVersionSet)
                            .IfNone(true);

        bool shouldExtractVersionSet(VersionSetName name) =>
            findConfigurationVersionSets()
                .Map(names => names.Contains(name))
                .IfNone(true);

        async ValueTask<Option<(ApiSpecification, BinaryData)>> tryGetSpecificationContents(ApiName name, ApiDto dto, CancellationToken cancellationToken)
        {
            var specificationOption = tryGetSpecification(dto);

            return await specificationOption.BindTask(async specification =>
            {
                var uri = ApiUri.From(name, serviceUri);
                var contentsOption = await uri.TryGetSpecificationContents(specification, pipeline, cancellationToken);

                return from contents in contentsOption
                       select (specification, contents);
            });
        }

        Option<ApiSpecification> tryGetSpecification(ApiDto dto) =>
            (dto.Properties.Type ?? dto.Properties.ApiType) switch
            {
                "graphql" => new ApiSpecification.GraphQl(),
                "soap" => new ApiSpecification.Wsdl(),
                "http" => defaultApiSpecification.Value,
                null => defaultApiSpecification.Value,
                _ => Option<ApiSpecification>.None
            };
    }