public static NpmPackage ToNpmPackage(this Package package)
        {
            var npmPackage = new NpmPackage()
            {
                Id      = package.Id,
                Version = package.Version,
                Name    = package.Title,
                Dist    = new Dictionary <string, string>()
                {
                    { NpmPackage.ArchiveKey, package.PackageDownloadUrl },
                    { NpmPackage.HashKey, package.PackageHash }
                }
            };

            return(npmPackage);
        }
        public static Package ToPackage(this NpmPackage npmPackage)
        {
            var match      = Regex.Match(npmPackage.Id, prereleaseRegEx);
            var prerelease = match.Groups["Prerelease"].Value.Any();
            var package    = new Package()
            {
                // Remove the version from the NPM Package ID. SynchroFeed uses Id and Version together to uniquely identify a package.
                Id                 = npmPackage.Id.Substring(1).LastIndexOf('@') == -1 ? npmPackage.Id : npmPackage.Id.Substring(0, npmPackage.Id.LastIndexOf('@')),
                Version            = npmPackage.Version,
                Title              = npmPackage.Name,
                PackageDownloadUrl = npmPackage.Dist[NpmPackage.ArchiveKey],
                PackageHash        = npmPackage.Dist[NpmPackage.HashKey],
                IsPrerelease       = prerelease
            };

            return(package);
        }
        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));
        }