diff --git a/integrations/api_notification_test.go b/integrations/api_notification_test.go new file mode 100644 index 0000000000..2c5477dfb0 --- /dev/null +++ b/integrations/api_notification_test.go @@ -0,0 +1,106 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package integrations + +import ( + "fmt" + "net/http" + "testing" + + "code.gitea.io/gitea/models" + api "code.gitea.io/gitea/modules/structs" + + "github.com/stretchr/testify/assert" +) + +func TestAPINotification(t *testing.T) { + defer prepareTestEnv(t)() + + user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) + repo1 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) + thread5 := models.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification) + assert.NoError(t, thread5.LoadAttributes()) + session := loginUser(t, user2.Name) + token := getTokenForLoggedInUser(t, session) + + // -- GET /notifications -- + // test filter + since := "2000-01-01T00%3A50%3A01%2B00%3A00" //946687801 + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?since=%s&token=%s", since, token)) + resp := session.MakeRequest(t, req, http.StatusOK) + var apiNL []api.NotificationThread + DecodeJSON(t, resp, &apiNL) + + assert.Len(t, apiNL, 1) + assert.EqualValues(t, 5, apiNL[0].ID) + + // test filter + before := "2000-01-01T01%3A06%3A59%2B00%3A00" //946688819 + + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?all=%s&before=%s&token=%s", "true", before, token)) + resp = session.MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &apiNL) + + assert.Len(t, apiNL, 3) + assert.EqualValues(t, 4, apiNL[0].ID) + assert.EqualValues(t, true, apiNL[0].Unread) + assert.EqualValues(t, false, apiNL[0].Pinned) + assert.EqualValues(t, 3, apiNL[1].ID) + assert.EqualValues(t, false, apiNL[1].Unread) + assert.EqualValues(t, true, apiNL[1].Pinned) + assert.EqualValues(t, 2, apiNL[2].ID) + assert.EqualValues(t, false, apiNL[2].Unread) + assert.EqualValues(t, false, apiNL[2].Pinned) + + // -- GET /repos/{owner}/{repo}/notifications -- + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?token=%s", user2.Name, repo1.Name, token)) + resp = session.MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &apiNL) + + assert.Len(t, apiNL, 1) + assert.EqualValues(t, 4, apiNL[0].ID) + + // -- GET /notifications/threads/{id} -- + // get forbidden + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/threads/%d?token=%s", 1, token)) + resp = session.MakeRequest(t, req, http.StatusForbidden) + + // get own + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/threads/%d?token=%s", thread5.ID, token)) + resp = session.MakeRequest(t, req, http.StatusOK) + var apiN api.NotificationThread + DecodeJSON(t, resp, &apiN) + + assert.EqualValues(t, 5, apiN.ID) + assert.EqualValues(t, false, apiN.Pinned) + assert.EqualValues(t, true, apiN.Unread) + assert.EqualValues(t, "issue4", apiN.Subject.Title) + assert.EqualValues(t, "Issue", apiN.Subject.Type) + assert.EqualValues(t, thread5.Issue.APIURL(), apiN.Subject.URL) + assert.EqualValues(t, thread5.Repository.HTMLURL(), apiN.Repository.HTMLURL) + + // -- mark notifications as read -- + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token)) + resp = session.MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &apiNL) + assert.Len(t, apiNL, 2) + + lastReadAt := "2000-01-01T00%3A50%3A01%2B00%3A00" //946687801 <- only Notification 4 is in this filter ... + req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token)) + resp = session.MakeRequest(t, req, http.StatusResetContent) + + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s", token)) + resp = session.MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &apiNL) + assert.Len(t, apiNL, 1) + + // -- PATCH /notifications/threads/{id} -- + req = NewRequest(t, "PATCH", fmt.Sprintf("/api/v1/notifications/threads/%d?token=%s", thread5.ID, token)) + resp = session.MakeRequest(t, req, http.StatusResetContent) + + assert.Equal(t, models.NotificationStatusUnread, thread5.Status) + thread5 = models.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification) + assert.Equal(t, models.NotificationStatusRead, thread5.Status) +} diff --git a/integrations/api_team_test.go b/integrations/api_team_test.go index be56e37edf..d893854470 100644 --- a/integrations/api_team_test.go +++ b/integrations/api_team_test.go @@ -71,19 +71,33 @@ func TestAPITeam(t *testing.T) { teamID := apiTeam.ID // Edit team. + editDescription := "team 1" + editFalse := false teamToEdit := &api.EditTeamOption{ Name: "teamone", - Description: "team 1", - IncludesAllRepositories: false, + Description: &editDescription, Permission: "admin", + IncludesAllRepositories: &editFalse, Units: []string{"repo.code", "repo.pulls", "repo.releases"}, } + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d?token=%s", teamID, token), teamToEdit) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiTeam) - checkTeamResponse(t, &apiTeam, teamToEdit.Name, teamToEdit.Description, teamToEdit.IncludesAllRepositories, + checkTeamResponse(t, &apiTeam, teamToEdit.Name, *teamToEdit.Description, *teamToEdit.IncludesAllRepositories, teamToEdit.Permission, teamToEdit.Units) - checkTeamBean(t, apiTeam.ID, teamToEdit.Name, teamToEdit.Description, teamToEdit.IncludesAllRepositories, + checkTeamBean(t, apiTeam.ID, teamToEdit.Name, *teamToEdit.Description, *teamToEdit.IncludesAllRepositories, + teamToEdit.Permission, teamToEdit.Units) + + // Edit team Description only + editDescription = "first team" + teamToEditDesc := api.EditTeamOption{Description: &editDescription} + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d?token=%s", teamID, token), teamToEditDesc) + resp = session.MakeRequest(t, req, http.StatusOK) + DecodeJSON(t, resp, &apiTeam) + checkTeamResponse(t, &apiTeam, teamToEdit.Name, *teamToEditDesc.Description, *teamToEdit.IncludesAllRepositories, + teamToEdit.Permission, teamToEdit.Units) + checkTeamBean(t, apiTeam.ID, teamToEdit.Name, *teamToEditDesc.Description, *teamToEdit.IncludesAllRepositories, teamToEdit.Permission, teamToEdit.Units) // Read team. @@ -91,7 +105,7 @@ func TestAPITeam(t *testing.T) { req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamID) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiTeam) - checkTeamResponse(t, &apiTeam, teamRead.Name, teamRead.Description, teamRead.IncludesAllRepositories, + checkTeamResponse(t, &apiTeam, teamRead.Name, *teamToEditDesc.Description, teamRead.IncludesAllRepositories, teamRead.Authorize.String(), teamRead.GetUnitNames()) // Delete team. diff --git a/models/action.go b/models/action.go index 6725f55194..c7bb84c1ea 100644 --- a/models/action.go +++ b/models/action.go @@ -13,10 +13,8 @@ import ( "time" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "github.com/unknwon/com" @@ -284,130 +282,6 @@ func (a *Action) GetIssueContent() string { return issue.Content } -// PushCommit represents a commit in a push operation. -type PushCommit struct { - Sha1 string - Message string - AuthorEmail string - AuthorName string - CommitterEmail string - CommitterName string - Timestamp time.Time -} - -// PushCommits represents list of commits in a push operation. -type PushCommits struct { - Len int - Commits []*PushCommit - CompareURL string - - avatars map[string]string - emailUsers map[string]*User -} - -// NewPushCommits creates a new PushCommits object. -func NewPushCommits() *PushCommits { - return &PushCommits{ - avatars: make(map[string]string), - emailUsers: make(map[string]*User), - } -} - -// ToAPIPayloadCommits converts a PushCommits object to -// api.PayloadCommit format. -func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.PayloadCommit, error) { - commits := make([]*api.PayloadCommit, len(pc.Commits)) - - if pc.emailUsers == nil { - pc.emailUsers = make(map[string]*User) - } - var err error - for i, commit := range pc.Commits { - authorUsername := "" - author, ok := pc.emailUsers[commit.AuthorEmail] - if !ok { - author, err = GetUserByEmail(commit.AuthorEmail) - if err == nil { - authorUsername = author.Name - pc.emailUsers[commit.AuthorEmail] = author - } - } else { - authorUsername = author.Name - } - - committerUsername := "" - committer, ok := pc.emailUsers[commit.CommitterEmail] - if !ok { - committer, err = GetUserByEmail(commit.CommitterEmail) - if err == nil { - // TODO: check errors other than email not found. - committerUsername = committer.Name - pc.emailUsers[commit.CommitterEmail] = committer - } - } else { - committerUsername = committer.Name - } - - fileStatus, err := git.GetCommitFileStatus(repoPath, commit.Sha1) - if err != nil { - return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %v", commit.Sha1, err) - } - - commits[i] = &api.PayloadCommit{ - ID: commit.Sha1, - Message: commit.Message, - URL: fmt.Sprintf("%s/commit/%s", repoLink, commit.Sha1), - Author: &api.PayloadUser{ - Name: commit.AuthorName, - Email: commit.AuthorEmail, - UserName: authorUsername, - }, - Committer: &api.PayloadUser{ - Name: commit.CommitterName, - Email: commit.CommitterEmail, - UserName: committerUsername, - }, - Added: fileStatus.Added, - Removed: fileStatus.Removed, - Modified: fileStatus.Modified, - Timestamp: commit.Timestamp, - } - } - return commits, nil -} - -// AvatarLink tries to match user in database with e-mail -// in order to show custom avatar, and falls back to general avatar link. -func (pc *PushCommits) AvatarLink(email string) string { - if pc.avatars == nil { - pc.avatars = make(map[string]string) - } - avatar, ok := pc.avatars[email] - if ok { - return avatar - } - - u, ok := pc.emailUsers[email] - if !ok { - var err error - u, err = GetUserByEmail(email) - if err != nil { - pc.avatars[email] = base.AvatarLink(email) - if !IsErrUserNotExist(err) { - log.Error("GetUserByEmail: %v", err) - return "" - } - } else { - pc.emailUsers[email] = u - } - } - if u != nil { - pc.avatars[email] = u.RelAvatarLink() - } - - return pc.avatars[email] -} - // GetFeedsOptions options for retrieving feeds type GetFeedsOptions struct { RequestedUser *User // the user we want activity for diff --git a/models/action_test.go b/models/action_test.go index 31ba6af8f5..ccdec8f532 100644 --- a/models/action_test.go +++ b/models/action_test.go @@ -27,106 +27,6 @@ func TestAction_GetRepoLink(t *testing.T) { assert.Equal(t, expected, action.GetRepoLink()) } -func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { - pushCommits := NewPushCommits() - pushCommits.Commits = []*PushCommit{ - { - Sha1: "69554a6", - CommitterEmail: "user2@example.com", - CommitterName: "User2", - AuthorEmail: "user2@example.com", - AuthorName: "User2", - Message: "not signed commit", - }, - { - Sha1: "27566bd", - CommitterEmail: "user2@example.com", - CommitterName: "User2", - AuthorEmail: "user2@example.com", - AuthorName: "User2", - Message: "good signed commit (with not yet validated email)", - }, - { - Sha1: "5099b81", - CommitterEmail: "user2@example.com", - CommitterName: "User2", - AuthorEmail: "user2@example.com", - AuthorName: "User2", - Message: "good signed commit", - }, - } - pushCommits.Len = len(pushCommits.Commits) - - repo := AssertExistsAndLoadBean(t, &Repository{ID: 16}).(*Repository) - payloadCommits, err := pushCommits.ToAPIPayloadCommits(repo.RepoPath(), "/user2/repo16") - assert.NoError(t, err) - assert.EqualValues(t, 3, len(payloadCommits)) - - assert.Equal(t, "69554a6", payloadCommits[0].ID) - assert.Equal(t, "not signed commit", payloadCommits[0].Message) - assert.Equal(t, "/user2/repo16/commit/69554a6", payloadCommits[0].URL) - assert.Equal(t, "User2", payloadCommits[0].Committer.Name) - assert.Equal(t, "user2", payloadCommits[0].Committer.UserName) - assert.Equal(t, "User2", payloadCommits[0].Author.Name) - assert.Equal(t, "user2", payloadCommits[0].Author.UserName) - assert.EqualValues(t, []string{}, payloadCommits[0].Added) - assert.EqualValues(t, []string{}, payloadCommits[0].Removed) - assert.EqualValues(t, []string{"readme.md"}, payloadCommits[0].Modified) - - assert.Equal(t, "27566bd", payloadCommits[1].ID) - assert.Equal(t, "good signed commit (with not yet validated email)", payloadCommits[1].Message) - assert.Equal(t, "/user2/repo16/commit/27566bd", payloadCommits[1].URL) - assert.Equal(t, "User2", payloadCommits[1].Committer.Name) - assert.Equal(t, "user2", payloadCommits[1].Committer.UserName) - assert.Equal(t, "User2", payloadCommits[1].Author.Name) - assert.Equal(t, "user2", payloadCommits[1].Author.UserName) - assert.EqualValues(t, []string{}, payloadCommits[1].Added) - assert.EqualValues(t, []string{}, payloadCommits[1].Removed) - assert.EqualValues(t, []string{"readme.md"}, payloadCommits[1].Modified) - - assert.Equal(t, "5099b81", payloadCommits[2].ID) - assert.Equal(t, "good signed commit", payloadCommits[2].Message) - assert.Equal(t, "/user2/repo16/commit/5099b81", payloadCommits[2].URL) - assert.Equal(t, "User2", payloadCommits[2].Committer.Name) - assert.Equal(t, "user2", payloadCommits[2].Committer.UserName) - assert.Equal(t, "User2", payloadCommits[2].Author.Name) - assert.Equal(t, "user2", payloadCommits[2].Author.UserName) - assert.EqualValues(t, []string{"readme.md"}, payloadCommits[2].Added) - assert.EqualValues(t, []string{}, payloadCommits[2].Removed) - assert.EqualValues(t, []string{}, payloadCommits[2].Modified) -} - -func TestPushCommits_AvatarLink(t *testing.T) { - pushCommits := NewPushCommits() - pushCommits.Commits = []*PushCommit{ - { - Sha1: "abcdef1", - CommitterEmail: "user2@example.com", - CommitterName: "User Two", - AuthorEmail: "user4@example.com", - AuthorName: "User Four", - Message: "message1", - }, - { - Sha1: "abcdef2", - CommitterEmail: "user2@example.com", - CommitterName: "User Two", - AuthorEmail: "user2@example.com", - AuthorName: "User Two", - Message: "message2", - }, - } - pushCommits.Len = len(pushCommits.Commits) - - assert.Equal(t, - "/suburl/user/avatar/user2/-1", - pushCommits.AvatarLink("user2@example.com")) - - assert.Equal(t, - "https://secure.gravatar.com/avatar/19ade630b94e1e0535b3df7387434154?d=identicon", - pushCommits.AvatarLink("nonexistent@example.com")) -} - func TestGetFeeds(t *testing.T) { // test with an individual user assert.NoError(t, PrepareTestDatabase()) diff --git a/models/fixtures/notification.yml b/models/fixtures/notification.yml index fe5c47287d..bd279d4bb2 100644 --- a/models/fixtures/notification.yml +++ b/models/fixtures/notification.yml @@ -7,7 +7,7 @@ updated_by: 2 issue_id: 1 created_unix: 946684800 - updated_unix: 946684800 + updated_unix: 946684820 - id: 2 @@ -17,8 +17,8 @@ source: 1 # issue updated_by: 1 issue_id: 2 - created_unix: 946684800 - updated_unix: 946684800 + created_unix: 946685800 + updated_unix: 946685820 - id: 3 @@ -27,9 +27,9 @@ status: 3 # pinned source: 1 # issue updated_by: 1 - issue_id: 2 - created_unix: 946684800 - updated_unix: 946684800 + issue_id: 3 + created_unix: 946686800 + updated_unix: 946686800 - id: 4 @@ -38,6 +38,17 @@ status: 1 # unread source: 1 # issue updated_by: 1 - issue_id: 2 - created_unix: 946684800 - updated_unix: 946684800 \ No newline at end of file + issue_id: 5 + created_unix: 946687800 + updated_unix: 946687800 + +- + id: 5 + user_id: 2 + repo_id: 2 + status: 1 # unread + source: 1 # issue + updated_by: 5 + issue_id: 4 + created_unix: 946688800 + updated_unix: 946688820 diff --git a/models/issue.go b/models/issue.go index 3986aeee15..aeeb70d27b 100644 --- a/models/issue.go +++ b/models/issue.go @@ -843,6 +843,20 @@ func (issue *Issue) GetLastEventLabel() string { return "repo.issues.opened_by" } +// GetLastComment return last comment for the current issue. +func (issue *Issue) GetLastComment() (*Comment, error) { + var c Comment + exist, err := x.Where("type = ?", CommentTypeComment). + And("issue_id = ?", issue.ID).Desc("id").Get(&c) + if err != nil { + return nil, err + } + if !exist { + return nil, nil + } + return &c, nil +} + // GetLastEventLabelFake returns the localization label for the current issue without providing a link in the username. func (issue *Issue) GetLastEventLabelFake() string { if issue.IsClosed { diff --git a/models/issue_comment.go b/models/issue_comment.go index 3ba6790216..9caab1dc45 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -8,6 +8,7 @@ package models import ( "fmt" + "path" "strings" "code.gitea.io/gitea/modules/git" @@ -235,6 +236,22 @@ func (c *Comment) HTMLURL() string { return fmt.Sprintf("%s#%s", c.Issue.HTMLURL(), c.HashTag()) } +// APIURL formats a API-string to the issue-comment +func (c *Comment) APIURL() string { + err := c.LoadIssue() + if err != nil { // Silently dropping errors :unamused: + log.Error("LoadIssue(%d): %v", c.IssueID, err) + return "" + } + err = c.Issue.loadRepo(x) + if err != nil { // Silently dropping errors :unamused: + log.Error("loadRepo(%d): %v", c.Issue.RepoID, err) + return "" + } + + return c.Issue.Repo.APIURL() + "/" + path.Join("issues/comments", fmt.Sprint(c.ID)) +} + // IssueURL formats a URL-string to the issue func (c *Comment) IssueURL() string { err := c.LoadIssue() diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 7c3107541d..9a77d24d38 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -293,6 +293,8 @@ var migrations = []Migration{ // v118 -> v119 NewMigration("Add commit id and stale to reviews", addReviewCommitAndStale), // v119 -> v120 + NewMigration("Fix migrated repositories' git service type", fixMigratedRepositoryServiceType), + // v120 -> v121 NewMigration("add is_restricted column for users table", addIsRestricted), } diff --git a/models/migrations/v119.go b/models/migrations/v119.go index c1ff7df3ad..746a04ead4 100644 --- a/models/migrations/v119.go +++ b/models/migrations/v119.go @@ -4,14 +4,13 @@ package migrations -import "xorm.io/xorm" +import ( + "code.gitea.io/gitea/modules/structs" -func addIsRestricted(x *xorm.Engine) error { - // User see models/user.go - type User struct { - ID int64 `xorm:"pk autoincr"` - IsRestricted bool `xorm:"NOT NULL DEFAULT false"` - } + "xorm.io/xorm" +) - return x.Sync2(new(User)) +func fixMigratedRepositoryServiceType(x *xorm.Engine) error { + _, err := x.Exec("UPDATE repository SET original_service_type = ? WHERE original_url LIKE 'https://github.com/%'", structs.GithubService) + return err } diff --git a/models/migrations/v120.go b/models/migrations/v120.go new file mode 100644 index 0000000000..c1ff7df3ad --- /dev/null +++ b/models/migrations/v120.go @@ -0,0 +1,17 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import "xorm.io/xorm" + +func addIsRestricted(x *xorm.Engine) error { + // User see models/user.go + type User struct { + ID int64 `xorm:"pk autoincr"` + IsRestricted bool `xorm:"NOT NULL DEFAULT false"` + } + + return x.Sync2(new(User)) +} diff --git a/models/notification.go b/models/notification.go index 5c03b49257..8e9bca0dc6 100644 --- a/models/notification.go +++ b/models/notification.go @@ -6,8 +6,14 @@ package models import ( "fmt" + "path" + "code.gitea.io/gitea/modules/setting" + api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/builder" + "xorm.io/xorm" ) type ( @@ -47,17 +53,67 @@ type Notification struct { IssueID int64 `xorm:"INDEX NOT NULL"` CommitID string `xorm:"INDEX"` CommentID int64 - Comment *Comment `xorm:"-"` UpdatedBy int64 `xorm:"INDEX NOT NULL"` Issue *Issue `xorm:"-"` Repository *Repository `xorm:"-"` + Comment *Comment `xorm:"-"` + User *User `xorm:"-"` CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"` UpdatedUnix timeutil.TimeStamp `xorm:"updated INDEX NOT NULL"` } +// FindNotificationOptions represent the filters for notifications. If an ID is 0 it will be ignored. +type FindNotificationOptions struct { + UserID int64 + RepoID int64 + IssueID int64 + Status NotificationStatus + UpdatedAfterUnix int64 + UpdatedBeforeUnix int64 +} + +// ToCond will convert each condition into a xorm-Cond +func (opts *FindNotificationOptions) ToCond() builder.Cond { + cond := builder.NewCond() + if opts.UserID != 0 { + cond = cond.And(builder.Eq{"notification.user_id": opts.UserID}) + } + if opts.RepoID != 0 { + cond = cond.And(builder.Eq{"notification.repo_id": opts.RepoID}) + } + if opts.IssueID != 0 { + cond = cond.And(builder.Eq{"notification.issue_id": opts.IssueID}) + } + if opts.Status != 0 { + cond = cond.And(builder.Eq{"notification.status": opts.Status}) + } + if opts.UpdatedAfterUnix != 0 { + cond = cond.And(builder.Gte{"notification.updated_unix": opts.UpdatedAfterUnix}) + } + if opts.UpdatedBeforeUnix != 0 { + cond = cond.And(builder.Lte{"notification.updated_unix": opts.UpdatedBeforeUnix}) + } + return cond +} + +// ToSession will convert the given options to a xorm Session by using the conditions from ToCond and joining with issue table if required +func (opts *FindNotificationOptions) ToSession(e Engine) *xorm.Session { + return e.Where(opts.ToCond()) +} + +func getNotifications(e Engine, options FindNotificationOptions) (nl NotificationList, err error) { + err = options.ToSession(e).OrderBy("notification.updated_unix DESC").Find(&nl) + return +} + +// GetNotifications returns all notifications that fit to the given options. +func GetNotifications(opts FindNotificationOptions) (NotificationList, error) { + return getNotifications(x, opts) +} + // CreateOrUpdateIssueNotifications creates an issue notification // for each watcher, or updates it if already exists func CreateOrUpdateIssueNotifications(issueID, commentID int64, notificationAuthorID int64) error { @@ -238,22 +294,124 @@ func notificationsForUser(e Engine, user *User, statuses []NotificationStatus, p return } +// APIFormat converts a Notification to api.NotificationThread +func (n *Notification) APIFormat() *api.NotificationThread { + result := &api.NotificationThread{ + ID: n.ID, + Unread: !(n.Status == NotificationStatusRead || n.Status == NotificationStatusPinned), + Pinned: n.Status == NotificationStatusPinned, + UpdatedAt: n.UpdatedUnix.AsTime(), + URL: n.APIURL(), + } + + //since user only get notifications when he has access to use minimal access mode + if n.Repository != nil { + result.Repository = n.Repository.APIFormat(AccessModeRead) + } + + //handle Subject + switch n.Source { + case NotificationSourceIssue: + result.Subject = &api.NotificationSubject{Type: "Issue"} + if n.Issue != nil { + result.Subject.Title = n.Issue.Title + result.Subject.URL = n.Issue.APIURL() + comment, err := n.Issue.GetLastComment() + if err == nil && comment != nil { + result.Subject.LatestCommentURL = comment.APIURL() + } + } + case NotificationSourcePullRequest: + result.Subject = &api.NotificationSubject{Type: "Pull"} + if n.Issue != nil { + result.Subject.Title = n.Issue.Title + result.Subject.URL = n.Issue.APIURL() + comment, err := n.Issue.GetLastComment() + if err == nil && comment != nil { + result.Subject.LatestCommentURL = comment.APIURL() + } + } + case NotificationSourceCommit: + result.Subject = &api.NotificationSubject{ + Type: "Commit", + Title: n.CommitID, + } + //unused until now + } + + return result +} + +// LoadAttributes load Repo Issue User and Comment if not loaded +func (n *Notification) LoadAttributes() (err error) { + return n.loadAttributes(x) +} + +func (n *Notification) loadAttributes(e Engine) (err error) { + if err = n.loadRepo(e); err != nil { + return + } + if err = n.loadIssue(e); err != nil { + return + } + if err = n.loadUser(e); err != nil { + return + } + if err = n.loadComment(e); err != nil { + return + } + return +} + +func (n *Notification) loadRepo(e Engine) (err error) { + if n.Repository == nil { + n.Repository, err = getRepositoryByID(e, n.RepoID) + if err != nil { + return fmt.Errorf("getRepositoryByID [%d]: %v", n.RepoID, err) + } + } + return nil +} + +func (n *Notification) loadIssue(e Engine) (err error) { + if n.Issue == nil { + n.Issue, err = getIssueByID(e, n.IssueID) + if err != nil { + return fmt.Errorf("getIssueByID [%d]: %v", n.IssueID, err) + } + return n.Issue.loadAttributes(e) + } + return nil +} + +func (n *Notification) loadComment(e Engine) (err error) { + if n.Comment == nil && n.CommentID > 0 { + n.Comment, err = GetCommentByID(n.CommentID) + if err != nil { + return fmt.Errorf("GetCommentByID [%d]: %v", n.CommentID, err) + } + } + return nil +} + +func (n *Notification) loadUser(e Engine) (err error) { + if n.User == nil { + n.User, err = getUserByID(e, n.UserID) + if err != nil { + return fmt.Errorf("getUserByID [%d]: %v", n.UserID, err) + } + } + return nil +} + // GetRepo returns the repo of the notification func (n *Notification) GetRepo() (*Repository, error) { - n.Repository = new(Repository) - _, err := x. - Where("id = ?", n.RepoID). - Get(n.Repository) - return n.Repository, err + return n.Repository, n.loadRepo(x) } // GetIssue returns the issue of the notification func (n *Notification) GetIssue() (*Issue, error) { - n.Issue = new(Issue) - _, err := x. - Where("id = ?", n.IssueID). - Get(n.Issue) - return n.Issue, err + return n.Issue, n.loadIssue(x) } // HTMLURL formats a URL-string to the notification @@ -264,9 +422,34 @@ func (n *Notification) HTMLURL() string { return n.Issue.HTMLURL() } +// APIURL formats a URL-string to the notification +func (n *Notification) APIURL() string { + return setting.AppURL + path.Join("api/v1/notifications/threads", fmt.Sprintf("%d", n.ID)) +} + // NotificationList contains a list of notifications type NotificationList []*Notification +// APIFormat converts a NotificationList to api.NotificationThread list +func (nl NotificationList) APIFormat() []*api.NotificationThread { + var result = make([]*api.NotificationThread, 0, len(nl)) + for _, n := range nl { + result = append(result, n.APIFormat()) + } + return result +} + +// LoadAttributes load Repo Issue User and Comment if not loaded +func (nl NotificationList) LoadAttributes() (err error) { + for i := 0; i < len(nl); i++ { + err = nl[i].LoadAttributes() + if err != nil { + return + } + } + return +} + func (nl NotificationList) getPendingRepoIDs() []int64 { var ids = make(map[int64]struct{}, len(nl)) for _, notification := range nl { @@ -486,7 +669,7 @@ func setNotificationStatusReadIfUnread(e Engine, userID, issueID int64) error { // SetNotificationStatus change the notification status func SetNotificationStatus(notificationID int64, user *User, status NotificationStatus) error { - notification, err := getNotificationByID(notificationID) + notification, err := getNotificationByID(x, notificationID) if err != nil { return err } @@ -501,9 +684,14 @@ func SetNotificationStatus(notificationID int64, user *User, status Notification return err } -func getNotificationByID(notificationID int64) (*Notification, error) { +// GetNotificationByID return notification by ID +func GetNotificationByID(notificationID int64) (*Notification, error) { + return getNotificationByID(x, notificationID) +} + +func getNotificationByID(e Engine, notificationID int64) (*Notification, error) { notification := new(Notification) - ok, err := x. + ok, err := e. Where("id = ?", notificationID). Get(notification) @@ -512,7 +700,7 @@ func getNotificationByID(notificationID int64) (*Notification, error) { } if !ok { - return nil, fmt.Errorf("Notification %d does not exists", notificationID) + return nil, ErrNotExist{ID: notificationID} } return notification, nil diff --git a/models/notification_test.go b/models/notification_test.go index 728be7182c..6485f8dc7a 100644 --- a/models/notification_test.go +++ b/models/notification_test.go @@ -31,11 +31,13 @@ func TestNotificationsForUser(t *testing.T) { statuses := []NotificationStatus{NotificationStatusRead, NotificationStatusUnread} notfs, err := NotificationsForUser(user, statuses, 1, 10) assert.NoError(t, err) - if assert.Len(t, notfs, 2) { - assert.EqualValues(t, 2, notfs[0].ID) + if assert.Len(t, notfs, 3) { + assert.EqualValues(t, 5, notfs[0].ID) assert.EqualValues(t, user.ID, notfs[0].UserID) assert.EqualValues(t, 4, notfs[1].ID) assert.EqualValues(t, user.ID, notfs[1].UserID) + assert.EqualValues(t, 2, notfs[2].ID) + assert.EqualValues(t, user.ID, notfs[2].UserID) } } diff --git a/models/org_team.go b/models/org_team.go index 63c6e11636..0c0a1e7b79 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -590,7 +590,8 @@ func UpdateTeam(t *Team, authChanged bool, includeAllChanged bool) (err error) { return ErrTeamAlreadyExist{t.OrgID, t.LowerName} } - if _, err = sess.ID(t.ID).AllCols().Update(t); err != nil { + if _, err = sess.ID(t.ID).Cols("name", "lower_name", "description", + "can_create_org_repo", "authorize", "includes_all_repositories").Update(t); err != nil { return fmt.Errorf("update: %v", err) } @@ -605,8 +606,7 @@ func UpdateTeam(t *Team, authChanged bool, includeAllChanged bool) (err error) { Delete(new(TeamUnit)); err != nil { return err } - - if _, err = sess.Insert(&t.Units); err != nil { + if _, err = sess.Cols("org_id", "team_id", "type").Insert(&t.Units); err != nil { errRollback := sess.Rollback() if errRollback != nil { log.Error("UpdateTeam sess.Rollback: %v", errRollback) diff --git a/models/pull.go b/models/pull.go index 876036c9e1..e2a35c5920 100644 --- a/models/pull.go +++ b/models/pull.go @@ -13,7 +13,6 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" ) @@ -35,6 +34,7 @@ const ( PullRequestStatusChecking PullRequestStatusMergeable PullRequestStatusManuallyMerged + PullRequestStatusError ) // PullRequest represents relation between pull request and repositories. @@ -396,139 +396,6 @@ func (pr *PullRequest) GetGitRefName() string { return fmt.Sprintf("refs/pull/%d/head", pr.Index) } -// APIFormat assumes following fields have been assigned with valid values: -// Required - Issue -// Optional - Merger -func (pr *PullRequest) APIFormat() *api.PullRequest { - return pr.apiFormat(x) -} - -func (pr *PullRequest) apiFormat(e Engine) *api.PullRequest { - var ( - baseBranch *git.Branch - headBranch *git.Branch - baseCommit *git.Commit - headCommit *git.Commit - err error - ) - if err = pr.Issue.loadRepo(e); err != nil { - log.Error("loadRepo[%d]: %v", pr.ID, err) - return nil - } - apiIssue := pr.Issue.apiFormat(e) - if pr.BaseRepo == nil { - pr.BaseRepo, err = getRepositoryByID(e, pr.BaseRepoID) - if err != nil { - log.Error("GetRepositoryById[%d]: %v", pr.ID, err) - return nil - } - } - if pr.HeadRepo == nil { - pr.HeadRepo, err = getRepositoryByID(e, pr.HeadRepoID) - if err != nil { - log.Error("GetRepositoryById[%d]: %v", pr.ID, err) - return nil - } - } - - if err = pr.Issue.loadRepo(e); err != nil { - log.Error("pr.Issue.loadRepo[%d]: %v", pr.ID, err) - return nil - } - - apiPullRequest := &api.PullRequest{ - ID: pr.ID, - URL: pr.Issue.HTMLURL(), - Index: pr.Index, - Poster: apiIssue.Poster, - Title: apiIssue.Title, - Body: apiIssue.Body, - Labels: apiIssue.Labels, - Milestone: apiIssue.Milestone, - Assignee: apiIssue.Assignee, - Assignees: apiIssue.Assignees, - State: apiIssue.State, - Comments: apiIssue.Comments, - HTMLURL: pr.Issue.HTMLURL(), - DiffURL: pr.Issue.DiffURL(), - PatchURL: pr.Issue.PatchURL(), - HasMerged: pr.HasMerged, - MergeBase: pr.MergeBase, - Deadline: apiIssue.Deadline, - Created: pr.Issue.CreatedUnix.AsTimePtr(), - Updated: pr.Issue.UpdatedUnix.AsTimePtr(), - } - baseBranch, err = pr.BaseRepo.GetBranch(pr.BaseBranch) - if err != nil { - if git.IsErrBranchNotExist(err) { - apiPullRequest.Base = nil - } else { - log.Error("GetBranch[%s]: %v", pr.BaseBranch, err) - return nil - } - } else { - apiBaseBranchInfo := &api.PRBranchInfo{ - Name: pr.BaseBranch, - Ref: pr.BaseBranch, - RepoID: pr.BaseRepoID, - Repository: pr.BaseRepo.innerAPIFormat(e, AccessModeNone, false), - } - baseCommit, err = baseBranch.GetCommit() - if err != nil { - if git.IsErrNotExist(err) { - apiBaseBranchInfo.Sha = "" - } else { - log.Error("GetCommit[%s]: %v", baseBranch.Name, err) - return nil - } - } else { - apiBaseBranchInfo.Sha = baseCommit.ID.String() - } - apiPullRequest.Base = apiBaseBranchInfo - } - - headBranch, err = pr.HeadRepo.GetBranch(pr.HeadBranch) - if err != nil { - if git.IsErrBranchNotExist(err) { - apiPullRequest.Head = nil - } else { - log.Error("GetBranch[%s]: %v", pr.HeadBranch, err) - return nil - } - } else { - apiHeadBranchInfo := &api.PRBranchInfo{ - Name: pr.HeadBranch, - Ref: pr.HeadBranch, - RepoID: pr.HeadRepoID, - Repository: pr.HeadRepo.innerAPIFormat(e, AccessModeNone, false), - } - headCommit, err = headBranch.GetCommit() - if err != nil { - if git.IsErrNotExist(err) { - apiHeadBranchInfo.Sha = "" - } else { - log.Error("GetCommit[%s]: %v", headBranch.Name, err) - return nil - } - } else { - apiHeadBranchInfo.Sha = headCommit.ID.String() - } - apiPullRequest.Head = apiHeadBranchInfo - } - - if pr.Status != PullRequestStatusChecking { - mergeable := pr.Status != PullRequestStatusConflict && !pr.IsWorkInProgress() - apiPullRequest.Mergeable = mergeable - } - if pr.HasMerged { - apiPullRequest.Merged = pr.MergedUnix.AsTimePtr() - apiPullRequest.MergedCommitID = &pr.MergedCommitID - apiPullRequest.MergedBy = pr.Merger.APIFormat() - } - - return apiPullRequest -} - func (pr *PullRequest) getHeadRepo(e Engine) (err error) { pr.HeadRepo, err = getRepositoryByID(e, pr.HeadRepoID) if err != nil && !IsErrRepoNotExist(err) { diff --git a/models/pull_test.go b/models/pull_test.go index 325818e0bf..9c27b603aa 100644 --- a/models/pull_test.go +++ b/models/pull_test.go @@ -29,16 +29,6 @@ func TestPullRequest_LoadIssue(t *testing.T) { assert.Equal(t, int64(2), pr.Issue.ID) } -func TestPullRequest_APIFormat(t *testing.T) { - assert.NoError(t, PrepareTestDatabase()) - pr := AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) - assert.NoError(t, pr.LoadAttributes()) - assert.NoError(t, pr.LoadIssue()) - apiPullRequest := pr.APIFormat() - assert.NotNil(t, apiPullRequest) - assert.Nil(t, apiPullRequest.Head) -} - func TestPullRequest_GetBaseRepo(t *testing.T) { assert.NoError(t, PrepareTestDatabase()) pr := AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) @@ -182,7 +172,7 @@ func TestPullRequest_UpdateCols(t *testing.T) { BaseBranch: "baseBranch", HeadBranch: "headBranch", } - pr.UpdateCols("head_branch") + assert.NoError(t, pr.UpdateCols("head_branch")) pr = AssertExistsAndLoadBean(t, &PullRequest{ID: 1}).(*PullRequest) assert.Equal(t, "master", pr.BaseBranch) diff --git a/models/repo.go b/models/repo.go index 0dbdcc11b5..6c9623ea2c 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1071,17 +1071,18 @@ func initRepoCommit(tmpPath string, repo *Repository, u *User) (err error) { // CreateRepoOptions contains the create repository options type CreateRepoOptions struct { - Name string - Description string - OriginalURL string - Gitignores string - IssueLabels string - License string - Readme string - IsPrivate bool - IsMirror bool - AutoInit bool - Status RepositoryStatus + Name string + Description string + OriginalURL string + GitServiceType structs.GitServiceType + Gitignores string + IssueLabels string + License string + Readme string + IsPrivate bool + IsMirror bool + AutoInit bool + Status RepositoryStatus } func getRepoInitFile(tp, name string) ([]byte, error) { @@ -1369,6 +1370,7 @@ func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err LowerName: strings.ToLower(opts.Name), Description: opts.Description, OriginalURL: opts.OriginalURL, + OriginalServiceType: opts.GitServiceType, IsPrivate: opts.IsPrivate, IsFsckEnabled: !opts.IsMirror, CloseIssuesViaCommitInAnyBranch: setting.Repository.DefaultCloseIssuesViaCommitsInAnyBranch, diff --git a/models/task.go b/models/task.go index 763644e039..e1d751bc3c 100644 --- a/models/task.go +++ b/models/task.go @@ -194,12 +194,13 @@ func CreateMigrateTask(doer, u *User, opts base.MigrateOptions) (*Task, error) { } repo, err := CreateRepository(doer, u, CreateRepoOptions{ - Name: opts.RepoName, - Description: opts.Description, - OriginalURL: opts.OriginalURL, - IsPrivate: opts.Private, - IsMirror: opts.Mirror, - Status: RepositoryBeingMigrated, + Name: opts.RepoName, + Description: opts.Description, + OriginalURL: opts.OriginalURL, + GitServiceType: opts.GitServiceType, + IsPrivate: opts.Private, + IsMirror: opts.Mirror, + Status: RepositoryBeingMigrated, }) if err != nil { task.EndTime = timeutil.TimeStampNow() diff --git a/models/update.go b/models/update.go index 212f22cfc1..17ee9ad5fa 100644 --- a/models/update.go +++ b/models/update.go @@ -5,7 +5,6 @@ package models import ( - "container/list" "fmt" "strings" "time" @@ -27,33 +26,6 @@ const ( EnvIsInternal = "GITEA_INTERNAL_PUSH" ) -// CommitToPushCommit transforms a git.Commit to PushCommit type. -func CommitToPushCommit(commit *git.Commit) *PushCommit { - return &PushCommit{ - Sha1: commit.ID.String(), - Message: commit.Message(), - AuthorEmail: commit.Author.Email, - AuthorName: commit.Author.Name, - CommitterEmail: commit.Committer.Email, - CommitterName: commit.Committer.Name, - Timestamp: commit.Author.When, - } -} - -// ListToPushCommits transforms a list.List to PushCommits type. -func ListToPushCommits(l *list.List) *PushCommits { - var commits []*PushCommit - var actEmail string - for e := l.Front(); e != nil; e = e.Next() { - commit := e.Value.(*git.Commit) - if actEmail == "" { - actEmail = commit.Committer.Email - } - commits = append(commits, CommitToPushCommit(commit)) - } - return &PushCommits{l.Len(), commits, "", make(map[string]string), make(map[string]*User)} -} - // PushUpdateAddDeleteTags updates a number of added and delete tags func PushUpdateAddDeleteTags(repo *Repository, gitRepo *git.Repository, addTags, delTags []string) error { sess := x.NewSession() @@ -258,75 +230,25 @@ func pushUpdateAddTags(e Engine, repo *Repository, gitRepo *git.Repository, tags return nil } -// PushUpdateAddTag must be called for any push actions to add tag -func PushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string) error { - rel, err := GetRelease(repo.ID, tagName) +// SaveOrUpdateTag must be called for any push actions to add tag +func SaveOrUpdateTag(repo *Repository, newRel *Release) error { + rel, err := GetRelease(repo.ID, newRel.TagName) if err != nil && !IsErrReleaseNotExist(err) { return fmt.Errorf("GetRelease: %v", err) } - tag, err := gitRepo.GetTag(tagName) - if err != nil { - return fmt.Errorf("GetTag: %v", err) - } - commit, err := tag.Commit() - if err != nil { - return fmt.Errorf("Commit: %v", err) - } - - sig := tag.Tagger - if sig == nil { - sig = commit.Author - } - if sig == nil { - sig = commit.Committer - } - - var author *User - var createdAt = time.Unix(1, 0) - - if sig != nil { - author, err = GetUserByEmail(sig.Email) - if err != nil && !IsErrUserNotExist(err) { - return fmt.Errorf("GetUserByEmail: %v", err) - } - createdAt = sig.When - } - - commitsCount, err := commit.CommitsCount() - if err != nil { - return fmt.Errorf("CommitsCount: %v", err) - } - if rel == nil { - rel = &Release{ - RepoID: repo.ID, - Title: "", - TagName: tagName, - LowerTagName: strings.ToLower(tagName), - Target: "", - Sha1: commit.ID.String(), - NumCommits: commitsCount, - Note: "", - IsDraft: false, - IsPrerelease: false, - IsTag: true, - CreatedUnix: timeutil.TimeStamp(createdAt.Unix()), - } - if author != nil { - rel.PublisherID = author.ID - } - - if _, err = x.InsertOne(rel); err != nil { + rel = newRel + if _, err = x.Insert(rel); err != nil { return fmt.Errorf("InsertOne: %v", err) } } else { - rel.Sha1 = commit.ID.String() - rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix()) - rel.NumCommits = commitsCount + rel.Sha1 = newRel.Sha1 + rel.CreatedUnix = newRel.CreatedUnix + rel.NumCommits = newRel.NumCommits rel.IsDraft = false - if rel.IsTag && author != nil { - rel.PublisherID = author.ID + if rel.IsTag && newRel.PublisherID > 0 { + rel.PublisherID = newRel.PublisherID } if _, err = x.ID(rel.ID).AllCols().Update(rel); err != nil { return fmt.Errorf("Update: %v", err) diff --git a/models/update_test.go b/models/update_test.go deleted file mode 100644 index f2219a4e68..0000000000 --- a/models/update_test.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2016 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package models - -import ( - "container/list" - "testing" - "time" - - "code.gitea.io/gitea/modules/git" - - "github.com/stretchr/testify/assert" -) - -func TestCommitToPushCommit(t *testing.T) { - now := time.Now() - sig := &git.Signature{ - Email: "example@example.com", - Name: "John Doe", - When: now, - } - const hexString = "0123456789abcdef0123456789abcdef01234567" - sha1, err := git.NewIDFromString(hexString) - assert.NoError(t, err) - pushCommit := CommitToPushCommit(&git.Commit{ - ID: sha1, - Author: sig, - Committer: sig, - CommitMessage: "Commit Message", - }) - assert.Equal(t, hexString, pushCommit.Sha1) - assert.Equal(t, "Commit Message", pushCommit.Message) - assert.Equal(t, "example@example.com", pushCommit.AuthorEmail) - assert.Equal(t, "John Doe", pushCommit.AuthorName) - assert.Equal(t, "example@example.com", pushCommit.CommitterEmail) - assert.Equal(t, "John Doe", pushCommit.CommitterName) - assert.Equal(t, now, pushCommit.Timestamp) -} - -func TestListToPushCommits(t *testing.T) { - now := time.Now() - sig := &git.Signature{ - Email: "example@example.com", - Name: "John Doe", - When: now, - } - - const hexString1 = "0123456789abcdef0123456789abcdef01234567" - hash1, err := git.NewIDFromString(hexString1) - assert.NoError(t, err) - const hexString2 = "fedcba9876543210fedcba9876543210fedcba98" - hash2, err := git.NewIDFromString(hexString2) - assert.NoError(t, err) - - l := list.New() - l.PushBack(&git.Commit{ - ID: hash1, - Author: sig, - Committer: sig, - CommitMessage: "Message1", - }) - l.PushBack(&git.Commit{ - ID: hash2, - Author: sig, - Committer: sig, - CommitMessage: "Message2", - }) - - pushCommits := ListToPushCommits(l) - assert.Equal(t, 2, pushCommits.Len) - if assert.Len(t, pushCommits.Commits, 2) { - assert.Equal(t, "Message1", pushCommits.Commits[0].Message) - assert.Equal(t, hexString1, pushCommits.Commits[0].Sha1) - assert.Equal(t, "example@example.com", pushCommits.Commits[0].AuthorEmail) - assert.Equal(t, now, pushCommits.Commits[0].Timestamp) - - assert.Equal(t, "Message2", pushCommits.Commits[1].Message) - assert.Equal(t, hexString2, pushCommits.Commits[1].Sha1) - assert.Equal(t, "example@example.com", pushCommits.Commits[1].AuthorEmail) - assert.Equal(t, now, pushCommits.Commits[1].Timestamp) - } -} - -// TODO TestPushUpdate diff --git a/modules/context/context.go b/modules/context/context.go index 4b590a7181..f8663b9c03 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -1,4 +1,5 @@ // Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2020 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. @@ -122,7 +123,7 @@ func (ctx *Context) RedirectToFirst(location ...string) { } u, err := url.Parse(loc) - if err != nil || (u.Scheme != "" && !strings.HasPrefix(strings.ToLower(loc), strings.ToLower(setting.AppURL))) { + if err != nil || ((u.Scheme != "" || u.Host != "") && !strings.HasPrefix(strings.ToLower(loc), strings.ToLower(setting.AppURL))) { continue } diff --git a/modules/convert/main_test.go b/modules/convert/main_test.go new file mode 100644 index 0000000000..8720ff0427 --- /dev/null +++ b/modules/convert/main_test.go @@ -0,0 +1,16 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package convert + +import ( + "path/filepath" + "testing" + + "code.gitea.io/gitea/models" +) + +func TestMain(m *testing.M) { + models.MainTest(m, filepath.Join("..", "..")) +} diff --git a/modules/convert/pull.go b/modules/convert/pull.go new file mode 100644 index 0000000000..f8534f839a --- /dev/null +++ b/modules/convert/pull.go @@ -0,0 +1,141 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package convert + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + api "code.gitea.io/gitea/modules/structs" +) + +// ToAPIPullRequest assumes following fields have been assigned with valid values: +// Required - Issue +// Optional - Merger +func ToAPIPullRequest(pr *models.PullRequest) *api.PullRequest { + var ( + baseBranch *git.Branch + headBranch *git.Branch + baseCommit *git.Commit + headCommit *git.Commit + err error + ) + if err = pr.Issue.LoadRepo(); err != nil { + log.Error("loadRepo[%d]: %v", pr.ID, err) + return nil + } + apiIssue := pr.Issue.APIFormat() + if pr.BaseRepo == nil { + pr.BaseRepo, err = models.GetRepositoryByID(pr.BaseRepoID) + if err != nil { + log.Error("GetRepositoryById[%d]: %v", pr.ID, err) + return nil + } + } + if pr.HeadRepo == nil { + pr.HeadRepo, err = models.GetRepositoryByID(pr.HeadRepoID) + if err != nil { + log.Error("GetRepositoryById[%d]: %v", pr.ID, err) + return nil + } + } + + if err = pr.Issue.LoadRepo(); err != nil { + log.Error("pr.Issue.loadRepo[%d]: %v", pr.ID, err) + return nil + } + + apiPullRequest := &api.PullRequest{ + ID: pr.ID, + URL: pr.Issue.HTMLURL(), + Index: pr.Index, + Poster: apiIssue.Poster, + Title: apiIssue.Title, + Body: apiIssue.Body, + Labels: apiIssue.Labels, + Milestone: apiIssue.Milestone, + Assignee: apiIssue.Assignee, + Assignees: apiIssue.Assignees, + State: apiIssue.State, + Comments: apiIssue.Comments, + HTMLURL: pr.Issue.HTMLURL(), + DiffURL: pr.Issue.DiffURL(), + PatchURL: pr.Issue.PatchURL(), + HasMerged: pr.HasMerged, + MergeBase: pr.MergeBase, + Deadline: apiIssue.Deadline, + Created: pr.Issue.CreatedUnix.AsTimePtr(), + Updated: pr.Issue.UpdatedUnix.AsTimePtr(), + } + baseBranch, err = pr.BaseRepo.GetBranch(pr.BaseBranch) + if err != nil { + if git.IsErrBranchNotExist(err) { + apiPullRequest.Base = nil + } else { + log.Error("GetBranch[%s]: %v", pr.BaseBranch, err) + return nil + } + } else { + apiBaseBranchInfo := &api.PRBranchInfo{ + Name: pr.BaseBranch, + Ref: pr.BaseBranch, + RepoID: pr.BaseRepoID, + Repository: pr.BaseRepo.APIFormat(models.AccessModeNone), + } + baseCommit, err = baseBranch.GetCommit() + if err != nil { + if git.IsErrNotExist(err) { + apiBaseBranchInfo.Sha = "" + } else { + log.Error("GetCommit[%s]: %v", baseBranch.Name, err) + return nil + } + } else { + apiBaseBranchInfo.Sha = baseCommit.ID.String() + } + apiPullRequest.Base = apiBaseBranchInfo + } + + headBranch, err = pr.HeadRepo.GetBranch(pr.HeadBranch) + if err != nil { + if git.IsErrBranchNotExist(err) { + apiPullRequest.Head = nil + } else { + log.Error("GetBranch[%s]: %v", pr.HeadBranch, err) + return nil + } + } else { + apiHeadBranchInfo := &api.PRBranchInfo{ + Name: pr.HeadBranch, + Ref: pr.HeadBranch, + RepoID: pr.HeadRepoID, + Repository: pr.HeadRepo.APIFormat(models.AccessModeNone), + } + headCommit, err = headBranch.GetCommit() + if err != nil { + if git.IsErrNotExist(err) { + apiHeadBranchInfo.Sha = "" + } else { + log.Error("GetCommit[%s]: %v", headBranch.Name, err) + return nil + } + } else { + apiHeadBranchInfo.Sha = headCommit.ID.String() + } + apiPullRequest.Head = apiHeadBranchInfo + } + + if pr.Status != models.PullRequestStatusChecking { + mergeable := !(pr.Status == models.PullRequestStatusConflict || pr.Status == models.PullRequestStatusError) && !pr.IsWorkInProgress() + apiPullRequest.Mergeable = mergeable + } + if pr.HasMerged { + apiPullRequest.Merged = pr.MergedUnix.AsTimePtr() + apiPullRequest.MergedCommitID = &pr.MergedCommitID + apiPullRequest.MergedBy = pr.Merger.APIFormat() + } + + return apiPullRequest +} diff --git a/modules/convert/pull_test.go b/modules/convert/pull_test.go new file mode 100644 index 0000000000..9055d555e8 --- /dev/null +++ b/modules/convert/pull_test.go @@ -0,0 +1,23 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package convert + +import ( + "testing" + + "code.gitea.io/gitea/models" + + "github.com/stretchr/testify/assert" +) + +func TestPullRequest_APIFormat(t *testing.T) { + assert.NoError(t, models.PrepareTestDatabase()) + pr := models.AssertExistsAndLoadBean(t, &models.PullRequest{ID: 1}).(*models.PullRequest) + assert.NoError(t, pr.LoadAttributes()) + assert.NoError(t, pr.LoadIssue()) + apiPullRequest := ToAPIPullRequest(pr) + assert.NotNil(t, apiPullRequest) + assert.Nil(t, apiPullRequest.Head) +} diff --git a/modules/migrations/gitea.go b/modules/migrations/gitea.go index f52f6c585a..94e81bd9a5 100644 --- a/modules/migrations/gitea.go +++ b/modules/migrations/gitea.go @@ -101,12 +101,13 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate var r *models.Repository if opts.MigrateToRepoID <= 0 { r, err = models.CreateRepository(g.doer, owner, models.CreateRepoOptions{ - Name: g.repoName, - Description: repo.Description, - OriginalURL: repo.OriginalURL, - IsPrivate: opts.Private, - IsMirror: opts.Mirror, - Status: models.RepositoryBeingMigrated, + Name: g.repoName, + Description: repo.Description, + OriginalURL: repo.OriginalURL, + GitServiceType: opts.GitServiceType, + IsPrivate: opts.Private, + IsMirror: opts.Mirror, + Status: models.RepositoryBeingMigrated, }) } else { r, err = models.GetRepositoryByID(opts.MigrateToRepoID) diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index 00f049d432..74e661c4f9 100644 --- a/modules/notification/action/action.go +++ b/modules/notification/action/action.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification/base" + "code.gitea.io/gitea/modules/repository" ) type actionNotifier struct { @@ -266,7 +267,7 @@ func (*actionNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *mode } } -func (a *actionNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { +func (a *actionNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) { data, err := json.Marshal(commits) if err != nil { log.Error("json.Marshal: %v", err) diff --git a/modules/notification/base/notifier.go b/modules/notification/base/notifier.go index 48846b3446..12fde1737d 100644 --- a/modules/notification/base/notifier.go +++ b/modules/notification/base/notifier.go @@ -7,6 +7,7 @@ package base import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/repository" ) // Notifier defines an interface to notify receiver @@ -45,11 +46,11 @@ type Notifier interface { NotifyUpdateRelease(doer *models.User, rel *models.Release) NotifyDeleteRelease(doer *models.User, rel *models.Release) - NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) + NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) NotifyCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) NotifyDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) - NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) + NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) NotifySyncCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) } diff --git a/modules/notification/base/null.go b/modules/notification/base/null.go index bea4e55277..1f90f6519d 100644 --- a/modules/notification/base/null.go +++ b/modules/notification/base/null.go @@ -7,6 +7,7 @@ package base import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/repository" ) // NullNotifier implements a blank notifier @@ -116,7 +117,7 @@ func (*NullNotifier) NotifyMigrateRepository(doer *models.User, u *models.User, } // NotifyPushCommits notifies commits pushed to notifiers -func (*NullNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { +func (*NullNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) { } // NotifyCreateRef notifies branch or tag creation to notifiers @@ -136,7 +137,7 @@ func (*NullNotifier) NotifyTransferRepository(doer *models.User, repo *models.Re } // NotifySyncPushCommits places a place holder function -func (*NullNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { +func (*NullNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) { } // NotifySyncCreateRef places a place holder function diff --git a/modules/notification/indexer/indexer.go b/modules/notification/indexer/indexer.go index 4ca5e64c3e..e87f522061 100644 --- a/modules/notification/indexer/indexer.go +++ b/modules/notification/indexer/indexer.go @@ -10,6 +10,7 @@ import ( issue_indexer "code.gitea.io/gitea/modules/indexer/issues" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification/base" + "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" ) @@ -117,7 +118,7 @@ func (r *indexerNotifier) NotifyMigrateRepository(doer *models.User, u *models.U } } -func (r *indexerNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { +func (r *indexerNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) { if setting.Indexer.RepoIndexerEnabled && refName == repo.DefaultBranch { code_indexer.UpdateRepoIndexer(repo) } diff --git a/modules/notification/notification.go b/modules/notification/notification.go index f567552df5..ed7204c9e0 100644 --- a/modules/notification/notification.go +++ b/modules/notification/notification.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/notification/mail" "code.gitea.io/gitea/modules/notification/ui" "code.gitea.io/gitea/modules/notification/webhook" + "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" ) @@ -215,7 +216,7 @@ func NotifyRenameRepository(doer *models.User, repo *models.Repository, oldName } // NotifyPushCommits notifies commits pushed to notifiers -func NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { +func NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) { for _, notifier := range notifiers { notifier.NotifyPushCommits(pusher, repo, refName, oldCommitID, newCommitID, commits) } @@ -236,7 +237,7 @@ func NotifyDeleteRef(pusher *models.User, repo *models.Repository, refType, refF } // NotifySyncPushCommits notifies commits pushed to notifiers -func NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { +func NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) { for _, notifier := range notifiers { notifier.NotifySyncPushCommits(pusher, repo, refName, oldCommitID, newCommitID, commits) } diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go index e0801445d8..3f993df88e 100644 --- a/modules/notification/webhook/webhook.go +++ b/modules/notification/webhook/webhook.go @@ -6,9 +6,11 @@ package webhook import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification/base" + "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" webhook_module "code.gitea.io/gitea/modules/webhook" @@ -49,7 +51,7 @@ func (m *webhookNotifier) NotifyIssueClearLabels(doer *models.User, issue *model err = webhook_module.PrepareWebhooks(issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{ Action: api.HookIssueLabelCleared, Index: issue.Index, - PullRequest: issue.PullRequest.APIFormat(), + PullRequest: convert.ToAPIPullRequest(issue.PullRequest), Repository: issue.Repo.APIFormat(mode), Sender: doer.APIFormat(), }) @@ -135,7 +137,7 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *models.User, issue *mo issue.PullRequest.Issue = issue apiPullRequest := &api.PullRequestPayload{ Index: issue.Index, - PullRequest: issue.PullRequest.APIFormat(), + PullRequest: convert.ToAPIPullRequest(issue.PullRequest), Repository: issue.Repo.APIFormat(mode), Sender: doer.APIFormat(), } @@ -187,7 +189,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(doer *models.User, issue *model From: oldTitle, }, }, - PullRequest: issue.PullRequest.APIFormat(), + PullRequest: convert.ToAPIPullRequest(issue.PullRequest), Repository: issue.Repo.APIFormat(mode), Sender: doer.APIFormat(), }) @@ -222,7 +224,7 @@ func (m *webhookNotifier) NotifyIssueChangeStatus(doer *models.User, issue *mode // Merge pull request calls issue.changeStatus so we need to handle separately. apiPullRequest := &api.PullRequestPayload{ Index: issue.Index, - PullRequest: issue.PullRequest.APIFormat(), + PullRequest: convert.ToAPIPullRequest(issue.PullRequest), Repository: issue.Repo.APIFormat(mode), Sender: doer.APIFormat(), } @@ -291,7 +293,7 @@ func (m *webhookNotifier) NotifyNewPullRequest(pull *models.PullRequest) { if err := webhook_module.PrepareWebhooks(pull.Issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{ Action: api.HookIssueOpened, Index: pull.Issue.Index, - PullRequest: pull.APIFormat(), + PullRequest: convert.ToAPIPullRequest(pull), Repository: pull.Issue.Repo.APIFormat(mode), Sender: pull.Issue.Poster.APIFormat(), }); err != nil { @@ -312,7 +314,7 @@ func (m *webhookNotifier) NotifyIssueChangeContent(doer *models.User, issue *mod From: oldContent, }, }, - PullRequest: issue.PullRequest.APIFormat(), + PullRequest: convert.ToAPIPullRequest(issue.PullRequest), Repository: issue.Repo.APIFormat(mode), Sender: doer.APIFormat(), }) @@ -439,7 +441,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(doer *models.User, issue *mode err = webhook_module.PrepareWebhooks(issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{ Action: api.HookIssueLabelUpdated, Index: issue.Index, - PullRequest: issue.PullRequest.APIFormat(), + PullRequest: convert.ToAPIPullRequest(issue.PullRequest), Repository: issue.Repo.APIFormat(models.AccessModeNone), Sender: doer.APIFormat(), }) @@ -481,7 +483,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *models.User, issue *m err = webhook_module.PrepareWebhooks(issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{ Action: hookAction, Index: issue.Index, - PullRequest: issue.PullRequest.APIFormat(), + PullRequest: convert.ToAPIPullRequest(issue.PullRequest), Repository: issue.Repo.APIFormat(mode), Sender: doer.APIFormat(), }) @@ -499,7 +501,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *models.User, issue *m } } -func (m *webhookNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { +func (m *webhookNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) { apiPusher := pusher.APIFormat() apiCommits, err := commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL()) if err != nil { @@ -547,7 +549,7 @@ func (*webhookNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *mod // Merge pull request calls issue.changeStatus so we need to handle separately. apiPullRequest := &api.PullRequestPayload{ Index: pr.Issue.Index, - PullRequest: pr.APIFormat(), + PullRequest: convert.ToAPIPullRequest(pr), Repository: pr.Issue.Repo.APIFormat(mode), Sender: doer.APIFormat(), Action: api.HookIssueClosed, @@ -580,7 +582,7 @@ func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *models.User, From: oldBranch, }, }, - PullRequest: issue.PullRequest.APIFormat(), + PullRequest: convert.ToAPIPullRequest(issue.PullRequest), Repository: issue.Repo.APIFormat(mode), Sender: doer.APIFormat(), }) @@ -619,7 +621,7 @@ func (m *webhookNotifier) NotifyPullRequestReview(pr *models.PullRequest, review if err := webhook_module.PrepareWebhooks(review.Issue.Repo, reviewHookType, &api.PullRequestPayload{ Action: api.HookIssueSynchronized, Index: review.Issue.Index, - PullRequest: pr.APIFormat(), + PullRequest: convert.ToAPIPullRequest(pr), Repository: review.Issue.Repo.APIFormat(mode), Sender: review.Reviewer.APIFormat(), Review: &api.ReviewPayload{ @@ -674,7 +676,7 @@ func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *models.User, pr *m if err := webhook_module.PrepareWebhooks(pr.Issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{ Action: api.HookIssueSynchronized, Index: pr.Issue.Index, - PullRequest: pr.Issue.PullRequest.APIFormat(), + PullRequest: convert.ToAPIPullRequest(pr), Repository: pr.Issue.Repo.APIFormat(models.AccessModeNone), Sender: doer.APIFormat(), }); err != nil { @@ -727,7 +729,7 @@ func (m *webhookNotifier) NotifyDeleteRelease(doer *models.User, rel *models.Rel sendReleaseHook(doer, rel, api.HookReleaseDeleted) } -func (m *webhookNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { +func (m *webhookNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) { apiPusher := pusher.APIFormat() apiCommits, err := commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL()) if err != nil { diff --git a/modules/repofiles/action.go b/modules/repofiles/action.go index d207247114..07bc1b875b 100644 --- a/modules/repofiles/action.go +++ b/modules/repofiles/action.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/references" + "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" ) @@ -59,7 +60,7 @@ func changeIssueStatus(repo *models.Repository, issue *models.Issue, doer *model } // UpdateIssuesCommit checks if issues are manipulated by commit message. -func UpdateIssuesCommit(doer *models.User, repo *models.Repository, commits []*models.PushCommit, branchName string) error { +func UpdateIssuesCommit(doer *models.User, repo *models.Repository, commits []*repository.PushCommit, branchName string) error { // Commits are appended in the reverse order. for i := len(commits) - 1; i >= 0; i-- { c := commits[i] @@ -154,7 +155,7 @@ type CommitRepoActionOptions struct { RefFullName string OldCommitID string NewCommitID string - Commits *models.PushCommits + Commits *repository.PushCommits } // CommitRepoAction adds new commit action to the repository, and prepare @@ -216,10 +217,10 @@ func CommitRepoAction(optsList ...*CommitRepoActionOptions) error { if opts.NewCommitID == git.EmptySHA { opType = models.ActionDeleteTag } - opts.Commits = &models.PushCommits{} + opts.Commits = &repository.PushCommits{} } else if opts.NewCommitID == git.EmptySHA { opType = models.ActionDeleteBranch - opts.Commits = &models.PushCommits{} + opts.Commits = &repository.PushCommits{} } else { // if not the first commit, set the compare URL. if opts.OldCommitID == git.EmptySHA { diff --git a/modules/repofiles/action_test.go b/modules/repofiles/action_test.go index 97ac1c45e9..85bf39c835 100644 --- a/modules/repofiles/action_test.go +++ b/modules/repofiles/action_test.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/repository" "github.com/stretchr/testify/assert" ) @@ -34,8 +35,8 @@ func TestCommitRepoAction(t *testing.T) { RefFullName: "refName", OldCommitID: "oldCommitID", NewCommitID: "newCommitID", - Commits: &models.PushCommits{ - Commits: []*models.PushCommit{ + Commits: &repository.PushCommits{ + Commits: []*repository.PushCommit{ { Sha1: "69554a6", CommitterEmail: "user2@example.com", @@ -68,7 +69,7 @@ func TestCommitRepoAction(t *testing.T) { RefFullName: git.TagPrefix + "v1.1", OldCommitID: git.EmptySHA, NewCommitID: "newCommitID", - Commits: &models.PushCommits{}, + Commits: &repository.PushCommits{}, }, action: models.Action{ OpType: models.ActionPushTag, @@ -82,7 +83,7 @@ func TestCommitRepoAction(t *testing.T) { RefFullName: git.TagPrefix + "v1.1", OldCommitID: "oldCommitID", NewCommitID: git.EmptySHA, - Commits: &models.PushCommits{}, + Commits: &repository.PushCommits{}, }, action: models.Action{ OpType: models.ActionDeleteTag, @@ -96,7 +97,7 @@ func TestCommitRepoAction(t *testing.T) { RefFullName: git.BranchPrefix + "feature/1", OldCommitID: "oldCommitID", NewCommitID: git.EmptySHA, - Commits: &models.PushCommits{}, + Commits: &repository.PushCommits{}, }, action: models.Action{ OpType: models.ActionDeleteBranch, @@ -127,7 +128,7 @@ func TestCommitRepoAction(t *testing.T) { func TestUpdateIssuesCommit(t *testing.T) { assert.NoError(t, models.PrepareTestDatabase()) - pushCommits := []*models.PushCommit{ + pushCommits := []*repository.PushCommit{ { Sha1: "abcdef1", CommitterEmail: "user2@example.com", @@ -174,7 +175,7 @@ func TestUpdateIssuesCommit(t *testing.T) { models.CheckConsistencyFor(t, &models.Action{}) // Test that push to a non-default branch closes no issue. - pushCommits = []*models.PushCommit{ + pushCommits = []*repository.PushCommit{ { Sha1: "abcdef1", CommitterEmail: "user2@example.com", @@ -203,7 +204,7 @@ func TestUpdateIssuesCommit(t *testing.T) { func TestUpdateIssuesCommit_Colon(t *testing.T) { assert.NoError(t, models.PrepareTestDatabase()) - pushCommits := []*models.PushCommit{ + pushCommits := []*repository.PushCommit{ { Sha1: "abcdef2", CommitterEmail: "user2@example.com", @@ -231,7 +232,7 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) { user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) // Test that push to a non-default branch closes an issue. - pushCommits := []*models.PushCommit{ + pushCommits := []*repository.PushCommit{ { Sha1: "abcdef1", CommitterEmail: "user2@example.com", @@ -266,7 +267,7 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) { // Test that a push to default branch closes issue in another repo // If the user also has push permissions to that repo - pushCommits := []*models.PushCommit{ + pushCommits := []*repository.PushCommit{ { Sha1: "abcdef1", CommitterEmail: "user2@example.com", @@ -301,7 +302,7 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) { // Test that a push with close reference *can not* close issue // If the commiter doesn't have push rights in that repo - pushCommits := []*models.PushCommit{ + pushCommits := []*repository.PushCommit{ { Sha1: "abcdef3", CommitterEmail: "user10@example.com", diff --git a/modules/repofiles/update.go b/modules/repofiles/update.go index 7ad4a4d388..3a0ba668c1 100644 --- a/modules/repofiles/update.go +++ b/modules/repofiles/update.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" pull_service "code.gitea.io/gitea/services/pull" @@ -549,7 +550,7 @@ func createCommitRepoActions(repo *models.Repository, gitRepo *git.Repository, o if isNewRef && isDelRef { return nil, fmt.Errorf("Old and new revisions are both %s", git.EmptySHA) } - var commits = &models.PushCommits{} + var commits = &repository.PushCommits{} if strings.HasPrefix(opts.RefFullName, git.TagPrefix) { // If is tag reference tagName := opts.RefFullName[len(git.TagPrefix):] @@ -584,7 +585,7 @@ func createCommitRepoActions(repo *models.Repository, gitRepo *git.Repository, o } } - commits = models.ListToPushCommits(l) + commits = repository.ListToPushCommits(l) } actions = append(actions, &CommitRepoActionOptions{ PusherName: opts.PusherName, @@ -609,7 +610,7 @@ func createCommitRepoActionOption(repo *models.Repository, gitRepo *git.Reposito return nil, fmt.Errorf("Old and new revisions are both %s", git.EmptySHA) } - var commits = &models.PushCommits{} + var commits = &repository.PushCommits{} if strings.HasPrefix(opts.RefFullName, git.TagPrefix) { // If is tag reference tagName := opts.RefFullName[len(git.TagPrefix):] @@ -620,7 +621,7 @@ func createCommitRepoActionOption(repo *models.Repository, gitRepo *git.Reposito } else { // Clear cache for tag commit count cache.Remove(repo.GetCommitsCountCacheKey(tagName, true)) - if err := models.PushUpdateAddTag(repo, gitRepo, tagName); err != nil { + if err := repository.PushUpdateAddTag(repo, gitRepo, tagName); err != nil { return nil, fmt.Errorf("PushUpdateAddTag: %v", err) } } @@ -649,7 +650,7 @@ func createCommitRepoActionOption(repo *models.Repository, gitRepo *git.Reposito } } - commits = models.ListToPushCommits(l) + commits = repository.ListToPushCommits(l) } return &CommitRepoActionOptions{ diff --git a/modules/repository/commits.go b/modules/repository/commits.go new file mode 100644 index 0000000000..7345aaae24 --- /dev/null +++ b/modules/repository/commits.go @@ -0,0 +1,168 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repository + +import ( + "container/list" + "fmt" + "time" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + api "code.gitea.io/gitea/modules/structs" +) + +// PushCommit represents a commit in a push operation. +type PushCommit struct { + Sha1 string + Message string + AuthorEmail string + AuthorName string + CommitterEmail string + CommitterName string + Timestamp time.Time +} + +// PushCommits represents list of commits in a push operation. +type PushCommits struct { + Len int + Commits []*PushCommit + CompareURL string + + avatars map[string]string + emailUsers map[string]*models.User +} + +// NewPushCommits creates a new PushCommits object. +func NewPushCommits() *PushCommits { + return &PushCommits{ + avatars: make(map[string]string), + emailUsers: make(map[string]*models.User), + } +} + +// ToAPIPayloadCommits converts a PushCommits object to +// api.PayloadCommit format. +func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.PayloadCommit, error) { + commits := make([]*api.PayloadCommit, len(pc.Commits)) + + if pc.emailUsers == nil { + pc.emailUsers = make(map[string]*models.User) + } + var err error + for i, commit := range pc.Commits { + authorUsername := "" + author, ok := pc.emailUsers[commit.AuthorEmail] + if !ok { + author, err = models.GetUserByEmail(commit.AuthorEmail) + if err == nil { + authorUsername = author.Name + pc.emailUsers[commit.AuthorEmail] = author + } + } else { + authorUsername = author.Name + } + + committerUsername := "" + committer, ok := pc.emailUsers[commit.CommitterEmail] + if !ok { + committer, err = models.GetUserByEmail(commit.CommitterEmail) + if err == nil { + // TODO: check errors other than email not found. + committerUsername = committer.Name + pc.emailUsers[commit.CommitterEmail] = committer + } + } else { + committerUsername = committer.Name + } + + fileStatus, err := git.GetCommitFileStatus(repoPath, commit.Sha1) + if err != nil { + return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %v", commit.Sha1, err) + } + + commits[i] = &api.PayloadCommit{ + ID: commit.Sha1, + Message: commit.Message, + URL: fmt.Sprintf("%s/commit/%s", repoLink, commit.Sha1), + Author: &api.PayloadUser{ + Name: commit.AuthorName, + Email: commit.AuthorEmail, + UserName: authorUsername, + }, + Committer: &api.PayloadUser{ + Name: commit.CommitterName, + Email: commit.CommitterEmail, + UserName: committerUsername, + }, + Added: fileStatus.Added, + Removed: fileStatus.Removed, + Modified: fileStatus.Modified, + Timestamp: commit.Timestamp, + } + } + return commits, nil +} + +// AvatarLink tries to match user in database with e-mail +// in order to show custom avatar, and falls back to general avatar link. +func (pc *PushCommits) AvatarLink(email string) string { + if pc.avatars == nil { + pc.avatars = make(map[string]string) + } + avatar, ok := pc.avatars[email] + if ok { + return avatar + } + + u, ok := pc.emailUsers[email] + if !ok { + var err error + u, err = models.GetUserByEmail(email) + if err != nil { + pc.avatars[email] = base.AvatarLink(email) + if !models.IsErrUserNotExist(err) { + log.Error("GetUserByEmail: %v", err) + return "" + } + } else { + pc.emailUsers[email] = u + } + } + if u != nil { + pc.avatars[email] = u.RelAvatarLink() + } + + return pc.avatars[email] +} + +// CommitToPushCommit transforms a git.Commit to PushCommit type. +func CommitToPushCommit(commit *git.Commit) *PushCommit { + return &PushCommit{ + Sha1: commit.ID.String(), + Message: commit.Message(), + AuthorEmail: commit.Author.Email, + AuthorName: commit.Author.Name, + CommitterEmail: commit.Committer.Email, + CommitterName: commit.Committer.Name, + Timestamp: commit.Author.When, + } +} + +// ListToPushCommits transforms a list.List to PushCommits type. +func ListToPushCommits(l *list.List) *PushCommits { + var commits []*PushCommit + var actEmail string + for e := l.Front(); e != nil; e = e.Next() { + commit := e.Value.(*git.Commit) + if actEmail == "" { + actEmail = commit.Committer.Email + } + commits = append(commits, CommitToPushCommit(commit)) + } + return &PushCommits{l.Len(), commits, "", make(map[string]string), make(map[string]*models.User)} +} diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go new file mode 100644 index 0000000000..2f61ce3329 --- /dev/null +++ b/modules/repository/commits_test.go @@ -0,0 +1,190 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repository + +import ( + "container/list" + "testing" + "time" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/git" + "github.com/stretchr/testify/assert" +) + +func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { + assert.NoError(t, models.PrepareTestDatabase()) + + pushCommits := NewPushCommits() + pushCommits.Commits = []*PushCommit{ + { + Sha1: "69554a6", + CommitterEmail: "user2@example.com", + CommitterName: "User2", + AuthorEmail: "user2@example.com", + AuthorName: "User2", + Message: "not signed commit", + }, + { + Sha1: "27566bd", + CommitterEmail: "user2@example.com", + CommitterName: "User2", + AuthorEmail: "user2@example.com", + AuthorName: "User2", + Message: "good signed commit (with not yet validated email)", + }, + { + Sha1: "5099b81", + CommitterEmail: "user2@example.com", + CommitterName: "User2", + AuthorEmail: "user2@example.com", + AuthorName: "User2", + Message: "good signed commit", + }, + } + pushCommits.Len = len(pushCommits.Commits) + + repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository) + payloadCommits, err := pushCommits.ToAPIPayloadCommits(repo.RepoPath(), "/user2/repo16") + assert.NoError(t, err) + assert.EqualValues(t, 3, len(payloadCommits)) + + assert.Equal(t, "69554a6", payloadCommits[0].ID) + assert.Equal(t, "not signed commit", payloadCommits[0].Message) + assert.Equal(t, "/user2/repo16/commit/69554a6", payloadCommits[0].URL) + assert.Equal(t, "User2", payloadCommits[0].Committer.Name) + assert.Equal(t, "user2", payloadCommits[0].Committer.UserName) + assert.Equal(t, "User2", payloadCommits[0].Author.Name) + assert.Equal(t, "user2", payloadCommits[0].Author.UserName) + assert.EqualValues(t, []string{}, payloadCommits[0].Added) + assert.EqualValues(t, []string{}, payloadCommits[0].Removed) + assert.EqualValues(t, []string{"readme.md"}, payloadCommits[0].Modified) + + assert.Equal(t, "27566bd", payloadCommits[1].ID) + assert.Equal(t, "good signed commit (with not yet validated email)", payloadCommits[1].Message) + assert.Equal(t, "/user2/repo16/commit/27566bd", payloadCommits[1].URL) + assert.Equal(t, "User2", payloadCommits[1].Committer.Name) + assert.Equal(t, "user2", payloadCommits[1].Committer.UserName) + assert.Equal(t, "User2", payloadCommits[1].Author.Name) + assert.Equal(t, "user2", payloadCommits[1].Author.UserName) + assert.EqualValues(t, []string{}, payloadCommits[1].Added) + assert.EqualValues(t, []string{}, payloadCommits[1].Removed) + assert.EqualValues(t, []string{"readme.md"}, payloadCommits[1].Modified) + + assert.Equal(t, "5099b81", payloadCommits[2].ID) + assert.Equal(t, "good signed commit", payloadCommits[2].Message) + assert.Equal(t, "/user2/repo16/commit/5099b81", payloadCommits[2].URL) + assert.Equal(t, "User2", payloadCommits[2].Committer.Name) + assert.Equal(t, "user2", payloadCommits[2].Committer.UserName) + assert.Equal(t, "User2", payloadCommits[2].Author.Name) + assert.Equal(t, "user2", payloadCommits[2].Author.UserName) + assert.EqualValues(t, []string{"readme.md"}, payloadCommits[2].Added) + assert.EqualValues(t, []string{}, payloadCommits[2].Removed) + assert.EqualValues(t, []string{}, payloadCommits[2].Modified) +} + +func TestPushCommits_AvatarLink(t *testing.T) { + assert.NoError(t, models.PrepareTestDatabase()) + + pushCommits := NewPushCommits() + pushCommits.Commits = []*PushCommit{ + { + Sha1: "abcdef1", + CommitterEmail: "user2@example.com", + CommitterName: "User Two", + AuthorEmail: "user4@example.com", + AuthorName: "User Four", + Message: "message1", + }, + { + Sha1: "abcdef2", + CommitterEmail: "user2@example.com", + CommitterName: "User Two", + AuthorEmail: "user2@example.com", + AuthorName: "User Two", + Message: "message2", + }, + } + pushCommits.Len = len(pushCommits.Commits) + + assert.Equal(t, + "/user/avatar/user2/-1", + pushCommits.AvatarLink("user2@example.com")) + + assert.Equal(t, + "https://secure.gravatar.com/avatar/19ade630b94e1e0535b3df7387434154?d=identicon", + pushCommits.AvatarLink("nonexistent@example.com")) +} + +func TestCommitToPushCommit(t *testing.T) { + now := time.Now() + sig := &git.Signature{ + Email: "example@example.com", + Name: "John Doe", + When: now, + } + const hexString = "0123456789abcdef0123456789abcdef01234567" + sha1, err := git.NewIDFromString(hexString) + assert.NoError(t, err) + pushCommit := CommitToPushCommit(&git.Commit{ + ID: sha1, + Author: sig, + Committer: sig, + CommitMessage: "Commit Message", + }) + assert.Equal(t, hexString, pushCommit.Sha1) + assert.Equal(t, "Commit Message", pushCommit.Message) + assert.Equal(t, "example@example.com", pushCommit.AuthorEmail) + assert.Equal(t, "John Doe", pushCommit.AuthorName) + assert.Equal(t, "example@example.com", pushCommit.CommitterEmail) + assert.Equal(t, "John Doe", pushCommit.CommitterName) + assert.Equal(t, now, pushCommit.Timestamp) +} + +func TestListToPushCommits(t *testing.T) { + now := time.Now() + sig := &git.Signature{ + Email: "example@example.com", + Name: "John Doe", + When: now, + } + + const hexString1 = "0123456789abcdef0123456789abcdef01234567" + hash1, err := git.NewIDFromString(hexString1) + assert.NoError(t, err) + const hexString2 = "fedcba9876543210fedcba9876543210fedcba98" + hash2, err := git.NewIDFromString(hexString2) + assert.NoError(t, err) + + l := list.New() + l.PushBack(&git.Commit{ + ID: hash1, + Author: sig, + Committer: sig, + CommitMessage: "Message1", + }) + l.PushBack(&git.Commit{ + ID: hash2, + Author: sig, + Committer: sig, + CommitMessage: "Message2", + }) + + pushCommits := ListToPushCommits(l) + assert.Equal(t, 2, pushCommits.Len) + if assert.Len(t, pushCommits.Commits, 2) { + assert.Equal(t, "Message1", pushCommits.Commits[0].Message) + assert.Equal(t, hexString1, pushCommits.Commits[0].Sha1) + assert.Equal(t, "example@example.com", pushCommits.Commits[0].AuthorEmail) + assert.Equal(t, now, pushCommits.Commits[0].Timestamp) + + assert.Equal(t, "Message2", pushCommits.Commits[1].Message) + assert.Equal(t, hexString2, pushCommits.Commits[1].Sha1) + assert.Equal(t, "example@example.com", pushCommits.Commits[1].AuthorEmail) + assert.Equal(t, now, pushCommits.Commits[1].Timestamp) + } +} + +// TODO TestPushUpdate diff --git a/modules/repository/main_test.go b/modules/repository/main_test.go new file mode 100644 index 0000000000..f13f358635 --- /dev/null +++ b/modules/repository/main_test.go @@ -0,0 +1,16 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package repository + +import ( + "path/filepath" + "testing" + + "code.gitea.io/gitea/models" +) + +func TestMain(m *testing.M) { + models.MainTest(m, filepath.Join("..", "..")) +} diff --git a/modules/repository/repo.go b/modules/repository/repo.go index 9351ab397e..b0b118e038 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -214,10 +214,61 @@ func SyncReleasesWithTags(repo *models.Repository, gitRepo *git.Repository) erro } for _, tagName := range tags { if _, ok := existingRelTags[strings.ToLower(tagName)]; !ok { - if err := models.PushUpdateAddTag(repo, gitRepo, tagName); err != nil { - return fmt.Errorf("pushUpdateAddTag: %s: %v", tagName, err) + if err := PushUpdateAddTag(repo, gitRepo, tagName); err != nil { + return fmt.Errorf("pushUpdateAddTag: %v", err) } } } return nil } + +// PushUpdateAddTag must be called for any push actions to add tag +func PushUpdateAddTag(repo *models.Repository, gitRepo *git.Repository, tagName string) error { + tag, err := gitRepo.GetTag(tagName) + if err != nil { + return fmt.Errorf("GetTag: %v", err) + } + commit, err := tag.Commit() + if err != nil { + return fmt.Errorf("Commit: %v", err) + } + + sig := tag.Tagger + if sig == nil { + sig = commit.Author + } + if sig == nil { + sig = commit.Committer + } + + var author *models.User + var createdAt = time.Unix(1, 0) + + if sig != nil { + author, err = models.GetUserByEmail(sig.Email) + if err != nil && !models.IsErrUserNotExist(err) { + return fmt.Errorf("GetUserByEmail: %v", err) + } + createdAt = sig.When + } + + commitsCount, err := commit.CommitsCount() + if err != nil { + return fmt.Errorf("CommitsCount: %v", err) + } + + var rel = models.Release{ + RepoID: repo.ID, + TagName: tagName, + LowerTagName: strings.ToLower(tagName), + Sha1: commit.ID.String(), + NumCommits: commitsCount, + CreatedUnix: timeutil.TimeStamp(createdAt.Unix()), + IsTag: true, + } + if author != nil { + rel.PublisherID = author.ID + } + + return models.SaveOrUpdateTag(repo, &rel) +} diff --git a/modules/structs/notifications.go b/modules/structs/notifications.go new file mode 100644 index 0000000000..b1e8b7781c --- /dev/null +++ b/modules/structs/notifications.go @@ -0,0 +1,28 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package structs + +import ( + "time" +) + +// NotificationThread expose Notification on API +type NotificationThread struct { + ID int64 `json:"id"` + Repository *Repository `json:"repository"` + Subject *NotificationSubject `json:"subject"` + Unread bool `json:"unread"` + Pinned bool `json:"pinned"` + UpdatedAt time.Time `json:"updated_at"` + URL string `json:"url"` +} + +// NotificationSubject contains the notification subject (Issue/Pull/Commit) +type NotificationSubject struct { + Title string `json:"title"` + URL string `json:"url"` + LatestCommentURL string `json:"latest_comment_url"` + Type string `json:"type" binding:"In(Issue,Pull,Commit)"` +} diff --git a/modules/structs/org_team.go b/modules/structs/org_team.go index 16f83823d6..a742b7b224 100644 --- a/modules/structs/org_team.go +++ b/modules/structs/org_team.go @@ -35,12 +35,12 @@ type CreateTeamOption struct { // EditTeamOption options for editing a team type EditTeamOption struct { // required: true - Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"` - Description string `json:"description" binding:"MaxSize(255)"` - IncludesAllRepositories bool `json:"includes_all_repositories"` + Name string `json:"name" binding:"AlphaDashDot;MaxSize(30)"` + Description *string `json:"description" binding:"MaxSize(255)"` + IncludesAllRepositories *bool `json:"includes_all_repositories"` // enum: read,write,admin Permission string `json:"permission"` // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.ext_wiki"] Units []string `json:"units"` - CanCreateOrgRepo bool `json:"can_create_org_repo"` + CanCreateOrgRepo *bool `json:"can_create_org_repo"` } diff --git a/modules/templates/helper.go b/modules/templates/helper.go index c3c92f856b..a9fc652ca9 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -27,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -579,8 +580,8 @@ func ActionIcon(opType models.ActionType) string { } // ActionContent2Commits converts action content to push commits -func ActionContent2Commits(act Actioner) *models.PushCommits { - push := models.NewPushCommits() +func ActionContent2Commits(act Actioner) *repository.PushCommits { + push := repository.NewPushCommits() if err := json.Unmarshal([]byte(act.GetContent()), push); err != nil { log.Error("json.Unmarshal:\n%s\nERROR: %v", act.GetContent(), err) } diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 2b1fcae835..5661323132 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -2025,6 +2025,20 @@ monitor.execute_time=Ausführungszeit monitor.process.cancel=Prozess abbrechen monitor.process.cancel_desc=Abbrechen eines Prozesses kann Datenverlust verursachen monitor.process.cancel_notices=Abbrechen: %s? +monitor.queues=Warteschlangen +monitor.queue=Warteschlange: %s +monitor.queue.name=Name +monitor.queue.type=Typ +monitor.queue.numberworkers=Anzahl der Worker +monitor.queue.maxnumberworkers=Maximale Anzahl der Worker +monitor.queue.review=Konfiguration überprüfen +monitor.queue.review_add=Worker hinzufügen/prüfen +monitor.queue.configuration=Erstkonfiguration +monitor.queue.nopool.title=Kein Worker-Pool +monitor.queue.nopool.desc=Diese Warteschlange umgibt andere Warteschlangen und hat selbst keinen Worker-Pool. +monitor.queue.pool.timeout=Timeout +monitor.queue.pool.addworkers.title=Worker hinzufügen +monitor.queue.pool.addworkers.submit=Worker hinzufügen diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 3367b45879..78ed5a9598 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -1412,6 +1412,8 @@ settings.protect_approvals_whitelist_enabled=Restringir aprovações a usuários settings.protect_approvals_whitelist_enabled_desc=Somente as avaliações de usuários ou equipes da lista permitida serão contadas com as aprovações necessárias. Sem aprovação da lista permitida, as revisões de qualquer pessoa com acesso de escrita contam para as aprovações necessárias. settings.protect_approvals_whitelist_users=Usuários com permissão de revisão: settings.protect_approvals_whitelist_teams=Equipes com permissão de revisão: +settings.dismiss_stale_approvals=Descartar aprovações obsoletas +settings.dismiss_stale_approvals_desc=Quando novos commits que mudam o conteúdo do pull request são enviados para o branch, as antigas aprovações serão descartadas. settings.add_protected_branch=Habilitar proteção settings.delete_protected_branch=Desabilitar proteção settings.update_protect_branch_success=Proteção do branch '%s' foi atualizada. diff --git a/package-lock.json b/package-lock.json index 9f182fb6dd..e0409b64d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,15 +12,15 @@ } }, "@babel/core": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.4.tgz", - "integrity": "sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.7.tgz", + "integrity": "sha512-jlSjuj/7z138NLZALxVgrx13AOtqip42ATZP7+kYl53GvDV6+4dCek1mVUo8z8c8Xnw/mx2q3d9HWh3griuesQ==", "dev": true, "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", + "@babel/generator": "^7.7.7", "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.4", + "@babel/parser": "^7.7.7", "@babel/template": "^7.7.4", "@babel/traverse": "^7.7.4", "@babel/types": "^7.7.4", @@ -34,9 +34,9 @@ } }, "@babel/generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", - "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz", + "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==", "dev": true, "requires": { "@babel/types": "^7.7.4", @@ -154,9 +154,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.4.tgz", - "integrity": "sha512-ehGBu4mXrhs0FxAqN8tWkzF8GSIGAiEumu4ONZ/hD9M88uHcD+Yu2ttKfOCgwzoesJOJrtQh7trI5YPbRtMmnA==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz", + "integrity": "sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.7.4", @@ -270,9 +270,9 @@ } }, "@babel/parser": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.4.tgz", - "integrity": "sha512-jIwvLO0zCL+O/LmEJQjWA75MQTWwx3c3u2JOTDK5D3/9egrWRRA0/0hk9XXywYnXZVVpzrBYeIQTmhwUaePI9g==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz", + "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -307,9 +307,9 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.4.tgz", - "integrity": "sha512-rnpnZR3/iWKmiQyJ3LKJpSwLDcX/nSXhdLk4Aq/tXOApIvyu7qoabrige0ylsAJffaUC51WiBu209Q0U+86OWQ==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.7.7.tgz", + "integrity": "sha512-3qp9I8lelgzNedI3hrhkvhaEYree6+WHnyA/q4Dza9z7iEIs1eyhWyJnetk3jJ69RT0AT4G0UhEGwyGFJ7GUuQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -327,9 +327,9 @@ } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.4.tgz", - "integrity": "sha512-cHgqHgYvffluZk85dJ02vloErm3Y6xtH+2noOBOJ2kXOJH3aVCDnj5eR/lVNlTnYu4hndAPJD3rTFjW3qee0PA==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.7.tgz", + "integrity": "sha512-80PbkKyORBUVm1fbTLrHpYdJxMThzM1UqFGh0ALEhO9TYbG86Ah9zQYAB/84axz2vcxefDLdZwWwZNlYARlu9w==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.7.4", @@ -464,9 +464,9 @@ } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.4.tgz", - "integrity": "sha512-mk0cH1zyMa/XHeb6LOTXTbG7uIJ8Rrjlzu91pUx/KS3JpcgaTDwMS8kM+ar8SLOvlL2Lofi4CGBAjCo3a2x+lw==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.7.7.tgz", + "integrity": "sha512-b4in+YlTeE/QmTgrllnb3bHA0HntYvjz8O3Mcbx75UBPJA2xhb5A8nle498VhxSXJHQefjtQxpnLPehDJ4TRlg==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.7.4", @@ -530,23 +530,23 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.4.tgz", - "integrity": "sha512-/542/5LNA18YDtg1F+QHvvUSlxdvjZoD/aldQwkq+E3WCkbEjNSN9zdrOXaSlfg3IfGi22ijzecklF/A7kVZFQ==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.5.tgz", + "integrity": "sha512-CT57FG4A2ZUNU1v+HdvDSDrjNWBrtCmSH6YbbgN3Lrf0Di/q/lWRxZrE72p3+HCCz9UjfZOEBdphgC0nzOS6DQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.7.4", + "@babel/helper-module-transforms": "^7.7.5", "@babel/helper-plugin-utils": "^7.0.0", "babel-plugin-dynamic-import-node": "^2.3.0" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz", - "integrity": "sha512-k8iVS7Jhc367IcNF53KCwIXtKAH7czev866ThsTgy8CwlXjnKZna2VHwChglzLleYrcHz1eQEIJlGRQxB53nqA==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz", + "integrity": "sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.7.4", + "@babel/helper-module-transforms": "^7.7.5", "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-simple-access": "^7.7.4", "babel-plugin-dynamic-import-node": "^2.3.0" @@ -602,9 +602,9 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.4.tgz", - "integrity": "sha512-VJwhVePWPa0DqE9vcfptaJSzNDKrWU/4FbYCjZERtmqEs05g3UMXnYMZoXja7JAJ7Y7sPZipwm/pGApZt7wHlw==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.7.7.tgz", + "integrity": "sha512-OhGSrf9ZBrr1fw84oFXj5hgi8Nmg+E2w5L7NhnG0lPvpDtqd7dbyilM2/vR8CKbJ907RyxPh2kj6sBCSSfI9Ew==", "dev": true, "requires": { "@babel/helper-call-delegate": "^7.7.4", @@ -622,9 +622,9 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.4.tgz", - "integrity": "sha512-e7MWl5UJvmPEwFJTwkBlPmqixCtr9yAASBqff4ggXTNicZiwbF8Eefzm6NVgfiBp7JdAGItecnctKTgH44q2Jw==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz", + "integrity": "sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw==", "dev": true, "requires": { "regenerator-transform": "^0.14.0" @@ -640,9 +640,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.4.tgz", - "integrity": "sha512-O8kSkS5fP74Ad/8pfsCMGa8sBRdLxYoSReaARRNSz3FbFQj3z/QUvoUmJ28gn9BO93YfnXc3j+Xyaqe8cKDNBQ==", + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.6.tgz", + "integrity": "sha512-tajQY+YmXR7JjTwRvwL4HePqoL3DYxpYXIHKVvrOIvJmeHe2y1w4tz5qz9ObUDC9m76rCzIMPyn4eERuwA4a4A==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.7.4", @@ -709,9 +709,9 @@ } }, "@babel/preset-env": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.7.4.tgz", - "integrity": "sha512-Dg+ciGJjwvC1NIe/DGblMbcGq1HOtKbw8RLl4nIjlfcILKEOkWT/vRqPpumswABEBVudii6dnVwrBtzD7ibm4g==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.7.7.tgz", + "integrity": "sha512-pCu0hrSSDVI7kCVUOdcMNQEbOPJ52E+LrQ14sN8uL2ALfSqePZQlKrOy+tM4uhEdYlCHi4imr8Zz2cZe9oSdIg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.7.4", @@ -719,9 +719,9 @@ "@babel/plugin-proposal-async-generator-functions": "^7.7.4", "@babel/plugin-proposal-dynamic-import": "^7.7.4", "@babel/plugin-proposal-json-strings": "^7.7.4", - "@babel/plugin-proposal-object-rest-spread": "^7.7.4", + "@babel/plugin-proposal-object-rest-spread": "^7.7.7", "@babel/plugin-proposal-optional-catch-binding": "^7.7.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.7.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.7.7", "@babel/plugin-syntax-async-generators": "^7.7.4", "@babel/plugin-syntax-dynamic-import": "^7.7.4", "@babel/plugin-syntax-json-strings": "^7.7.4", @@ -735,23 +735,23 @@ "@babel/plugin-transform-classes": "^7.7.4", "@babel/plugin-transform-computed-properties": "^7.7.4", "@babel/plugin-transform-destructuring": "^7.7.4", - "@babel/plugin-transform-dotall-regex": "^7.7.4", + "@babel/plugin-transform-dotall-regex": "^7.7.7", "@babel/plugin-transform-duplicate-keys": "^7.7.4", "@babel/plugin-transform-exponentiation-operator": "^7.7.4", "@babel/plugin-transform-for-of": "^7.7.4", "@babel/plugin-transform-function-name": "^7.7.4", "@babel/plugin-transform-literals": "^7.7.4", "@babel/plugin-transform-member-expression-literals": "^7.7.4", - "@babel/plugin-transform-modules-amd": "^7.7.4", - "@babel/plugin-transform-modules-commonjs": "^7.7.4", + "@babel/plugin-transform-modules-amd": "^7.7.5", + "@babel/plugin-transform-modules-commonjs": "^7.7.5", "@babel/plugin-transform-modules-systemjs": "^7.7.4", "@babel/plugin-transform-modules-umd": "^7.7.4", "@babel/plugin-transform-named-capturing-groups-regex": "^7.7.4", "@babel/plugin-transform-new-target": "^7.7.4", "@babel/plugin-transform-object-super": "^7.7.4", - "@babel/plugin-transform-parameters": "^7.7.4", + "@babel/plugin-transform-parameters": "^7.7.7", "@babel/plugin-transform-property-literals": "^7.7.4", - "@babel/plugin-transform-regenerator": "^7.7.4", + "@babel/plugin-transform-regenerator": "^7.7.5", "@babel/plugin-transform-reserved-words": "^7.7.4", "@babel/plugin-transform-shorthand-properties": "^7.7.4", "@babel/plugin-transform-spread": "^7.7.4", @@ -761,16 +761,16 @@ "@babel/plugin-transform-unicode-regex": "^7.7.4", "@babel/types": "^7.7.4", "browserslist": "^4.6.0", - "core-js-compat": "^3.1.1", + "core-js-compat": "^3.6.0", "invariant": "^2.2.2", "js-levenshtein": "^1.1.3", "semver": "^5.5.0" } }, "@babel/runtime": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.4.tgz", - "integrity": "sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==", + "version": "7.7.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.7.tgz", + "integrity": "sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA==", "dev": true, "requires": { "regenerator-runtime": "^0.13.2" @@ -825,12 +825,32 @@ "glob-to-regexp": "^0.3.0" } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", "dev": true }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -861,9 +881,9 @@ "dev": true }, "@types/node": { - "version": "12.12.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", - "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==", + "version": "13.1.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.6.tgz", + "integrity": "sha512-Jg1F+bmxcpENHP23sVKkNuU3uaxPnsBMW0cLjleiikFKomJQbsn0Cqk2yDvQArqzZN6ABfBkZ0To7pQ8sLdWDg==", "dev": true }, "@types/parse-json": { @@ -1195,24 +1215,13 @@ } }, "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "aproba": { @@ -1255,23 +1264,21 @@ "dev": true }, "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" } }, "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true }, "array-uniq": { "version": "1.0.3", @@ -1285,6 +1292,16 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -1524,11 +1541,21 @@ "dev": true }, "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -1558,32 +1585,12 @@ } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "fill-range": "^7.0.1" } }, "brorand": { @@ -1664,14 +1671,14 @@ } }, "browserslist": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.2.tgz", - "integrity": "sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.3.tgz", + "integrity": "sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001015", + "caniuse-lite": "^1.0.30001017", "electron-to-chromium": "^1.3.322", - "node-releases": "^1.1.42" + "node-releases": "^1.1.44" } }, "buffer": { @@ -1825,9 +1832,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001015", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz", - "integrity": "sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ==", + "version": "1.0.30001020", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001020.tgz", + "integrity": "sha512-yWIvwA68wRHKanAVS1GjN8vajAv7MBFshullKCeq/eKpK7pJBVDgFFEqvgWTkcP2+wIDeQGYFRXECjKZnLkUjA==", "dev": true }, "caseless": { @@ -1885,46 +1892,19 @@ "dev": true }, "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.3.0" } }, "chownr": { @@ -1997,45 +1977,23 @@ "dev": true }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.0" } } } @@ -2066,12 +2024,6 @@ "q": "^1.1.2" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "collapse-white-space": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz", @@ -2167,6 +2119,32 @@ "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "confusing-browser-globals": { @@ -2223,25 +2201,25 @@ "dev": true }, "core-js": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.4.7.tgz", - "integrity": "sha512-qaPVGw30J1wQ0GR3GvoPqlGf9GZfKKF4kFC7kiHlcsPTqH3txrs9crCp3ZiMAXuSenhz89Jnl4GZs/67S5VOSg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.2.tgz", + "integrity": "sha512-hIE5dXkRzRvnZ5vhkRfQxUvDxQZmD9oueA08jDYRBKJHx+VIl/Pne/e0A4x9LObEEthC/TqiZybUoNM4tRgnKg==", "dev": true }, "core-js-compat": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.4.7.tgz", - "integrity": "sha512-57+mgz/P/xsGdjwQYkwtBZR3LuISaxD1dEwVDtbk8xJMqAmwqaxLOvnNT7kdJ7jYE/NjNptyzXi+IQFMi/2fCw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.2.tgz", + "integrity": "sha512-+G28dzfYGtAM+XGvB1C5AS1ZPKfQ47HLhcdeIQdZgQnJVdp7/D0m+W/TErwhgsX6CujRUk/LebB6dCrKrtJrvQ==", "dev": true, "requires": { - "browserslist": "^4.8.0", - "semver": "^6.3.0" + "browserslist": "^4.8.3", + "semver": "7.0.0" }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", "dev": true } } @@ -2350,9 +2328,9 @@ } }, "css-loader": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.2.1.tgz", - "integrity": "sha512-q40kYdcBNzMvkIImCL2O+wk8dh+RGwPPV9Dfz3n7XtOYPXqe2Z6VgtvoxjkLHz02gmhepG9sOAJOUlx+3hHsBg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.1.tgz", + "integrity": "sha512-+ybmv7sVxxNEenQhkifQDvny/1iNQM7YooJbSfVUdQQvisyg1aKIqgGjCjoFSyVLJMp17z9rfZFQaR5HGHcMbw==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -2676,27 +2654,18 @@ } }, "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { - "path-type": "^3.0.0" + "path-type": "^4.0.0" }, "dependencies": { "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true } } @@ -2778,6 +2747,32 @@ "inherits": "^2.0.1", "readable-stream": "^2.0.0", "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "ecc-jsbn": { @@ -2792,9 +2787,9 @@ } }, "electron-to-chromium": { - "version": "1.3.322", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz", - "integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==", + "version": "1.3.329", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.329.tgz", + "integrity": "sha512-CoyYGbkQLwmOpaWRUZgeSNnEPH5fE5R8T7dhQIWV/rlIt+Kx6NFppQJ2oHELmzw8ZGabOBY5CrjGjyA+74QVoQ==", "dev": true }, "elliptic": { @@ -2863,6 +2858,30 @@ "errno": "^0.1.3", "readable-stream": "^2.0.1" } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } } } }, @@ -2897,21 +2916,22 @@ } }, "es-abstract": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.3.tgz", - "integrity": "sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz", + "integrity": "sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" } }, "es-to-primitive": { @@ -2947,9 +2967,9 @@ "dev": true }, "eslint": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz", - "integrity": "sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -3063,12 +3083,12 @@ } }, "eslint-module-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", - "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.0.tgz", + "integrity": "sha512-kCo8pZaNz2dsAW7nCUjuVoI11EBXXpIzfNxmaoLhXoRDOnqXLC4iSGVRdZPhOitfbdEfMEfKOiENaK6wDPZEGw==", "dev": true, "requires": { - "debug": "^2.6.8", + "debug": "^2.6.9", "pkg-dir": "^2.0.0" }, "dependencies": { @@ -3142,22 +3162,23 @@ } }, "eslint-plugin-import": { - "version": "2.18.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", - "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz", + "integrity": "sha512-x68131aKoCZlCae7rDXKSAQmbT5DQuManyXo2sK6fJJ0aK5CWAkv6A6HJZGgqC8IhjQxYPgo6/IY4Oz8AFsbBw==", "dev": true, "requires": { "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", "contains-path": "^0.1.0", "debug": "^2.6.9", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.0", + "eslint-module-utils": "^2.4.1", "has": "^1.0.3", "minimatch": "^3.0.4", "object.values": "^1.1.0", "read-pkg-up": "^2.0.0", - "resolve": "^1.11.0" + "resolve": "^1.12.0" }, "dependencies": { "debug": { @@ -3260,9 +3281,9 @@ "dev": true }, "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", "dev": true }, "evp_bytestokey": { @@ -3475,46 +3496,22 @@ "dev": true }, "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", + "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==", "dev": true, "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" } }, "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { @@ -3523,6 +3520,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", @@ -3547,27 +3553,20 @@ "flat-cache": "^2.0.1" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "to-regex-range": "^5.0.1" } }, "find-cache-dir": { @@ -3600,6 +3599,111 @@ "is-glob": "^4.0.0", "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, "flat-cache": { @@ -3627,6 +3731,32 @@ "requires": { "inherits": "^2.0.3", "readable-stream": "^2.3.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "for-in": { @@ -3671,15 +3801,41 @@ "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } @@ -3703,428 +3859,13 @@ "iferr": "^0.1.5", "imurmurhash": "^0.1.4", "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" }, "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, "readable-stream": { - "version": "2.3.6", - "bundled": true, + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, - "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4135,130 +3876,30 @@ "util-deprecate": "~1.0.1" } }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, "string_decoder": { "version": "1.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "optional": true, "requires": { "safe-buffer": "~5.1.0" } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true } } }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -4272,15 +3913,15 @@ "dev": true }, "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", "dev": true }, "get-stream": { @@ -4364,19 +4005,27 @@ "dev": true }, "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", "dev": true, "requires": { "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + } } }, "globjoin": { @@ -4468,6 +4117,26 @@ "kind-of": "^4.0.0" }, "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -4574,17 +4243,6 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "dev": true - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } } } }, @@ -4803,9 +4461,9 @@ "dev": true }, "inquirer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", - "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.3.tgz", + "integrity": "sha512-+OiOVeVydu4hnCGLCSX+wedovR/Yzskv9BFqUNNKq9uU2qg7LCcCo3R86S2E7WLo0y/x2pnEZfZe1CoYnORUAw==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", @@ -4817,7 +4475,7 @@ "lodash": "^4.17.15", "mute-stream": "0.0.8", "run-async": "^2.2.0", - "rxjs": "^6.4.0", + "rxjs": "^6.5.3", "string-width": "^4.1.0", "strip-ansi": "^5.1.0", "through": "^2.3.6" @@ -4905,12 +4563,12 @@ "dev": true }, "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "^2.0.0" } }, "is-buffer": { @@ -4920,9 +4578,9 @@ "dev": true }, "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", "dev": true }, "is-color-stop": { @@ -4960,9 +4618,9 @@ } }, "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true }, "is-decimal": { @@ -5030,24 +4688,10 @@ "dev": true }, "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-obj": { "version": "1.0.1", @@ -5077,12 +4721,12 @@ "dev": true }, "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", "dev": true, "requires": { - "has": "^1.0.1" + "has": "^1.0.3" } }, "is-regexp": { @@ -5103,6 +4747,12 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-svg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", @@ -5631,6 +5281,32 @@ "requires": { "errno": "^0.1.3", "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "meow": { @@ -5771,24 +5447,13 @@ "dev": true }, "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "miller-rabin": { @@ -5809,20 +5474,20 @@ "optional": true }, "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", "dev": true, "optional": true }, "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", "dev": true, "optional": true, "requires": { - "mime-db": "1.42.0" + "mime-db": "1.43.0" } }, "mimic-fn": { @@ -6098,13 +5763,39 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } } } }, "node-releases": { - "version": "1.1.42", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.42.tgz", - "integrity": "sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA==", + "version": "1.1.45", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.45.tgz", + "integrity": "sha512-cXvGSfhITKI8qsV116u2FTzH5EWZJfgG7d4cpqwF8I8+1tWpD6AsvvGRKq2onR0DNj1jfqsjkXZsm14JMS7Cyg==", "dev": true, "requires": { "semver": "^6.3.0" @@ -6178,12 +5869,6 @@ "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", "dev": true }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -6262,25 +5947,25 @@ } }, "object.entries": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", - "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", + "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", + "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" } }, "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" } }, "object.pick": { @@ -6293,13 +5978,13 @@ } }, "object.values": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", - "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.12.0", + "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" } @@ -6378,9 +6063,9 @@ "dev": true }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -6425,6 +6110,32 @@ "cyclist": "^1.0.1", "inherits": "^2.0.3", "readable-stream": "^2.1.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "parent-module": { @@ -6568,9 +6279,9 @@ "optional": true }, "picomatch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", - "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", "dev": true }, "pify": { @@ -6595,9 +6306,9 @@ "dev": true }, "postcss": { - "version": "7.0.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.23.tgz", - "integrity": "sha512-hOlMf3ouRIFXD+j2VJecwssTwbvsPGJVMzupptg+85WA+i7MwyrydmQAgY3R+m0Bc0exunhbJmijy8u8+vufuQ==", + "version": "7.0.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz", + "integrity": "sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -6660,23 +6371,75 @@ } }, "postcss-cli": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-6.1.3.tgz", - "integrity": "sha512-eieqJU+OR1OFc/lQqMsDmROTJpoMZFvoAQ+82utBQ8/8qGMTfH9bBSPsTdsagYA8uvNzxHw2I2cNSSJkLAGhvw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-7.1.0.tgz", + "integrity": "sha512-tCGK0GO2reu644dUHxks8U2SAtKnzftQTAXN1dwzFPoKXZr0b7VX4vTkQ2Pl2Lunas6+o8uHR56hlcYBm1srZg==", "dev": true, "requires": { - "chalk": "^2.1.0", - "chokidar": "^2.0.0", + "chalk": "^3.0.0", + "chokidar": "^3.3.0", "dependency-graph": "^0.8.0", - "fs-extra": "^7.0.0", - "get-stdin": "^6.0.0", - "globby": "^9.0.0", + "fs-extra": "^8.1.0", + "get-stdin": "^7.0.0", + "globby": "^10.0.1", "postcss": "^7.0.0", "postcss-load-config": "^2.0.0", "postcss-reporter": "^6.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", - "yargs": "^12.0.1" + "yargs": "^15.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "postcss-colormin": { @@ -7363,9 +7126,9 @@ "dev": true }, "psl": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", - "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", "dev": true, "optional": true }, @@ -7576,29 +7339,23 @@ } }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "picomatch": "^2.0.7" } }, "redent": { @@ -7688,9 +7445,9 @@ "dev": true }, "regjsparser": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", - "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.2.tgz", + "integrity": "sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -7820,15 +7577,15 @@ "dev": true }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.2.tgz", + "integrity": "sha512-EjlOBLBO1kxsUxsKjLt7TAECyKW6fOh1VRkykQkKGzcBbjjPIxBqGh0jf7GJ3k/f5mxMqW3htMD3WdTUVtW8HQ==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -7913,6 +7670,12 @@ "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rgb-regex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", @@ -7953,6 +7716,12 @@ "is-promise": "^2.1.0" } }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", @@ -7963,9 +7732,9 @@ } }, "rxjs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", - "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -8015,9 +7784,9 @@ "dev": true }, "serialize-javascript": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.1.tgz", - "integrity": "sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", "dev": true }, "set-blocking": { @@ -8104,9 +7873,9 @@ } }, "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "slice-ansi": { @@ -8300,12 +8069,12 @@ "dev": true }, "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "dev": true, "requires": { - "atob": "^2.1.1", + "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", @@ -8458,6 +8227,32 @@ "requires": { "inherits": "~2.0.1", "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "stream-each": { @@ -8481,12 +8276,38 @@ "readable-stream": "^2.3.6", "to-arraybuffer": "^1.0.0", "xtend": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", "dev": true }, "string-width": { @@ -8512,9 +8333,9 @@ } }, "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", "dev": true, "requires": { "define-properties": "^1.1.3", @@ -8522,9 +8343,9 @@ } }, "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", "dev": true, "requires": { "define-properties": "^1.1.3", @@ -8532,12 +8353,20 @@ } }, "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } } }, "stringify-entities": { @@ -8594,9 +8423,9 @@ "dev": true }, "style-loader": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.0.1.tgz", - "integrity": "sha512-CnpEkSR1C+REjudiTWCv4+ssP7SCiuaQZJTZDWBRwTJoS90mdqkB8uOGMHKgVeUzpaU7IfLWoyQbvvs5Joj3Xw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.1.2.tgz", + "integrity": "sha512-0Mpq1ZHFDCNq1F+6avNBgv+7q8V+mWRuzehxyJT+aKgzyN/yfKTwjYqaYwBgx+11UpQxL21zNQfzzlz+JcGURw==", "dev": true, "requires": { "loader-utils": "^1.2.3", @@ -8634,9 +8463,9 @@ } }, "stylelint": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-12.0.0.tgz", - "integrity": "sha512-TwqtATrFOT07SPlUGyHN7tVhWqxwitn5BlAvyBQy/ekA+Nwu4mLU9L1dvGQPNxHUBLowjvkSW18QzHHR6/FVVQ==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-12.0.1.tgz", + "integrity": "sha512-1mn39pqZiC/e8KUPoRMc1WMM83Upb2ILaSGxkCvKxALHutEOs2txcPQocJiXdO4Zx4FY4prGqjlkwrbthAxqig==", "dev": true, "requires": { "autoprefixer": "^9.7.1", @@ -8689,23 +8518,58 @@ "write-file-atomic": "^3.0.1" }, "dependencies": { + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, "ansi-styles": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.0.tgz", - "integrity": "sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "dev": true, "requires": { - "fill-range": "^7.0.1" + "array-uniq": "^1.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } } }, "chalk": { @@ -8746,20 +8610,142 @@ "yaml": "^1.7.2" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", "dev": true, "requires": { - "to-regex-range": "^5.0.1" + "path-type": "^3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } } }, - "get-stdin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", - "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", - "dev": true + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "dependencies": { + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } }, "has-flag": { "version": "4.0.0", @@ -8792,10 +8778,24 @@ } }, "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } }, "log-symbols": { "version": "3.0.0", @@ -8858,16 +8858,6 @@ } } }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, "parse-json": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", @@ -8903,12 +8893,6 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", @@ -8928,12 +8912,13 @@ } }, "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "^7.0.0" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } } } @@ -9042,9 +9027,9 @@ "dev": true }, "terser": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz", - "integrity": "sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.2.tgz", + "integrity": "sha512-6FUjJdY2i3WZAtYBtnV06OOcOfzl+4hSKYE9wgac8rkLRBToPDDrBB2AcHwQD/OKDxbnvhVy2YgOPWO2SsKWqg==", "dev": true, "requires": { "commander": "^2.20.0", @@ -9061,25 +9046,25 @@ } }, "terser-webpack-plugin": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.2.1.tgz", - "integrity": "sha512-jwdauV5Al7zopR6OAYvIIRcxXCSvLjZjr7uZE8l2tIWb/ryrGN48sJftqGf5k9z09tWhajx53ldp0XPI080YnA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.2.tgz", + "integrity": "sha512-SmvB/6gtEPv+CJ88MH5zDOsZdKXPS/Uzv2//e90+wM1IHFUhsguPKEILgzqrM1nQ4acRXN/SV4Obr55SXC+0oA==", "dev": true, "requires": { "cacache": "^13.0.1", - "find-cache-dir": "^3.0.0", + "find-cache-dir": "^3.2.0", "jest-worker": "^24.9.0", - "schema-utils": "^2.5.0", - "serialize-javascript": "^2.1.0", + "schema-utils": "^2.6.1", + "serialize-javascript": "^2.1.2", "source-map": "^0.6.1", - "terser": "^4.3.9", + "terser": "^4.4.3", "webpack-sources": "^1.4.3" }, "dependencies": { "find-cache-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.1.0.tgz", - "integrity": "sha512-zw+EFiNBNPgI2NTrKkDd1xd7q0cs6wr/iWnr/oUkI0yF9K9GqQ+riIt4aiyFaaqpaWbxPrJXHI+QvmNUQbX+0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.2.0.tgz", + "integrity": "sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg==", "dev": true, "requires": { "commondir": "^1.0.1", @@ -9173,6 +9158,32 @@ "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "timers-browserify": { @@ -9244,13 +9255,12 @@ } }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" } }, "tough-cookie": { @@ -9562,9 +9572,9 @@ "dev": true }, "updates": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/updates/-/updates-9.3.0.tgz", - "integrity": "sha512-+CXkc/3xEeCgn4v87GXMS/1EJwIRGX/ucjzWx1Fn8vEn3x7FpuTb3z0qF8JElJGmiCU+Gb/kw0NNkAir9jCI/g==", + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/updates/-/updates-9.3.3.tgz", + "integrity": "sha512-BDhVPXLyr5LTxRgXmgCfv04TI+JWbGBQpvOAq3uDqGMPubBcahtNFhmpQ676OturvwjKZHluOMZPyZYi2WUvnA==", "dev": true, "requires": { "chalk": "3.0.0", @@ -9574,15 +9584,15 @@ "minimist": "1.2.0", "rc": "1.2.8", "registry-auth-token": "4.0.0", - "semver": "6.3.0", + "semver": "7.0.0", "string-width": "4.2.0", "text-table": "0.2.0" }, "dependencies": { "ansi-styles": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.0.tgz", - "integrity": "sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { "@types/color-name": "^1.1.1", @@ -9664,9 +9674,9 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", "dev": true }, "supports-color": { @@ -9859,12 +9869,787 @@ "chokidar": "^2.0.2", "graceful-fs": "^4.1.2", "neo-async": "^2.5.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fsevents": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", + "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, "webpack": { - "version": "4.41.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", - "integrity": "sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A==", + "version": "4.41.5", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.5.tgz", + "integrity": "sha512-wp0Co4vpyumnp3KlkmpM5LWuzvZYayDwM2n17EHFr4qxBBbRokC7DJawPJC7TfSFZ9HZ6GsdH40EBj4UV0nmpw==", "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", @@ -9887,7 +10672,7 @@ "node-libs-browser": "^2.2.1", "schema-utils": "^1.0.0", "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.1", + "terser-webpack-plugin": "^1.4.3", "watchpack": "^1.6.0", "webpack-sources": "^1.4.1" }, @@ -9898,6 +10683,35 @@ "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", "dev": true }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, "cacache": { "version": "12.0.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", @@ -9931,6 +10745,70 @@ "estraverse": "^4.1.1" } }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", @@ -9942,12 +10820,6 @@ "ajv-keywords": "^3.1.0" } }, - "serialize-javascript": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", - "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -9964,21 +10836,31 @@ } }, "terser-webpack-plugin": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", - "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", "dev": true, "requires": { "cacache": "^12.0.2", "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", + "serialize-javascript": "^2.1.2", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", "worker-farm": "^1.7.0" } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, @@ -10029,24 +10911,12 @@ "tapable": "^1.0.0" } }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -10164,48 +11034,48 @@ } }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.0" } } } @@ -10271,62 +11141,64 @@ } }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", + "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", "dev": true, "requires": { - "cliui": "^4.0.0", + "cliui": "^6.0.0", "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^4.2.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^16.1.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "strip-ansi": { + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true } } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", + "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index dc95584905..5d0d20060e 100644 --- a/package.json +++ b/package.json @@ -5,26 +5,26 @@ "node": ">=10" }, "devDependencies": { - "@babel/core": "7.7.4", - "@babel/plugin-transform-runtime": "7.7.4", - "@babel/preset-env": "7.7.4", - "@babel/runtime": "7.7.4", + "@babel/core": "7.7.7", + "@babel/plugin-transform-runtime": "7.7.6", + "@babel/preset-env": "7.7.7", + "@babel/runtime": "7.7.7", "autoprefixer": "9.7.3", "babel-loader": "8.0.6", - "core-js": "3.4.7", - "css-loader": "3.2.1", + "core-js": "3.6.2", + "css-loader": "3.4.1", "cssnano": "4.1.10", - "eslint": "6.7.2", + "eslint": "6.8.0", "eslint-config-airbnb-base": "14.0.0", - "eslint-plugin-import": "2.18.2", + "eslint-plugin-import": "2.19.1", "less": "3.10.3", - "postcss-cli": "6.1.3", - "style-loader": "1.0.1", - "stylelint": "12.0.0", + "postcss-cli": "7.1.0", + "style-loader": "1.1.2", + "stylelint": "12.0.1", "stylelint-config-standard": "19.0.0", - "terser-webpack-plugin": "2.2.1", - "updates": "9.3.0", - "webpack": "4.41.2", + "terser-webpack-plugin": "2.3.2", + "updates": "9.3.3", + "webpack": "4.41.5", "webpack-cli": "3.3.10" }, "browserslist": [ diff --git a/public/vendor/plugins/fomantic/semantic.css b/public/vendor/plugins/fomantic/semantic.css index bb4ffb4b81..2059e58ca1 100644 --- a/public/vendor/plugins/fomantic/semantic.css +++ b/public/vendor/plugins/fomantic/semantic.css @@ -8,7 +8,6 @@ * http://opensource.org/licenses/MIT * */ -@import url('https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic&subset=latin&display=swap'); /*! * # Fomantic-UI - Reset * http://github.com/fomantic/Fomantic-UI/ diff --git a/public/vendor/plugins/fomantic/semantic.min.css b/public/vendor/plugins/fomantic/semantic.min.css index 9f2dab4a36..4d71b4b903 100644 --- a/public/vendor/plugins/fomantic/semantic.min.css +++ b/public/vendor/plugins/fomantic/semantic.min.css @@ -7,8 +7,7 @@ * Released under the MIT license * http://opensource.org/licenses/MIT * - */ -@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic&subset=latin&display=swap);/*! + *//*! * # Fomantic-UI - Reset * http://github.com/fomantic/Fomantic-UI/ * diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 7387037d33..ebc651516a 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -56,10 +56,10 @@ func CreateUser(ctx *context.APIContext, form api.CreateUserOption) { // responses: // "201": // "$ref": "#/responses/User" - // "403": - // "$ref": "#/responses/forbidden" // "400": // "$ref": "#/responses/error" + // "403": + // "$ref": "#/responses/forbidden" // "422": // "$ref": "#/responses/validationError" diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 9f18951893..fd7f7c05cf 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -70,6 +70,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/admin" "code.gitea.io/gitea/routers/api/v1/misc" + "code.gitea.io/gitea/routers/api/v1/notify" "code.gitea.io/gitea/routers/api/v1/org" "code.gitea.io/gitea/routers/api/v1/repo" _ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation @@ -512,6 +513,16 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown) m.Post("/markdown/raw", misc.MarkdownRaw) + // Notifications + m.Group("/notifications", func() { + m.Combo(""). + Get(notify.ListNotifications). + Put(notify.ReadNotifications) + m.Combo("/threads/:id"). + Get(notify.GetThread). + Patch(notify.ReadThread) + }, reqToken()) + // Users m.Group("/users", func() { m.Get("/search", user.Search) @@ -593,23 +604,24 @@ func RegisterRoutes(m *macaron.Macaron) { }, reqToken()) // Repositories - m.Post("/org/:org/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) - - m.Group("/repos", func() { - m.Get("/search", repo.Search) - }) - - m.Get("/repos/issues/search", repo.SearchIssues) + m.Post("/org/:org/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepoDeprecated) m.Combo("/repositories/:id", reqToken()).Get(repo.GetByID) m.Group("/repos", func() { + m.Get("/search", repo.Search) + + m.Get("/issues/search", repo.SearchIssues) + m.Post("/migrate", reqToken(), bind(auth.MigrateRepoForm{}), repo.Migrate) m.Group("/:username/:reponame", func() { m.Combo("").Get(reqAnyRepoReader(), repo.Get). Delete(reqToken(), reqOwner(), repo.Delete). Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), context.RepoRef(), repo.Edit) + m.Combo("/notifications"). + Get(reqToken(), notify.ListRepoNotifications). + Put(reqToken(), notify.ReadRepoNotifications) m.Group("/hooks", func() { m.Combo("").Get(repo.ListHooks). Post(bind(api.CreateHookOption{}), repo.CreateHook) @@ -810,10 +822,11 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/users/:username/orgs", org.ListUserOrgs) m.Post("/orgs", reqToken(), bind(api.CreateOrgOption{}), org.Create) m.Group("/orgs/:orgname", func() { - m.Get("/repos", user.ListOrgRepos) m.Combo("").Get(org.Get). Patch(reqToken(), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). Delete(reqToken(), reqOrgOwnership(), org.Delete) + m.Combo("/repos").Get(user.ListOrgRepos). + Post(reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) m.Group("/members", func() { m.Get("", org.ListMembers) m.Combo("/:username").Get(org.IsMember). diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go new file mode 100644 index 0000000000..b939d90f06 --- /dev/null +++ b/routers/api/v1/notify/repo.go @@ -0,0 +1,151 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package notify + +import ( + "net/http" + "strings" + "time" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/routers/api/v1/utils" +) + +// ListRepoNotifications list users's notification threads on a specific repo +func ListRepoNotifications(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/notifications notification notifyGetRepoList + // --- + // summary: List users's notification threads on a specific repo + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: all + // in: query + // description: If true, show notifications marked as read. Default value is false + // type: string + // required: false + // - name: since + // in: query + // description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format + // type: string + // format: date-time + // required: false + // - name: before + // in: query + // description: Only show notifications updated before the given time. This is a timestamp in RFC 3339 format + // type: string + // format: date-time + // required: false + // responses: + // "200": + // "$ref": "#/responses/NotificationThreadList" + + before, since, err := utils.GetQueryBeforeSince(ctx) + if err != nil { + ctx.InternalServerError(err) + return + } + opts := models.FindNotificationOptions{ + UserID: ctx.User.ID, + RepoID: ctx.Repo.Repository.ID, + UpdatedBeforeUnix: before, + UpdatedAfterUnix: since, + } + qAll := strings.Trim(ctx.Query("all"), " ") + if qAll != "true" { + opts.Status = models.NotificationStatusUnread + } + nl, err := models.GetNotifications(opts) + if err != nil { + ctx.InternalServerError(err) + return + } + err = nl.LoadAttributes() + if err != nil { + ctx.InternalServerError(err) + return + } + + ctx.JSON(http.StatusOK, nl.APIFormat()) +} + +// ReadRepoNotifications mark notification threads as read on a specific repo +func ReadRepoNotifications(ctx *context.APIContext) { + // swagger:operation PUT /repos/{owner}/{repo}/notifications notification notifyReadRepoList + // --- + // summary: Mark notification threads as read on a specific repo + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: last_read_at + // in: query + // description: Describes the last point that notifications were checked. Anything updated since this time will not be updated. + // type: string + // format: date-time + // required: false + // responses: + // "205": + // "$ref": "#/responses/empty" + + lastRead := int64(0) + qLastRead := strings.Trim(ctx.Query("last_read_at"), " ") + if len(qLastRead) > 0 { + tmpLastRead, err := time.Parse(time.RFC3339, qLastRead) + if err != nil { + ctx.InternalServerError(err) + return + } + if !tmpLastRead.IsZero() { + lastRead = tmpLastRead.Unix() + } + } + opts := models.FindNotificationOptions{ + UserID: ctx.User.ID, + RepoID: ctx.Repo.Repository.ID, + UpdatedBeforeUnix: lastRead, + Status: models.NotificationStatusUnread, + } + nl, err := models.GetNotifications(opts) + if err != nil { + ctx.InternalServerError(err) + return + } + + for _, n := range nl { + err := models.SetNotificationStatus(n.ID, ctx.User, models.NotificationStatusRead) + if err != nil { + ctx.InternalServerError(err) + return + } + ctx.Status(http.StatusResetContent) + } + + ctx.Status(http.StatusResetContent) +} diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go new file mode 100644 index 0000000000..d0119e9938 --- /dev/null +++ b/routers/api/v1/notify/threads.go @@ -0,0 +1,101 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package notify + +import ( + "fmt" + "net/http" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" +) + +// GetThread get notification by ID +func GetThread(ctx *context.APIContext) { + // swagger:operation GET /notifications/threads/{id} notification notifyGetThread + // --- + // summary: Get notification thread by ID + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: id + // in: path + // description: id of notification thread + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/NotificationThread" + // "403": + // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" + + n := getThread(ctx) + if n == nil { + return + } + if err := n.LoadAttributes(); err != nil { + ctx.InternalServerError(err) + return + } + + ctx.JSON(http.StatusOK, n.APIFormat()) +} + +// ReadThread mark notification as read by ID +func ReadThread(ctx *context.APIContext) { + // swagger:operation PATCH /notifications/threads/{id} notification notifyReadThread + // --- + // summary: Mark notification thread as read by ID + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: id + // in: path + // description: id of notification thread + // type: string + // required: true + // responses: + // "205": + // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" + + n := getThread(ctx) + if n == nil { + return + } + + err := models.SetNotificationStatus(n.ID, ctx.User, models.NotificationStatusRead) + if err != nil { + ctx.InternalServerError(err) + return + } + ctx.Status(http.StatusResetContent) +} + +func getThread(ctx *context.APIContext) *models.Notification { + n, err := models.GetNotificationByID(ctx.ParamsInt64(":id")) + if err != nil { + if models.IsErrNotExist(err) { + ctx.Error(http.StatusNotFound, "GetNotificationByID", err) + } else { + ctx.InternalServerError(err) + } + return nil + } + if n.UserID != ctx.User.ID && !ctx.User.IsAdmin { + ctx.Error(http.StatusForbidden, "GetNotificationByID", fmt.Errorf("only user itself and admin are allowed to read/change this thread %d", n.ID)) + return nil + } + return n +} diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go new file mode 100644 index 0000000000..d16e4da0e0 --- /dev/null +++ b/routers/api/v1/notify/user.go @@ -0,0 +1,129 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package notify + +import ( + "net/http" + "strings" + "time" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/routers/api/v1/utils" +) + +// ListNotifications list users's notification threads +func ListNotifications(ctx *context.APIContext) { + // swagger:operation GET /notifications notification notifyGetList + // --- + // summary: List users's notification threads + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: all + // in: query + // description: If true, show notifications marked as read. Default value is false + // type: string + // required: false + // - name: since + // in: query + // description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format + // type: string + // format: date-time + // required: false + // - name: before + // in: query + // description: Only show notifications updated before the given time. This is a timestamp in RFC 3339 format + // type: string + // format: date-time + // required: false + // responses: + // "200": + // "$ref": "#/responses/NotificationThreadList" + + before, since, err := utils.GetQueryBeforeSince(ctx) + if err != nil { + ctx.InternalServerError(err) + return + } + opts := models.FindNotificationOptions{ + UserID: ctx.User.ID, + UpdatedBeforeUnix: before, + UpdatedAfterUnix: since, + } + qAll := strings.Trim(ctx.Query("all"), " ") + if qAll != "true" { + opts.Status = models.NotificationStatusUnread + } + nl, err := models.GetNotifications(opts) + if err != nil { + ctx.InternalServerError(err) + return + } + err = nl.LoadAttributes() + if err != nil { + ctx.InternalServerError(err) + return + } + + ctx.JSON(http.StatusOK, nl.APIFormat()) +} + +// ReadNotifications mark notification threads as read +func ReadNotifications(ctx *context.APIContext) { + // swagger:operation PUT /notifications notification notifyReadList + // --- + // summary: Mark notification threads as read + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: last_read_at + // in: query + // description: Describes the last point that notifications were checked. Anything updated since this time will not be updated. + // type: string + // format: date-time + // required: false + // responses: + // "205": + // "$ref": "#/responses/empty" + + lastRead := int64(0) + qLastRead := strings.Trim(ctx.Query("last_read_at"), " ") + if len(qLastRead) > 0 { + tmpLastRead, err := time.Parse(time.RFC3339, qLastRead) + if err != nil { + ctx.InternalServerError(err) + return + } + if !tmpLastRead.IsZero() { + lastRead = tmpLastRead.Unix() + } + } + opts := models.FindNotificationOptions{ + UserID: ctx.User.ID, + UpdatedBeforeUnix: lastRead, + Status: models.NotificationStatusUnread, + } + nl, err := models.GetNotifications(opts) + if err != nil { + ctx.InternalServerError(err) + return + } + + for _, n := range nl { + err := models.SetNotificationStatus(n.ID, ctx.User, models.NotificationStatusRead) + if err != nil { + ctx.InternalServerError(err) + return + } + ctx.Status(http.StatusResetContent) + } + + ctx.Status(http.StatusResetContent) +} diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index 73714e6a66..446287a343 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -192,37 +192,52 @@ func EditTeam(ctx *context.APIContext, form api.EditTeamOption) { // "$ref": "#/responses/Team" team := ctx.Org.Team - team.Description = form.Description - unitTypes := models.FindUnitTypes(form.Units...) - team.CanCreateOrgRepo = form.CanCreateOrgRepo + if err := team.GetUnits(); err != nil { + ctx.InternalServerError(err) + return + } + + if form.CanCreateOrgRepo != nil { + team.CanCreateOrgRepo = *form.CanCreateOrgRepo + } + + if len(form.Name) > 0 { + team.Name = form.Name + } + + if form.Description != nil { + team.Description = *form.Description + } isAuthChanged := false isIncludeAllChanged := false - if !team.IsOwnerTeam() { + if !team.IsOwnerTeam() && len(form.Permission) != 0 { // Validate permission level. auth := models.ParseAccessMode(form.Permission) - team.Name = form.Name if team.Authorize != auth { isAuthChanged = true team.Authorize = auth } - if team.IncludesAllRepositories != form.IncludesAllRepositories { + if form.IncludesAllRepositories != nil { isIncludeAllChanged = true - team.IncludesAllRepositories = form.IncludesAllRepositories + team.IncludesAllRepositories = *form.IncludesAllRepositories } } if team.Authorize < models.AccessModeOwner { - var units = make([]*models.TeamUnit, 0, len(form.Units)) - for _, tp := range unitTypes { - units = append(units, &models.TeamUnit{ - OrgID: ctx.Org.Team.OrgID, - Type: tp, - }) + if len(form.Units) > 0 { + var units = make([]*models.TeamUnit, 0, len(form.Units)) + unitTypes := models.FindUnitTypes(form.Units...) + for _, tp := range unitTypes { + units = append(units, &models.TeamUnit{ + OrgID: ctx.Org.Team.OrgID, + Type: tp, + }) + } + team.Units = units } - team.Units = units } if err := models.UpdateTeam(team, isAuthChanged, isIncludeAllChanged); err != nil { diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index d0551320fd..8e6677116d 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/auth" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" @@ -102,7 +103,7 @@ func ListPullRequests(ctx *context.APIContext, form api.ListPullRequestsOptions) ctx.Error(http.StatusInternalServerError, "GetHeadRepo", err) return } - apiPrs[i] = prs[i].APIFormat() + apiPrs[i] = convert.ToAPIPullRequest(prs[i]) } ctx.SetLinkHeader(int(maxResults), models.ItemsPerPage) @@ -136,6 +137,8 @@ func GetPullRequest(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/PullRequest" + // "404": + // "$ref": "#/responses/notFound" pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { @@ -155,7 +158,7 @@ func GetPullRequest(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "GetHeadRepo", err) return } - ctx.JSON(http.StatusOK, pr.APIFormat()) + ctx.JSON(http.StatusOK, convert.ToAPIPullRequest(pr)) } // CreatePullRequest does what it says @@ -319,7 +322,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption notification.NotifyNewPullRequest(pr) log.Trace("Pull request created: %d/%d", repo.ID, prIssue.ID) - ctx.JSON(http.StatusCreated, pr.APIFormat()) + ctx.JSON(http.StatusCreated, convert.ToAPIPullRequest(pr)) } // EditPullRequest does what it says @@ -477,7 +480,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { } // TODO this should be 200, not 201 - ctx.JSON(http.StatusCreated, pr.APIFormat()) + ctx.JSON(http.StatusCreated, convert.ToAPIPullRequest(pr)) } // IsPullRequestMerged checks if a PR exists given an index diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 487b7ca11d..ee7bf8288c 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -282,11 +282,12 @@ func Create(ctx *context.APIContext, opt api.CreateRepoOption) { CreateUserRepo(ctx, ctx.User, opt) } -// CreateOrgRepo create one repository of the organization -func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) { - // swagger:operation POST /org/{org}/repos organization createOrgRepo +// CreateOrgRepoDeprecated create one repository of the organization +func CreateOrgRepoDeprecated(ctx *context.APIContext, opt api.CreateRepoOption) { + // swagger:operation POST /org/{org}/repos organization createOrgRepoDeprecated // --- // summary: Create a repository in an organization + // deprecated: true // consumes: // - application/json // produces: @@ -309,6 +310,37 @@ func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) { // "403": // "$ref": "#/responses/forbidden" + CreateOrgRepo(ctx, opt) +} + +// CreateOrgRepo create one repository of the organization +func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) { + // swagger:operation POST /orgs/{org}/repos organization createOrgRepo + // --- + // summary: Create a repository in an organization + // deprecated: true + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: org + // in: path + // description: name of organization + // type: string + // required: true + // - name: body + // in: body + // schema: + // "$ref": "#/definitions/CreateRepoOption" + // responses: + // "201": + // "$ref": "#/responses/Repository" + // "404": + // "$ref": "#/responses/notFound" + // "403": + // "$ref": "#/responses/forbidden" + org, err := models.GetOrgByName(ctx.Params(":org")) if err != nil { if models.IsErrOrgNotExist(err) { @@ -452,12 +484,13 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) { } repo, err := models.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{ - Name: opts.RepoName, - Description: opts.Description, - OriginalURL: form.CloneAddr, - IsPrivate: opts.Private, - IsMirror: opts.Mirror, - Status: models.RepositoryBeingMigrated, + Name: opts.RepoName, + Description: opts.Description, + OriginalURL: form.CloneAddr, + GitServiceType: gitServiceType, + IsPrivate: opts.Private, + IsMirror: opts.Mirror, + Status: models.RepositoryBeingMigrated, }) if err != nil { handleMigrateError(ctx, ctxUser, remoteAddr, err) diff --git a/routers/api/v1/swagger/notify.go b/routers/api/v1/swagger/notify.go new file mode 100644 index 0000000000..7d45da0e12 --- /dev/null +++ b/routers/api/v1/swagger/notify.go @@ -0,0 +1,23 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package swagger + +import ( + api "code.gitea.io/gitea/modules/structs" +) + +// NotificationThread +// swagger:response NotificationThread +type swaggerNotificationThread struct { + // in:body + Body api.NotificationThread `json:"body"` +} + +// NotificationThreadList +// swagger:response NotificationThreadList +type swaggerNotificationThreadList struct { + // in:body + Body []api.NotificationThread `json:"body"` +} diff --git a/routers/repo/repo.go b/routers/repo/repo.go index d6d91f0843..0bd9f1d56b 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -6,6 +6,7 @@ package repo import ( "fmt" + "net/url" "os" "path" "strings" @@ -18,6 +19,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/migrations" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/task" "code.gitea.io/gitea/modules/util" repo_service "code.gitea.io/gitea/services/repository" @@ -330,22 +332,29 @@ func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) { return } + var gitServiceType = structs.PlainGitService + u, err := url.Parse(form.CloneAddr) + if err == nil && strings.EqualFold(u.Host, "github.com") { + gitServiceType = structs.GithubService + } + var opts = migrations.MigrateOptions{ - OriginalURL: form.CloneAddr, - CloneAddr: remoteAddr, - RepoName: form.RepoName, - Description: form.Description, - Private: form.Private || setting.Repository.ForcePrivate, - Mirror: form.Mirror, - AuthUsername: form.AuthUsername, - AuthPassword: form.AuthPassword, - Wiki: form.Wiki, - Issues: form.Issues, - Milestones: form.Milestones, - Labels: form.Labels, - Comments: true, - PullRequests: form.PullRequests, - Releases: form.Releases, + OriginalURL: form.CloneAddr, + GitServiceType: gitServiceType, + CloneAddr: remoteAddr, + RepoName: form.RepoName, + Description: form.Description, + Private: form.Private || setting.Repository.ForcePrivate, + Mirror: form.Mirror, + AuthUsername: form.AuthUsername, + AuthPassword: form.AuthPassword, + Wiki: form.Wiki, + Issues: form.Issues, + Milestones: form.Milestones, + Labels: form.Labels, + Comments: true, + PullRequests: form.PullRequests, + Releases: form.Releases, } if opts.Mirror { opts.Issues = false diff --git a/services/mirror/mirror.go b/services/mirror/mirror.go index 28b2e2a127..d4f97c2600 100644 --- a/services/mirror/mirror.go +++ b/services/mirror/mirror.go @@ -403,7 +403,7 @@ func syncMirror(repoID string) { continue } - theCommits := models.ListToPushCommits(commits) + theCommits := repository.ListToPushCommits(commits) if len(theCommits.Commits) > setting.UI.FeedMaxCommitNum { theCommits.Commits = theCommits.Commits[:setting.UI.FeedMaxCommitNum] } diff --git a/services/pull/check.go b/services/pull/check.go index 74185b6815..c5d8a585cb 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -194,10 +194,16 @@ func TestPullRequests(ctx context.Context) { if err != nil { log.Error("GetPullRequestByID[%s]: %v", prID, err) continue + } else if pr.Status != models.PullRequestStatusChecking { + continue } else if manuallyMerged(pr) { continue } else if err = TestPatch(pr); err != nil { log.Error("testPatch[%d]: %v", pr.ID, err) + pr.Status = models.PullRequestStatusError + if err := pr.UpdateCols("status"); err != nil { + log.Error("update pr [%d] status to PullRequestStatusError failed: %v", pr.ID, err) + } continue } checkAndUpdateStatus(pr) diff --git a/services/release/release.go b/services/release/release.go index fd0c410e7c..0f19db9ee2 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" + "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/timeutil" ) @@ -43,7 +44,7 @@ func createTag(gitRepo *git.Repository, rel *models.Release) error { } notification.NotifyPushCommits( rel.Publisher, rel.Repo, git.TagPrefix+rel.TagName, - git.EmptySHA, commit.ID.String(), models.NewPushCommits()) + git.EmptySHA, commit.ID.String(), repository.NewPushCommits()) notification.NotifyCreateRef(rel.Publisher, rel.Repo, "tag", git.TagPrefix+rel.TagName) } commit, err := gitRepo.GetTagCommit(rel.TagName) diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl index b1e6feeba0..9dedc7dad7 100644 --- a/templates/repo/issue/view_content/pull.tmpl +++ b/templates/repo/issue/view_content/pull.tmpl @@ -153,7 +153,7 @@