diff --git a/src/code/PSResourceInfo.cs b/src/code/PSResourceInfo.cs index d2351da35..38e6b8c26 100644 --- a/src/code/PSResourceInfo.cs +++ b/src/code/PSResourceInfo.cs @@ -469,6 +469,150 @@ private static Version GetVersionInfo( return GetProperty(nameof(PSResourceInfo.Version), psObjectInfo); } + public static bool TryConvertXmlFromGraphQL( + XmlNode entry, + out PSResourceInfo psGetInfo, + PSRepositoryInfo repository, + out string errorMsg) + { + psGetInfo = null; + errorMsg = String.Empty; + + if (entry == null) + { + errorMsg = "TryConvertXmlFromGraphQL: Invalid XmlNode object. Object cannot be null."; + return false; + } + + try + { + Hashtable metadata = new Hashtable(StringComparer.InvariantCultureIgnoreCase); + + // this is where the metadata properties reside + var entryChildNodes = entry.ChildNodes; + foreach (XmlElement entryChild in entryChildNodes) + { + var infoPropertyKey = entryChild.LocalName; + if (infoPropertyKey.Equals("packageId")) + { + metadata["id"] = entryChild.InnerText; + } + else if (infoPropertyKey.Equals("package") && entryChild.HasChildNodes) + { + var pkgInfoElements = entryChild.ChildNodes; + foreach (XmlElement pkgObjChild in pkgInfoElements) + { + var metadataPropertyKey = pkgObjChild.LocalName; + var metadataPropertyValue = pkgObjChild.InnerText; + if (metadataPropertyKey.Equals("version")) + { + metadata[metadataPropertyKey] = ParseHttpVersion(metadataPropertyValue, out string prereleaseLabel); + metadata["prerelease"] = prereleaseLabel; + } + else if (metadataPropertyKey.EndsWith("Url")) + { + metadata[metadataPropertyKey] = ParseHttpUrl(metadataPropertyValue) as Uri; + } + else if (metadataPropertyKey.Equals("tags")) + { + metadata[metadataPropertyKey] = metadataPropertyValue.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + } + else if (metadataPropertyKey.Equals("published")) + { + metadata[metadataPropertyKey] = ParseHttpDateTime(metadataPropertyValue); + } + else if (metadataPropertyKey.Equals("flattenedDependencies")) + { + metadata["dependencies"] = ParseHttpDependencies(metadataPropertyValue); + } + else if (metadataPropertyKey.Equals("isPrerelease")) + { + bool.TryParse(metadataPropertyValue, out bool isPrerelease); + + metadata[metadataPropertyKey] = isPrerelease; + } + else if (metadataPropertyKey.Equals("normalizedVersion")) + { + if (!NuGetVersion.TryParse(metadataPropertyValue, out NuGetVersion parsedNormalizedVersion)) + { + errorMsg = string.Format( + CultureInfo.InvariantCulture, + @"TryReadPSGetInfo: Cannot parse NormalizedVersion"); + + parsedNormalizedVersion = new NuGetVersion("1.0.0.0"); + } + + metadata[metadataPropertyKey] = parsedNormalizedVersion; + } + else if (metadataPropertyKey.Equals("flattenedAuthors")) + { + metadata["authors"] = metadataPropertyValue; + } + else + { + metadata[metadataPropertyKey] = metadataPropertyValue; + } + } + + } + } + + var typeInfo = ParseHttpMetadataType(metadata["tags"] as string[], out ArrayList commandNames, out ArrayList cmdletNames, out ArrayList dscResourceNames); + var resourceHashtable = new Hashtable { + { nameof(PSResourceInfo.Includes.Command), new PSObject(commandNames) }, + { nameof(PSResourceInfo.Includes.Cmdlet), new PSObject(cmdletNames) }, + { nameof(PSResourceInfo.Includes.DscResource), new PSObject(dscResourceNames) } + }; + + var additionalMetadataHashtable = new Dictionary(); + + // Only add NormalizedVersion to additionalMetadata if server response included it + if (metadata.ContainsKey("normalizedVersion")) + { + additionalMetadataHashtable.Add("NormalizedVersion", metadata["normalizedVersion"].ToString()); + } + + var includes = new ResourceIncludes(resourceHashtable); + + psGetInfo = new PSResourceInfo( + additionalMetadata: additionalMetadataHashtable, + author: metadata["authors"] as String, + companyName: metadata["companyName"] as String, + copyright: metadata["copyright"] as String, + dependencies: metadata["dependencies"] as Dependency[], + description: metadata["description"] as String, + iconUri: metadata["iconUrl"] as Uri, + includes: includes, + installedDate: null, + installedLocation: null, + isPrerelease: (bool)metadata["isPrerelease"], + licenseUri: metadata["licenseUrl"] as Uri, + name: metadata["id"] as String, + powershellGetFormatVersion: null, + prerelease: metadata["prerelease"] as String, + projectUri: metadata["projectUrl"] as Uri, + publishedDate: metadata["published"] as DateTime?, + releaseNotes: metadata["releaseNotes"] as String, + repository: repository.Name, + repositorySourceLocation: repository.Uri.ToString(), + tags: metadata["tags"] as string[], + type: typeInfo, + updatedDate: null, + version: metadata["version"] as Version); + + return true; + } + catch (Exception ex) + { + errorMsg = string.Format( + CultureInfo.InvariantCulture, + @"TryConvertXmlFromGraphQL: Cannot parse PSResourceInfo from xml string with error: {0}", + ex.Message); + + return false; + } + } + /// /// Converts XML entry to PSResourceInfo instance /// used for V2 Server API call find response conversion to PSResourceInfo object @@ -1601,6 +1745,9 @@ internal static Uri ParseHttpUrl(string uriString) internal static Dependency[] ParseHttpDependencies(string dependencyString) { + /* + RequiredModule1:(, ):|RequiredModule2:[2.0.0, ):|RequiredModule3:[2.5.0, 2.5.0]:|RequiredModule4:[1.1.0, 2.0.0]:|RequiredModule5:(, 1.5.0]: + */ /* Az.Profile:[0.1.0, ):|Az.Aks:[0.1.0, ):|Az.AnalysisServices:[0.1.0, ): Post 1st Split: diff --git a/src/code/V2ResponseUtil.cs b/src/code/V2ResponseUtil.cs index e62d15e77..0fcc755bc 100644 --- a/src/code/V2ResponseUtil.cs +++ b/src/code/V2ResponseUtil.cs @@ -40,29 +40,56 @@ public override IEnumerable ConvertToPSResourceResult(FindResu foreach (string response in responses) { - var elemList = ConvertResponseToXML(response); - if (elemList.Length == 0) + if (Repository.Uri.AbsoluteUri.Contains("www.powershellgallery.com")) { - // this indicates we got a non-empty, XML response (as noticed for V2 server) but it's not a response that's meaningful (contains 'properties') - Exception notFoundException = new ResourceNotFoundException("Package does not exist on the server"); + string responseToConvert = response.Trim('\"').Replace("\\n", "").Replace("\\r", ""); + var elemList = ConvertGraphQLResponseToXML(responseToConvert); + if (elemList.Length == 0) + { + // this indicates we got a non-empty, XML response (as noticed for V2 server) but it's not a response that's meaningful (contains 'properties') + Exception notFoundException = new ResourceNotFoundException("Package does not exist on the server"); - yield return new PSResourceResult(returnedObject: null, exception: notFoundException, isTerminatingError: false); - } + yield return new PSResourceResult(returnedObject: null, exception: notFoundException, isTerminatingError: false); + } - foreach (var element in elemList) + foreach(var element in elemList) + { + if (!PSResourceInfo.TryConvertXmlFromGraphQL(element, out PSResourceInfo psGetInfo, Repository, out string errorMsg)) + { + Exception parseException = new XmlParsingException(errorMsg); + + yield return new PSResourceResult(returnedObject: null, exception: parseException, isTerminatingError: false); + } + + yield return new PSResourceResult(returnedObject: psGetInfo, exception: null, isTerminatingError: false); + } + } + else { - if (!PSResourceInfo.TryConvertFromXml(element, out PSResourceInfo psGetInfo, Repository, out string errorMsg)) + var elemList = ConvertResponseToXML(response); + if (elemList.Length == 0) { - Exception parseException = new XmlParsingException(errorMsg); + // this indicates we got a non-empty, XML response (as noticed for V2 server) but it's not a response that's meaningful (contains 'properties') + Exception notFoundException = new ResourceNotFoundException("Package does not exist on the server"); - yield return new PSResourceResult(returnedObject: null, exception: parseException, isTerminatingError: false); + yield return new PSResourceResult(returnedObject: null, exception: notFoundException, isTerminatingError: false); } - // For V2 resources, specifically PSGallery, return unlisted version resources only when not requested with wildcard name - // Unlisted versions will have a published year as 1900 or earlier. - if (!isResourceRequestedWithWildcard || !psGetInfo.PublishedDate.HasValue || psGetInfo.PublishedDate.Value.Year > 1900) + foreach (var element in elemList) { - yield return new PSResourceResult(returnedObject: psGetInfo, exception: null, isTerminatingError: false); + if (!PSResourceInfo.TryConvertFromXml(element, out PSResourceInfo psGetInfo, Repository, out string errorMsg)) + { + Exception parseException = new XmlParsingException(errorMsg); + + yield return new PSResourceResult(returnedObject: null, exception: parseException, isTerminatingError: false); + } + + // For V2 resources, specifically PSGallery, return unlisted version resources only when not requested with wildcard name + // Unlisted versions will have a published year as 1900 or earlier. + if (!isResourceRequestedWithWildcard || !psGetInfo.PublishedDate.HasValue || psGetInfo.PublishedDate.Value.Year > 1900) + { + yield return new PSResourceResult(returnedObject: psGetInfo, exception: null, isTerminatingError: false); + } } } } @@ -72,7 +99,8 @@ public override IEnumerable ConvertToPSResourceResult(FindResu #region V2 Specific Methods - public XmlNode[] ConvertResponseToXML(string httpResponse) { + public XmlNode[] ConvertResponseToXML(string httpResponse) + { NuGetVersion emptyVersion = new NuGetVersion("0.0.0.0"); NuGetVersion firstVersion = emptyVersion; NuGetVersion lastVersion = emptyVersion; @@ -136,6 +164,48 @@ public XmlNode[] ConvertResponseToXML(string httpResponse) { return nodes; } + + public XmlNode[] ConvertGraphQLResponseToXML(string graphQLResponse) + { + List nodeList = new List(); + // GraphQL response is a stringified XML, so trim quotes and remove extra space and newline escaped characters + string responseToConvert = graphQLResponse.Trim('\"').Replace("\\n", "").Replace("\\r", ""); + + // root + // operationName1 + // pkgId + // Package + // operationName2 + // pkgId + // Package + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(responseToConvert); + XmlElement rootElement = doc.DocumentElement; + if (!rootElement.HasChildNodes) + { + return nodeList.ToArray(); // TODO some error message? + } + + // operationName based element, there will be as many nodes as there were responses found (i.e if 2 packages matched, 2 operationName based elements) + var entryElements = rootElement.ChildNodes; + int entriesFound = entryElements.Count; + + foreach (XmlNode entry in entryElements) + { + if (entry.HasChildNodes) + { + // this node's child nodes will contain the metadata + nodeList.Add(entry); + } + else + { + continue; // what if FindName "existant", "nonExistant" returns -- more testing needed + } + } + + return nodeList.ToArray(); + } #endregion } } diff --git a/src/code/V2ServerAPICalls.cs b/src/code/V2ServerAPICalls.cs index 94d0b3a0b..60cd71aaa 100644 --- a/src/code/V2ServerAPICalls.cs +++ b/src/code/V2ServerAPICalls.cs @@ -44,6 +44,8 @@ internal class V2ServerAPICalls : ServerApiCall private bool _isADORepo; private bool _isJFrogRepo; private bool _isPSGalleryRepo; + private bool _useGraphQL; + private string _graphQLUrl; #endregion @@ -82,6 +84,8 @@ public V2ServerAPICalls (PSRepositoryInfo repository, PSCmdlet cmdletPassedIn, N _isADORepo = repoURL.Contains("pkgs.dev.azure.com") || repoURL.Contains("pkgs.visualstudio.com"); _isJFrogRepo = repoURL.Contains("jfrog") || repoURL.Contains("artifactory"); _isPSGalleryRepo = repoURL.Contains("powershellgallery.com/api/v2"); + _useGraphQL = _isPSGalleryRepo; + _graphQLUrl = "https://localhost:7239"; } #endregion @@ -109,31 +113,39 @@ public override FindResults FindAll(bool includePrerelease, ResourceType type, o return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); } - int initialScriptCount = GetCountFromResponse(initialScriptResponse, out errRecord); - if (errRecord != null) + if (!_useGraphQL) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); - } + int initialScriptCount = GetCountFromResponse(initialScriptResponse, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } - if (initialScriptCount != 0) - { - responses.Add(initialScriptResponse); - int count = initialScriptCount / 6000; - // if more than 100 count, loop and add response to list - while (count > 0) + if (initialScriptCount != 0) { - _cmdletPassedIn.WriteDebug($"Count is '{count}'"); - scriptSkip += 6000; - var tmpResponse = FindAllFromTypeEndPoint(includePrerelease, isSearchingModule: false, scriptSkip, out errRecord); - if (errRecord != null) + responses.Add(initialScriptResponse); + int count = initialScriptCount / 6000; + // if more than 100 count, loop and add response to list + while (count > 0) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + _cmdletPassedIn.WriteDebug($"Count is '{count}'"); + scriptSkip += 6000; + var tmpResponse = FindAllFromTypeEndPoint(includePrerelease, isSearchingModule: false, scriptSkip, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + + responses.Add(tmpResponse); + count--; } - - responses.Add(tmpResponse); - count--; } } + else if(!initialScriptResponse.Equals("\"\"")) + { + // only add response if it's non-empty, i.e not just root node signifying empty response + responses.Add(initialScriptResponse); + } } if (type != ResourceType.Script) { @@ -144,32 +156,39 @@ public override FindResults FindAll(bool includePrerelease, ResourceType type, o return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); } - int initialModuleCount = GetCountFromResponse(initialModuleResponse, out errRecord); - if (errRecord != null) + if (!_useGraphQL) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); - } - - if (initialModuleCount != 0) - { - responses.Add(initialModuleResponse); - int count = initialModuleCount / 6000; + int initialModuleCount = GetCountFromResponse(initialModuleResponse, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } - // if more than 100 count, loop and add response to list - while (count > 0) + if (initialModuleCount != 0) { - _cmdletPassedIn.WriteDebug($"Count is '{count}'"); - moduleSkip += 6000; - var tmpResponse = FindAllFromTypeEndPoint(includePrerelease, isSearchingModule: true, moduleSkip, out errRecord); - if (errRecord != null) + responses.Add(initialModuleResponse); + int count = initialModuleCount / 6000; + + // if more than 100 count, loop and add response to list + while (count > 0) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + _cmdletPassedIn.WriteDebug($"Count is '{count}'"); + moduleSkip += 6000; + var tmpResponse = FindAllFromTypeEndPoint(includePrerelease, isSearchingModule: true, moduleSkip, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + + responses.Add(tmpResponse); + count--; } - - responses.Add(tmpResponse); - count--; } } + else if(!initialModuleResponse.Equals("\"\"")) + { + responses.Add(initialModuleResponse); + } } return new FindResults(stringResponse: responses.ToArray(), hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); @@ -191,37 +210,46 @@ public override FindResults FindTags(string[] tags, bool includePrerelease, Reso { int scriptSkip = 0; string initialScriptResponse = FindTagFromEndpoint(tags, includePrerelease, isSearchingModule: false, scriptSkip, out errRecord); - if (errRecord != null) - { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); - } - int initialScriptCount = GetCountFromResponse(initialScriptResponse, out errRecord); if (errRecord != null) { return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); } - if (initialScriptCount != 0) + if (!_useGraphQL) { - responses.Add(initialScriptResponse); - int count = initialScriptCount / 100; - // if more than 100 count, loop and add response to list - while (count > 0) + int initialScriptCount = GetCountFromResponse(initialScriptResponse, out errRecord); + if (errRecord != null) { - _cmdletPassedIn.WriteDebug($"Count is '{count}'"); - // skip 100 - scriptSkip += 100; - var tmpResponse = FindTagFromEndpoint(tags, includePrerelease, isSearchingModule: false, scriptSkip, out errRecord); - if (errRecord != null) + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + + if (initialScriptCount != 0) + { + responses.Add(initialScriptResponse); + int count = initialScriptCount / 100; + // if more than 100 count, loop and add response to list + while (count > 0) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + _cmdletPassedIn.WriteDebug($"Count is '{count}'"); + // skip 100 + scriptSkip += 100; + var tmpResponse = FindTagFromEndpoint(tags, includePrerelease, isSearchingModule: false, scriptSkip, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + + responses.Add(tmpResponse); + count--; } - - responses.Add(tmpResponse); - count--; } } + else if(!initialScriptResponse.Equals("\"\"")) + { + // only add response if it's non-empty, i.e not just root node signifying empty response + responses.Add(initialScriptResponse); + } } if (_type != ResourceType.Script) { @@ -232,34 +260,41 @@ public override FindResults FindTags(string[] tags, bool includePrerelease, Reso return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); } - int initialModuleCount = GetCountFromResponse(initialModuleResponse, out errRecord); - if (errRecord != null) + if (!_useGraphQL) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); - } + int initialModuleCount = GetCountFromResponse(initialModuleResponse, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } - if (initialModuleCount != 0) - { - responses.Add(initialModuleResponse); - int count = initialModuleCount / 100; - // if more than 100 count, loop and add response to list - while (count > 0) + if (initialModuleCount != 0) { - _cmdletPassedIn.WriteDebug($"Count is '{count}'"); - moduleSkip += 100; - var tmpResponse = FindTagFromEndpoint(tags, includePrerelease, isSearchingModule: true, moduleSkip, out errRecord); - if (errRecord != null) + responses.Add(initialModuleResponse); + int count = initialModuleCount / 100; + // if more than 100 count, loop and add response to list + while (count > 0) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + _cmdletPassedIn.WriteDebug($"Count is '{count}'"); + moduleSkip += 100; + var tmpResponse = FindTagFromEndpoint(tags, includePrerelease, isSearchingModule: true, moduleSkip, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + + responses.Add(tmpResponse); + count--; } - - responses.Add(tmpResponse); - count--; } } + else if(!initialModuleResponse.Equals("\"\"")) + { + responses.Add(initialModuleResponse); + } } - if (responses.Count == 0) + if (!_useGraphQL && responses.Count == 0) { errRecord = new ErrorRecord( new ResourceNotFoundException($"Package with Tags '{String.Join(", ", tags)}' could not be found in repository '{Repository.Name}'."), @@ -360,38 +395,54 @@ public override FindResults FindName(string packageName, bool includePrerelease, filterBuilder.AddCriterion(GetTypeFilterForRequest(type)); } - var requestUrlV2 = $"{Repository.Uri}/FindPackagesById()?{queryBuilder.BuildQueryString()}"; - string response = HttpRequestCall(requestUrlV2, out errRecord); - if (errRecord != null) + var requestUrlV2 = ""; + string response = ""; + errRecord = null; + + if (_useGraphQL) { - // usually this is for errors in calling the V2 server, but for ADO V2 this error will include package not found errors which we want to deliver in a standard message - if (_isADORepo && errRecord.Exception is ResourceNotFoundException) + requestUrlV2 = $"{_graphQLUrl}/api/v2/FindPackagesById?{queryBuilder.BuildQueryString()}"; + response = HttpRequestCall(requestUrlV2, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + } + else + { + requestUrlV2 = $"{Repository.Uri}/FindPackagesById()?{queryBuilder.BuildQueryString()}"; + response = HttpRequestCall(requestUrlV2, out errRecord); + if (errRecord != null) + { + // usually this is for errors in calling the V2 server, but for ADO V2 this error will include package not found errors which we want to deliver in a standard message + if (_isADORepo && errRecord.Exception is ResourceNotFoundException) + { + errRecord = new ErrorRecord( + new ResourceNotFoundException($"Package with name '{packageName}' could not be found in repository '{Repository.Name}'. For ADO feed, if the package is in an upstream feed make sure you are authenticated to the upstream feed.", errRecord.Exception), + "PackageNotFound", + ErrorCategory.ObjectNotFound, + this); + response = string.Empty; + } + + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + + int count = GetCountFromResponse(response, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + + if (count == 0) { errRecord = new ErrorRecord( - new ResourceNotFoundException($"Package with name '{packageName}' could not be found in repository '{Repository.Name}'. For ADO feed, if the package is in an upstream feed make sure you are authenticated to the upstream feed.", errRecord.Exception), + new ResourceNotFoundException($"Package with name '{packageName}' could not be found in repository '{Repository.Name}'."), "PackageNotFound", ErrorCategory.ObjectNotFound, this); response = string.Empty; } - - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); - } - - int count = GetCountFromResponse(response, out errRecord); - if (errRecord != null) - { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); - } - - if (count == 0) - { - errRecord = new ErrorRecord( - new ResourceNotFoundException($"Package with name '{packageName}' could not be found in repository '{Repository.Name}'."), - "PackageNotFound", - ErrorCategory.ObjectNotFound, - this); - response = string.Empty; } return new FindResults(stringResponse: new string[]{ response }, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); @@ -589,35 +640,42 @@ public override FindResults FindVersionGlobbing(string packageName, VersionRange return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); } - int initialCount = GetCountFromResponse(initialResponse, out errRecord); - if (errRecord != null) + if (_useGraphQL) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + responses.Add(initialResponse); } - - if (initialCount == 0) + else { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); - } + int initialCount = GetCountFromResponse(initialResponse, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } - responses.Add(initialResponse); + if (initialCount == 0) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } - if (!getOnlyLatest) - { - int count = (int)Math.Ceiling((double)(initialCount / 100)); + responses.Add(initialResponse); - while (count > 0) + if (!getOnlyLatest) { - _cmdletPassedIn.WriteDebug($"Count is '{count}'"); - // skip 100 - skip += 100; - var tmpResponse = FindVersionGlobbing(packageName, versionRange, includePrerelease, type, skip, getOnlyLatest, out errRecord); - if (errRecord != null) + int count = (int)Math.Ceiling((double)(initialCount / 100)); + + while (count > 0) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + _cmdletPassedIn.WriteDebug($"Count is '{count}'"); + // skip 100 + skip += 100; + var tmpResponse = FindVersionGlobbing(packageName, versionRange, includePrerelease, type, skip, getOnlyLatest, out errRecord); + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + responses.Add(tmpResponse); + count--; } - responses.Add(tmpResponse); - count--; } } @@ -655,7 +713,16 @@ public override FindResults FindVersion(string packageName, string version, Reso filterBuilder.AddCriterion(GetTypeFilterForRequest(type)); } - var requestUrlV2 = $"{Repository.Uri}/FindPackagesById()?{queryBuilder.BuildQueryString()}"; + string requestUrlV2 = ""; + if (_useGraphQL) + { + requestUrlV2 = $"{_graphQLUrl}/api/v2/FindPackagesById?{queryBuilder.BuildQueryString()}"; + } + else + { + requestUrlV2 = $"{Repository.Uri}/FindPackagesById()?{queryBuilder.BuildQueryString()}"; + } + string response = HttpRequestCall(requestUrlV2, out errRecord); if (errRecord != null) { @@ -673,22 +740,25 @@ public override FindResults FindVersion(string packageName, string version, Reso return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); } - int count = GetCountFromResponse(response, out errRecord); - _cmdletPassedIn.WriteDebug($"Count from response is '{count}'"); - - if (errRecord != null) + if (!_useGraphQL) { - return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); - } + int count = GetCountFromResponse(response, out errRecord); + _cmdletPassedIn.WriteDebug($"Count from response is '{count}'"); - if (count == 0) - { - errRecord = new ErrorRecord( - new ResourceNotFoundException($"Package with name '{packageName}', version '{version}' could not be found in repository '{Repository.Name}'."), - "PackageNotFound", - ErrorCategory.ObjectNotFound, - this); - response = string.Empty; + if (errRecord != null) + { + return new FindResults(stringResponse: Utils.EmptyStrArray, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); + } + + if (count == 0) + { + errRecord = new ErrorRecord( + new ResourceNotFoundException($"Package with name '{packageName}', version '{version}' could not be found in repository '{Repository.Name}'."), + "PackageNotFound", + ErrorCategory.ObjectNotFound, + this); + response = string.Empty; + } } return new FindResults(stringResponse: new string[] { response }, hashtableResponse: emptyHashResponses, responseType: v2FindResponseType); @@ -935,7 +1005,16 @@ private string FindAllFromTypeEndPoint(bool includePrerelease, bool isSearchingM } } - var requestUrlV2 = $"{Repository.Uri}{typeEndpoint}/Search()?{queryBuilder.BuildQueryString()}"; + string requestUrlV2 = ""; + if (_useGraphQL) + { + requestUrlV2 = $"{_graphQLUrl}/api/v2/FindPackagesById?{queryBuilder.BuildQueryString()}"; + } + else + { + requestUrlV2 = $"{Repository.Uri}{typeEndpoint}/Search()?{queryBuilder.BuildQueryString()}"; + } + return HttpRequestCall(requestUrlV2, out errRecord); } @@ -991,7 +1070,15 @@ private string FindTagFromEndpoint(string[] tags, bool includePrerelease, bool i filterBuilder.AddCriterion($"substringof('{tag}', Tags) eq true"); } - var requestUrlV2 = $"{Repository.Uri}{typeEndpoint}/Search()?{queryBuilder.BuildQueryString()}"; + string requestUrlV2 = ""; + if (_useGraphQL) + { + requestUrlV2 = $"{_graphQLUrl}/api/v2/FindPackagesById?{queryBuilder.BuildQueryString()}"; + } + else + { + requestUrlV2 = $"{Repository.Uri}{typeEndpoint}/Search()?{queryBuilder.BuildQueryString()}"; + } return HttpRequestCall(requestUrlV2: requestUrlV2, out errRecord); } @@ -1366,8 +1453,15 @@ private string FindVersionGlobbing(string packageName, VersionRange versionRange filterBuilder.AddCriterion($"substringof('PS{type.ToString()}', Tags) eq true"); } - - var requestUrlV2 = $"{Repository.Uri}/FindPackagesById()?{queryBuilder.BuildQueryString()}"; + string requestUrlV2 = ""; + if (_useGraphQL) + { + requestUrlV2 = $"{_graphQLUrl}/api/v2/FindPackagesById?{queryBuilder.BuildQueryString()}"; + } + else + { + requestUrlV2 = $"{Repository.Uri}/FindPackagesById()?{queryBuilder.BuildQueryString()}"; + } return HttpRequestCall(requestUrlV2, out errRecord); }