{"action":"created","comment":{"url":"https://api.github.com/repos/strongbox/strongbox/pulls/comments/152714832","pull_request_review_id":78617669,"id":152714832,"diff_hunk":"@@ -0,0 +1,313 @@\n+package org.carlspring.strongbox.controllers.npm;\n+\n+import java.io.ByteArrayInputStream;\n+import java.io.IOException;\n+import java.io.InputStream;\n+import java.io.OutputStream;\n+import java.io.StringWriter;\n+import java.nio.file.Files;\n+import java.nio.file.Path;\n+import java.nio.file.StandardCopyOption;\n+import java.nio.file.StandardOpenOption;\n+import java.security.NoSuchAlgorithmException;\n+import java.util.Optional;\n+\n+import javax.inject.Inject;\n+import javax.servlet.ServletInputStream;\n+import javax.servlet.http.HttpServletRequest;\n+import javax.ws.rs.core.MediaType;\n+\n+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;\n+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;\n+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;\n+import org.apache.commons.io.IOUtils;\n+import org.carlspring.strongbox.artifact.coordinates.NpmArtifactCoordinates;\n+import org.carlspring.strongbox.controllers.BaseArtifactController;\n+import org.carlspring.strongbox.npm.metadata.Package;\n+import org.carlspring.strongbox.providers.ProviderImplementationException;\n+import org.carlspring.strongbox.providers.io.RepositoryPath;\n+import org.carlspring.strongbox.providers.layout.NpmLayoutProvider;\n+import org.carlspring.strongbox.services.ArtifactManagementService;\n+import org.carlspring.strongbox.storage.repository.Repository;\n+import org.javatuples.Pair;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+import org.springframework.beans.factory.annotation.Qualifier;\n+import org.springframework.http.ResponseEntity;\n+import org.springframework.security.access.prepost.PreAuthorize;\n+import org.springframework.util.Assert;\n+import org.springframework.web.bind.annotation.PathVariable;\n+import org.springframework.web.bind.annotation.RequestMapping;\n+import org.springframework.web.bind.annotation.RequestMethod;\n+import org.springframework.web.bind.annotation.RestController;\n+\n+import com.fasterxml.jackson.core.JsonFactory;\n+import com.fasterxml.jackson.core.JsonParser;\n+import com.fasterxml.jackson.core.JsonProcessingException;\n+import com.fasterxml.jackson.core.JsonToken;\n+import com.fasterxml.jackson.databind.JsonNode;\n+import com.fasterxml.jackson.databind.ObjectMapper;\n+\n+/**\n+ * This Controller used to handle npm requests.\n+ * \n+ * @author Sergey Bespalov\n+ *\n+ */\n+@RestController\n+@RequestMapping(path = NpmPackageController.ROOT_CONTEXT, headers = \"user-agent=npm/*\")\n+public class NpmPackageController extends BaseArtifactController\n+{\n+\n+    private static final String FIELD_NAME_LENGTH = \"length\";\n+\n+    private static final String FIELD_NAME_ATTACHMENTS = \"_attachments\";\n+\n+    private static final String FIELD_NAME_VERSION = \"versions\";\n+\n+    private static final Logger logger = LoggerFactory.getLogger(NpmPackageController.class);\n+\n+    public final static String ROOT_CONTEXT = \"/storages\";\n+\n+    @Inject\n+    private ArtifactManagementService npmArtifactManagementService;\n+\n+    @Inject\n+    private NpmLayoutProvider npmLayoutProvider;\n+\n+    @Inject\n+    @Qualifier(\"npmJackasonMapper\")\n+    private ObjectMapper npmJackasonMapper;\n+\n+    @PreAuthorize(\"hasAuthority('ARTIFACTS_DEPLOY')\")\n+    @RequestMapping(path = \"{storageId}/{repositoryId}/{name:.+}\", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON)\n+    public ResponseEntity publish(@PathVariable(name = \"storageId\") String storageId,\n+                                  @PathVariable(name = \"repositoryId\") String repositoryId,\n+                                  @PathVariable(name = \"name\") String name,","path":"strongbox-web-core/src/main/java/org/carlspring/strongbox/controllers/npm/NpmPackageController.java","position":86,"original_position":86,"commit_id":"c8619429bb8be1e1c0e1e21a1435c73aa38a38a9","original_commit_id":"c8619429bb8be1e1c0e1e21a1435c73aa38a38a9","user":{"login":"sbespalov","id":22783811,"avatar_url":"https://avatars2.githubusercontent.com/u/22783811?v=4","gravatar_id":"","url":"https://api.github.com/users/sbespalov","html_url":"https://github.com/sbespalov","followers_url":"https://api.github.com/users/sbespalov/followers","following_url":"https://api.github.com/users/sbespalov/following{/other_user}","gists_url":"https://api.github.com/users/sbespalov/gists{/gist_id}","starred_url":"https://api.github.com/users/sbespalov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sbespalov/subscriptions","organizations_url":"https://api.github.com/users/sbespalov/orgs","repos_url":"https://api.github.com/users/sbespalov/repos","events_url":"https://api.github.com/users/sbespalov/events{/privacy}","received_events_url":"https://api.github.com/users/sbespalov/received_events","type":"User","site_admin":false},"body":"`name` is how it named in npm. [see here](https://docs.npmjs.com/files/package.json#name)","created_at":"2017-11-23T02:17:42Z","updated_at":"2017-11-23T02:17:42Z","html_url":"https://github.com/strongbox/strongbox/pull/383#discussion_r152714832","pull_request_url":"https://api.github.com/repos/strongbox/strongbox/pulls/383","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/strongbox/strongbox/pulls/comments/152714832"},"html":{"href":"https://github.com/strongbox/strongbox/pull/383#discussion_r152714832"},"pull_request":{"href":"https://api.github.com/repos/strongbox/strongbox/pulls/383"}},"in_reply_to_id":152656830},"pull_request":{"url":"https://api.github.com/repos/strongbox/strongbox/pulls/383","id":152042465,"html_url":"https://github.com/strongbox/strongbox/pull/383","diff_url":"https://github.com/strongbox/strongbox/pull/383.diff","patch_url":"https://github.com/strongbox/strongbox/pull/383.patch","issue_url":"https://api.github.com/repos/strongbox/strongbox/issues/383","number":383,"state":"open","locked":false,"title":"SB-884: NPM layout provider initial implementation [ready]","user":{"login":"sbespalov","id":22783811,"avatar_url":"https://avatars2.githubusercontent.com/u/22783811?v=4","gravatar_id":"","url":"https://api.github.com/users/sbespalov","html_url":"https://github.com/sbespalov","followers_url":"https://api.github.com/users/sbespalov/followers","following_url":"https://api.github.com/users/sbespalov/following{/other_user}","gists_url":"https://api.github.com/users/sbespalov/gists{/gist_id}","starred_url":"https://api.github.com/users/sbespalov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sbespalov/subscriptions","organizations_url":"https://api.github.com/users/sbespalov/orgs","repos_url":"https://api.github.com/users/sbespalov/repos","events_url":"https://api.github.com/users/sbespalov/events{/privacy}","received_events_url":"https://api.github.com/users/sbespalov/received_events","type":"User","site_admin":false},"body":"","created_at":"2017-11-11T05:07:49Z","updated_at":"2017-11-23T02:17:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0d54212205c965b9f5a56c9b12f9cad2fcf1b92c","assignee":null,"assignees":[],"requested_reviewers":[{"login":"fuss86","id":12829566,"avatar_url":"https://avatars1.githubusercontent.com/u/12829566?v=4","gravatar_id":"","url":"https://api.github.com/users/fuss86","html_url":"https://github.com/fuss86","followers_url":"https://api.github.com/users/fuss86/followers","following_url":"https://api.github.com/users/fuss86/following{/other_user}","gists_url":"https://api.github.com/users/fuss86/gists{/gist_id}","starred_url":"https://api.github.com/users/fuss86/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fuss86/subscriptions","organizations_url":"https://api.github.com/users/fuss86/orgs","repos_url":"https://api.github.com/users/fuss86/repos","events_url":"https://api.github.com/users/fuss86/events{/privacy}","received_events_url":"https://api.github.com/users/fuss86/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/strongbox/strongbox/pulls/383/commits","review_comments_url":"https://api.github.com/repos/strongbox/strongbox/pulls/383/comments","review_comment_url":"https://api.github.com/repos/strongbox/strongbox/pulls/comments{/number}","comments_url":"https://api.github.com/repos/strongbox/strongbox/issues/383/comments","statuses_url":"https://api.github.com/repos/strongbox/strongbox/statuses/c8619429bb8be1e1c0e1e21a1435c73aa38a38a9","head":{"label":"sbespalov:sbespalov_SB-884","ref":"sbespalov_SB-884","sha":"c8619429bb8be1e1c0e1e21a1435c73aa38a38a9","user":{"login":"sbespalov","id":22783811,"avatar_url":"https://avatars2.githubusercontent.com/u/22783811?v=4","gravatar_id":"","url":"https://api.github.com/users/sbespalov","html_url":"https://github.com/sbespalov","followers_url":"https://api.github.com/users/sbespalov/followers","following_url":"https://api.github.com/users/sbespalov/following{/other_user}","gists_url":"https://api.github.com/users/sbespalov/gists{/gist_id}","starred_url":"https://api.github.com/users/sbespalov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sbespalov/subscriptions","organizations_url":"https://api.github.com/users/sbespalov/orgs","repos_url":"https://api.github.com/users/sbespalov/repos","events_url":"https://api.github.com/users/sbespalov/events{/privacy}","received_events_url":"https://api.github.com/users/sbespalov/received_events","type":"User","site_admin":false},"repo":{"id":72494340,"name":"strongbox","full_name":"sbespalov/strongbox","owner":{"login":"sbespalov","id":22783811,"avatar_url":"https://avatars2.githubusercontent.com/u/22783811?v=4","gravatar_id":"","url":"https://api.github.com/users/sbespalov","html_url":"https://github.com/sbespalov","followers_url":"https://api.github.com/users/sbespalov/followers","following_url":"https://api.github.com/users/sbespalov/following{/other_user}","gists_url":"https://api.github.com/users/sbespalov/gists{/gist_id}","starred_url":"https://api.github.com/users/sbespalov/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sbespalov/subscriptions","organizations_url":"https://api.github.com/users/sbespalov/orgs","repos_url":"https://api.github.com/users/sbespalov/repos","events_url":"https://api.github.com/users/sbespalov/events{/privacy}","received_events_url":"https://api.github.com/users/sbespalov/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/sbespalov/strongbox","description":null,"fork":true,"url":"https://api.github.com/repos/sbespalov/strongbox","forks_url":"https://api.github.com/repos/sbespalov/strongbox/forks","keys_url":"https://api.github.com/repos/sbespalov/strongbox/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sbespalov/strongbox/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sbespalov/strongbox/teams","hooks_url":"https://api.github.com/repos/sbespalov/strongbox/hooks","issue_events_url":"https://api.github.com/repos/sbespalov/strongbox/issues/events{/number}","events_url":"https://api.github.com/repos/sbespalov/strongbox/events","assignees_url":"https://api.github.com/repos/sbespalov/strongbox/assignees{/user}","branches_url":"https://api.github.com/repos/sbespalov/strongbox/branches{/branch}","tags_url":"https://api.github.com/repos/sbespalov/strongbox/tags","blobs_url":"https://api.github.com/repos/sbespalov/strongbox/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sbespalov/strongbox/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sbespalov/strongbox/git/refs{/sha}","trees_url":"https://api.github.com/repos/sbespalov/strongbox/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sbespalov/strongbox/statuses/{sha}","languages_url":"https://api.github.com/repos/sbespalov/strongbox/languages","stargazers_url":"https://api.github.com/repos/sbespalov/strongbox/stargazers","contributors_url":"https://api.github.com/repos/sbespalov/strongbox/contributors","subscribers_url":"https://api.github.com/repos/sbespalov/strongbox/subscribers","subscription_url":"https://api.github.com/repos/sbespalov/strongbox/subscription","commits_url":"https://api.github.com/repos/sbespalov/strongbox/commits{/sha}","git_commits_url":"https://api.github.com/repos/sbespalov/strongbox/git/commits{/sha}","comments_url":"https://api.github.com/repos/sbespalov/strongbox/comments{/number}","issue_comment_url":"https://api.github.com/repos/sbespalov/strongbox/issues/comments{/number}","contents_url":"https://api.github.com/repos/sbespalov/strongbox/contents/{+path}","compare_url":"https://api.github.com/repos/sbespalov/strongbox/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sbespalov/strongbox/merges","archive_url":"https://api.github.com/repos/sbespalov/strongbox/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sbespalov/strongbox/downloads","issues_url":"https://api.github.com/repos/sbespalov/strongbox/issues{/number}","pulls_url":"https://api.github.com/repos/sbespalov/strongbox/pulls{/number}","milestones_url":"https://api.github.com/repos/sbespalov/strongbox/milestones{/number}","notifications_url":"https://api.github.com/repos/sbespalov/strongbox/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sbespalov/strongbox/labels{/name}","releases_url":"https://api.github.com/repos/sbespalov/strongbox/releases{/id}","deployments_url":"https://api.github.com/repos/sbespalov/strongbox/deployments","created_at":"2016-11-01T01:54:58Z","updated_at":"2016-11-01T01:55:00Z","pushed_at":"2017-11-22T09:41:55Z","git_url":"git://github.com/sbespalov/strongbox.git","ssh_url":"git@github.com:sbespalov/strongbox.git","clone_url":"https://github.com/sbespalov/strongbox.git","svn_url":"https://github.com/sbespalov/strongbox","homepage":null,"size":6575,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"strongbox:master","ref":"master","sha":"db35eeab6d4460e448bb607beb5dcf7bdbafaf28","user":{"login":"strongbox","id":5637881,"avatar_url":"https://avatars0.githubusercontent.com/u/5637881?v=4","gravatar_id":"","url":"https://api.github.com/users/strongbox","html_url":"https://github.com/strongbox","followers_url":"https://api.github.com/users/strongbox/followers","following_url":"https://api.github.com/users/strongbox/following{/other_user}","gists_url":"https://api.github.com/users/strongbox/gists{/gist_id}","starred_url":"https://api.github.com/users/strongbox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongbox/subscriptions","organizations_url":"https://api.github.com/users/strongbox/orgs","repos_url":"https://api.github.com/users/strongbox/repos","events_url":"https://api.github.com/users/strongbox/events{/privacy}","received_events_url":"https://api.github.com/users/strongbox/received_events","type":"Organization","site_admin":false},"repo":{"id":11830269,"name":"strongbox","full_name":"strongbox/strongbox","owner":{"login":"strongbox","id":5637881,"avatar_url":"https://avatars0.githubusercontent.com/u/5637881?v=4","gravatar_id":"","url":"https://api.github.com/users/strongbox","html_url":"https://github.com/strongbox","followers_url":"https://api.github.com/users/strongbox/followers","following_url":"https://api.github.com/users/strongbox/following{/other_user}","gists_url":"https://api.github.com/users/strongbox/gists{/gist_id}","starred_url":"https://api.github.com/users/strongbox/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongbox/subscriptions","organizations_url":"https://api.github.com/users/strongbox/orgs","repos_url":"https://api.github.com/users/strongbox/repos","events_url":"https://api.github.com/users/strongbox/events{/privacy}","received_events_url":"https://api.github.com/users/strongbox/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/strongbox/strongbox","description":"Strongbox is an artifact repository manager.","fork":false,"url":"https://api.github.com/repos/strongbox/strongbox","forks_url":"https://api.github.com/repos/strongbox/strongbox/forks","keys_url":"https://api.github.com/repos/strongbox/strongbox/keys{/key_id}","collaborators_url":"https://api.github.com/repos/strongbox/strongbox/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/strongbox/strongbox/teams","hooks_url":"https://api.github.com/repos/strongbox/strongbox/hooks","issue_events_url":"https://api.github.com/repos/strongbox/strongbox/issues/events{/number}","events_url":"https://api.github.com/repos/strongbox/strongbox/events","assignees_url":"https://api.github.com/repos/strongbox/strongbox/assignees{/user}","branches_url":"https://api.github.com/repos/strongbox/strongbox/branches{/branch}","tags_url":"https://api.github.com/repos/strongbox/strongbox/tags","blobs_url":"https://api.github.com/repos/strongbox/strongbox/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/strongbox/strongbox/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/strongbox/strongbox/git/refs{/sha}","trees_url":"https://api.github.com/repos/strongbox/strongbox/git/trees{/sha}","statuses_url":"https://api.github.com/repos/strongbox/strongbox/statuses/{sha}","languages_url":"https://api.github.com/repos/strongbox/strongbox/languages","stargazers_url":"https://api.github.com/repos/strongbox/strongbox/stargazers","contributors_url":"https://api.github.com/repos/strongbox/strongbox/contributors","subscribers_url":"https://api.github.com/repos/strongbox/strongbox/subscribers","subscription_url":"https://api.github.com/repos/strongbox/strongbox/subscription","commits_url":"https://api.github.com/repos/strongbox/strongbox/commits{/sha}","git_commits_url":"https://api.github.com/repos/strongbox/strongbox/git/commits{/sha}","comments_url":"https://api.github.com/repos/strongbox/strongbox/comments{/number}","issue_comment_url":"https://api.github.com/repos/strongbox/strongbox/issues/comments{/number}","contents_url":"https://api.github.com/repos/strongbox/strongbox/contents/{+path}","compare_url":"https://api.github.com/repos/strongbox/strongbox/compare/{base}...{head}","merges_url":"https://api.github.com/repos/strongbox/strongbox/merges","archive_url":"https://api.github.com/repos/strongbox/strongbox/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/strongbox/strongbox/downloads","issues_url":"https://api.github.com/repos/strongbox/strongbox/issues{/number}","pulls_url":"https://api.github.com/repos/strongbox/strongbox/pulls{/number}","milestones_url":"https://api.github.com/repos/strongbox/strongbox/milestones{/number}","notifications_url":"https://api.github.com/repos/strongbox/strongbox/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/strongbox/strongbox/labels{/name}","releases_url":"https://api.github.com/repos/strongbox/strongbox/releases{/id}","deployments_url":"https://api.github.com/repos/strongbox/strongbox/deployments","created_at":"2013-08-01T23:27:37Z","updated_at":"2017-11-16T13:54:55Z","pushed_at":"2017-11-22T23:17:54Z","git_url":"git://github.com/strongbox/strongbox.git","ssh_url":"git@github.com:strongbox/strongbox.git","clone_url":"https://github.com/strongbox/strongbox.git","svn_url":"https://github.com/strongbox/strongbox","homepage":"","size":6555,"stargazers_count":10,"watchers_count":10,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":27,"mirror_url":null,"archived":false,"open_issues_count":13,"forks":27,"open_issues":13,"watchers":10,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/strongbox/strongbox/pulls/383"},"html":{"href":"https://github.com/strongbox/strongbox/pull/383"},"issue":{"href":"https://api.github.com/repos/strongbox/strongbox/issues/383"},"comments":{"href":"https://api.github.com/repos/strongbox/strongbox/issues/383/comments"},"review_comments":{"href":"https://api.github.com/repos/strongbox/strongbox/pulls/383/comments"},"review_comment":{"href":"https://api.github.com/repos/strongbox/strongbox/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/strongbox/strongbox/pulls/383/commits"},"statuses":{"href":"https://api.github.com/repos/strongbox/strongbox/statuses/c8619429bb8be1e1c0e1e21a1435c73aa38a38a9"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"sbespalov"}}