예제 #1
0
        public static async Task <Error> NpmDeletePackageAsync(this NpmClient client, string packageId, string version)
        {
            var uri      = new Uri(client.Uri);
            var hostUri  = uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);
            var feedName = uri.Segments.Last().Replace("/", "");

            var sourceClient = new ProGetClient(hostUri, client.ApiKey);
            var sourceFeeds  = await sourceClient.Feeds_GetFeedsAsync(false);

            var sourceFeed = sourceFeeds.SingleOrDefault(f => f.Feed_Name.Equals(feedName, StringComparison.CurrentCultureIgnoreCase));

            if (sourceFeed == null)
            {
                return(new Error(HttpStatusCode.NotFound, $"NPM Feed not found {client.FeedName} on {client.Uri}"));
            }
            var(name, scope) = ParseNpmId(packageId);
            var result = await sourceClient.NpmPackages_DeletePackageAsync(sourceFeed.Feed_Id, name, scope, version);

            if (result)
            {
                return(null);
            }

            return(new Error(HttpStatusCode.ServiceUnavailable, "Error"));
        }
예제 #2
0
        private static async Task <Package> ConvertNpmPackageVersionToPackageAsync(NpmClient client, NpmPackageAllVersions npmPackageAllVersions)
        {
            var(npmPackage, error) = await client.NpmGetPackageAsync(GetNpmName(npmPackageAllVersions.Package_Name, npmPackageAllVersions.Scope_Name), npmPackageAllVersions.Version_Text);

            if (error != null)
            {
                throw new WebException(error.ErrorMessage);
            }

            var match      = Regex.Match(npmPackage.Id, prereleaseRegEx);
            var prerelease = match.Groups["Prerelease"].Value.Any();
            var package    = new Package
            {
                Id                 = ConvertNpmPackageNameToId(npmPackageAllVersions),
                Version            = npmPackageAllVersions.Version_Text,
                PackageDownloadUrl = npmPackage.Dist[NpmPackage.ArchiveKey],
                PackageHash        = npmPackage.Dist[NpmPackage.HashKey],
                IsPrerelease       = prerelease
            };

            return(package);
        }
예제 #3
0
        public static async Task <(NpmPackage Package, Error Error)> NpmAddPackageAsync(this NpmClient client, NpmPackage package, byte[] packageContent)
        {
            var publishPackage = new NpmPublish
            {
                Id          = package.Id,
                Name        = package.Name,
                Description = package.Description,
                Readme      = "",
                Versions    = new Dictionary <string, NpmPackage>
                {
                    { package.Version, package }
                },
            };

            var attachment = new NpmAttachment()
            {
                ContentType = MediaTypeNames.Application.Octet,
                Data        = Convert.ToBase64String(packageContent),
                Length      = packageContent.LongLength
            };

            var archiveUri = new Uri(package.Dist[NpmPackage.ArchiveKey]);

            publishPackage.Attachments = new Dictionary <string, NpmAttachment>
            {
                { archiveUri.Segments.Last(), attachment }
            };

            var content = new StringContent(JsonConvert.SerializeObject(publishPackage, new JsonSerializerSettings {
                MissingMemberHandling = MissingMemberHandling.Ignore
            }), Encoding.UTF8, "application/json");

            // TODO: Scope is included in the package.Name - need to do some testing to see if scope if actually needed
            using var response = await client.HttpClient.PutAsync(new Uri (new Uri(client.Uri), GetNpmPath(package.Name, package.Version)), content);

            if (response.IsSuccessStatusCode)
            {
                return(package, null);
            }

            return(null, new Error(response.StatusCode, response.ReasonPhrase));
        }
예제 #4
0
        public static async Task <(IEnumerable <Package> Packages, Error Error)> NpmFetchPackagesAsync(this NpmClient client, string searchTerm, bool includePreRelease, bool downloadPackageContent)
        {
            var uri      = new Uri(client.Uri);
            var hostUri  = uri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);
            var feedName = uri.Segments.Last().Replace("/", "");

            var  sourceClient = new ProGetClient(hostUri, client.ApiKey);
            Feed sourceFeed;

            try
            {
                sourceFeed = (await sourceClient.Feeds_GetFeedsAsync(false))
                             .SingleOrDefault(f => f.Feed_Name.Equals(feedName, StringComparison.CurrentCultureIgnoreCase));
            }
            catch (FlurlHttpException ex)
            {
                var statusCode = ex.Message.Contains("403")
                    ? HttpStatusCode.Forbidden
                    : HttpStatusCode.NotFound;

                return(null, new Error(statusCode, ex.Message));
            }

            if (sourceFeed == null)
            {
                return(null, new Error(HttpStatusCode.NotFound, $"Feed not found ({client.FeedName}) on {hostUri}"));
            }

            var packageVersions = await sourceClient.NpmFeeds_GetAllPackageVersionsAsync(sourceFeed.Feed_Id);

            var npmPackageVersionsArray = packageVersions as NpmPackageAllVersions[] ?? packageVersions.ToArray();

            var tasks = npmPackageVersionsArray
                        .Select(p => ConvertNpmPackageVersionToPackageAsync(client, p))
                        .ToArray();

            await Task.WhenAll(tasks);

            searchTerm ??= string.Empty;

            var packages = tasks
                           .Select(x => x.Result)
                           .Where(p => p.Id.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase) && (includePreRelease || !p.IsPrerelease))
                           .ToList();

            if (downloadPackageContent)
            {
                foreach (var package in packages)
                {
                    var(content, error) = await client.NpmDownloadPackageAsync(package);

                    if (error != null)
                    {
                        throw new WebException(error.ErrorMessage);
                    }

                    package.Content = content;
                }
            }

            return(packages, null);
        }
예제 #5
0
        public static async Task <(byte[] Content, Error Error)> NpmDownloadPackageAsync(this NpmClient client, Package package, bool validateHash = true)
        {
            using var packageDownloadResponse = await client.HttpClient.GetAsync(package.PackageDownloadUrl);

            if (packageDownloadResponse.IsSuccessStatusCode)
            {
                var content = await packageDownloadResponse.Content.ReadAsByteArrayAsync();

                if (validateHash && !HashValid(package, content))
                {
                    Console.WriteLine($"SHA1 hash of NPM package downloaded doesn't match expected SHA {package.PackageHash}");
                    return(content,
                           new Error(HttpStatusCode.InternalServerError, $"SHA1 hash of NPM package downloaded doesn't match expected SHA {package.PackageHash}"));
                }

                return(content, null);
            }

            return(null, new Error(packageDownloadResponse.StatusCode, packageDownloadResponse.ReasonPhrase));
        }
예제 #6
0
        public static async Task <(NpmPackage Package, Error Error)> NpmGetPackageAsync(this NpmClient client, string packageName, string version)
        {
            using var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri(new Uri(client.Uri), GetNpmPath(packageName, version)));
            requestMessage.Headers.Add("Accept", "application/json");
            using var response = await client.HttpClient.SendAsync(requestMessage);

            if (response.IsSuccessStatusCode)
            {
                var json = await response.Content.ReadAsStringAsync();

                var npmPackage = JsonConvert.DeserializeObject <NpmPackage>(json, new JsonSerializerSettings {
                    MissingMemberHandling = MissingMemberHandling.Ignore
                });
                return(npmPackage, null);
            }

            return(null, new Error(response.StatusCode, response.ReasonPhrase));
        }