From e429616f38de07272a51d7a9ed4202d9361b3e00 Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Wed, 29 Aug 2018 11:52:05 +0200 Subject: [PATCH 01/12] #8630 add the changeset endpoint getAll --- .../scm/api/v2/resources/RepositoryResource.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java index 3ee27f5f84..9066642167 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java @@ -37,6 +37,7 @@ public class RepositoryResource { private final Provider sourceRootResource; private final Provider contentResource; private final Provider permissionRootResource; + private final Provider diffRootResource; @Inject public RepositoryResource( @@ -45,7 +46,9 @@ public class RepositoryResource { Provider tagRootResource, Provider branchRootResource, Provider changesetRootResource, - Provider sourceRootResource, Provider contentResource, Provider permissionRootResource) { + Provider sourceRootResource, Provider contentResource, + Provider permissionRootResource, + Provider diffRootResource) { this.dtoToRepositoryMapper = dtoToRepositoryMapper; this.manager = manager; this.repositoryToDtoMapper = repositoryToDtoMapper; @@ -56,6 +59,7 @@ public class RepositoryResource { this.sourceRootResource = sourceRootResource; this.contentResource = contentResource; this.permissionRootResource = permissionRootResource; + this.diffRootResource = diffRootResource; } /** @@ -144,6 +148,11 @@ public class RepositoryResource { return tagRootResource.get(); } + @Path("diff/") + public DiffRootResource diff() { + return diffRootResource.get(); + } + @Path("branches/") public BranchRootResource branches(@PathParam("namespace") String namespace, @PathParam("name") String name) { return branchRootResource.get(); From c6203082e35ae7727a400d984bb259f55bd8a0e8 Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Wed, 29 Aug 2018 12:03:56 +0200 Subject: [PATCH 02/12] #8630 add the changeset endpoint getAll --- .../java/sonia/scm/repository/Changeset.java | 166 +++++++++--------- .../java/sonia/scm/repository/Person.java | 14 +- .../main/java/sonia/scm/web/VndMediaType.java | 2 + .../resources/BasicCollectionToDtoMapper.java | 24 +-- .../BranchCollectionToDtoMapper.java | 7 +- .../ChangesetCollectionToDtoMapper.java | 42 +++++ .../scm/api/v2/resources/ChangesetDto.java | 49 ++++++ .../v2/resources/ChangesetRootResource.java | 73 +++++++- .../ChangesetToChangesetDtoMapper.java | 78 ++++++++ .../resources/ChangesetToParentDtoMapper.java | 38 ++++ .../api/v2/resources/DiffRootResource.java | 27 +++ .../resources/GroupCollectionToDtoMapper.java | 2 +- .../scm/api/v2/resources/MapperModule.java | 5 + .../api/v2/resources/ParentChangesetDto.java | 27 +++ .../sonia/scm/api/v2/resources/PersonDto.java | 22 +++ .../RepositoryCollectionToDtoMapper.java | 2 +- .../RepositoryToRepositoryDtoMapper.java | 4 +- .../scm/api/v2/resources/ResourceLinks.java | 38 +++- .../v2/resources/TagCollectionResource.java | 18 -- .../resources/TagCollectionToDtoMapper.java | 49 ++++++ .../sonia/scm/api/v2/resources/TagDto.java | 24 +++ .../scm/api/v2/resources/TagRootResource.java | 27 +-- .../api/v2/resources/TagToTagDtoMapper.java | 31 ++++ .../resources/UserCollectionToDtoMapper.java | 2 +- .../v2/resources/BranchRootResourceTest.java | 2 +- .../resources/PermissionRootResourceTest.java | 13 +- .../resources/RepositoryRootResourceTest.java | 2 +- .../api/v2/resources/ResourceLinksMock.java | 2 +- .../api/v2/resources/ResourceLinksTest.java | 4 +- 29 files changed, 637 insertions(+), 157 deletions(-) create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetDto.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToChangesetDtoMapper.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToParentDtoMapper.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffRootResource.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/ParentChangesetDto.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/PersonDto.java delete mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionResource.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagCollectionToDtoMapper.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagDto.java create mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java diff --git a/scm-core/src/main/java/sonia/scm/repository/Changeset.java b/scm-core/src/main/java/sonia/scm/repository/Changeset.java index fecfd74cc9..ca2c9ac5db 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Changeset.java +++ b/scm-core/src/main/java/sonia/scm/repository/Changeset.java @@ -33,27 +33,20 @@ package sonia.scm.repository; -//~--- non-JDK imports -------------------------------------------------------- - import com.google.common.base.Objects; - import sonia.scm.BasicPropertiesAware; -import sonia.scm.Validateable; +import sonia.scm.ModelObject; import sonia.scm.util.Util; import sonia.scm.util.ValidationUtil; -//~--- JDK imports ------------------------------------------------------------ - -import java.io.Serializable; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + /** * Represents a changeset/commit of a repository. @@ -62,43 +55,58 @@ import javax.xml.bind.annotation.XmlRootElement; */ @XmlRootElement(name = "changeset") @XmlAccessorType(XmlAccessType.FIELD) -public class Changeset extends BasicPropertiesAware - implements Validateable, Serializable -{ +public class Changeset extends BasicPropertiesAware implements ModelObject { - /** Field description */ private static final long serialVersionUID = -8373308448928993039L; - //~--- constructors --------------------------------------------------------- + /** + * The author of the changeset + */ + private Person author; /** - * Constructs a new instance of changeset. - * + * The name of the branches on which the changeset was committed. */ + private List branches; + + /** + * The date when the changeset was committed + */ + private Long date; + + /** + * The text of the changeset description + */ + private String description; + + /** + * The changeset identification string + */ + private String id; + + /** + * List of files changed by this changeset + */ + @XmlElement(name = "modifications") + private Modifications modifications; + + /** + * parent changeset ids + */ + private List parents; + + /** + * The tags associated with the changeset + */ + private List tags; + public Changeset() {} - /** - * Constructs a new instance of changeset. - * - * - * @param id id of the changeset - * @param date date of the changeset - * @param author author of the changeset - */ public Changeset(String id, Long date, Person author) { this(id, date, author, null); } - /** - * Constructs a new instance of changeset. - * - * - * @param id id of the changeset - * @param date date of the changeset - * @param author author of the changeset - * @param description description of the changeset - */ public Changeset(String id, Long date, Person author, String description) { this.id = id; @@ -107,16 +115,6 @@ public class Changeset extends BasicPropertiesAware this.description = description; } - //~--- methods -------------------------------------------------------------- - - /** - * {@inheritDoc} - * - * - * @param obj - * - * @return - */ @Override public boolean equals(Object obj) { @@ -125,15 +123,14 @@ public class Changeset extends BasicPropertiesAware return false; } - if (getClass() != obj.getClass()) - { + if (getClass() != obj.getClass()) { return false; } final Changeset other = (Changeset) obj; //J- - return Objects.equal(id, other.id) + return Objects.equal(id, other.id) && Objects.equal(date, other.date) && Objects.equal(author, other.author) && Objects.equal(description, other.description) @@ -195,7 +192,21 @@ public class Changeset extends BasicPropertiesAware return out.toString(); } - //~--- get methods ---------------------------------------------------------- + + /** + * Returns a timestamp of the creation date of the {@link Changeset}. + * + * @return a timestamp of the creation date of the {@link Changeset} + */ + public Long getCreationDate() { + return getDate(); + } + + @Override + public void setCreationDate(Long timestamp) { + this.setDate(timestamp); + } + /** * Returns the author of the changeset. @@ -203,14 +214,13 @@ public class Changeset extends BasicPropertiesAware * * @return author of the changeset */ - public Person getAuthor() - { + public Person getAuthor() { return author; } /** - * Returns the branches of the changeset. In the most cases a changeset is - * only related to one branch, but in the case of receive hooks it is possible + * Returns the branches of the changeset. In the most cases a changeset is + * only related to one branch, but in the case of receive hooks it is possible * that a changeset is related to more than a branch. * * @@ -254,11 +264,27 @@ public class Changeset extends BasicPropertiesAware * * @return id of the changeset */ - public String getId() - { + @Override + public String getId() { return id; } + @Override + public void setLastModified(Long timestamp) { + this.setDate(timestamp); + } + + @Override + public Long getLastModified() { + return getCreationDate(); + } + + @Override + public String getType() { + return "Changeset"; + } + + /** * Returns the file modifications, which was done with this changeset. * @@ -321,8 +347,6 @@ public class Changeset extends BasicPropertiesAware && (date != null); } - //~--- set methods ---------------------------------------------------------- - /** * Sets the author of the changeset. * @@ -412,30 +436,4 @@ public class Changeset extends BasicPropertiesAware this.tags = tags; } - //~--- fields --------------------------------------------------------------- - - /** The author of the changeset */ - private Person author; - - /** The name of the branches on which the changeset was committed. */ - private List branches; - - /** The date when the changeset was committed */ - private Long date; - - /** The text of the changeset description */ - private String description; - - /** The changeset identification string */ - private String id; - - /** List of files changed by this changeset */ - @XmlElement(name = "modifications") - private Modifications modifications; - - /** parent changeset ids */ - private List parents; - - /** The tags associated with the changeset */ - private List tags; } diff --git a/scm-core/src/main/java/sonia/scm/repository/Person.java b/scm-core/src/main/java/sonia/scm/repository/Person.java index b3bf15c49a..8b5e66f61a 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Person.java +++ b/scm-core/src/main/java/sonia/scm/repository/Person.java @@ -36,18 +36,16 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.base.Objects; - import sonia.scm.Validateable; import sonia.scm.util.Util; import sonia.scm.util.ValidationUtil; -//~--- JDK imports ------------------------------------------------------------ - -import java.io.Serializable; - import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; + +//~--- JDK imports ------------------------------------------------------------ /** * The {@link Person} (author) of a changeset. @@ -251,9 +249,11 @@ public class Person implements Validateable, Serializable //~--- fields --------------------------------------------------------------- - /** name of the person */ + /** mail address of the person */ private String mail; - /** mail address of the person */ + /** + * name of the person + */ private String name; } diff --git a/scm-core/src/main/java/sonia/scm/web/VndMediaType.java b/scm-core/src/main/java/sonia/scm/web/VndMediaType.java index afb1417670..7541dd9766 100644 --- a/scm-core/src/main/java/sonia/scm/web/VndMediaType.java +++ b/scm-core/src/main/java/sonia/scm/web/VndMediaType.java @@ -17,6 +17,8 @@ public class VndMediaType { public static final String GROUP = PREFIX + "group" + SUFFIX; public static final String REPOSITORY = PREFIX + "repository" + SUFFIX; public static final String PERMISSION = PREFIX + "permission" + SUFFIX; + public static final String CHANGESET = PREFIX + "changeset" + SUFFIX; + public static final String CHANGESET_COLLECTION = PREFIX + "changesetCollection" + SUFFIX; public static final String BRANCH = PREFIX + "branch" + SUFFIX; public static final String USER_COLLECTION = PREFIX + "userCollection" + SUFFIX; public static final String GROUP_COLLECTION = PREFIX + "groupCollection" + SUFFIX; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BasicCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BasicCollectionToDtoMapper.java index 4700d22841..4787452003 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BasicCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BasicCollectionToDtoMapper.java @@ -11,6 +11,7 @@ import sonia.scm.PageResult; import javax.inject.Inject; import java.util.EnumSet; import java.util.List; +import java.util.function.Function; import static com.damnhandy.uri.template.UriTemplate.fromTemplate; import static de.otto.edison.hal.Embedded.embeddedBuilder; @@ -19,25 +20,28 @@ import static de.otto.edison.hal.Links.linkingTo; import static de.otto.edison.hal.paging.NumberedPaging.zeroBasedNumberedPaging; import static java.util.stream.Collectors.toList; -abstract class BasicCollectionToDtoMapper { +abstract class BasicCollectionToDtoMapper> { private final String collectionName; - private final BaseMapper entityToDtoMapper; + + protected final M entityToDtoMapper; @Inject - public BasicCollectionToDtoMapper(String collectionName, BaseMapper entityToDtoMapper) { + public BasicCollectionToDtoMapper(String collectionName, M entityToDtoMapper) { this.collectionName = collectionName; this.entityToDtoMapper = entityToDtoMapper; } public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult) { - NumberedPaging paging = zeroBasedNumberedPaging(pageNumber, pageSize, pageResult.getOverallCount()); - List dtos = pageResult.getEntities().stream().map(entityToDtoMapper::map).collect(toList()); + return map(pageNumber, pageSize, pageResult, entityToDtoMapper::map, createSelfLink()); + } + public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Function mapper, String selfLink) { + NumberedPaging paging = zeroBasedNumberedPaging(pageNumber, pageSize, pageResult.getOverallCount()); + List dtos = pageResult.getEntities().stream().map(mapper).collect(toList()); CollectionDto collectionDto = new CollectionDto( - createLinks(paging), - embedDtos(dtos) - ); + createLinks(paging, selfLink), + embedDtos(dtos)); collectionDto.setPage(pageNumber); collectionDto.setPageTotal(computePageTotal(pageSize, pageResult)); return collectionDto; @@ -51,9 +55,7 @@ abstract class BasicCollectionToDtoMapper branches) { - List dtos = branches.stream().map(branch -> branchToDtoMapper.map(branch, new NamespaceAndName(namespace, name))).collect(toList()); - return new HalRepresentation(createLinks(namespace, name), embedDtos(dtos)); + return new HalRepresentation(createLinks(namespace, name), embedDtos(getBranchDtoList(namespace, name, branches))); + } + + public List getBranchDtoList(String namespace, String name, Collection branches) { + return branches.stream().map(branch -> branchToDtoMapper.map(branch, new NamespaceAndName(namespace, name))).collect(toList()); } private Links createLinks(String namespace, String name) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java new file mode 100644 index 0000000000..93eb372fe9 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java @@ -0,0 +1,42 @@ +package sonia.scm.api.v2.resources; + +import sonia.scm.PageResult; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.Repository; + +import javax.inject.Inject; + +public class ChangesetCollectionToDtoMapper extends BasicCollectionToDtoMapper { + + private final ResourceLinks resourceLinks; + + @Inject + public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { + super("changesets", changesetToChangesetDtoMapper); + this.resourceLinks = resourceLinks; + } + + public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository) { + return super.map(pageNumber, pageSize, pageResult, changeset -> super.entityToDtoMapper.map(changeset, repository), createSelfLink(repository)); + } + + + @Override + String createCreateLink() { + return null; + } + + @Override + String createSelfLink() { + return null; + } + + private String createSelfLink(Repository repository) { + return resourceLinks.changeset().all(repository.getNamespace(), repository.getName()); + } + + @Override + boolean isCreatePermitted() { + return false; + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetDto.java new file mode 100644 index 0000000000..162d5d6699 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetDto.java @@ -0,0 +1,49 @@ +package sonia.scm.api.v2.resources; + +import de.otto.edison.hal.HalRepresentation; +import de.otto.edison.hal.Links; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.Instant; +import java.util.List; + +@Getter +@Setter +@NoArgsConstructor +public class ChangesetDto extends HalRepresentation { + + /** + * The changeset identification string + */ + private String id; + + /** + * The author of the changeset + */ + private PersonDto author; + + /** + * The date when the changeset was committed + */ + private Instant date; + + /** + * The text of the changeset description + */ + private String description; + + @Override + @SuppressWarnings("squid:S1185") // We want to have this method available in this package + protected HalRepresentation add(Links links) { + return super.add(links); + } + + @SuppressWarnings("squid:S1185") // We want to have this method available in this package + protected HalRepresentation withEmbedded(String rel, List halRepresentations) { + return super.withEmbedded(rel, halRepresentations); + } + + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java index 42ffbdd6c1..aa3aa5924b 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java @@ -1,25 +1,84 @@ package sonia.scm.api.v2.resources; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; +import com.webcohesion.enunciate.metadata.rs.TypeHint; +import lombok.extern.slf4j.Slf4j; +import sonia.scm.PageResult; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.RepositoryNotFoundException; +import sonia.scm.repository.api.RepositoryService; +import sonia.scm.repository.api.RepositoryServiceFactory; +import sonia.scm.web.VndMediaType; + +import javax.inject.Inject; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; +import java.io.IOException; + +@Slf4j public class ChangesetRootResource { + private final RepositoryServiceFactory serviceFactory; + + private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + + @Inject + public ChangesetRootResource(RepositoryServiceFactory serviceFactory, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) { + this.serviceFactory = serviceFactory; + this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper; + } + @GET @Path("") - public Response getAll(@DefaultValue("0") @QueryParam("page") int page, - @DefaultValue("10") @QueryParam("pageSize") int pageSize, - @QueryParam("sortBy") String sortBy, - @DefaultValue("false") @QueryParam("desc") boolean desc) { - throw new UnsupportedOperationException(); + @StatusCodes({ + @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), + @ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the changeset"), + @ResponseCode(code = 404, condition = "not found, no changeset with the specified name available in the repository"), + @ResponseCode(code = 500, condition = "internal server error") + }) + @Produces(VndMediaType.CHANGESET_COLLECTION) + @TypeHint(CollectionDto.class) + public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @DefaultValue("0") @QueryParam("page") int page, + @DefaultValue("10") @QueryParam("pageSize") int pageSize) { + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { + ChangesetPagingResult changesets; + Repository repository = repositoryService.getRepository(); + changesets = repositoryService.getLogCommand() + .setPagingStart(page) + .setPagingLimit(pageSize) + .getChangesets(); + if (changesets != null) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + } else { + return Response.ok().build(); + } + } catch (RepositoryNotFoundException e) { + log.debug("Not found in repository {}/{}", namespace, name, e); + return Response.status(Response.Status.NOT_FOUND).build(); + } catch (RepositoryException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return Response.ok().build(); } @GET - @Path("{revision}") - public Response get() { + @Path("{id}") + public Response get(@PathParam("id") String id) { throw new UnsupportedOperationException(); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToChangesetDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToChangesetDtoMapper.java new file mode 100644 index 0000000000..f047e3bbaa --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToChangesetDtoMapper.java @@ -0,0 +1,78 @@ +package sonia.scm.api.v2.resources; + +import de.otto.edison.hal.Links; +import org.mapstruct.AfterMapping; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import sonia.scm.repository.Branch; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.Repository; +import sonia.scm.repository.Tag; +import sonia.scm.repository.api.Command; +import sonia.scm.repository.api.RepositoryService; +import sonia.scm.repository.api.RepositoryServiceFactory; + +import javax.inject.Inject; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static de.otto.edison.hal.Link.link; +import static de.otto.edison.hal.Links.linkingTo; + +@Mapper +public abstract class ChangesetToChangesetDtoMapper extends BaseMapper { + + @Inject + private RepositoryServiceFactory serviceFactory; + + @Inject + private ResourceLinks resourceLinks; + + + @Inject + private BranchCollectionToDtoMapper branchCollectionToDtoMapper; + + @Inject + private ChangesetToParentDtoMapper changesetToParentDtoMapper; + + @Inject + private TagCollectionToDtoMapper tagCollectionToDtoMapper; + + + @Mapping(target = "attributes", ignore = true) // We do not map HAL attributes + public abstract ChangesetDto map(Changeset changeset, @Context Repository repository); + + + @AfterMapping + void appendLinks(Changeset source, @MappingTarget ChangesetDto target, @Context Repository repository) { + String namespace = repository.getNamespace(); + String name = repository.getName(); + + try (RepositoryService repositoryService = serviceFactory.create(repository)) { + if (repositoryService.isSupported(Command.TAGS)) { + target.withEmbedded("tags", tagCollectionToDtoMapper.getTagDtoList(namespace, name, + getListOfObjects(source.getTags(), tagName -> new Tag(tagName, source.getId())))); + } + if (repositoryService.isSupported(Command.BRANCHES)) { + target.withEmbedded("branches", branchCollectionToDtoMapper.getBranchDtoList(namespace, name, + getListOfObjects(source.getBranches(), branchName -> new Branch(branchName, source.getId())))); + } + } + target.withEmbedded("parents", getListOfObjects(source.getParents(), parent -> changesetToParentDtoMapper.map(new Changeset(parent, 0L, null), repository))); + + Links.Builder linksBuilder = linkingTo() + .self(resourceLinks.changeset().self(repository.getNamespace(), repository.getName(), target.getId())) + .single(link("diff", resourceLinks.diff().self(namespace, name, target.getId()))); + target.add(linksBuilder.build()); + } + + private List getListOfObjects(List list, Function mapFunction) { + return list + .stream() + .map(mapFunction) + .collect(Collectors.toList()); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToParentDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToParentDtoMapper.java new file mode 100644 index 0000000000..611f5e6cbb --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetToParentDtoMapper.java @@ -0,0 +1,38 @@ +package sonia.scm.api.v2.resources; + + +import de.otto.edison.hal.Links; +import org.mapstruct.AfterMapping; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.Repository; + +import javax.inject.Inject; + +import static de.otto.edison.hal.Link.link; +import static de.otto.edison.hal.Links.linkingTo; + +@Mapper +public abstract class ChangesetToParentDtoMapper extends BaseMapper { + + @Inject + private ResourceLinks resourceLinks; + + @Mapping(target = "attributes", ignore = true) // We do not map HAL attributes + public abstract ParentChangesetDto map(Changeset changeset, @Context Repository repository); + + + @AfterMapping + void appendLinks(@MappingTarget ParentChangesetDto target, @Context Repository repository) { + String namespace = repository.getNamespace(); + String name = repository.getName(); + Links.Builder linksBuilder = linkingTo() + .self(resourceLinks.changeset().self(repository.getNamespace(), repository.getName(), target.getId())) + .single(link("diff", resourceLinks.diff().self(namespace, name, target.getId()))); + target.add(linksBuilder.build()); + } + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffRootResource.java new file mode 100644 index 0000000000..176a86dda7 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/DiffRootResource.java @@ -0,0 +1,27 @@ +package sonia.scm.api.v2.resources; + +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +public class DiffRootResource { + + + @GET + @Path("") + public Response getAll(@DefaultValue("0") @QueryParam("page") int page, + @DefaultValue("10") @QueryParam("pageSize") int pageSize, + @QueryParam("sortBy") String sortBy, + @DefaultValue("false") @QueryParam("desc") boolean desc) { + throw new UnsupportedOperationException(); + } + + @GET + @Path("{id}") + public Response get(String id) { + throw new UnsupportedOperationException(); + } + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionToDtoMapper.java index 415f04bfaf..8d13662b10 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionToDtoMapper.java @@ -5,7 +5,7 @@ import sonia.scm.group.GroupPermissions; import javax.inject.Inject; -public class GroupCollectionToDtoMapper extends BasicCollectionToDtoMapper { +public class GroupCollectionToDtoMapper extends BasicCollectionToDtoMapper { private final ResourceLinks resourceLinks; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java index 0605d943e7..9c7a390597 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MapperModule.java @@ -28,6 +28,11 @@ public class MapperModule extends AbstractModule { bind(PermissionDtoToPermissionMapper.class).to(Mappers.getMapper(PermissionDtoToPermissionMapper.class).getClass()); bind(PermissionToPermissionDtoMapper.class).to(Mappers.getMapper(PermissionToPermissionDtoMapper.class).getClass()); + bind(ChangesetToChangesetDtoMapper.class).to(Mappers.getMapper(ChangesetToChangesetDtoMapper.class).getClass()); + bind(ChangesetToParentDtoMapper.class).to(Mappers.getMapper(ChangesetToParentDtoMapper.class).getClass()); + + bind(TagToTagDtoMapper.class).to(Mappers.getMapper(TagToTagDtoMapper.class).getClass()); + bind(UriInfoStore.class).in(ServletScopes.REQUEST); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ParentChangesetDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ParentChangesetDto.java new file mode 100644 index 0000000000..17dbc0df22 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ParentChangesetDto.java @@ -0,0 +1,27 @@ +package sonia.scm.api.v2.resources; + +import de.otto.edison.hal.HalRepresentation; +import de.otto.edison.hal.Links; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +@NoArgsConstructor +public class ParentChangesetDto extends HalRepresentation { + + /** + * the id of the parent changeset + */ + private String id; + + @Override + @SuppressWarnings("squid:S1185") // We want to have this method available in this package + protected HalRepresentation add(Links links) { + return super.add(links); + } + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PersonDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PersonDto.java new file mode 100644 index 0000000000..ce35b507c8 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PersonDto.java @@ -0,0 +1,22 @@ +package sonia.scm.api.v2.resources; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class PersonDto { + + /** + * mail address of the person + */ + private String mail; + + /** + * name of the person + */ + private String name; + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionToDtoMapper.java index a1cf0218e4..9a5fbb1429 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionToDtoMapper.java @@ -7,7 +7,7 @@ import javax.inject.Inject; // Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection. @SuppressWarnings("squid:S3306") -public class RepositoryCollectionToDtoMapper extends BasicCollectionToDtoMapper { +public class RepositoryCollectionToDtoMapper extends BasicCollectionToDtoMapper { private final ResourceLinks resourceLinks; diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java index 0263b81048..84ad8f57bc 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java @@ -40,13 +40,13 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper tags) { + return new HalRepresentation(createLinks(namespace, name), embedDtos(getTagDtoList(namespace, name, tags))); + } + + public List getTagDtoList(String namespace, String name, Collection tags) { + return tags.stream().map(tag -> tagToTagDtoMapper.map(tag, new NamespaceAndName(namespace, name))).collect(toList()); + } + + private Links createLinks(String namespace, String name) { + return + linkingTo() + .self(resourceLinks.tag().all(namespace, name)) + .build(); + } + + private Embedded embedDtos(List dtos) { + return embeddedBuilder() + .with("tags", dtos) + .build(); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagDto.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagDto.java new file mode 100644 index 0000000000..8af036f5a3 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagDto.java @@ -0,0 +1,24 @@ +package sonia.scm.api.v2.resources; + +import de.otto.edison.hal.HalRepresentation; +import de.otto.edison.hal.Links; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class TagDto extends HalRepresentation { + + private String name; + + private String revision; + + @Override + @SuppressWarnings("squid:S1185") // We want to have this method available in this package + protected HalRepresentation add(Links links) { + return super.add(links); + } + +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java index 29a2a922ca..10b4607fbc 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagRootResource.java @@ -1,20 +1,27 @@ package sonia.scm.api.v2.resources; -import javax.inject.Inject; -import javax.inject.Provider; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; public class TagRootResource { - private final Provider tagCollectionResource; - - @Inject - public TagRootResource(Provider tagCollectionResource) { - this.tagCollectionResource = tagCollectionResource; - } + @GET @Path("") - public TagCollectionResource getTagCollectionResource() { - return tagCollectionResource.get(); + public Response getAll(@DefaultValue("0") @QueryParam("page") int page, + @DefaultValue("10") @QueryParam("pageSize") int pageSize, + @QueryParam("sortBy") String sortBy, + @DefaultValue("false") @QueryParam("desc") boolean desc) { + throw new UnsupportedOperationException(); } + + @GET + @Path("{id}") + public Response get(String id) { + throw new UnsupportedOperationException(); + } + } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java new file mode 100644 index 0000000000..ada0fa2887 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java @@ -0,0 +1,31 @@ +package sonia.scm.api.v2.resources; + +import de.otto.edison.hal.Links; +import org.mapstruct.AfterMapping; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Tag; + +import javax.inject.Inject; + +import static de.otto.edison.hal.Links.linkingTo; + +@Mapper +public abstract class TagToTagDtoMapper { + + @Inject + private ResourceLinks resourceLinks; + + @Mapping(target = "attributes", ignore = true) // We do not map HAL attributes + public abstract TagDto map(Tag tag, @Context NamespaceAndName namespaceAndName); + + @AfterMapping + void appendLinks(@MappingTarget TagDto target, @Context NamespaceAndName namespaceAndName) { + Links.Builder linksBuilder = linkingTo() + .self(resourceLinks.tag().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getName())); + target.add(linksBuilder.build()); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionToDtoMapper.java index db2a9afc9f..01517d63e7 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionToDtoMapper.java @@ -7,7 +7,7 @@ import javax.inject.Inject; // Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection. @SuppressWarnings("squid:S3306") -public class UserCollectionToDtoMapper extends BasicCollectionToDtoMapper { +public class UserCollectionToDtoMapper extends BasicCollectionToDtoMapper { private final ResourceLinks resourceLinks; diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java index 1b23b18f27..6ace303b21 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java @@ -45,7 +45,7 @@ public class BranchRootResourceTest { public void prepareEnvironment() throws Exception { BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks); BranchRootResource branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper); - RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(new RepositoryResource(null, null, null, null, MockProvider.of(branchRootResource), null, null, null, null)), null); + RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(new RepositoryResource(null, null, null, null, MockProvider.of(branchRootResource), null, null, null, null, null)), null); dispatcher.getRegistry().addSingletonResource(repositoryRootResource); when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PermissionRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PermissionRootResourceTest.java index 3736f99301..8f7e40425a 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PermissionRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/PermissionRootResourceTest.java @@ -28,7 +28,11 @@ import org.junit.jupiter.api.TestFactory; import org.mockito.InjectMocks; import org.mockito.Mock; import sonia.scm.api.rest.AuthorizationExceptionMapper; -import sonia.scm.repository.*; +import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Permission; +import sonia.scm.repository.PermissionType; +import sonia.scm.repository.Repository; +import sonia.scm.repository.RepositoryManager; import sonia.scm.web.VndMediaType; import java.io.IOException; @@ -46,7 +50,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; import static org.junit.jupiter.api.DynamicTest.dynamicTest; import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @Slf4j @@ -129,7 +136,7 @@ public class PermissionRootResourceTest { permissionCollectionToDtoMapper = new PermissionCollectionToDtoMapper(permissionToPermissionDtoMapper, resourceLinks); permissionRootResource = new PermissionRootResource(permissionDtoToPermissionMapper, permissionToPermissionDtoMapper, permissionCollectionToDtoMapper, resourceLinks, repositoryManager); RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider - .of(new RepositoryResource(null, null, null, null, null, null, null, null, MockProvider.of(permissionRootResource))), null); + .of(new RepositoryResource(null, null, null, null, null, null, null, null, MockProvider.of(permissionRootResource), null)), null); subjectThreadState.bind(); ThreadContext.bind(subject); dispatcher.getRegistry().addSingletonResource(repositoryRootResource); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java index 31cacf2d72..e7912c55bc 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java @@ -80,7 +80,7 @@ public class RepositoryRootResourceTest { @Before public void prepareEnvironment() { initMocks(this); - RepositoryResource repositoryResource = new RepositoryResource(repositoryToDtoMapper, dtoToRepositoryMapper, repositoryManager, null, null, null, null, null, null); + RepositoryResource repositoryResource = new RepositoryResource(repositoryToDtoMapper, dtoToRepositoryMapper, repositoryManager, null, null, null, null, null, null, null); RepositoryCollectionToDtoMapper repositoryCollectionToDtoMapper = new RepositoryCollectionToDtoMapper(repositoryToDtoMapper, resourceLinks); RepositoryCollectionResource repositoryCollectionResource = new RepositoryCollectionResource(repositoryManager, repositoryCollectionToDtoMapper, dtoToRepositoryMapper, resourceLinks); RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(repositoryResource), MockProvider.of(repositoryCollectionResource)); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java index 6df5ac1a7a..6be360c585 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java @@ -19,7 +19,7 @@ public class ResourceLinksMock { when(resourceLinks.groupCollection()).thenReturn(new ResourceLinks.GroupCollectionLinks(uriInfo)); when(resourceLinks.repository()).thenReturn(new ResourceLinks.RepositoryLinks(uriInfo)); when(resourceLinks.repositoryCollection()).thenReturn(new ResourceLinks.RepositoryCollectionLinks(uriInfo)); - when(resourceLinks.tagCollection()).thenReturn(new ResourceLinks.TagCollectionLinks(uriInfo)); + when(resourceLinks.tag()).thenReturn(new ResourceLinks.TagCollectionLinks(uriInfo)); when(resourceLinks.branchCollection()).thenReturn(new ResourceLinks.BranchCollectionLinks(uriInfo)); when(resourceLinks.changeset()).thenReturn(new ResourceLinks.ChangesetLinks(uriInfo)); when(resourceLinks.source()).thenReturn(new ResourceLinks.SourceLinks(uriInfo)); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksTest.java index 000e628f26..b65b516902 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksTest.java @@ -105,7 +105,7 @@ public class ResourceLinksTest { @Test public void shouldCreateCorrectTagCollectionUrl() { - String url = resourceLinks.tagCollection().self("space", "repo"); + String url = resourceLinks.tag().all("space", "repo"); assertEquals(BASE_URL + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/tags/", url); } @@ -141,7 +141,7 @@ public class ResourceLinksTest { @Test public void shouldCreateCorrectChangesetCollectionUrl() { - String url = resourceLinks.changeset().self("space", "repo"); + String url = resourceLinks.changeset().all("space", "repo"); assertEquals(BASE_URL + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/changesets/", url); } From 2bd3fb5a4ff37f4b122cb3f6de551ef9eb743939 Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Thu, 30 Aug 2018 12:11:24 +0200 Subject: [PATCH 03/12] #8630 implement the get changeset endpoint --- .../api/v2/resources/BranchRootResource.java | 50 +++++- .../v2/resources/ChangesetRootResource.java | 69 +++++--- .../v2/resources/BranchRootResourceTest.java | 88 +++++++++- .../resources/ChangesetRootResourceTest.java | 165 ++++++++++++++++++ .../api/v2/resources/ResourceLinksMock.java | 1 + 5 files changed, 335 insertions(+), 38 deletions(-) create mode 100644 scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java index b06b5b9eba..a521f2b116 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java @@ -3,34 +3,44 @@ package sonia.scm.api.v2.resources; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; +import sonia.scm.PageResult; import sonia.scm.repository.Branches; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryNotFoundException; +import sonia.scm.repository.RepositoryPermissions; import sonia.scm.repository.api.CommandNotSupportedException; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.web.VndMediaType; import javax.inject.Inject; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.io.IOException; public class BranchRootResource { - private final RepositoryServiceFactory servicefactory; + private final RepositoryServiceFactory serviceFactory; private final BranchToBranchDtoMapper branchToDtoMapper; private final BranchCollectionToDtoMapper branchCollectionToDtoMapper; + private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + @Inject - public BranchRootResource(RepositoryServiceFactory servicefactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper) { - this.servicefactory = servicefactory; + public BranchRootResource(RepositoryServiceFactory serviceFactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) { + this.serviceFactory = serviceFactory; this.branchToDtoMapper = branchToDtoMapper; this.branchCollectionToDtoMapper = branchCollectionToDtoMapper; + this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper; } /** @@ -56,7 +66,7 @@ public class BranchRootResource { @ResponseCode(code = 500, condition = "internal server error") }) public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("branch") String branchName) throws IOException, RepositoryException { - try (RepositoryService repositoryService = servicefactory.create(new NamespaceAndName(namespace, name))) { + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { Branches branches = repositoryService.getBranchesCommand().getBranches(); return branches.getBranches() .stream() @@ -75,8 +85,34 @@ public class BranchRootResource { @Path("{branch}/changesets/") @GET - public Response history(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("branch") String branchName) { - throw new UnsupportedOperationException(); + @StatusCodes({ + @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), + @ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the changeset"), + @ResponseCode(code = 404, condition = "not found, no changesets available in the repository"), + @ResponseCode(code = 500, condition = "internal server error") + }) + @Produces(VndMediaType.CHANGESET_COLLECTION) + @TypeHint(CollectionDto.class) + public Response history(@PathParam("namespace") String namespace, + @PathParam("name") String name, + @PathParam("branch") String branchName, + @DefaultValue("0") @QueryParam("page") int page, + @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws Exception { + RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name)); + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = repositoryService.getLogCommand() + .setPagingStart(page) + .setPagingLimit(pageSize) + .setBranch(branchName) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + } else { + return Response.ok().build(); + } } /** @@ -101,7 +137,7 @@ public class BranchRootResource { @ResponseCode(code = 500, condition = "internal server error") }) public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name) throws IOException, RepositoryException { - try (RepositoryService repositoryService = servicefactory.create(new NamespaceAndName(namespace, name))) { + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { Branches branches = repositoryService.getBranchesCommand().getBranches(); return Response.ok(branchCollectionToDtoMapper.map(namespace, name, branches.getBranches())).build(); } catch (CommandNotSupportedException ex) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java index aa3aa5924b..57194d5851 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java @@ -10,7 +10,7 @@ import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryException; -import sonia.scm.repository.RepositoryNotFoundException; +import sonia.scm.repository.RepositoryPermissions; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.web.VndMediaType; @@ -33,10 +33,13 @@ public class ChangesetRootResource { private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper; + @Inject - public ChangesetRootResource(RepositoryServiceFactory serviceFactory, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) { + public ChangesetRootResource(RepositoryServiceFactory serviceFactory, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper, ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper) { this.serviceFactory = serviceFactory; this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper; + this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper; } @GET @@ -45,40 +48,52 @@ public class ChangesetRootResource { @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), @ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the changeset"), - @ResponseCode(code = 404, condition = "not found, no changeset with the specified name available in the repository"), + @ResponseCode(code = 404, condition = "not found, no changesets available in the repository"), @ResponseCode(code = 500, condition = "internal server error") }) @Produces(VndMediaType.CHANGESET_COLLECTION) @TypeHint(CollectionDto.class) public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @DefaultValue("0") @QueryParam("page") int page, - @DefaultValue("10") @QueryParam("pageSize") int pageSize) { - try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { - ChangesetPagingResult changesets; - Repository repository = repositoryService.getRepository(); - changesets = repositoryService.getLogCommand() - .setPagingStart(page) - .setPagingLimit(pageSize) - .getChangesets(); - if (changesets != null) { - PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); - return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); - } else { - return Response.ok().build(); - } - } catch (RepositoryNotFoundException e) { - log.debug("Not found in repository {}/{}", namespace, name, e); - return Response.status(Response.Status.NOT_FOUND).build(); - } catch (RepositoryException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException, RepositoryException { + RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name)); + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = repositoryService.getLogCommand() + .setPagingStart(page) + .setPagingLimit(pageSize) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + } else { + return Response.ok().build(); } - return Response.ok().build(); } @GET + @StatusCodes({ + @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), + @ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the changeset"), + @ResponseCode(code = 404, condition = "not found, no changeset with the specified id is available in the repository"), + @ResponseCode(code = 500, condition = "internal server error") + }) + @Produces(VndMediaType.CHANGESET) + @TypeHint(ChangesetDto.class) @Path("{id}") - public Response get(@PathParam("id") String id) { - throw new UnsupportedOperationException(); + public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("id") String id) throws RepositoryException, IOException { + RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name)); + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = repositoryService.getLogCommand() + .setStartChangeset(id) + .setEndChangeset(id) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null && changesets.getChangesets().size() == 1) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetToChangesetDtoMapper.map(changesets.getChangesets().get(0), repository)).build(); + } else { + return Response.status(Response.Status.NOT_FOUND).build(); + } } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java index 6ace303b21..c7f0b128df 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java @@ -1,5 +1,11 @@ package sonia.scm.api.v2.resources; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.support.SubjectThreadState; +import org.apache.shiro.util.ThreadContext; +import org.apache.shiro.util.ThreadState; +import org.assertj.core.util.Lists; import org.jboss.resteasy.core.Dispatcher; import org.jboss.resteasy.mock.MockDispatcherFactory; import org.jboss.resteasy.mock.MockHttpRequest; @@ -12,20 +18,35 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import sonia.scm.repository.Branch; import sonia.scm.repository.Branches; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Person; +import sonia.scm.repository.Repository; import sonia.scm.repository.api.BranchesCommandBuilder; +import sonia.scm.repository.api.LogCommandBuilder; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; import java.net.URI; +import java.time.Instant; +import java.util.Date; +import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.Silent.class) +@Slf4j public class BranchRootResourceTest { + public static final String BRANCH_PATH = "space/repo/branches/master"; + public static final String BRANCH_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + BRANCH_PATH; private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher(); private final URI baseUri = URI.create("/"); @@ -38,25 +59,57 @@ public class BranchRootResourceTest { @Mock private BranchesCommandBuilder branchesCommandBuilder; + @Mock + private LogCommandBuilder logCommandBuilder; + @InjectMocks private BranchToBranchDtoMapperImpl branchToDtoMapper; + private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + + private BranchRootResource branchRootResource; + + @Mock + private BranchCollectionToDtoMapper branchCollectionToDtoMapper; + + @Mock + private ChangesetToParentDtoMapper changesetToParentDtoMapper; + + @Mock + private TagCollectionToDtoMapper tagCollectionToDtoMapper; + + + @InjectMocks + private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper; + + private final Subject subject = mock(Subject.class); + private final ThreadState subjectThreadState = new SubjectThreadState(subject); + + @Before public void prepareEnvironment() throws Exception { + changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks); BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks); - BranchRootResource branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper); + branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper, changesetCollectionToDtoMapper); RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(new RepositoryResource(null, null, null, null, MockProvider.of(branchRootResource), null, null, null, null, null)), null); dispatcher.getRegistry().addSingletonResource(repositoryRootResource); when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service); + when(serviceFactory.create(any(Repository.class))).thenReturn(service); + when(service.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo")); + when(service.getBranchesCommand()).thenReturn(branchesCommandBuilder); + when(service.getLogCommand()).thenReturn(logCommandBuilder); + subjectThreadState.bind(); + ThreadContext.bind(subject); + when(subject.isPermitted(any(String.class))).thenReturn(true); } @Test public void shouldHandleMissingBranch() throws Exception { when(branchesCommandBuilder.getBranches()).thenReturn(new Branches()); - MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/branches/master"); + MockHttpRequest request = MockHttpRequest.get(BRANCH_URL); MockHttpResponse response = new MockHttpResponse(); dispatcher.invoke(request, response); @@ -68,13 +121,40 @@ public class BranchRootResourceTest { public void shouldFindExistingBranch() throws Exception { when(branchesCommandBuilder.getBranches()).thenReturn(new Branches(new Branch("master", "revision"))); - MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/branches/master"); + MockHttpRequest request = MockHttpRequest.get(BRANCH_URL); MockHttpResponse response = new MockHttpResponse(); dispatcher.invoke(request, response); assertEquals(200, response.getStatus()); - System.out.println(response.getContentAsString()); + log.info("Response :{}", response.getContentAsString()); assertTrue(response.getContentAsString().contains("\"revision\":\"revision\"")); } + + @Test + public void shouldFindHistory() throws Exception { + String id = "revision_123"; + Instant creationDate = Instant.now(); + String authorName = "name"; + String authorEmail = "em@i.l"; + String commit = "my branch commit"; + ChangesetPagingResult changesetPagingResult = mock(ChangesetPagingResult.class); + List changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit)); + when(changesetPagingResult.getChangesets()).thenReturn(changesetList); + when(changesetPagingResult.getTotal()).thenReturn(1); + when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setBranch(anyString())).thenReturn(logCommandBuilder); + when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); + MockHttpRequest request = MockHttpRequest.get(BRANCH_URL + "/changesets/"); + MockHttpResponse response = new MockHttpResponse(); + dispatcher.invoke(request, response); + assertEquals(200, response.getStatus()); + log.info("Response :{}", response.getContentAsString()); + assertTrue(response.getContentAsString().contains(String.format("\"id\":\"%s\"", id))); + assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName))); + assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java new file mode 100644 index 0000000000..4e7215c8eb --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java @@ -0,0 +1,165 @@ +package sonia.scm.api.v2.resources; + + +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.support.SubjectThreadState; +import org.apache.shiro.util.ThreadContext; +import org.apache.shiro.util.ThreadState; +import org.assertj.core.util.Lists; +import org.jboss.resteasy.core.Dispatcher; +import org.jboss.resteasy.mock.MockDispatcherFactory; +import org.jboss.resteasy.mock.MockHttpRequest; +import org.jboss.resteasy.mock.MockHttpResponse; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import sonia.scm.api.rest.AuthorizationExceptionMapper; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.ChangesetPagingResult; +import sonia.scm.repository.NamespaceAndName; +import sonia.scm.repository.Person; +import sonia.scm.repository.Repository; +import sonia.scm.repository.api.LogCommandBuilder; +import sonia.scm.repository.api.RepositoryService; +import sonia.scm.repository.api.RepositoryServiceFactory; +import sonia.scm.web.VndMediaType; + +import java.net.URI; +import java.time.Instant; +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.Silent.class) +@Slf4j +public class ChangesetRootResourceTest { + + + public static final String CHANGESET_PATH = "space/repo/changesets/"; + public static final String CHANGESET_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + CHANGESET_PATH; + private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher(); + + private final URI baseUri = URI.create("/"); + private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri); + + @Mock + private RepositoryServiceFactory serviceFactory; + + @Mock + private RepositoryService service; + + @Mock + private LogCommandBuilder logCommandBuilder; + + private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + + @Mock + private BranchCollectionToDtoMapper branchCollectionToDtoMapper; + + @Mock + private ChangesetToParentDtoMapperImpl changesetToParentDtoMapper; + + @Mock + private TagCollectionToDtoMapper tagCollectionToDtoMapper; + + + @InjectMocks + private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper; + + private ChangesetRootResource changesetRootResource; + + + private final Subject subject = mock(Subject.class); + private final ThreadState subjectThreadState = new SubjectThreadState(subject); + + + @Before + public void prepareEnvironment() throws Exception { + changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks); + changesetRootResource = new ChangesetRootResource(serviceFactory, changesetCollectionToDtoMapper, changesetToChangesetDtoMapper); + RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider + .of(new RepositoryResource(null, null, null, null, null, + MockProvider.of(changesetRootResource), null, null, null, null)), null); + dispatcher.getRegistry().addSingletonResource(repositoryRootResource); + when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service); + when(serviceFactory.create(any(Repository.class))).thenReturn(service); + when(service.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo")); + dispatcher.getProviderFactory().registerProvider(RepositoryNotFoundExceptionMapper.class); + dispatcher.getProviderFactory().registerProvider(AuthorizationExceptionMapper.class); + when(service.getLogCommand()).thenReturn(logCommandBuilder); + subjectThreadState.bind(); + ThreadContext.bind(subject); + when(subject.isPermitted(any(String.class))).thenReturn(true); + } + + @Test + public void shouldGetChangeSets() throws Exception { + String id = "revision_123"; + Instant creationDate = Instant.now(); + String authorName = "name"; + String authorEmail = "em@i.l"; + String commit = "my branch commit"; + ChangesetPagingResult changesetPagingResult = mock(ChangesetPagingResult.class); + List changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit)); + when(changesetPagingResult.getChangesets()).thenReturn(changesetList); + when(changesetPagingResult.getTotal()).thenReturn(1); + when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setBranch(anyString())).thenReturn(logCommandBuilder); + when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); + MockHttpRequest request = MockHttpRequest + .get(CHANGESET_URL) + .accept(VndMediaType.CHANGESET_COLLECTION); + MockHttpResponse response = new MockHttpResponse(); + dispatcher.invoke(request, response); + assertEquals(200, response.getStatus()); + log.info("Response :{}", response.getContentAsString()); + assertTrue(response.getContentAsString().contains(String.format("\"id\":\"%s\"", id))); + assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName))); + assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + } + + @Test + public void shouldGetChangeSet() throws Exception { + String id = "revision_123"; + Instant creationDate = Instant.now(); + String authorName = "name"; + String authorEmail = "em@i.l"; + String commit = "my branch commit"; + ChangesetPagingResult changesetPagingResult = mock(ChangesetPagingResult.class); + List changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit)); + when(changesetPagingResult.getChangesets()).thenReturn(changesetList); + when(changesetPagingResult.getTotal()).thenReturn(1); + when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setEndChangeset(anyString())).thenReturn(logCommandBuilder); + when(logCommandBuilder.setStartChangeset(anyString())).thenReturn(logCommandBuilder); + when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); + MockHttpRequest request = MockHttpRequest + .get(CHANGESET_URL + "id") + .accept(VndMediaType.CHANGESET); + MockHttpResponse response = new MockHttpResponse(); + dispatcher.invoke(request, response); + assertEquals(200, response.getStatus()); + log.info("Response :{}", response.getContentAsString()); + assertTrue(response.getContentAsString().contains(String.format("\"id\":\"%s\"", id))); + assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName))); + assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); + } + +} diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java index 6be360c585..ff729a6478 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ResourceLinksMock.java @@ -26,6 +26,7 @@ public class ResourceLinksMock { when(resourceLinks.permission()).thenReturn(new ResourceLinks.PermissionLinks(uriInfo)); when(resourceLinks.config()).thenReturn(new ResourceLinks.ConfigLinks(uriInfo)); when(resourceLinks.branch()).thenReturn(new ResourceLinks.BranchLinks(uriInfo)); + when(resourceLinks.diff()).thenReturn(new ResourceLinks.DiffLinks(uriInfo)); when(resourceLinks.repositoryType()).thenReturn(new ResourceLinks.RepositoryTypeLinks(uriInfo)); when(resourceLinks.repositoryTypeCollection()).thenReturn(new ResourceLinks.RepositoryTypeCollectionLinks(uriInfo)); From 2420c9141c4608295925c5cb7e5806380f39b0f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 31 Aug 2018 08:46:56 +0200 Subject: [PATCH 04/12] Unbind subjects after unit tests --- .../sonia/scm/api/v2/resources/BranchRootResourceTest.java | 6 ++++++ .../scm/api/v2/resources/ChangesetRootResourceTest.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java index c7f0b128df..e23d3dc39b 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java @@ -10,6 +10,7 @@ import org.jboss.resteasy.core.Dispatcher; import org.jboss.resteasy.mock.MockDispatcherFactory; import org.jboss.resteasy.mock.MockHttpRequest; import org.jboss.resteasy.mock.MockHttpResponse; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -105,6 +106,11 @@ public class BranchRootResourceTest { when(subject.isPermitted(any(String.class))).thenReturn(true); } + @After + public void cleanupContext() { + ThreadContext.unbindSubject(); + } + @Test public void shouldHandleMissingBranch() throws Exception { when(branchesCommandBuilder.getBranches()).thenReturn(new Branches()); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java index cb9c545041..8be8866395 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java @@ -11,6 +11,7 @@ import org.jboss.resteasy.core.Dispatcher; import org.jboss.resteasy.mock.MockDispatcherFactory; import org.jboss.resteasy.mock.MockHttpRequest; import org.jboss.resteasy.mock.MockHttpResponse; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -103,6 +104,11 @@ public class ChangesetRootResourceTest { when(subject.isPermitted(any(String.class))).thenReturn(true); } + @After + public void cleanupContext() { + ThreadContext.unbindSubject(); + } + @Test public void shouldGetChangeSets() throws Exception { String id = "revision_123"; From ed98d04be4060b9a7cb74078efa67384aa9aaae2 Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Fri, 31 Aug 2018 09:55:45 +0200 Subject: [PATCH 05/12] #8630 use try-with-resources to close used resources --- .../repository/api/BundleCommandBuilder.java | 2 +- .../scm/repository/GitSubModuleParser.java | 103 +++++------------- .../api/v2/resources/BranchRootResource.java | 35 +++--- .../v2/resources/ChangesetRootResource.java | 50 +++++---- .../sonia/scm/plugin/PluginProcessor.java | 22 ++-- 5 files changed, 80 insertions(+), 132 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/api/BundleCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/BundleCommandBuilder.java index 4fed0a7b60..1f4defbd8b 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/BundleCommandBuilder.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/BundleCommandBuilder.java @@ -140,7 +140,7 @@ public final class BundleCommandBuilder throws IOException { checkNotNull(sink, "byte sink is required"); - logger.info("bundle {} to byte sink"); + logger.info("bundle {} to byte sink", sink); return bundleCommand.bundle(new BundleCommandRequest(sink)); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitSubModuleParser.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitSubModuleParser.java index 7244a1f2bb..82e2919996 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitSubModuleParser.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitSubModuleParser.java @@ -1,19 +1,19 @@ /** * Copyright (c) 2010, Sebastian Sdorra * All rights reserved. - * + *

* Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + *

* 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. + * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. * 3. Neither the name of SCM-Manager; nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + *

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -24,96 +24,49 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + *

* http://bitbucket.org/sdorra/scm-manager - * */ - package sonia.scm.repository; -//~--- non-JDK imports -------------------------------------------------------- - import sonia.scm.util.Util; -//~--- JDK imports ------------------------------------------------------------ - import java.util.HashMap; import java.util.Map; import java.util.Scanner; /** - * * @author Sebastian Sdorra */ -public final class GitSubModuleParser -{ +public final class GitSubModuleParser { - /** - * Constructs ... - * - */ - private GitSubModuleParser() {} + private GitSubModuleParser() { + } - //~--- methods -------------------------------------------------------------- - - /** - * //~--- methods -------------------------------------------------------------- - * - * - * Method description - * - * - * @param content - * - * @return - */ - public static Map parse(String content) - { - Map subRepositories = new HashMap(); - Scanner scanner = new Scanner(content); - SubRepository repository = null; - - while (scanner.hasNextLine()) - { - String line = scanner.nextLine(); - - if (Util.isNotEmpty(line)) - { - line = line.trim(); - - if (line.startsWith("[") && line.endsWith("]")) - { - repository = new SubRepository(); - } - else if (line.startsWith("path")) - { - subRepositories.put(getValue(line), repository); - } - else if (line.startsWith("url")) - { - repository.setRepositoryUrl(getValue(line)); + public static Map parse(String content) { + Map subRepositories = new HashMap<>(); + try (Scanner scanner = new Scanner(content)) { + SubRepository repository = null; + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (Util.isNotEmpty(line)) { + line = line.trim(); + if (line.startsWith("[") && line.endsWith("]")) { + repository = new SubRepository(); + } else if (line.startsWith("path")) { + subRepositories.put(getValue(line), repository); + } else if (line.startsWith("url")) { + repository.setRepositoryUrl(getValue(line)); + } } } } - return subRepositories; } - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param line - * - * @return - */ - private static String getValue(String line) - { + private static String getValue(String line) { return line.split("=")[1].trim(); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java index fb094ea6ff..9763f11def 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java @@ -47,10 +47,9 @@ public class BranchRootResource { * * Note: This method requires "repository" privilege. * - * @param namespace the namespace of the repository - * @param name the name of the repository + * @param namespace the namespace of the repository + * @param name the name of the repository * @param branchName the name of the branch - * */ @GET @Path("{branch}") @@ -98,19 +97,20 @@ public class BranchRootResource { @PathParam("branch") String branchName, @DefaultValue("0") @QueryParam("page") int page, @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws Exception { - RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name)); - Repository repository = repositoryService.getRepository(); - RepositoryPermissions.read(repository).check(); - ChangesetPagingResult changesets = repositoryService.getLogCommand() - .setPagingStart(page) - .setPagingLimit(pageSize) - .setBranch(branchName) - .getChangesets(); - if (changesets != null && changesets.getChangesets() != null) { - PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); - return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); - } else { - return Response.ok().build(); + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = repositoryService.getLogCommand() + .setPagingStart(page) + .setPagingLimit(pageSize) + .setBranch(branchName) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + } else { + return Response.ok().build(); + } } } @@ -120,8 +120,7 @@ public class BranchRootResource { * Note: This method requires "repository" privilege. * * @param namespace the namespace of the repository - * @param name the name of the repository - * + * @param name the name of the repository */ @GET @Path("") diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java index cb827e1546..c3fa71f8ed 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java @@ -56,18 +56,19 @@ public class ChangesetRootResource { @TypeHint(CollectionDto.class) public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @DefaultValue("0") @QueryParam("page") int page, @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException, RevisionNotFoundException, RepositoryNotFoundException { - RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name)); - Repository repository = repositoryService.getRepository(); - RepositoryPermissions.read(repository).check(); - ChangesetPagingResult changesets = repositoryService.getLogCommand() - .setPagingStart(page) - .setPagingLimit(pageSize) - .getChangesets(); - if (changesets != null && changesets.getChangesets() != null) { - PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); - return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); - } else { - return Response.ok().build(); + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = repositoryService.getLogCommand() + .setPagingStart(page) + .setPagingLimit(pageSize) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + } else { + return Response.ok().build(); + } } } @@ -83,18 +84,19 @@ public class ChangesetRootResource { @TypeHint(ChangesetDto.class) @Path("{id}") public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("id") String id) throws IOException, RevisionNotFoundException, RepositoryNotFoundException { - RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name)); - Repository repository = repositoryService.getRepository(); - RepositoryPermissions.read(repository).check(); - ChangesetPagingResult changesets = repositoryService.getLogCommand() - .setStartChangeset(id) - .setEndChangeset(id) - .getChangesets(); - if (changesets != null && changesets.getChangesets() != null && changesets.getChangesets().size() == 1) { - PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); - return Response.ok(changesetToChangesetDtoMapper.map(changesets.getChangesets().get(0), repository)).build(); - } else { - return Response.status(Response.Status.NOT_FOUND).build(); + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = repositoryService.getLogCommand() + .setStartChangeset(id) + .setEndChangeset(id) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null && changesets.getChangesets().size() == 1) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(changesetToChangesetDtoMapper.map(changesets.getChangesets().get(0), repository)).build(); + } else { + return Response.status(Response.Status.NOT_FOUND).build(); + } } } } diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/PluginProcessor.java b/scm-webapp/src/main/java/sonia/scm/plugin/PluginProcessor.java index 2de00a0f58..4e4e97591a 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/PluginProcessor.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/PluginProcessor.java @@ -39,34 +39,27 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.hash.Hashing; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import sonia.scm.plugin.ExplodedSmp.PathTransformer; -//~--- JDK imports ------------------------------------------------------------ - +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; - import java.net.URL; - import java.nio.file.DirectoryStream; import java.nio.file.DirectoryStream.Filter; import java.nio.file.Files; import java.nio.file.Path; - import java.text.SimpleDateFormat; - import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; +//~--- JDK imports ------------------------------------------------------------ /** * @@ -370,9 +363,10 @@ public final class PluginProcessor if (Files.exists(libDir)) { - for (Path f : Files.newDirectoryStream(libDir, GLOB_JAR)) - { - urls.add(f.toUri().toURL()); + try (DirectoryStream pathDirectoryStream = Files.newDirectoryStream(libDir, GLOB_JAR)) { + for (Path f : pathDirectoryStream) { + urls.add(f.toUri().toURL()); + } } } @@ -656,7 +650,7 @@ public final class PluginProcessor break; } } - + logger.debug("move installed archive to {}", installed); Files.move(archive, installed); From d4a8c05c2513d6ad3f1f176d43b949573ac912f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 31 Aug 2018 12:05:05 +0200 Subject: [PATCH 06/12] Remove dead code --- .../scm/api/v2/resources/ChangesetRootResource.java | 1 - .../api/v2/resources/ChangesetRootResourceTest.java | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java index c3fa71f8ed..717b8d7198 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetRootResource.java @@ -92,7 +92,6 @@ public class ChangesetRootResource { .setEndChangeset(id) .getChangesets(); if (changesets != null && changesets.getChangesets() != null && changesets.getChangesets().size() == 1) { - PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); return Response.ok(changesetToChangesetDtoMapper.map(changesets.getChangesets().get(0), repository)).build(); } else { return Response.status(Response.Status.NOT_FOUND).build(); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java index 8be8866395..570830d651 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ChangesetRootResourceTest.java @@ -65,16 +65,6 @@ public class ChangesetRootResourceTest { private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; - @Mock - private BranchCollectionToDtoMapper branchCollectionToDtoMapper; - - @Mock - private ChangesetToParentDtoMapperImpl changesetToParentDtoMapper; - - @Mock - private TagCollectionToDtoMapper tagCollectionToDtoMapper; - - @InjectMocks private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper; From 6fa2ba7f61a7e9d7451a9180f293d59dd2a6c825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 31 Aug 2018 12:05:39 +0200 Subject: [PATCH 07/12] Recognize missing revisions in git --- .../scm/repository/spi/GitLogCommand.java | 60 ++++++---------- .../scm/repository/spi/GitLogCommandTest.java | 72 +++---------------- 2 files changed, 33 insertions(+), 99 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java index 65a6f9daf8..beb79cb921 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitLogCommand.java @@ -37,6 +37,7 @@ package sonia.scm.repository.spi; import com.google.common.base.Strings; import com.google.common.collect.Lists; +import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; @@ -51,6 +52,7 @@ import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.GitChangesetConverter; import sonia.scm.repository.GitUtil; import sonia.scm.repository.InternalRepositoryException; +import sonia.scm.repository.RevisionNotFoundException; import sonia.scm.util.IOUtil; import java.io.IOException; @@ -156,15 +158,11 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand * @return * * @throws IOException - * @throws RepositoryException */ @Override @SuppressWarnings("unchecked") - public ChangesetPagingResult getChangesets(LogCommandRequest request) - throws IOException - { - if (logger.isDebugEnabled()) - { + public ChangesetPagingResult getChangesets(LogCommandRequest request) throws RevisionNotFoundException { + if (logger.isDebugEnabled()) { logger.debug("fetch changesets for request: {}", request); } @@ -172,17 +170,13 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand GitChangesetConverter converter = null; RevWalk revWalk = null; - try (org.eclipse.jgit.lib.Repository gr = open()) - { - if (!gr.getAllRefs().isEmpty()) - { + try (org.eclipse.jgit.lib.Repository gr = open()) { + if (!gr.getAllRefs().isEmpty()) { int counter = 0; int start = request.getPagingStart(); - if (start < 0) - { - if (logger.isErrorEnabled()) - { + if (start < 0) { + if (logger.isErrorEnabled()) { logger.error("start parameter is negative, reset to 0"); } @@ -193,15 +187,13 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand int limit = request.getPagingLimit(); ObjectId startId = null; - if (!Strings.isNullOrEmpty(request.getStartChangeset())) - { + if (!Strings.isNullOrEmpty(request.getStartChangeset())) { startId = gr.resolve(request.getStartChangeset()); } ObjectId endId = null; - if (!Strings.isNullOrEmpty(request.getEndChangeset())) - { + if (!Strings.isNullOrEmpty(request.getEndChangeset())) { endId = gr.resolve(request.getEndChangeset()); } @@ -209,57 +201,51 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand converter = new GitChangesetConverter(gr, revWalk); - if (!Strings.isNullOrEmpty(request.getPath())) - { + if (!Strings.isNullOrEmpty(request.getPath())) { revWalk.setTreeFilter( AndTreeFilter.create( PathFilter.create(request.getPath()), TreeFilter.ANY_DIFF)); } - + ObjectId head = getBranchOrDefault(gr, request.getBranch()); - if (head != null) - { - if (startId != null) - { + if (head != null) { + if (startId != null) { revWalk.markStart(revWalk.lookupCommit(startId)); - } - else - { + } else { revWalk.markStart(revWalk.lookupCommit(head)); } Iterator iterator = revWalk.iterator(); - while (iterator.hasNext()) - { + while (iterator.hasNext()) { RevCommit commit = iterator.next(); if ((counter >= start) - && ((limit < 0) || (counter < start + limit))) - { + && ((limit < 0) || (counter < start + limit))) { changesetList.add(converter.createChangeset(commit)); } counter++; - if ((endId != null) && commit.getId().equals(endId)) - { + if ((endId != null) && commit.getId().equals(endId)) { break; } } } changesets = new ChangesetPagingResult(counter, changesetList); - } - else if (logger.isWarnEnabled()) - { + } else if (logger.isWarnEnabled()) { logger.warn("the repository {} seems to be empty", repository.getName()); changesets = new ChangesetPagingResult(0, Collections.EMPTY_LIST); } } + catch (MissingObjectException e) + { + throw new RevisionNotFoundException(e.getObjectId().name()); + } catch (Exception ex) { throw new InternalRepositoryException("could not create change log", ex); diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java index 1d78485ae3..51df1298e5 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitLogCommandTest.java @@ -35,15 +35,12 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- -import org.eclipse.jgit.api.errors.GitAPIException; import org.junit.Test; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.GitConstants; import sonia.scm.repository.Modifications; -import java.io.IOException; - import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -55,7 +52,7 @@ import static org.junit.Assert.assertTrue; /** * Unit tests for {@link GitLogCommand}. - * + * * @author Sebastian Sdorra */ public class GitLogCommandTest extends AbstractGitCommandTestBase @@ -63,13 +60,9 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase /** * Tests log command with the usage of a default branch. - * - * @throws IOException - * @throws GitAPIException - * @ */ @Test - public void testGetDefaultBranch() throws IOException, GitAPIException { + public void testGetDefaultBranch() throws Exception { // without default branch, the repository head should be used ChangesetPagingResult result = createCommand().getChangesets(new LogCommandRequest()); @@ -79,10 +72,10 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1", result.getChangesets().get(1).getId()); assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(2).getId()); assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(3).getId()); - + // set default branch and fetch again repository.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "test-branch"); - + result = createCommand().getChangesets(new LogCommandRequest()); assertNotNull(result); @@ -91,16 +84,9 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(1).getId()); assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(2).getId()); } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ + @Test - public void testGetAll() throws IOException + public void testGetAll() throws Exception { ChangesetPagingResult result = createCommand().getChangesets(new LogCommandRequest()); @@ -110,15 +96,8 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals(4, result.getChangesets().size()); } - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ @Test - public void testGetAllByPath() throws IOException + public void testGetAllByPath() throws Exception { LogCommandRequest request = new LogCommandRequest(); @@ -133,15 +112,8 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(1).getId()); } - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ @Test - public void testGetAllWithLimit() throws IOException + public void testGetAllWithLimit() throws Exception { LogCommandRequest request = new LogCommandRequest(); @@ -164,15 +136,8 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1", c2.getId()); } - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ @Test - public void testGetAllWithPaging() throws IOException + public void testGetAllWithPaging() throws Exception { LogCommandRequest request = new LogCommandRequest(); @@ -196,10 +161,6 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("592d797cd36432e591416e8b2b98154f4f163411", c2.getId()); } - /** - * Method description - * - */ @Test public void testGetCommit() { @@ -224,15 +185,8 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertThat(mods.getAdded(), contains("a.txt", "b.txt")); } - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ @Test - public void testGetRange() throws IOException + public void testGetRange() throws Exception { LogCommandRequest request = new LogCommandRequest(); @@ -254,12 +208,6 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", c2.getId()); } - /** - * Method description - * - * - * @return - */ private GitLogCommand createCommand() { return new GitLogCommand(createContext(), repository); From b4ae92d12368da0862577bbe6f5b084786aadf50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Wed, 29 Aug 2018 13:34:53 +0200 Subject: [PATCH 08/12] Add simple changeset integration test --- .../sonia/scm/it/RepositoryAccessITCase.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java index a7ee8da41d..a9139f18c8 100644 --- a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java +++ b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java @@ -14,7 +14,9 @@ import sonia.scm.repository.client.api.RepositoryClient; import java.io.File; import java.io.IOException; import java.util.Collection; +import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; import static java.lang.Thread.sleep; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertNotNull; @@ -124,4 +126,31 @@ public class RepositoryAccessITCase { .statusCode(HttpStatus.SC_OK) .body(equalTo("sub-a")); } + + @Test + public void shouldFindChangesets() throws IOException { + RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder); + + RepositoryUtil.createAndCommitFile(repositoryClient, "scmadmin", "a.txt", "a"); + RepositoryUtil.createAndCommitFile(repositoryClient, "scmadmin", "b.txt", "b"); + + String changesetsUrl = given() + .when() + .get(TestData.getDefaultRepositoryUrl(repositoryType)) + .then() + .statusCode(HttpStatus.SC_OK) + .extract() + .path("_links.changesets.href"); + + List changesets = given() + .when() + .get(changesetsUrl) + .then() + .statusCode(HttpStatus.SC_OK) + .extract() + .path("_embedded.changesets.id"); + + assertThat(changesets).size().isBetween(2, 3); // svn has an implicit root revision '0' that is extra to the two commits + } } + From 715ac0dab4ec7d6b1213e7324e71239d8258aad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 31 Aug 2018 15:59:50 +0200 Subject: [PATCH 09/12] Do not modify changesets --- scm-core/src/main/java/sonia/scm/repository/Changeset.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/Changeset.java b/scm-core/src/main/java/sonia/scm/repository/Changeset.java index ca2c9ac5db..18ede493f6 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Changeset.java +++ b/scm-core/src/main/java/sonia/scm/repository/Changeset.java @@ -271,12 +271,12 @@ public class Changeset extends BasicPropertiesAware implements ModelObject { @Override public void setLastModified(Long timestamp) { - this.setDate(timestamp); + throw new UnsupportedOperationException("changesets are immutable"); } @Override public Long getLastModified() { - return getCreationDate(); + return null; } @Override From 87044d0a92d3fda7a079eb4dfbc94389eb4db17d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 30 Aug 2018 09:19:10 +0200 Subject: [PATCH 10/12] Mind LSP for sub classes --- .../resources/BasicCollectionToDtoMapper.java | 29 +++++++------------ .../ChangesetCollectionToDtoMapper.java | 21 +++----------- .../resources/GroupCollectionToDtoMapper.java | 22 +++++++------- .../RepositoryCollectionToDtoMapper.java | 20 +++++++------ .../resources/UserCollectionToDtoMapper.java | 20 +++++++------ 5 files changed, 49 insertions(+), 63 deletions(-) diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BasicCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BasicCollectionToDtoMapper.java index 4787452003..b189a22d1c 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BasicCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BasicCollectionToDtoMapper.java @@ -11,6 +11,7 @@ import sonia.scm.PageResult; import javax.inject.Inject; import java.util.EnumSet; import java.util.List; +import java.util.Optional; import java.util.function.Function; import static com.damnhandy.uri.template.UriTemplate.fromTemplate; @@ -24,7 +25,7 @@ abstract class BasicCollectionToDtoMapper pageResult) { - return map(pageNumber, pageSize, pageResult, entityToDtoMapper::map, createSelfLink()); + CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, String selfLink, Optional createLink) { + return map(pageNumber, pageSize, pageResult, selfLink, createLink, entityToDtoMapper::map); } - public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Function mapper, String selfLink) { + CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, String selfLink, Optional createLink, Function mapper) { NumberedPaging paging = zeroBasedNumberedPaging(pageNumber, pageSize, pageResult.getOverallCount()); - List dtos = pageResult.getEntities().stream().map(mapper).collect(toList()); + List dtos = pageResult.getEntities().stream().map(mapper).collect(toList()); CollectionDto collectionDto = new CollectionDto( - createLinks(paging, selfLink), + createLinks(paging, selfLink, createLink), embedDtos(dtos)); collectionDto.setPage(pageNumber); collectionDto.setPageTotal(computePageTotal(pageSize, pageResult)); @@ -55,24 +56,16 @@ abstract class BasicCollectionToDtoMapper createLink) { Links.Builder linksBuilder = linkingTo() .with(page.links( - fromTemplate(baseUrl + "{?page,pageSize}"), + fromTemplate(selfLink + "{?page,pageSize}"), EnumSet.allOf(PagingRel.class))); - if (isCreatePermitted()) { - linksBuilder.single(link("create", createCreateLink())); - } + createLink.ifPresent(link -> linksBuilder.single(link("create", link))); return linksBuilder.build(); } - abstract boolean isCreatePermitted(); - - abstract String createCreateLink(); - - abstract String createSelfLink(); - - private Embedded embedDtos(List dtos) { + private Embedded embedDtos(List dtos) { return embeddedBuilder() .with(collectionName, dtos) .build(); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java index 93eb372fe9..fcc4085486 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java @@ -5,38 +5,25 @@ import sonia.scm.repository.Changeset; import sonia.scm.repository.Repository; import javax.inject.Inject; +import java.util.Optional; public class ChangesetCollectionToDtoMapper extends BasicCollectionToDtoMapper { + private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper; private final ResourceLinks resourceLinks; @Inject public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { super("changesets", changesetToChangesetDtoMapper); + this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper; this.resourceLinks = resourceLinks; } public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository) { - return super.map(pageNumber, pageSize, pageResult, changeset -> super.entityToDtoMapper.map(changeset, repository), createSelfLink(repository)); - } - - - @Override - String createCreateLink() { - return null; - } - - @Override - String createSelfLink() { - return null; + return super.map(pageNumber, pageSize, pageResult, createSelfLink(repository), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository)); } private String createSelfLink(Repository repository) { return resourceLinks.changeset().all(repository.getNamespace(), repository.getName()); } - - @Override - boolean isCreatePermitted() { - return false; - } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionToDtoMapper.java index 8d13662b10..1550e57ce2 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/GroupCollectionToDtoMapper.java @@ -1,9 +1,14 @@ package sonia.scm.api.v2.resources; +import sonia.scm.PageResult; import sonia.scm.group.Group; import sonia.scm.group.GroupPermissions; import javax.inject.Inject; +import java.util.Optional; + +import static java.util.Optional.empty; +import static java.util.Optional.of; public class GroupCollectionToDtoMapper extends BasicCollectionToDtoMapper { @@ -15,18 +20,15 @@ public class GroupCollectionToDtoMapper extends BasicCollectionToDtoMapper pageResult) { + return map(pageNumber, pageSize, pageResult, this.createSelfLink(), this.createCreateLink()); } - @Override - String createSelfLink() { + private Optional createCreateLink() { + return GroupPermissions.create().isPermitted() ? of(resourceLinks.groupCollection().create()): empty(); + } + + private String createSelfLink() { return resourceLinks.groupCollection().self(); } - - @Override - boolean isCreatePermitted() { - return GroupPermissions.create().isPermitted(); - } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionToDtoMapper.java index 9a5fbb1429..77674270d7 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryCollectionToDtoMapper.java @@ -1,9 +1,14 @@ package sonia.scm.api.v2.resources; +import sonia.scm.PageResult; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryPermissions; import javax.inject.Inject; +import java.util.Optional; + +import static java.util.Optional.empty; +import static java.util.Optional.of; // Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection. @SuppressWarnings("squid:S3306") @@ -17,18 +22,15 @@ public class RepositoryCollectionToDtoMapper extends BasicCollectionToDtoMapper< this.resourceLinks = resourceLinks; } - @Override - String createCreateLink() { - return resourceLinks.repositoryCollection().create(); + public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult) { + return map(pageNumber, pageSize, pageResult, this.createSelfLink(), this.createCreateLink()); + } + + Optional createCreateLink() { + return RepositoryPermissions.create().isPermitted() ? of(resourceLinks.repositoryCollection().create()): empty(); } - @Override String createSelfLink() { return resourceLinks.repositoryCollection().self(); } - - @Override - boolean isCreatePermitted() { - return RepositoryPermissions.create().isPermitted(); - } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionToDtoMapper.java index 01517d63e7..c70bd268ff 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserCollectionToDtoMapper.java @@ -1,9 +1,14 @@ package sonia.scm.api.v2.resources; +import sonia.scm.PageResult; import sonia.scm.user.User; import sonia.scm.user.UserPermissions; import javax.inject.Inject; +import java.util.Optional; + +import static java.util.Optional.empty; +import static java.util.Optional.of; // Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection. @SuppressWarnings("squid:S3306") @@ -17,18 +22,15 @@ public class UserCollectionToDtoMapper extends BasicCollectionToDtoMapper pageResult) { + return map(pageNumber, pageSize, pageResult, this.createSelfLink(), this.createCreateLink()); + } + + Optional createCreateLink() { + return UserPermissions.create().isPermitted() ? of(resourceLinks.userCollection().create()): empty(); } - @Override String createSelfLink() { return resourceLinks.userCollection().self(); } - - @Override - boolean isCreatePermitted() { - return UserPermissions.create().isPermitted(); - } } From d20b69ea2385da777f730d94e5aa2049badbbd55 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 31 Aug 2018 10:47:42 +0200 Subject: [PATCH 11/12] fix flow and linter warnings --- scm-ui/.eslintrc | 28 +- scm-ui/package.json | 9 +- scm-ui/src/components/PluginLoader.js | 1 + scm-ui/src/components/layout/Subtitle.js | 1 + scm-ui/src/components/layout/Title.js | 1 + scm-ui/src/components/modals/ConfirmAlert.js | 34 +- scm-ui/src/config/containers/Config.js | 1 + scm-ui/src/containers/App.js | 2 + .../components/navLinks/EditGroupNavLink.js | 2 +- scm-ui/src/groups/modules/groups.test.js | 40 +- scm-ui/src/registerServiceWorker.js | 29 +- .../repos/components/list/RepositoryEntry.js | 1 - scm-ui/yarn.lock | 1252 +++++++++-------- 13 files changed, 706 insertions(+), 695 deletions(-) diff --git a/scm-ui/.eslintrc b/scm-ui/.eslintrc index 8411c357f5..13c5268429 100644 --- a/scm-ui/.eslintrc +++ b/scm-ui/.eslintrc @@ -1,29 +1,3 @@ { - "parser": "babel-eslint", - "extends": [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:flowtype/recommended" - ], - "plugins": [ - "flowtype", - "react", - "jsx-a11y", - "import" - ], - "rules": { - "quotes": ["error", "double"] - }, - "env": { - "browser": true - }, - "overrides": [ - { - "files": [ "*.test.js" ], - "env": { - "jest": true, - "browser": true - } - } - ] + "extends": "@scm-manager/eslint-config" } diff --git a/scm-ui/package.json b/scm-ui/package.json index e54baaba20..82f6322d91 100644 --- a/scm-ui/package.json +++ b/scm-ui/package.json @@ -42,18 +42,11 @@ "pre-commit": "jest && flow && eslint src" }, "devDependencies": { - "@scm-manager/ui-bundler": "^0.0.7", - "babel-eslint": "^8.2.6", + "@scm-manager/ui-bundler": "^0.0.9", "copyfiles": "^2.0.0", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", - "eslint": "^5.3.0", - "eslint-plugin-flowtype": "^2.50.0", - "eslint-plugin-import": "^2.14.0", - "eslint-plugin-jsx-a11y": "^6.1.1", - "eslint-plugin-react": "^7.10.0", "fetch-mock": "^6.5.0", - "flow-bin": "^0.77.0", "flow-typed": "^2.5.1", "jest": "^23.5.0", "node-sass-chokidar": "^1.3.0", diff --git a/scm-ui/src/components/PluginLoader.js b/scm-ui/src/components/PluginLoader.js index 13dd955b8e..69c8d78122 100644 --- a/scm-ui/src/components/PluginLoader.js +++ b/scm-ui/src/components/PluginLoader.js @@ -74,6 +74,7 @@ class PluginLoader extends React.Component { }) .then(script => { // TODO is this safe??? + // eslint-disable-next-line no-eval eval(script); // NOSONAR }); }; diff --git a/scm-ui/src/components/layout/Subtitle.js b/scm-ui/src/components/layout/Subtitle.js index e55dbde5e4..249c34023f 100644 --- a/scm-ui/src/components/layout/Subtitle.js +++ b/scm-ui/src/components/layout/Subtitle.js @@ -1,3 +1,4 @@ +// @flow import React from "react"; type Props = { diff --git a/scm-ui/src/components/layout/Title.js b/scm-ui/src/components/layout/Title.js index fbb58da14c..c6cc4faf0a 100644 --- a/scm-ui/src/components/layout/Title.js +++ b/scm-ui/src/components/layout/Title.js @@ -1,3 +1,4 @@ +// @flow import React from "react"; type Props = { diff --git a/scm-ui/src/components/modals/ConfirmAlert.js b/scm-ui/src/components/modals/ConfirmAlert.js index d53986cd09..a14a3560b8 100644 --- a/scm-ui/src/components/modals/ConfirmAlert.js +++ b/scm-ui/src/components/modals/ConfirmAlert.js @@ -1,18 +1,26 @@ +// @flow //modified from https://github.com/GA-MO/react-confirm-alert -import React from "react"; +import * as React from "react"; import { render, unmountComponentAtNode } from "react-dom"; import "./ConfirmAlert.css"; +type Button = { + label: string, + onClick: () => void | null +}; + type Props = { title: string, message: string, - buttons: array + buttons: Button[] }; class ConfirmAlert extends React.Component { - handleClickButton = button => { - if (button.onClick) button.onClick(); + handleClickButton = (button: Button) => { + if (button.onClick) { + button.onClick(); + } this.close(); }; @@ -48,20 +56,26 @@ class ConfirmAlert extends React.Component { } } -function createElementReconfirm(properties) { +function createElementReconfirm(properties: Props) { const divTarget = document.createElement("div"); divTarget.id = "react-confirm-alert"; - document.body.appendChild(divTarget); - render(, divTarget); + if (document.body) { + document.body.appendChild(divTarget); + render(, divTarget); + } } function removeElementReconfirm() { const target = document.getElementById("react-confirm-alert"); - unmountComponentAtNode(target); - target.parentNode.removeChild(target); + if (target) { + unmountComponentAtNode(target); + if (target.parentNode) { + target.parentNode.removeChild(target); + } + } } -export function confirmAlert(properties) { +export function confirmAlert(properties: Props) { createElementReconfirm(properties); } diff --git a/scm-ui/src/config/containers/Config.js b/scm-ui/src/config/containers/Config.js index e41d3cc653..2a202edbc9 100644 --- a/scm-ui/src/config/containers/Config.js +++ b/scm-ui/src/config/containers/Config.js @@ -1,3 +1,4 @@ +// @flow import React from "react"; import { translate } from "react-i18next"; import { Route } from "react-router"; diff --git a/scm-ui/src/containers/App.js b/scm-ui/src/containers/App.js index e4377f3450..b02c2099f5 100644 --- a/scm-ui/src/containers/App.js +++ b/scm-ui/src/containers/App.js @@ -1,3 +1,4 @@ +// @flow import React, { Component } from "react"; import Main from "./Main"; import { connect } from "react-redux"; @@ -15,6 +16,7 @@ import { PrimaryNavigation } from "../components/navigation"; import Loading from "../components/Loading"; import ErrorPage from "../components/ErrorPage"; import { Footer, Header } from "../components/layout"; +import type { Me } from "../types/Me"; type Props = { me: Me, diff --git a/scm-ui/src/groups/components/navLinks/EditGroupNavLink.js b/scm-ui/src/groups/components/navLinks/EditGroupNavLink.js index 1cba7c761f..05cd35724b 100644 --- a/scm-ui/src/groups/components/navLinks/EditGroupNavLink.js +++ b/scm-ui/src/groups/components/navLinks/EditGroupNavLink.js @@ -1,5 +1,5 @@ //@flow -import React from 'react'; +import React from "react"; import NavLink from "../../../components/navigation/NavLink"; import { translate } from "react-i18next"; import type { Group } from "../../types/Group"; diff --git a/scm-ui/src/groups/modules/groups.test.js b/scm-ui/src/groups/modules/groups.test.js index 6f3ce36ad0..5a15f68017 100644 --- a/scm-ui/src/groups/modules/groups.test.js +++ b/scm-ui/src/groups/modules/groups.test.js @@ -217,7 +217,7 @@ describe("groups fetch()", () => { const callMe = () => { called = true; - } + }; const store = mockStore({}); return store.dispatch(createGroup(humanGroup, callMe)).then(() => { const actions = store.getActions(); @@ -254,9 +254,9 @@ describe("groups fetch()", () => { const actions = store.getActions(); expect(actions[0].type).toEqual(MODIFY_GROUP_PENDING); expect(actions[1].type).toEqual(MODIFY_GROUP_SUCCESS); - expect(actions[1].payload).toEqual(humanGroup) + expect(actions[1].payload).toEqual(humanGroup); }); - }) + }); it("should call the callback after modifying group", () => { fetchMock.putOnce("http://localhost:8081/api/rest/v2/groups/humanGroup", { @@ -266,7 +266,7 @@ describe("groups fetch()", () => { let called = false; const callback = () => { called = true; - } + }; const store = mockStore({}); return store.dispatch(modifyGroup(humanGroup, callback)).then(() => { @@ -275,7 +275,7 @@ describe("groups fetch()", () => { expect(actions[1].type).toEqual(MODIFY_GROUP_SUCCESS); expect(called).toBe(true); }); - }) + }); it("should fail modifying group on HTTP 500", () => { fetchMock.putOnce("http://localhost:8081/api/rest/v2/groups/humanGroup", { @@ -290,7 +290,7 @@ describe("groups fetch()", () => { expect(actions[1].type).toEqual(MODIFY_GROUP_FAILURE); expect(actions[1].payload).toBeDefined(); }); - }) + }); it("should delete successfully group humanGroup", () => { fetchMock.deleteOnce("http://localhost:8081/api/rest/v2/groups/humanGroup", { @@ -493,7 +493,7 @@ describe("selector tests", () => { }); it("should return null when there are no groups in the state", () => { - expect(getGroupsFromState({})).toBe(null) + expect(getGroupsFromState({})).toBe(null); }); it("should return true, when fetch groups is pending", () => { @@ -563,23 +563,23 @@ describe("selector tests", () => { expect(isCreateGroupPending({pending: { [CREATE_GROUP]: true }})).toBeTruthy(); - }) + }); it("should return false if create group is not pending", () => { expect(isCreateGroupPending({})).toBe(false); - }) + }); it("should return error if creating group failed", () => { expect(getCreateGroupFailure({ failure: { [CREATE_GROUP]: error } - })).toEqual(error) - }) + })).toEqual(error); + }); it("should return undefined if creating group did not fail", () => { - expect(getCreateGroupFailure({})).toBeUndefined() - }) + expect(getCreateGroupFailure({})).toBeUndefined(); + }); it("should return true, when delete group humanGroup is pending", () => { @@ -613,20 +613,20 @@ describe("selector tests", () => { pending: { [CREATE_GROUP]: true } - } + }; expect(isCreateGroupPending(state)).toBe(true); - }) + }); it("should return false, if createGroup is not pending", () => { - expect(isCreateGroupPending({})).toBe(false) - }) + expect(isCreateGroupPending({})).toBe(false); + }); it("should return error of createGroup failed", () => { const state = { failure: { [CREATE_GROUP]: error } - } - expect(getCreateGroupFailure(state)).toEqual(error) - }) + }; + expect(getCreateGroupFailure(state)).toEqual(error); + }); }); diff --git a/scm-ui/src/registerServiceWorker.js b/scm-ui/src/registerServiceWorker.js index a3e6c0cfc1..26ac9c966c 100644 --- a/scm-ui/src/registerServiceWorker.js +++ b/scm-ui/src/registerServiceWorker.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ // In production, we register a service worker to serve assets from local cache. // This lets the app load faster on subsequent visits in production, and gives @@ -9,9 +10,9 @@ // This link also includes instructions on opting out of this behavior. const isLocalhost = Boolean( - window.location.hostname === 'localhost' || + window.location.hostname === "localhost" || // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || + window.location.hostname === "[::1]" || // 127.0.0.1/8 is considered localhost for IPv4. window.location.hostname.match( /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ @@ -19,7 +20,7 @@ const isLocalhost = Boolean( ); export default function register() { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { // The URL constructor is available in all browsers that support SW. const publicUrl = new URL(process.env.PUBLIC_URL, window.location); if (publicUrl.origin !== window.location.origin) { @@ -29,7 +30,7 @@ export default function register() { return; } - window.addEventListener('load', () => { + window.addEventListener("load", () => { const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; if (isLocalhost) { @@ -40,8 +41,8 @@ export default function register() { // service worker/PWA documentation. navigator.serviceWorker.ready.then(() => { console.log( - 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://goo.gl/SC7cgQ' + "This web app is being served cache-first by a service " + + "worker. To learn more, visit https://goo.gl/SC7cgQ" ); }); } else { @@ -59,25 +60,25 @@ function registerValidSW(swUrl) { registration.onupdatefound = () => { const installingWorker = registration.installing; installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { + if (installingWorker.state === "installed") { if (navigator.serviceWorker.controller) { // At this point, the old content will have been purged and // the fresh content will have been added to the cache. // It's the perfect time to display a "New content is // available; please refresh." message in your web app. - console.log('New content is available; please refresh.'); + console.log("New content is available; please refresh."); } else { // At this point, everything has been precached. // It's the perfect time to display a // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); + console.log("Content is cached for offline use."); } } }; }; }) .catch(error => { - console.error('Error during service worker registration:', error); + console.error("Error during service worker registration:", error); }); } @@ -88,7 +89,7 @@ function checkValidServiceWorker(swUrl) { // Ensure service worker exists, and that we really are getting a JS file. if ( response.status === 404 || - response.headers.get('content-type').indexOf('javascript') === -1 + response.headers.get("content-type").indexOf("javascript") === -1 ) { // No service worker found. Probably a different app. Reload the page. navigator.serviceWorker.ready.then(registration => { @@ -103,15 +104,17 @@ function checkValidServiceWorker(swUrl) { }) .catch(() => { console.log( - 'No internet connection found. App is running in offline mode.' + "No internet connection found. App is running in offline mode." ); }); } export function unregister() { - if ('serviceWorker' in navigator) { + if ("serviceWorker" in navigator) { navigator.serviceWorker.ready.then(registration => { registration.unregister(); }); } } + +/* eslint-enable no-console */ diff --git a/scm-ui/src/repos/components/list/RepositoryEntry.js b/scm-ui/src/repos/components/list/RepositoryEntry.js index 7f12d2a539..1ea60770e5 100644 --- a/scm-ui/src/repos/components/list/RepositoryEntry.js +++ b/scm-ui/src/repos/components/list/RepositoryEntry.js @@ -6,7 +6,6 @@ import type { Repository } from "../../types/Repositories"; import DateFromNow from "../../../components/DateFromNow"; import RepositoryEntryLink from "./RepositoryEntryLink"; import classNames from "classnames"; -import { ExtensionPoint } from "@scm-manager/ui-extensions"; import RepositoryAvatar from "./RepositoryAvatar"; const styles = { diff --git a/scm-ui/yarn.lock b/scm-ui/yarn.lock index 8c8a945215..9f7d80f11f 100644 --- a/scm-ui/yarn.lock +++ b/scm-ui/yarn.lock @@ -2,29 +2,29 @@ # yarn lockfile v1 -"@babel/code-frame@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" +"@babel/code-frame@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.51.tgz#bd71d9b192af978df915829d39d4094456439a0c" dependencies: - "@babel/highlight" "7.0.0-beta.44" + "@babel/highlight" "7.0.0-beta.51" -"@babel/code-frame@7.0.0-rc.2", "@babel/code-frame@^7.0.0-beta.35": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-rc.2.tgz#12b6daeb408238360744649d16c0e9fa7ab3859e" +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" dependencies: - "@babel/highlight" "7.0.0-rc.2" + "@babel/highlight" "^7.0.0" -"@babel/core@^7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0-rc.2.tgz#dcb46b3adb63e35b1e82c35d9130d9c27be58427" +"@babel/core@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.0.0.tgz#0cb0c0fd2e78a0a2bec97698f549ae9ce0b99515" dependencies: - "@babel/code-frame" "7.0.0-rc.2" - "@babel/generator" "7.0.0-rc.2" - "@babel/helpers" "7.0.0-rc.2" - "@babel/parser" "7.0.0-rc.2" - "@babel/template" "7.0.0-rc.2" - "@babel/traverse" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.0.0" + "@babel/helpers" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" convert-source-map "^1.1.0" debug "^3.1.0" json5 "^0.5.0" @@ -33,650 +33,654 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" +"@babel/generator@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.51.tgz#6c7575ffde761d07485e04baedc0392c6d9e30f6" dependencies: - "@babel/types" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.51" jsesc "^2.5.1" - lodash "^4.2.0" + lodash "^4.17.5" source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-rc.2.tgz#7aed8fb4ef1bdcc168225096b5b431744ba76bf8" +"@babel/generator@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0.tgz#1efd58bffa951dc846449e58ce3a1d7f02d393aa" dependencies: - "@babel/types" "7.0.0-rc.2" + "@babel/types" "^7.0.0" jsesc "^2.5.1" lodash "^4.17.10" source-map "^0.5.0" trim-right "^1.0.1" -"@babel/helper-annotate-as-pure@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-rc.2.tgz#490fa0e8cfe11305c3310485221c958817957cc7" +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" dependencies: - "@babel/types" "7.0.0-rc.2" + "@babel/types" "^7.0.0" -"@babel/helper-builder-binary-assignment-operator-visitor@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-rc.2.tgz#47904c65b4059893be8b9d16bfeac320df601ffa" +"@babel/helper-builder-binary-assignment-operator-visitor@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0.tgz#ba26336beb2abb547d58b6eba5b84d77975a39eb" dependencies: - "@babel/helper-explode-assignable-expression" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/helper-explode-assignable-expression" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/helper-builder-react-jsx@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0-rc.2.tgz#ba4018ba4d5ab50e24330c3e98bbbebd7286dbf0" +"@babel/helper-builder-react-jsx@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0.tgz#fa154cb53eb918cf2a9a7ce928e29eb649c5acdb" dependencies: - "@babel/types" "7.0.0-rc.2" + "@babel/types" "^7.0.0" esutils "^2.0.0" -"@babel/helper-call-delegate@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-rc.2.tgz#faa254987fc3b5b90a4dc366d9f65f9a1b083174" +"@babel/helper-call-delegate@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0.tgz#e036956bb33d76e59c07a04a1fff144e9f62ab78" dependencies: - "@babel/helper-hoist-variables" "7.0.0-rc.2" - "@babel/traverse" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/helper-hoist-variables" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/helper-define-map@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0-rc.2.tgz#68f19b9f125a0985e7b81841b35cddb1e4ae1c6e" +"@babel/helper-define-map@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.0.0.tgz#a5684dd2adf30f0137cf9b0bde436f8c2db17225" dependencies: - "@babel/helper-function-name" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/helper-function-name" "^7.0.0" + "@babel/types" "^7.0.0" lodash "^4.17.10" -"@babel/helper-explode-assignable-expression@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-rc.2.tgz#df9a0094aca800e3b40a317a1b3d434a61ee158f" +"@babel/helper-explode-assignable-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0.tgz#fdfa4c88603ae3e954d0fc3244d5ca82fb468497" dependencies: - "@babel/traverse" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/helper-function-name@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd" +"@babel/helper-function-name@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.51.tgz#21b4874a227cf99ecafcc30a90302da5a2640561" dependencies: - "@babel/helper-get-function-arity" "7.0.0-beta.44" - "@babel/template" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" + "@babel/helper-get-function-arity" "7.0.0-beta.51" + "@babel/template" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-function-name@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-rc.2.tgz#ad7bb9df383c5f53e4bf38c0fe0c7f93e6a27729" +"@babel/helper-function-name@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0.tgz#a68cc8d04420ccc663dd258f9cc41b8261efa2d4" dependencies: - "@babel/helper-get-function-arity" "7.0.0-rc.2" - "@babel/template" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/helper-get-function-arity@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15" +"@babel/helper-get-function-arity@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.51.tgz#3281b2d045af95c172ce91b20825d85ea4676411" dependencies: - "@babel/types" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-get-function-arity@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-rc.2.tgz#323cb82e2d805b40c0c36be1dfcb8ffcbd0434f3" +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" dependencies: - "@babel/types" "7.0.0-rc.2" + "@babel/types" "^7.0.0" -"@babel/helper-hoist-variables@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-rc.2.tgz#4bc902f06545b60d10f2fa1058a99730df6197b4" +"@babel/helper-hoist-variables@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88" dependencies: - "@babel/types" "7.0.0-rc.2" + "@babel/types" "^7.0.0" -"@babel/helper-member-expression-to-functions@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0-rc.2.tgz#5a9c585f86a35428860d8c93a315317ba565106c" +"@babel/helper-member-expression-to-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" dependencies: - "@babel/types" "7.0.0-rc.2" + "@babel/types" "^7.0.0" -"@babel/helper-module-imports@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0-rc.2.tgz#982f30e71431d3ea7e00b1b48da774c60470a21d" +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" dependencies: - "@babel/types" "7.0.0-rc.2" + "@babel/types" "^7.0.0" -"@babel/helper-module-transforms@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-rc.2.tgz#d9b2697790875a014282973ed74343bb3ad3c7c5" +"@babel/helper-module-transforms@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0.tgz#b01ee7d543e81e8c3fc404b19c9f26acb6e4cf4c" dependencies: - "@babel/helper-module-imports" "7.0.0-rc.2" - "@babel/helper-simple-access" "7.0.0-rc.2" - "@babel/helper-split-export-declaration" "7.0.0-rc.2" - "@babel/template" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-simple-access" "^7.0.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/types" "^7.0.0" lodash "^4.17.10" -"@babel/helper-optimise-call-expression@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-rc.2.tgz#6ddfecaf9470f96de38704223646d9c20dcc2377" +"@babel/helper-optimise-call-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" dependencies: - "@babel/types" "7.0.0-rc.2" + "@babel/types" "^7.0.0" -"@babel/helper-plugin-utils@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0-rc.2.tgz#95bc3225bf6aeda5a5ebc90af2546b5b9317c0b4" +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" -"@babel/helper-regex@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0-rc.2.tgz#445d802c3c50cb146a93458f421c77a7f041b495" +"@babel/helper-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27" dependencies: lodash "^4.17.10" -"@babel/helper-remap-async-to-generator@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-rc.2.tgz#2025ec555eed8275fcbe24532ab1f083ff973707" +"@babel/helper-remap-async-to-generator@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0.tgz#6512273c2feb91587822335cf913fdf680c26901" dependencies: - "@babel/helper-annotate-as-pure" "7.0.0-rc.2" - "@babel/helper-wrap-function" "7.0.0-rc.2" - "@babel/template" "7.0.0-rc.2" - "@babel/traverse" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-wrap-function" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/helper-replace-supers@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-rc.2.tgz#dcf619512a2171e35c0494aeb539a621f6ce7de2" +"@babel/helper-replace-supers@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0.tgz#b6f21237280e0be54f591f63a464b66627ced707" dependencies: - "@babel/helper-member-expression-to-functions" "7.0.0-rc.2" - "@babel/helper-optimise-call-expression" "7.0.0-rc.2" - "@babel/traverse" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/helper-simple-access@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0-rc.2.tgz#34043948cda9e6b883527bb827711bd427fea914" +"@babel/helper-simple-access@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.0.0.tgz#ff36a27983ae4c27122da2f7f294dced80ecbd08" dependencies: - "@babel/template" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/template" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/helper-split-export-declaration@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc" +"@babel/helper-split-export-declaration@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.51.tgz#8a6c3f66c4d265352fc077484f9f6e80a51ab978" dependencies: - "@babel/types" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.51" -"@babel/helper-split-export-declaration@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-rc.2.tgz#726b2dec4e46baeab32db67caa6e88b6521464f8" +"@babel/helper-split-export-declaration@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" dependencies: - "@babel/types" "7.0.0-rc.2" + "@babel/types" "^7.0.0" -"@babel/helper-wrap-function@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-rc.2.tgz#788cd70072254eefd33fc1f3936ba24cced28f48" +"@babel/helper-wrap-function@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0.tgz#1c8e42a2cfb0808e3140189dfe9490782a6fa740" dependencies: - "@babel/helper-function-name" "7.0.0-rc.2" - "@babel/template" "7.0.0-rc.2" - "@babel/traverse" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/helper-function-name" "^7.0.0" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/helpers@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0-rc.2.tgz#e21f54451824f55b4f5022c6e9d6fa7df65e8746" +"@babel/helpers@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.0.0.tgz#7213388341eeb07417f44710fd7e1d00acfa6ac0" dependencies: - "@babel/template" "7.0.0-rc.2" - "@babel/traverse" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/template" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/highlight@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" +"@babel/highlight@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.51.tgz#e8844ae25a1595ccfd42b89623b4376ca06d225d" dependencies: chalk "^2.0.0" esutils "^2.0.2" js-tokens "^3.0.0" -"@babel/highlight@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-rc.2.tgz#0af688a69e3709d9cf392e1837cda18c08d34d4f" +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" dependencies: chalk "^2.0.0" esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-rc.2.tgz#a98c01af5834e71d48a5108e3aeeee333cdf26c4" +"@babel/parser@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0-beta.51.tgz#27cec2df409df60af58270ed8f6aa55409ea86f6" -"@babel/plugin-proposal-async-generator-functions@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-rc.2.tgz#0f3b63fa74a8ffcd9cf1f4821a4725d2696a8622" - dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-remap-async-to-generator" "7.0.0-rc.2" - "@babel/plugin-syntax-async-generators" "7.0.0-rc.2" +"@babel/parser@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.0.0.tgz#697655183394facffb063437ddf52c0277698775" -"@babel/plugin-proposal-class-properties@^7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-rc.2.tgz#71f4f2297ec9c0848b57c231ef913bc83d49d85a" +"@babel/plugin-proposal-async-generator-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0.tgz#5d1eb6b44fd388b97f964350007ab9da090b1d70" dependencies: - "@babel/helper-function-name" "7.0.0-rc.2" - "@babel/helper-member-expression-to-functions" "7.0.0-rc.2" - "@babel/helper-optimise-call-expression" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-replace-supers" "7.0.0-rc.2" - "@babel/plugin-syntax-class-properties" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.0.0" + "@babel/plugin-syntax-async-generators" "^7.0.0" -"@babel/plugin-proposal-json-strings@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0-rc.2.tgz#ea4fd95eb00877e138e3e9f19969e66d9d47b3eb" +"@babel/plugin-proposal-class-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0.tgz#a16b5c076ba6c3d87df64d2480a380e979543731" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-syntax-json-strings" "7.0.0-rc.2" + "@babel/helper-function-name" "^7.0.0" + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.0.0" + "@babel/plugin-syntax-class-properties" "^7.0.0" -"@babel/plugin-proposal-object-rest-spread@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-rc.2.tgz#5552e7a4c80cde25f28dfcc6d050831d1d88a01f" +"@babel/plugin-proposal-json-strings@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-syntax-object-rest-spread" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.0.0" -"@babel/plugin-proposal-optional-catch-binding@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0-rc.2.tgz#61c5968932b6d1e9e5f028b3476f8d55bc317e1f" +"@babel/plugin-proposal-object-rest-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-syntax-optional-catch-binding" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" -"@babel/plugin-proposal-unicode-property-regex@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0-rc.2.tgz#6be37bb04dab59745c2a5e9f0472f8d5f6178330" +"@babel/plugin-proposal-optional-catch-binding@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-regex" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" regexpu-core "^4.2.0" -"@babel/plugin-syntax-async-generators@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-rc.2.tgz#2d1726dd0b4d375e1c16fcb983ab4d89c0eeb2b3" +"@babel/plugin-syntax-async-generators@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-class-properties@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-rc.2.tgz#3ecbb8ba2878f07fdc350f7b7bf4bb88d071e846" +"@babel/plugin-syntax-class-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0.tgz#e051af5d300cbfbcec4a7476e37a803489881634" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-flow@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0-rc.2.tgz#9a7538905383db328d6c36507ec05c9f89f2f8ab" +"@babel/plugin-syntax-flow@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.0.0.tgz#70638aeaad9ee426bc532e51523cff8ff02f6f17" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-json-strings@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0-rc.2.tgz#6c16304a379620034190c06b50da3812351967f2" +"@babel/plugin-syntax-json-strings@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-jsx@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0-rc.2.tgz#c070fd6057ad85c43ba4e7819723e28e760824ff" +"@babel/plugin-syntax-jsx@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.0.0.tgz#034d5e2b4e14ccaea2e4c137af7e4afb39375ffd" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-rc.2.tgz#551e2e0a8916d63b4ddf498afde649c8a7eee1b5" +"@babel/plugin-syntax-object-rest-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-catch-binding@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0-rc.2.tgz#8c752fe1a79490682a32836cefe03c3bd49d2180" +"@babel/plugin-syntax-optional-catch-binding@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-arrow-functions@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-rc.2.tgz#ab00f72ea24535dc47940962c3a96c656f4335c8" +"@babel/plugin-transform-arrow-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-async-to-generator@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0-rc.2.tgz#44a125e68baf24d617a9e48a4fc518371633ebf3" +"@babel/plugin-transform-async-to-generator@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0.tgz#feaf18f4bfeaf2236eea4b2d4879da83006cc8f5" dependencies: - "@babel/helper-module-imports" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-remap-async-to-generator" "7.0.0-rc.2" + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.0.0" -"@babel/plugin-transform-block-scoped-functions@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0-rc.2.tgz#953fa99802af1045b607b0f1cb2235419ee78482" +"@babel/plugin-transform-block-scoped-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-rc.2.tgz#ce5aaebaabde05af5ee2e0bdaccc7727bb4566a6" +"@babel/plugin-transform-block-scoping@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0.tgz#1745075edffd7cdaf69fab2fb6f9694424b7e9bc" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.10" -"@babel/plugin-transform-classes@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-rc.2.tgz#900550c5fcd76e42a6f72b0e8661e82d6e36ceb5" +"@babel/plugin-transform-classes@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0.tgz#9e65ca401747dde99e344baea90ab50dccb4c468" dependencies: - "@babel/helper-annotate-as-pure" "7.0.0-rc.2" - "@babel/helper-define-map" "7.0.0-rc.2" - "@babel/helper-function-name" "7.0.0-rc.2" - "@babel/helper-optimise-call-expression" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-replace-supers" "7.0.0-rc.2" - "@babel/helper-split-export-declaration" "7.0.0-rc.2" + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-define-map" "^7.0.0" + "@babel/helper-function-name" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.0.0" + "@babel/helper-split-export-declaration" "^7.0.0" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-rc.2.tgz#06e61765c350368c61eadbe0cd37c6835c21e665" +"@babel/plugin-transform-computed-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-destructuring@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-rc.2.tgz#ef82b75032275e2eaeba5cf4719b12b8263320b4" +"@babel/plugin-transform-destructuring@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0.tgz#68e911e1935dda2f06b6ccbbf184ffb024e9d43a" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-dotall-regex@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0-rc.2.tgz#012766ab7dcdf6afea5b3a1366f3e6fff368a37f" +"@babel/plugin-transform-dotall-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-regex" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" -"@babel/plugin-transform-duplicate-keys@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0-rc.2.tgz#d60eeb2ff7ed31b9e691c880a97dc2e8f7b0dd95" +"@babel/plugin-transform-duplicate-keys@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-exponentiation-operator@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-rc.2.tgz#171a4b44c5bb8ba9a57190f65f87f8da045d1db3" +"@babel/plugin-transform-exponentiation-operator@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0.tgz#c51b45e090a01876f64d32b5b46c0799c85ea56c" dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-flow-strip-types@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0-rc.2.tgz#87c482c195a3a5e2b8d392928db386a2b034c224" +"@babel/plugin-transform-flow-strip-types@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.0.0.tgz#c40ced34c2783985d90d9f9ac77a13e6fb396a01" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-syntax-flow" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.0.0" -"@babel/plugin-transform-for-of@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-rc.2.tgz#2ef81a326faf68fb7eca37a3ebf45c5426f84bae" +"@babel/plugin-transform-for-of@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-function-name@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-rc.2.tgz#c69c2241fdf3b8430bd6b98d06d7097e91b01bff" +"@babel/plugin-transform-function-name@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0.tgz#eeda18dc22584e13c3581a68f6be4822bb1d1d81" dependencies: - "@babel/helper-function-name" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-function-name" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-literals@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-rc.2.tgz#a4475d70d91c7dbed6c4ee280b3b1bfcd8221324" +"@babel/plugin-transform-literals@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-amd@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0-rc.2.tgz#f3c37e6de732c8ac07df01ea164cf976409de469" +"@babel/plugin-transform-modules-amd@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0.tgz#2430ab73db9960c4ca89966f425b803f5d0d0468" dependencies: - "@babel/helper-module-transforms" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-module-transforms" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-commonjs@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-rc.2.tgz#f6475129473b635bd68cbbab69448c76eb52718c" +"@babel/plugin-transform-modules-commonjs@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0.tgz#20b906e5ab130dd8e456b694a94d9575da0fd41f" dependencies: - "@babel/helper-module-transforms" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-simple-access" "7.0.0-rc.2" + "@babel/helper-module-transforms" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.0.0" -"@babel/plugin-transform-modules-systemjs@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0-rc.2.tgz#ced5ac5556f0e6068b1c5d600bff2e68004038ee" +"@babel/plugin-transform-modules-systemjs@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0.tgz#8873d876d4fee23209decc4d1feab8f198cf2df4" dependencies: - "@babel/helper-hoist-variables" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-hoist-variables" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-umd@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.0.0-rc.2.tgz#0e6eeb1e9138064a2ef28991bf03fa4d14536410" +"@babel/plugin-transform-modules-umd@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.0.0.tgz#e7bb4f2a6cd199668964241951a25013450349be" dependencies: - "@babel/helper-module-transforms" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-module-transforms" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-new-target@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0-rc.2.tgz#5b70d3e202a4d677ba6b12762395a85cb1ddc935" +"@babel/plugin-transform-new-target@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-object-super@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.0.0-rc.2.tgz#2c521240b3f817a4d08915022d1d889ee1ff10ec" +"@babel/plugin-transform-object-super@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.0.0.tgz#b8587d511309b3a0e96e9e38169908b3e392041e" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-replace-supers" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.0.0" -"@babel/plugin-transform-parameters@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-rc.2.tgz#5f81577721a3ce6ebc0bdc572209f75e3b723e3d" +"@babel/plugin-transform-parameters@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0.tgz#da864efa111816a6df161d492f33de10e74b1949" dependencies: - "@babel/helper-call-delegate" "7.0.0-rc.2" - "@babel/helper-get-function-arity" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-call-delegate" "^7.0.0" + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-react-display-name@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0-rc.2.tgz#b8a4ee0e098abefbbbd9386db703deaca54429a7" +"@babel/plugin-transform-react-display-name@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.0.0.tgz#93759e6c023782e52c2da3b75eca60d4f10533ee" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-react-jsx-self@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.0.0-rc.2.tgz#12ed61957d968a0f9c694064f720f7f4246ce980" +"@babel/plugin-transform-react-jsx-self@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.0.0.tgz#a84bb70fea302d915ea81d9809e628266bb0bc11" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-syntax-jsx" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" -"@babel/plugin-transform-react-jsx-source@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0-rc.2.tgz#b67ab723b83eb58cbb58041897c7081392355430" +"@babel/plugin-transform-react-jsx-source@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.0.0.tgz#28e00584f9598c0dd279f6280eee213fa0121c3c" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-syntax-jsx" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" -"@babel/plugin-transform-react-jsx@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0-rc.2.tgz#43f40c43c3c09a4304b1e82b04ff69acf13069c1" +"@babel/plugin-transform-react-jsx@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.0.0.tgz#524379e4eca5363cd10c4446ba163f093da75f3e" dependencies: - "@babel/helper-builder-react-jsx" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-syntax-jsx" "7.0.0-rc.2" + "@babel/helper-builder-react-jsx" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-jsx" "^7.0.0" -"@babel/plugin-transform-regenerator@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-rc.2.tgz#35c26152b0ddff76d93ca1fcf55417b16111ade8" +"@babel/plugin-transform-regenerator@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1" dependencies: regenerator-transform "^0.13.3" -"@babel/plugin-transform-shorthand-properties@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-rc.2.tgz#b920f4ffdcc4bbe75917cfb2e22f685a6771c231" +"@babel/plugin-transform-shorthand-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-spread@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-rc.2.tgz#827e032c206c9f08d01d3d43bb8800e573b3a501" +"@babel/plugin-transform-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-sticky-regex@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0-rc.2.tgz#b9febc20c1624455e8d5ca1008fb32315e3a414b" +"@babel/plugin-transform-sticky-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-regex" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" -"@babel/plugin-transform-template-literals@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-rc.2.tgz#89d701611bff91cceb478542921178f83f5a70c6" +"@babel/plugin-transform-template-literals@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" dependencies: - "@babel/helper-annotate-as-pure" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-typeof-symbol@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0-rc.2.tgz#3c9a0721f54ad8bbc8f469b6720304d843fd1ebe" +"@babel/plugin-transform-typeof-symbol@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-unicode-regex@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0-rc.2.tgz#6bc3d9e927151baa3c3715d3c46316ac3d8b4a2e" +"@babel/plugin-transform-unicode-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/helper-regex" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" -"@babel/preset-env@^7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.0.0-rc.2.tgz#66f7ed731234b67ee9a6189f1df60203873ac98b" +"@babel/preset-env@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.0.0.tgz#f450f200c14e713f98cb14d113bf0c2cfbb89ca9" dependencies: - "@babel/helper-module-imports" "7.0.0-rc.2" - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-proposal-async-generator-functions" "7.0.0-rc.2" - "@babel/plugin-proposal-json-strings" "7.0.0-rc.2" - "@babel/plugin-proposal-object-rest-spread" "7.0.0-rc.2" - "@babel/plugin-proposal-optional-catch-binding" "7.0.0-rc.2" - "@babel/plugin-proposal-unicode-property-regex" "7.0.0-rc.2" - "@babel/plugin-syntax-async-generators" "7.0.0-rc.2" - "@babel/plugin-syntax-object-rest-spread" "7.0.0-rc.2" - "@babel/plugin-syntax-optional-catch-binding" "7.0.0-rc.2" - "@babel/plugin-transform-arrow-functions" "7.0.0-rc.2" - "@babel/plugin-transform-async-to-generator" "7.0.0-rc.2" - "@babel/plugin-transform-block-scoped-functions" "7.0.0-rc.2" - "@babel/plugin-transform-block-scoping" "7.0.0-rc.2" - "@babel/plugin-transform-classes" "7.0.0-rc.2" - "@babel/plugin-transform-computed-properties" "7.0.0-rc.2" - "@babel/plugin-transform-destructuring" "7.0.0-rc.2" - "@babel/plugin-transform-dotall-regex" "7.0.0-rc.2" - "@babel/plugin-transform-duplicate-keys" "7.0.0-rc.2" - "@babel/plugin-transform-exponentiation-operator" "7.0.0-rc.2" - "@babel/plugin-transform-for-of" "7.0.0-rc.2" - "@babel/plugin-transform-function-name" "7.0.0-rc.2" - "@babel/plugin-transform-literals" "7.0.0-rc.2" - "@babel/plugin-transform-modules-amd" "7.0.0-rc.2" - "@babel/plugin-transform-modules-commonjs" "7.0.0-rc.2" - "@babel/plugin-transform-modules-systemjs" "7.0.0-rc.2" - "@babel/plugin-transform-modules-umd" "7.0.0-rc.2" - "@babel/plugin-transform-new-target" "7.0.0-rc.2" - "@babel/plugin-transform-object-super" "7.0.0-rc.2" - "@babel/plugin-transform-parameters" "7.0.0-rc.2" - "@babel/plugin-transform-regenerator" "7.0.0-rc.2" - "@babel/plugin-transform-shorthand-properties" "7.0.0-rc.2" - "@babel/plugin-transform-spread" "7.0.0-rc.2" - "@babel/plugin-transform-sticky-regex" "7.0.0-rc.2" - "@babel/plugin-transform-template-literals" "7.0.0-rc.2" - "@babel/plugin-transform-typeof-symbol" "7.0.0-rc.2" - "@babel/plugin-transform-unicode-regex" "7.0.0-rc.2" - browserslist "^3.0.0" + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-async-generator-functions" "^7.0.0" + "@babel/plugin-proposal-json-strings" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.0.0" + "@babel/plugin-syntax-async-generators" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.0.0" + "@babel/plugin-transform-block-scoped-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-dotall-regex" "^7.0.0" + "@babel/plugin-transform-duplicate-keys" "^7.0.0" + "@babel/plugin-transform-exponentiation-operator" "^7.0.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-modules-amd" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-modules-systemjs" "^7.0.0" + "@babel/plugin-transform-modules-umd" "^7.0.0" + "@babel/plugin-transform-new-target" "^7.0.0" + "@babel/plugin-transform-object-super" "^7.0.0" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-regenerator" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + "@babel/plugin-transform-typeof-symbol" "^7.0.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + browserslist "^4.1.0" invariant "^2.2.2" js-levenshtein "^1.1.3" semver "^5.3.0" -"@babel/preset-flow@^7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0-rc.2.tgz#415539cd74968b1d2ae5b53fe9572f8d16a355b9" +"@babel/preset-flow@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0.tgz#afd764835d9535ec63d8c7d4caf1c06457263da2" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-transform-flow-strip-types" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" -"@babel/preset-react@^7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0-rc.2.tgz#5430f089db83095df4cf134b2e8e8c39619ca60c" +"@babel/preset-react@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0.tgz#e86b4b3d99433c7b3e9e91747e2653958bc6b3c0" dependencies: - "@babel/helper-plugin-utils" "7.0.0-rc.2" - "@babel/plugin-transform-react-display-name" "7.0.0-rc.2" - "@babel/plugin-transform-react-jsx" "7.0.0-rc.2" - "@babel/plugin-transform-react-jsx-self" "7.0.0-rc.2" - "@babel/plugin-transform-react-jsx-source" "7.0.0-rc.2" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-react-jsx-self" "^7.0.0" + "@babel/plugin-transform-react-jsx-source" "^7.0.0" -"@babel/template@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" +"@babel/template@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.51.tgz#9602a40aebcf357ae9677e2532ef5fc810f5fbff" dependencies: - "@babel/code-frame" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - babylon "7.0.0-beta.44" - lodash "^4.2.0" + "@babel/code-frame" "7.0.0-beta.51" + "@babel/parser" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" + lodash "^4.17.5" -"@babel/template@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-rc.2.tgz#53f6be6c1336ddc7744625c9bdca9d10be5d5d72" +"@babel/template@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0.tgz#c2bc9870405959c89a9c814376a2ecb247838c80" dependencies: - "@babel/code-frame" "7.0.0-rc.2" - "@babel/parser" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/types" "^7.0.0" -"@babel/traverse@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" +"@babel/traverse@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.51.tgz#981daf2cec347a6231d3aa1d9e1803b03aaaa4a8" dependencies: - "@babel/code-frame" "7.0.0-beta.44" - "@babel/generator" "7.0.0-beta.44" - "@babel/helper-function-name" "7.0.0-beta.44" - "@babel/helper-split-export-declaration" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - babylon "7.0.0-beta.44" + "@babel/code-frame" "7.0.0-beta.51" + "@babel/generator" "7.0.0-beta.51" + "@babel/helper-function-name" "7.0.0-beta.51" + "@babel/helper-split-export-declaration" "7.0.0-beta.51" + "@babel/parser" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" debug "^3.1.0" globals "^11.1.0" invariant "^2.2.0" - lodash "^4.2.0" + lodash "^4.17.5" -"@babel/traverse@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-rc.2.tgz#6e54ebe82aa1b3b3cf5ec05594bc14d7c59c9766" +"@babel/traverse@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0.tgz#b1fe9b6567fdf3ab542cfad6f3b31f854d799a61" dependencies: - "@babel/code-frame" "7.0.0-rc.2" - "@babel/generator" "7.0.0-rc.2" - "@babel/helper-function-name" "7.0.0-rc.2" - "@babel/helper-split-export-declaration" "7.0.0-rc.2" - "@babel/parser" "7.0.0-rc.2" - "@babel/types" "7.0.0-rc.2" + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.0.0" + "@babel/helper-function-name" "^7.0.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/types" "^7.0.0" debug "^3.1.0" globals "^11.1.0" lodash "^4.17.10" -"@babel/types@7.0.0-beta.44": - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" +"@babel/types@7.0.0-beta.51": + version "7.0.0-beta.51" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.51.tgz#d802b7b543b5836c778aa691797abf00f3d97ea9" dependencies: esutils "^2.0.2" - lodash "^4.2.0" + lodash "^4.17.5" to-fast-properties "^2.0.0" -"@babel/types@7.0.0-rc.2": - version "7.0.0-rc.2" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-rc.2.tgz#8e025b78764cee8751823e308558a3ca144ebd9d" +"@babel/types@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0.tgz#6e191793d3c854d19c6749989e3bc55f0e962118" dependencies: esutils "^2.0.2" lodash "^4.17.10" @@ -724,16 +728,22 @@ node-fetch "^2.1.1" url-template "^2.0.8" -"@scm-manager/ui-bundler@^0.0.7": - version "0.0.7" - resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.7.tgz#4b14e89e60559617c5559226a7a9d4a342f7d8f4" +"@scm-manager/eslint-config@^0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@scm-manager/eslint-config/-/eslint-config-0.0.2.tgz#94cc8c3fb4f51f870b235893dc134fc6c423ae85" + +"@scm-manager/ui-bundler@^0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@scm-manager/ui-bundler/-/ui-bundler-0.0.9.tgz#b61bdccaf6cf0ff3f4856098f95b462223c626c8" dependencies: - "@babel/core" "^7.0.0-rc.2" - "@babel/plugin-proposal-class-properties" "^7.0.0-rc.2" - "@babel/preset-env" "^7.0.0-rc.2" - "@babel/preset-flow" "^7.0.0-rc.2" - "@babel/preset-react" "^7.0.0-rc.2" + "@babel/core" "^7.0.0" + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/preset-env" "^7.0.0" + "@babel/preset-flow" "^7.0.0" + "@babel/preset-react" "^7.0.0" + "@scm-manager/eslint-config" "^0.0.2" babel-core "^7.0.0-0" + babel-eslint "^9.0.0-beta.3" babel-jest "^23.4.2" babelify "^9.0.0" browser-sync "^2.24.7" @@ -742,7 +752,14 @@ colors "^1.3.1" commander "^2.17.1" connect-history-api-fallback "^1.5.0" + eslint "^5.4.0" + eslint-config-react-app "^2.1.0" + eslint-plugin-flowtype "^2.50.0" + eslint-plugin-import "^2.14.0" + eslint-plugin-jsx-a11y "^6.1.1" + eslint-plugin-react "^7.11.1" fast-xml-parser "^3.12.0" + flow-bin "^0.79.1" gulp "^3.9.1" gulp-sourcemaps "^2.6.4" gulp-util "^3.0.8" @@ -750,6 +767,7 @@ jest-junit "^5.1.0" node-mkdirs "^0.0.1" pom-parser "^1.1.1" + prettier "^1.14.2" vinyl-buffer "^1.0.1" vinyl-source-stream "^2.0.0" watchify "^3.11.0" @@ -762,8 +780,8 @@ react-dom "^16.4.2" "@types/node@*": - version "10.7.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.7.1.tgz#b704d7c259aa40ee052eec678758a68d07132a2e" + version "10.9.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.9.4.tgz#0f4cb2dc7c1de6096055357f70179043c33e9897" JSONStream@^1.0.3: version "1.3.4" @@ -813,14 +831,10 @@ acorn-node@^1.2.0, acorn-node@^1.3.0, acorn-node@^1.5.2: acorn-dynamic-import "^3.0.0" xtend "^4.0.1" -acorn@5.X: +acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.5.3, acorn@^5.6.0, acorn@^5.7.1: version "5.7.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.2.tgz#91fa871883485d06708800318404e72bfb26dcc5" -acorn@^5.0.0, acorn@^5.0.3, acorn@^5.5.3, acorn@^5.6.0, acorn@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" - after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" @@ -1175,14 +1189,14 @@ babel-core@^7.0.0-0: version "7.0.0-bridge.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" -babel-eslint@^8.2.6: - version "8.2.6" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9" +babel-eslint@^9.0.0-beta.3: + version "9.0.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-9.0.0.tgz#7d9445f81ed9f60aff38115f838970df9f2b6220" dependencies: - "@babel/code-frame" "7.0.0-beta.44" - "@babel/traverse" "7.0.0-beta.44" - "@babel/types" "7.0.0-beta.44" - babylon "7.0.0-beta.44" + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.0.0" + "@babel/traverse" "^7.0.0" + "@babel/types" "^7.0.0" eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" @@ -1234,7 +1248,7 @@ babel-plugin-jest-hoist@^23.2.0: babel-plugin-syntax-object-rest-spread@^6.13.0: version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + resolved "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" babel-polyfill@^6.26.0: version "6.26.0" @@ -1307,10 +1321,6 @@ babelify@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/babelify/-/babelify-9.0.0.tgz#6b2e39ffeeda3765aee60eeb5b581fd947cc64ec" -babylon@7.0.0-beta.44: - version "7.0.0-beta.44" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" - babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" @@ -1646,12 +1656,13 @@ browserify@^16.1.0, browserify@^16.2.2: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@^3.0.0: - version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" +browserslist@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.1.0.tgz#81cbb8e52dfa09918f93c6e051d779cb7360785d" dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" + caniuse-lite "^1.0.30000878" + electron-to-chromium "^1.3.61" + node-releases "^1.0.0-alpha.11" bs-recipes@1.3.4: version "1.3.4" @@ -1684,8 +1695,8 @@ buffer-xor@^1.0.3: resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" buffer@^5.0.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.0.tgz#53cf98241100099e9eeae20ee6d51d21b16e541e" + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -1773,9 +1784,9 @@ camelcase@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" -caniuse-lite@^1.0.30000844: - version "1.0.30000878" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000878.tgz#c644c39588dd42d3498e952234c372e5a40a4123" +caniuse-lite@^1.0.30000878: + version "1.0.30000883" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000883.tgz#597c1eabfb379bd9fbeaa778632762eb574706ac" capture-exit@^1.2.0: version "1.2.0" @@ -1806,7 +1817,7 @@ chainsaw@~0.1.0: chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + resolved "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -1995,14 +2006,14 @@ collection-visit@^1.0.0: object-visit "^1.0.0" color-convert@^1.9.0: - version "1.9.2" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" dependencies: - color-name "1.1.1" + color-name "1.1.3" -color-name@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" color-support@^1.1.3: version "1.1.3" @@ -2036,8 +2047,8 @@ commander@^2.11.0, commander@^2.17.1, commander@^2.2.0, commander@^2.9.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" compare-versions@^3.1.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.3.1.tgz#1ede3172b713c15f7c7beb98cb74d2d82576dad3" + version "3.4.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" component-bind@1.0.0: version "1.0.0" @@ -2593,9 +2604,9 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -electron-to-chromium@^1.3.47: - version "1.3.61" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.61.tgz#a8ac295b28d0f03d85e37326fd16b6b6b17a1795" +electron-to-chromium@^1.3.61: + version "1.3.62" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.62.tgz#2e8e2dc070c800ec8ce23ff9dfcceb585d6f9ed8" elliptic@^6.0.0: version "6.4.1" @@ -2687,29 +2698,28 @@ entities@^1.1.1, entities@~1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" enzyme-adapter-react-16@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.2.0.tgz#c6e80f334e0a817873262d7d01ee9e4747e3c97e" + version "1.3.1" + resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.3.1.tgz#a0f04273aee62c47521da7a2f6c7134182bd7f73" dependencies: - enzyme-adapter-utils "^1.5.0" + enzyme-adapter-utils "^1.6.0" function.prototype.name "^1.1.0" object.assign "^4.1.0" object.values "^1.0.4" prop-types "^15.6.2" react-is "^16.4.2" - react-reconciler "^0.7.0" react-test-renderer "^16.0.0-0" -enzyme-adapter-utils@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.5.0.tgz#a020ab3ae79bb1c85e1d51f48f35e995e0eed810" +enzyme-adapter-utils@^1.6.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.6.1.tgz#f19acb8b23ddd21b2de99506b181e46138368f2a" dependencies: function.prototype.name "^1.1.0" object.assign "^4.1.0" prop-types "^15.6.2" enzyme@^3.3.0: - version "3.4.4" - resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.4.4.tgz#92c7c6b9e59d4ef0c3d36a75dccc0e41a5c14d21" + version "3.5.0" + resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.5.0.tgz#fd452a698fd1352c737b641dd3a64e079f42d9d5" dependencies: array.prototype.flat "^1.2.1" cheerio "^1.0.0-rc.2" @@ -2720,7 +2730,8 @@ enzyme@^3.3.0: is-number-object "^1.0.3" is-string "^1.0.4" is-subset "^0.1.1" - lodash "^4.17.4" + lodash.escape "^4.0.1" + lodash.isequal "^4.5.0" object-inspect "^1.6.0" object-is "^1.0.1" object.assign "^4.1.0" @@ -2814,6 +2825,10 @@ escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +eslint-config-react-app@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-2.1.0.tgz#23c909f71cbaff76b945b831d2d814b8bde169eb" + eslint-import-resolver-node@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" @@ -2862,7 +2877,7 @@ eslint-plugin-jsx-a11y@^6.1.1: has "^1.0.3" jsx-ast-utils "^2.0.1" -eslint-plugin-react@^7.10.0: +eslint-plugin-react@^7.11.1: version "7.11.1" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c" dependencies: @@ -2894,7 +2909,7 @@ eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" -eslint@^5.3.0: +eslint@^5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.4.0.tgz#d068ec03006bb9e06b429dc85f7e46c1b69fac62" dependencies: @@ -3102,7 +3117,7 @@ extend@^3.0.0, extend@~3.0.0, extend@~3.0.1, extend@~3.0.2: external-editor@^2.1.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + resolved "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" dependencies: chardet "^0.4.0" iconv-lite "^0.4.17" @@ -3315,9 +3330,9 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -flow-bin@^0.77.0: - version "0.77.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.77.0.tgz#4e5c93929f289a0c28e08fb361a9734944a11297" +flow-bin@^0.79.1: + version "0.79.1" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.79.1.tgz#01c9f427baa6556753fa878c192d42e1ecb764b6" flow-typed@^2.5.1: version "2.5.1" @@ -3487,8 +3502,8 @@ gaze@^1.0.0: globule "^1.0.0" generate-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + version "2.2.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.2.0.tgz#1aeac896147293d27bce65eb295ce5f3f094a292" generate-object-property@^1.1.0: version "1.2.0" @@ -3578,19 +3593,9 @@ glob@^4.3.1: minimatch "^2.0.1" once "^1.3.0" -glob@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3782,7 +3787,7 @@ gulplog@^1.0.0: dependencies: glogg "^1.0.0" -handlebars@^4.0.3: +handlebars@^4.0.11: version "4.0.11" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" dependencies: @@ -4549,18 +4554,18 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" istanbul-api@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.1.tgz#4c3b05d18c0016d1022e079b98dc82c40f488954" + version "1.3.6" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.6.tgz#0c695f17e533131de8c49e0657175dcfd8af8a8f" dependencies: async "^2.1.4" compare-versions "^3.1.0" fileset "^2.0.2" istanbul-lib-coverage "^1.2.0" istanbul-lib-hook "^1.2.0" - istanbul-lib-instrument "^1.10.1" + istanbul-lib-instrument "^2.1.0" istanbul-lib-report "^1.1.4" - istanbul-lib-source-maps "^1.2.4" - istanbul-reports "^1.3.0" + istanbul-lib-source-maps "^1.2.5" + istanbul-reports "^1.4.1" js-yaml "^3.7.0" mkdirp "^0.5.1" once "^1.4.0" @@ -4569,6 +4574,10 @@ istanbul-lib-coverage@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341" +istanbul-lib-coverage@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda" + istanbul-lib-hook@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.1.tgz#f614ec45287b2a8fc4f07f5660af787575601805" @@ -4587,6 +4596,18 @@ istanbul-lib-instrument@^1.10.1: istanbul-lib-coverage "^1.2.0" semver "^5.3.0" +istanbul-lib-instrument@^2.1.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-2.3.2.tgz#b287cbae2b5f65f3567b05e2e29b275eaf92d25e" + dependencies: + "@babel/generator" "7.0.0-beta.51" + "@babel/parser" "7.0.0-beta.51" + "@babel/template" "7.0.0-beta.51" + "@babel/traverse" "7.0.0-beta.51" + "@babel/types" "7.0.0-beta.51" + istanbul-lib-coverage "^2.0.1" + semver "^5.5.0" + istanbul-lib-report@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz#e886cdf505c4ebbd8e099e4396a90d0a28e2acb5" @@ -4596,7 +4617,7 @@ istanbul-lib-report@^1.1.4: path-parse "^1.0.5" supports-color "^3.1.2" -istanbul-lib-source-maps@^1.2.4: +istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz#ffe6be4e7ab86d3603e4290d54990b14506fc9b1" dependencies: @@ -4606,11 +4627,11 @@ istanbul-lib-source-maps@^1.2.4: rimraf "^2.6.1" source-map "^0.5.3" -istanbul-reports@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.3.0.tgz#2f322e81e1d9520767597dca3c20a0cce89a3554" +istanbul-reports@^1.4.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.0.tgz#c6c2867fa65f59eb7dcedb7f845dfc76aaee70f9" dependencies: - handlebars "^4.0.3" + handlebars "^4.0.11" isurl@^1.0.0-alpha5: version "1.0.0" @@ -4919,8 +4940,8 @@ jest@^23.5.0: jest-cli "^23.5.0" js-base64@^2.1.8: - version "2.4.8" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.8.tgz#57a9b130888f956834aa40c5b165ba59c758f033" + version "2.4.9" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.9.tgz#748911fb04f48a60c4771b375cac45a80df11c03" js-levenshtein@^1.1.3: version "1.1.3" @@ -5164,8 +5185,8 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" kleur@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.1.tgz#7cc64b0d188d0dcbc98bdcdfdda2cc10619ddce8" + version "2.0.2" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300" labeled-stream-splicer@^2.0.0: version "2.0.1" @@ -5327,6 +5348,10 @@ lodash.escape@^3.0.0: dependencies: lodash._root "^3.0.0" +lodash.escape@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" + lodash.flattendeep@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" @@ -5339,6 +5364,10 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + lodash.isfinite@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3" @@ -5392,7 +5421,7 @@ lodash.templatesettings@^3.0.0: lodash._reinterpolate "^3.0.0" lodash.escape "^3.0.0" -lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10: +lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" @@ -5557,7 +5586,7 @@ micromatch@2.3.11, micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.0.4, micromatch@^3.1.4, micromatch@^3.1.8: +micromatch@^3.0.4, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" dependencies: @@ -5582,21 +5611,11 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@~1.35.0: - version "1.35.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47" - mime-db@~1.36.0: version "1.36.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.7: - version "2.1.19" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.19.tgz#71e464537a7ef81c15f2db9d97e913fc0ff606f0" - dependencies: - mime-db "~1.35.0" - -mime-types@~2.1.18: +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19, mime-types@~2.1.7: version "2.1.20" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" dependencies: @@ -5626,18 +5645,18 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -"minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - minimatch@^2.0.1: version "2.0.10" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" dependencies: brace-expansion "^1.0.0" +minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + minimatch@~0.2.11: version "0.2.14" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" @@ -5647,15 +5666,15 @@ minimatch@~0.2.11: minimist@0.0.8: version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" minimist@~0.0.1: version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" minipass@^2.2.1, minipass@^2.3.3: version "2.3.4" @@ -5679,7 +5698,7 @@ mixin-deep@^1.2.0: "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" @@ -5726,8 +5745,8 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" nan@^2.10.0, nan@^2.9.2: - version "2.10.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + version "2.11.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099" nanomatch@^1.2.9: version "1.2.13" @@ -5780,8 +5799,8 @@ next-tick@1: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" nice-try@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" nimn-date-parser@^1.0.0: version "1.0.0" @@ -5858,6 +5877,12 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" +node-releases@^1.0.0-alpha.11: + version "1.0.0-alpha.11" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.11.tgz#73c810acc2e5b741a17ddfbb39dfca9ab9359d8a" + dependencies: + semver "^5.3.0" + node-sass-chokidar@^1.3.0: version "1.3.3" resolved "https://registry.yarnpkg.com/node-sass-chokidar/-/node-sass-chokidar-1.3.3.tgz#0bc83b6f4a8264ae27cbc80b18c49ed445d07d68" @@ -6376,8 +6401,8 @@ path-to-regexp@^1.7.0: isarray "0.0.1" path-to-regexp@^2.2.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.3.0.tgz#690d682cb9e2dde26d25f41bcc2b4774b67d1fa2" + version "2.4.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.4.0.tgz#35ce7f333d5616f1c1e1bfe266c3aba2e5b2e704" path-type@^1.0.0: version "1.1.0" @@ -6489,7 +6514,7 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@^1.13.7: +prettier@^1.13.7, prettier@^1.14.2: version "1.14.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.2.tgz#0ac1c6e1a90baa22a62925f41963c841983282f9" @@ -6670,8 +6695,8 @@ react-dom@^16.4.2: prop-types "^15.6.0" react-i18next@^7.9.0: - version "7.10.1" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-7.10.1.tgz#9e119c15970eb401b9ef178336a2e09dd120bb15" + version "7.11.0" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-7.11.0.tgz#8933cc8d75dce015204ba921ece099810e2944d4" dependencies: hoist-non-react-statics "^2.3.1" html-parse-stringify2 "2.0.1" @@ -6691,15 +6716,6 @@ react-jss@^8.6.0: prop-types "^15.6.0" theming "^1.3.0" -react-reconciler@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.7.0.tgz#9614894103e5f138deeeb5eabaf3ee80eb1d026d" - dependencies: - fbjs "^0.8.16" - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.0" - react-redux@^5.0.7: version "5.0.7" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.7.tgz#0dc1076d9afb4670f993ffaef44b8f8c1155a4c8" @@ -6780,6 +6796,13 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -7005,7 +7028,7 @@ request-promise-native@^1.0.5: request@2.79.0: version "2.79.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + resolved "http://registry.npmjs.org/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" dependencies: aws-sign2 "~0.6.0" aws4 "^1.2.1" @@ -7202,8 +7225,8 @@ rx@4.1.0: resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" rxjs@^5.5.2: - version "5.5.11" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.11.tgz#f733027ca43e3bec6b994473be4ab98ad43ced87" + version "5.5.12" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" dependencies: symbol-observable "1.0.1" @@ -7642,8 +7665,8 @@ statuses@~1.4.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" stdout-stream@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b" + version "1.4.1" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" dependencies: readable-stream "^2.0.1" @@ -7868,13 +7891,12 @@ tar@^4: yallist "^3.0.2" test-exclude@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa" + version "4.2.2" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.2.tgz#8b67aa8408f84afc225b06669e25c510f8582820" dependencies: arrify "^1.0.1" - micromatch "^3.1.8" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" + minimatch "^3.0.4" + read-pkg-up "^3.0.0" require-main-filename "^1.0.1" text-table@^0.2.0: @@ -8030,10 +8052,10 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" "true-case-path@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62" + version "1.0.3" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" dependencies: - glob "^6.0.4" + glob "^7.1.2" tty-browserify@0.0.1: version "0.0.1" From 4349e2c61d76c2084dbda9ee02f116c4deb41b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Mon, 3 Sep 2018 15:44:22 +0200 Subject: [PATCH 12/12] Remove double class --- .../v2/resources/CollectionToDtoMapper.java | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionToDtoMapper.java diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionToDtoMapper.java deleted file mode 100644 index 4f8c6a6f3f..0000000000 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/CollectionToDtoMapper.java +++ /dev/null @@ -1,32 +0,0 @@ -package sonia.scm.api.v2.resources; - -import de.otto.edison.hal.HalRepresentation; - -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -import static de.otto.edison.hal.Embedded.embeddedBuilder; -import static de.otto.edison.hal.Links.linkingTo; - -abstract class CollectionToDtoMapper { - - private final String collectionName; - private final BaseMapper mapper; - - protected CollectionToDtoMapper(String collectionName, BaseMapper mapper) { - this.collectionName = collectionName; - this.mapper = mapper; - } - - public HalRepresentation map(Collection collection) { - List dtos = collection.stream().map(mapper::map).collect(Collectors.toList()); - return new HalRepresentation( - linkingTo().self(createSelfLink()).build(), - embeddedBuilder().with(collectionName, dtos).build() - ); - } - - protected abstract String createSelfLink(); - -}