private static async Task <NpmPackageInfo> CreatePackageInfoAsync(string packageName, NpmPackageInfo packageInfo, CancellationToken cancellationToken)
        {
            try
            {
                string  packageInfoUrl  = string.Format(NpmPackageInfoUrl, packageName);
                JObject packageInfoJSON = await WebRequestHandler.Instance.GetJsonObjectViaGetAsync(packageInfoUrl, cancellationToken).ConfigureAwait(false);

                if (packageInfoJSON != null && packageInfo == null)
                {
                    packageInfo = NpmPackageInfo.Parse(packageInfoJSON);
                }

                JObject versionsList = packageInfoJSON["versions"] as JObject;
                if (versionsList != null)
                {
                    List <SemanticVersion> semanticVersions = versionsList.Properties().Select(p => SemanticVersion.Parse(p.Name)).ToList <SemanticVersion>();
                    string latestVersion = semanticVersions.Max().OriginalText;
                    IList <SemanticVersion> filteredSemanticVersions = FilterOldPrereleaseVersions(semanticVersions);

                    packageInfo = new NpmPackageInfo(packageInfo.Name, packageInfo.Description, latestVersion, filteredSemanticVersions);
                }
            }
            catch (Exception)
            {
                packageInfo = new NpmPackageInfo(
                    packageName,
                    Resources.Text.LibraryDetail_Unavailable,
                    Resources.Text.LibraryDetail_Unavailable);
            }

            return(packageInfo);
        }
        private static async Task <NpmPackageInfo> GetPackageInfoForUnscopedPackageAsync(string packageName, CancellationToken cancellationToken)
        {
            NpmPackageInfo packageInfo = null;

            try
            {
                string  packageInfoUrl  = string.Format(NpmLatestPackgeInfoUrl, packageName);
                JObject packageInfoJSON = await WebRequestHandler.Instance.GetJsonObjectViaGetAsync(packageInfoUrl, cancellationToken).ConfigureAwait(false);

                if (packageInfoJSON != null)
                {
                    packageInfo = NpmPackageInfo.Parse(packageInfoJSON);
                }
            }
            catch (Exception)
            {
                packageInfo = new NpmPackageInfo(
                    packageName,
                    Resources.Text.LibraryDetail_Unavailable,
                    Resources.Text.LibraryDetail_Unavailable,
                    Resources.Text.LibraryDetail_Unavailable,
                    Resources.Text.LibraryDetail_Unavailable,
                    Resources.Text.LibraryDetail_Unavailable);
            }

            return(await CreatePackageInfoAsync(packageName, packageInfo, cancellationToken));
        }
Esempio n. 3
0
        private static async Task <IEnumerable <NpmPackageInfo> > GetPackageNamesWithScopeAsync(string searchTerm, CancellationToken cancellationToken)
        {
            Debug.Assert(searchTerm.StartsWith("@", StringComparison.Ordinal));
            List <NpmPackageInfo> packages = new List <NpmPackageInfo>();

            int slash = searchTerm.IndexOf("/", StringComparison.Ordinal);

            if (slash > 0)
            {
                string scope       = searchTerm.Substring(1, slash - 1);
                string packageName = searchTerm.Substring(slash + 1);

                // URL encode the values in the query to avoid a BadRequest
                scope       = HttpUtility.UrlEncode(scope);
                packageName = HttpUtility.UrlEncode(packageName);

                string searchUrl = string.Format(NpmsPackageSearchUrl, scope, packageName);

                JObject packageListJsonObject = await WebRequestHandler.Instance.GetJsonObjectViaGetAsync(searchUrl, cancellationToken);

                if (packageListJsonObject != null)
                {
                    // We get back something like this:
                    // {
                    //  "total":46,
                    //  "results": [
                    //      {
                    //          "package": {
                    //              "name":"@types/d3-selection",
                    //              /* lots of other crap */
                    //          }
                    //      },
                    //      {
                    //         "package": {
                    //              "name":"@types/d3-array",
                    //          }
                    //      }, ...

                    JArray resultsValues = packageListJsonObject["results"] as JArray;
                    if (resultsValues != null)
                    {
                        foreach (JObject packageEntry in resultsValues.Children())
                        {
                            if (packageEntry != null)
                            {
                                JObject packageDetails = packageEntry["package"] as JObject;
                                if (packageDetails != null)
                                {
                                    NpmPackageInfo packageInfo = NpmPackageInfo.Parse(packageDetails);
                                    packages.Add(packageInfo);
                                }
                            }
                        }
                    }
                }
            }

            return(packages);
        }
Esempio n. 4
0
        private async Task <IEnumerable <NpmPackageInfo> > GetPackageNamesFromSimpleQueryAsync(string searchTerm, CancellationToken cancellationToken)
        {
            string packageListUrl = string.Format(CultureInfo.InvariantCulture, NpmPackageSearchUrl, searchTerm);
            var    packages       = new List <NpmPackageInfo>();

            try
            {
                JObject topLevelObject = await _requestHandler.GetJsonObjectViaGetAsync(packageListUrl, cancellationToken).ConfigureAwait(false);

                if (topLevelObject != null)
                {
                    // We get back something like this:
                    //
                    //{
                    //  "objects": [
                    //    {
                    //      "package": {
                    //        "name": "yargs",
                    //        "version": "6.6.0",
                    //        "description": "yargs the modern, pirate-themed, successor to optimist.",
                    //        "keywords": [
                    //          "argument",
                    //          "args",
                    //          "option",
                    //          "parser",
                    //          "parsing",
                    //          "cli",
                    //          "command"
                    //        ],
                    //        "date": "2016-12-30T16:53:16.023Z",
                    //        "links": {
                    //          "npm": "https://www.npmjs.com/package/yargs",
                    //          "homepage": "http://yargs.js.org/",
                    //          "repository": "https://github.com/yargs/yargs",
                    //          "bugs": "https://github.com/yargs/yargs/issues"
                    //        },
                    //        "publisher": {
                    //          "username": "******",
                    //          "email": "*****@*****.**"
                    //        },
                    //        "maintainers": [
                    //          {
                    //            "username": "******",
                    //            "email": "*****@*****.**"
                    //          },
                    //          {
                    //            "username": "******",
                    //            "email": "*****@*****.**"
                    //          },
                    //          {
                    //            "username": "******",
                    //            "email": "*****@*****.**"
                    //          },
                    //          {
                    //            "username": "******",
                    //            "email": "*****@*****.**"
                    //          }
                    //        ]
                    //      },
                    //      "score": {
                    //        "final": 0.9237841281241451,
                    //        "detail": {
                    //          "quality": 0.9270640902288084,
                    //          "popularity": 0.8484861649808381,
                    //          "maintenance": 0.9962706951777409
                    //        }
                    //      },
                    //      "searchScore": 100000.914
                    //    }
                    //  ],
                    //  "total": 1,
                    //  "time": "Wed Jan 25 2017 19:23:35 GMT+0000 (UTC)"
                    //}

                    if (topLevelObject["objects"] is JArray searchResultList)
                    {
                        foreach (JObject searchResultObject in searchResultList.Children())
                        {
                            if (searchResultObject["package"] is JObject packageEntry)
                            {
                                var packageInfo = NpmPackageInfo.Parse(packageEntry);
                                packages.Add(packageInfo);
                            }
                        }
                    }
                }
            }
            catch
            {
                // TODO: telemetry.
                // should we report response failures separate from parse failures?
            }

            return(packages);
        }