From 471567b3baf20ea6adae6ba55f32fc5bf99ca409 Mon Sep 17 00:00:00 2001 From: Solomon Victorino Date: Wed, 28 Aug 2024 16:56:35 -0600 Subject: [PATCH 001/443] fix: use ValidateEmail as binding across web forms --- models/user/email_address.go | 99 ------------- models/user/email_address_test.go | 57 -------- models/user/user.go | 6 +- models/user/user_test.go | 3 +- modules/structs/admin_user.go | 2 +- modules/structs/user_email.go | 2 +- modules/validation/binding.go | 31 +++++ modules/validation/email.go | 131 ++++++++++++++++++ modules/validation/email_test.go | 67 +++++++++ modules/validation/helpers.go | 25 ---- modules/web/middleware/binding.go | 2 + routers/api/v1/activitypub/repository_test.go | 8 +- routers/api/v1/admin/user.go | 11 +- routers/api/v1/user/email.go | 7 +- routers/web/admin/users.go | 9 +- routers/web/auth/auth.go | 5 +- routers/web/org/teams.go | 3 +- routers/web/user/setting/account.go | 3 +- .../auth/source/pam/source_authenticate.go | 5 +- services/doctor/breaking.go | 5 +- services/forms/admin.go | 4 +- services/forms/user_form.go | 8 +- services/forms/user_form_auth_openid.go | 2 +- services/user/email.go | 7 +- 24 files changed, 281 insertions(+), 221 deletions(-) create mode 100644 modules/validation/email.go create mode 100644 modules/validation/email_test.go diff --git a/models/user/email_address.go b/models/user/email_address.go index 8c6f24e57b..b14ff7886c 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -7,8 +7,6 @@ package user import ( "context" "fmt" - "net/mail" - "regexp" "strings" "time" @@ -18,53 +16,10 @@ import ( "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/modules/validation" "xorm.io/builder" ) -// ErrEmailNotActivated e-mail address has not been activated error -var ErrEmailNotActivated = util.NewInvalidArgumentErrorf("e-mail address has not been activated") - -// ErrEmailCharIsNotSupported e-mail address contains unsupported character -type ErrEmailCharIsNotSupported struct { - Email string -} - -// IsErrEmailCharIsNotSupported checks if an error is an ErrEmailCharIsNotSupported -func IsErrEmailCharIsNotSupported(err error) bool { - _, ok := err.(ErrEmailCharIsNotSupported) - return ok -} - -func (err ErrEmailCharIsNotSupported) Error() string { - return fmt.Sprintf("e-mail address contains unsupported character [email: %s]", err.Email) -} - -func (err ErrEmailCharIsNotSupported) Unwrap() error { - return util.ErrInvalidArgument -} - -// ErrEmailInvalid represents an error where the email address does not comply with RFC 5322 -// or has a leading '-' character -type ErrEmailInvalid struct { - Email string -} - -// IsErrEmailInvalid checks if an error is an ErrEmailInvalid -func IsErrEmailInvalid(err error) bool { - _, ok := err.(ErrEmailInvalid) - return ok -} - -func (err ErrEmailInvalid) Error() string { - return fmt.Sprintf("e-mail invalid [email: %s]", err.Email) -} - -func (err ErrEmailInvalid) Unwrap() error { - return util.ErrInvalidArgument -} - // ErrEmailAlreadyUsed represents a "EmailAlreadyUsed" kind of error. type ErrEmailAlreadyUsed struct { Email string @@ -156,22 +111,6 @@ func UpdateEmailAddress(ctx context.Context, email *EmailAddress) error { return err } -var emailRegexp = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") - -// ValidateEmail check if email is a valid & allowed address -func ValidateEmail(email string) error { - if err := validateEmailBasic(email); err != nil { - return err - } - return validateEmailDomain(email) -} - -// ValidateEmailForAdmin check if email is a valid address when admins manually add or edit users -func ValidateEmailForAdmin(email string) error { - return validateEmailBasic(email) - // In this case we do not need to check the email domain -} - func GetEmailAddressByEmail(ctx context.Context, email string) (*EmailAddress, error) { ea := &EmailAddress{} if has, err := db.GetEngine(ctx).Where("lower_email=?", strings.ToLower(email)).Get(ea); err != nil { @@ -462,41 +401,3 @@ func ActivateUserEmail(ctx context.Context, userID int64, email string, activate return committer.Commit() } - -// validateEmailBasic checks whether the email complies with the rules -func validateEmailBasic(email string) error { - if len(email) == 0 { - return ErrEmailInvalid{email} - } - - if !emailRegexp.MatchString(email) { - return ErrEmailCharIsNotSupported{email} - } - - if email[0] == '-' { - return ErrEmailInvalid{email} - } - - if _, err := mail.ParseAddress(email); err != nil { - return ErrEmailInvalid{email} - } - - return nil -} - -// validateEmailDomain checks whether the email domain is allowed or blocked -func validateEmailDomain(email string) error { - if !IsEmailDomainAllowed(email) { - return ErrEmailInvalid{email} - } - - return nil -} - -func IsEmailDomainAllowed(email string) bool { - if len(setting.Service.EmailDomainAllowList) == 0 { - return !validation.IsEmailDomainListed(setting.Service.EmailDomainBlockList, email) - } - - return validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, email) -} diff --git a/models/user/email_address_test.go b/models/user/email_address_test.go index b918f21018..b00b91c5f2 100644 --- a/models/user/email_address_test.go +++ b/models/user/email_address_test.go @@ -130,63 +130,6 @@ func TestListEmails(t *testing.T) { assert.Greater(t, count, int64(len(emails))) } -func TestEmailAddressValidate(t *testing.T) { - kases := map[string]error{ - "abc@gmail.com": nil, - "132@hotmail.com": nil, - "1-3-2@test.org": nil, - "1.3.2@test.org": nil, - "a_123@test.org.cn": nil, - `first.last@iana.org`: nil, - `first!last@iana.org`: nil, - `first#last@iana.org`: nil, - `first$last@iana.org`: nil, - `first%last@iana.org`: nil, - `first&last@iana.org`: nil, - `first'last@iana.org`: nil, - `first*last@iana.org`: nil, - `first+last@iana.org`: nil, - `first/last@iana.org`: nil, - `first=last@iana.org`: nil, - `first?last@iana.org`: nil, - `first^last@iana.org`: nil, - "first`last@iana.org": nil, - `first{last@iana.org`: nil, - `first|last@iana.org`: nil, - `first}last@iana.org`: nil, - `first~last@iana.org`: nil, - `first;last@iana.org`: user_model.ErrEmailCharIsNotSupported{`first;last@iana.org`}, - ".233@qq.com": user_model.ErrEmailInvalid{".233@qq.com"}, - "!233@qq.com": nil, - "#233@qq.com": nil, - "$233@qq.com": nil, - "%233@qq.com": nil, - "&233@qq.com": nil, - "'233@qq.com": nil, - "*233@qq.com": nil, - "+233@qq.com": nil, - "-233@qq.com": user_model.ErrEmailInvalid{"-233@qq.com"}, - "/233@qq.com": nil, - "=233@qq.com": nil, - "?233@qq.com": nil, - "^233@qq.com": nil, - "_233@qq.com": nil, - "`233@qq.com": nil, - "{233@qq.com": nil, - "|233@qq.com": nil, - "}233@qq.com": nil, - "~233@qq.com": nil, - ";233@qq.com": user_model.ErrEmailCharIsNotSupported{";233@qq.com"}, - "Foo ": user_model.ErrEmailCharIsNotSupported{"Foo "}, - string([]byte{0xE2, 0x84, 0xAA}): user_model.ErrEmailCharIsNotSupported{string([]byte{0xE2, 0x84, 0xAA})}, - } - for kase, err := range kases { - t.Run(kase, func(t *testing.T) { - assert.EqualValues(t, err, user_model.ValidateEmail(kase)) - }) - } -} - func TestGetActivatedEmailAddresses(t *testing.T) { require.NoError(t, unittest.PrepareTestDatabase()) diff --git a/models/user/user.go b/models/user/user.go index b1731021fd..07b314a331 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -711,11 +711,11 @@ func createUser(ctx context.Context, u *User, createdByAdmin bool, overwriteDefa } if createdByAdmin { - if err := ValidateEmailForAdmin(u.Email); err != nil { + if err := validation.ValidateEmailForAdmin(u.Email); err != nil { return err } } else { - if err := ValidateEmail(u.Email); err != nil { + if err := validation.ValidateEmail(u.Email); err != nil { return err } } @@ -879,7 +879,7 @@ func (u User) Validate() []string { if err := ValidateUser(&u); err != nil { result = append(result, err.Error()) } - if err := ValidateEmail(u.Email); err != nil { + if err := validation.ValidateEmail(u.Email); err != nil { result = append(result, err.Error()) } return result diff --git a/models/user/user_test.go b/models/user/user_test.go index 8f4350f776..082c21063c 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -22,6 +22,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" @@ -320,7 +321,7 @@ func TestCreateUserInvalidEmail(t *testing.T) { err := user_model.CreateUser(db.DefaultContext, user) require.Error(t, err) - assert.True(t, user_model.IsErrEmailCharIsNotSupported(err)) + assert.True(t, validation.IsErrEmailCharIsNotSupported(err)) } func TestCreateUserEmailAlreadyUsed(t *testing.T) { diff --git a/modules/structs/admin_user.go b/modules/structs/admin_user.go index 5b7df127b4..8a4d066d72 100644 --- a/modules/structs/admin_user.go +++ b/modules/structs/admin_user.go @@ -15,7 +15,7 @@ type CreateUserOption struct { FullName string `json:"full_name" binding:"MaxSize(100)"` // required: true // swagger:strfmt email - Email string `json:"email" binding:"Required;Email;MaxSize(254)"` + Email string `json:"email" binding:"Required;EmailForAdmin;MaxSize(254)"` Password string `json:"password" binding:"MaxSize(255)"` MustChangePassword *bool `json:"must_change_password"` SendNotify bool `json:"send_notify"` diff --git a/modules/structs/user_email.go b/modules/structs/user_email.go index 9319667e8f..485d0de1af 100644 --- a/modules/structs/user_email.go +++ b/modules/structs/user_email.go @@ -7,7 +7,7 @@ package structs // Email an email address belonging to a user type Email struct { // swagger:strfmt email - Email string `json:"email"` + Email string `json:"email" binding:"EmailWithAllowedDomain"` Verified bool `json:"verified"` Primary bool `json:"primary"` UserID int64 `json:"user_id"` diff --git a/modules/validation/binding.go b/modules/validation/binding.go index cb0a5063e5..fe434500d5 100644 --- a/modules/validation/binding.go +++ b/modules/validation/binding.go @@ -26,6 +26,8 @@ const ( ErrUsername = "UsernameError" // ErrInvalidGroupTeamMap is returned when a group team mapping is invalid ErrInvalidGroupTeamMap = "InvalidGroupTeamMap" + // ErrEmail is returned when an email address is invalid + ErrEmail = "Email" ) // AddBindingRules adds additional binding rules @@ -38,6 +40,7 @@ func AddBindingRules() { addGlobOrRegexPatternRule() addUsernamePatternRule() addValidGroupTeamMapRule() + addEmailBindingRules() } func addGitRefNameBindingRule() { @@ -185,6 +188,34 @@ func addValidGroupTeamMapRule() { }) } +func addEmailBindingRules() { + binding.AddRule(&binding.Rule{ + IsMatch: func(rule string) bool { + return strings.HasPrefix(rule, "EmailWithAllowedDomain") + }, + IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) { + if err := ValidateEmail(fmt.Sprintf("%v", val)); err != nil { + errs.Add([]string{name}, ErrEmail, err.Error()) + return false, errs + } + return true, errs + }, + }) + + binding.AddRule(&binding.Rule{ + IsMatch: func(rule string) bool { + return strings.HasPrefix(rule, "EmailForAdmin") + }, + IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) { + if err := ValidateEmailForAdmin(fmt.Sprintf("%v", val)); err != nil { + errs.Add([]string{name}, ErrEmail, err.Error()) + return false, errs + } + return true, errs + }, + }) +} + func portOnly(hostport string) string { colon := strings.IndexByte(hostport, ':') if colon == -1 { diff --git a/modules/validation/email.go b/modules/validation/email.go new file mode 100644 index 0000000000..bef816586f --- /dev/null +++ b/modules/validation/email.go @@ -0,0 +1,131 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package validation + +import ( + "fmt" + "net/mail" + "regexp" + "strings" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" + + "github.com/gobwas/glob" +) + +// ErrEmailNotActivated e-mail address has not been activated error +var ErrEmailNotActivated = util.NewInvalidArgumentErrorf("e-mail address has not been activated") + +// ErrEmailCharIsNotSupported e-mail address contains unsupported character +type ErrEmailCharIsNotSupported struct { + Email string +} + +// IsErrEmailCharIsNotSupported checks if an error is an ErrEmailCharIsNotSupported +func IsErrEmailCharIsNotSupported(err error) bool { + _, ok := err.(ErrEmailCharIsNotSupported) + return ok +} + +func (err ErrEmailCharIsNotSupported) Error() string { + return fmt.Sprintf("e-mail address contains unsupported character [email: %s]", err.Email) +} + +// ErrEmailInvalid represents an error where the email address does not comply with RFC 5322 +// or has a leading '-' character +type ErrEmailInvalid struct { + Email string +} + +// IsErrEmailInvalid checks if an error is an ErrEmailInvalid +func IsErrEmailInvalid(err error) bool { + _, ok := err.(ErrEmailInvalid) + return ok +} + +func (err ErrEmailInvalid) Error() string { + return fmt.Sprintf("e-mail invalid [email: %s]", err.Email) +} + +func (err ErrEmailInvalid) Unwrap() error { + return util.ErrInvalidArgument +} + +var emailRegexp = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") + +// check if email is a valid address with allowed domain +func ValidateEmail(email string) error { + if err := validateEmailBasic(email); err != nil { + return err + } + return validateEmailDomain(email) +} + +// check if email is a valid address when admins manually add or edit users +func ValidateEmailForAdmin(email string) error { + return validateEmailBasic(email) + // In this case we do not need to check the email domain +} + +// validateEmailBasic checks whether the email complies with the rules +func validateEmailBasic(email string) error { + if len(email) == 0 { + return ErrEmailInvalid{email} + } + + if !emailRegexp.MatchString(email) { + return ErrEmailCharIsNotSupported{email} + } + + if email[0] == '-' { + return ErrEmailInvalid{email} + } + + if _, err := mail.ParseAddress(email); err != nil { + return ErrEmailInvalid{email} + } + + return nil +} + +func validateEmailDomain(email string) error { + if !IsEmailDomainAllowed(email) { + return ErrEmailInvalid{email} + } + + return nil +} + +func IsEmailDomainAllowed(email string) bool { + if len(setting.Service.EmailDomainAllowList) == 0 { + return !isEmailDomainListed(setting.Service.EmailDomainBlockList, email) + } + + return isEmailDomainListed(setting.Service.EmailDomainAllowList, email) +} + +// isEmailDomainListed checks whether the domain of an email address +// matches a list of domains +func isEmailDomainListed(globs []glob.Glob, email string) bool { + if len(globs) == 0 { + return false + } + + n := strings.LastIndex(email, "@") + if n <= 0 { + return false + } + + domain := strings.ToLower(email[n+1:]) + + for _, g := range globs { + if g.Match(domain) { + return true + } + } + + return false +} diff --git a/modules/validation/email_test.go b/modules/validation/email_test.go new file mode 100644 index 0000000000..e5125a9357 --- /dev/null +++ b/modules/validation/email_test.go @@ -0,0 +1,67 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package validation + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestEmailAddressValidate(t *testing.T) { + kases := map[string]error{ + "abc@gmail.com": nil, + "132@hotmail.com": nil, + "1-3-2@test.org": nil, + "1.3.2@test.org": nil, + "a_123@test.org.cn": nil, + `first.last@iana.org`: nil, + `first!last@iana.org`: nil, + `first#last@iana.org`: nil, + `first$last@iana.org`: nil, + `first%last@iana.org`: nil, + `first&last@iana.org`: nil, + `first'last@iana.org`: nil, + `first*last@iana.org`: nil, + `first+last@iana.org`: nil, + `first/last@iana.org`: nil, + `first=last@iana.org`: nil, + `first?last@iana.org`: nil, + `first^last@iana.org`: nil, + "first`last@iana.org": nil, + `first{last@iana.org`: nil, + `first|last@iana.org`: nil, + `first}last@iana.org`: nil, + `first~last@iana.org`: nil, + `first;last@iana.org`: ErrEmailCharIsNotSupported{`first;last@iana.org`}, + ".233@qq.com": ErrEmailInvalid{".233@qq.com"}, + "!233@qq.com": nil, + "#233@qq.com": nil, + "$233@qq.com": nil, + "%233@qq.com": nil, + "&233@qq.com": nil, + "'233@qq.com": nil, + "*233@qq.com": nil, + "+233@qq.com": nil, + "-233@qq.com": ErrEmailInvalid{"-233@qq.com"}, + "/233@qq.com": nil, + "=233@qq.com": nil, + "?233@qq.com": nil, + "^233@qq.com": nil, + "_233@qq.com": nil, + "`233@qq.com": nil, + "{233@qq.com": nil, + "|233@qq.com": nil, + "}233@qq.com": nil, + "~233@qq.com": nil, + ";233@qq.com": ErrEmailCharIsNotSupported{";233@qq.com"}, + "Foo ": ErrEmailCharIsNotSupported{"Foo "}, + string([]byte{0xE2, 0x84, 0xAA}): ErrEmailCharIsNotSupported{string([]byte{0xE2, 0x84, 0xAA})}, + } + for kase, err := range kases { + t.Run(kase, func(t *testing.T) { + assert.EqualValues(t, err, ValidateEmail(kase)) + }) + } +} diff --git a/modules/validation/helpers.go b/modules/validation/helpers.go index 567ad867fe..2f88fcbc60 100644 --- a/modules/validation/helpers.go +++ b/modules/validation/helpers.go @@ -10,8 +10,6 @@ import ( "strings" "code.gitea.io/gitea/modules/setting" - - "github.com/gobwas/glob" ) var externalTrackerRegex = regexp.MustCompile(`({?)(?:user|repo|index)+?(}?)`) @@ -50,29 +48,6 @@ func IsValidSiteURL(uri string) bool { return false } -// IsEmailDomainListed checks whether the domain of an email address -// matches a list of domains -func IsEmailDomainListed(globs []glob.Glob, email string) bool { - if len(globs) == 0 { - return false - } - - n := strings.LastIndex(email, "@") - if n <= 0 { - return false - } - - domain := strings.ToLower(email[n+1:]) - - for _, g := range globs { - if g.Match(domain) { - return true - } - } - - return false -} - // IsAPIURL checks if URL is current Gitea instance API URL func IsAPIURL(uri string) bool { return strings.HasPrefix(strings.ToLower(uri), strings.ToLower(setting.AppURL+"api")) diff --git a/modules/web/middleware/binding.go b/modules/web/middleware/binding.go index 8fa71a81bd..bc0735b2cd 100644 --- a/modules/web/middleware/binding.go +++ b/modules/web/middleware/binding.go @@ -143,6 +143,8 @@ func Validate(errs binding.Errors, data map[string]any, f any, l translation.Loc } case validation.ErrInvalidGroupTeamMap: data["ErrorMsg"] = trName + l.TrString("form.invalid_group_team_map_error", errs[0].Message) + case validation.ErrEmail: + data["ErrorMsg"] = trName + l.TrString("form.email_error") default: msg := errs[0].Classification if msg != "" && errs[0].Message != "" { diff --git a/routers/api/v1/activitypub/repository_test.go b/routers/api/v1/activitypub/repository_test.go index acd588d99b..1e5af6acac 100644 --- a/routers/api/v1/activitypub/repository_test.go +++ b/routers/api/v1/activitypub/repository_test.go @@ -6,22 +6,22 @@ package activitypub import ( "testing" - "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/validation" ) func Test_UserEmailValidate(t *testing.T) { sut := "ab@cd.ef" - if err := user.ValidateEmail(sut); err != nil { + if err := validation.ValidateEmail(sut); err != nil { t.Errorf("sut should be valid, %v, %v", sut, err) } sut = "83ce13c8-af0b-4112-8327-55a54e54e664@code.cartoon-aa.xyz" - if err := user.ValidateEmail(sut); err != nil { + if err := validation.ValidateEmail(sut); err != nil { t.Errorf("sut should be valid, %v, %v", sut, err) } sut = "1" - if err := user.ValidateEmail(sut); err == nil { + if err := validation.ValidateEmail(sut); err == nil { t.Errorf("sut should not be valid, %v", sut) } } diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 9ea210ee4e..b17200381a 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" @@ -138,8 +139,8 @@ func CreateUser(ctx *context.APIContext) { user_model.IsErrEmailAlreadyUsed(err) || db.IsErrNameReserved(err) || db.IsErrNameCharsNotAllowed(err) || - user_model.IsErrEmailCharIsNotSupported(err) || - user_model.IsErrEmailInvalid(err) || + validation.IsErrEmailCharIsNotSupported(err) || + validation.IsErrEmailInvalid(err) || db.IsErrNamePatternNotAllowed(err) { ctx.Error(http.StatusUnprocessableEntity, "", err) } else { @@ -148,7 +149,7 @@ func CreateUser(ctx *context.APIContext) { return } - if !user_model.IsEmailDomainAllowed(u.Email) { + if !validation.IsEmailDomainAllowed(u.Email) { ctx.Resp.Header().Add("X-Gitea-Warning", fmt.Sprintf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", u.Email)) } @@ -224,7 +225,7 @@ func EditUser(ctx *context.APIContext) { if form.Email != nil { if err := user_service.AdminAddOrSetPrimaryEmailAddress(ctx, ctx.ContextUser, *form.Email); err != nil { switch { - case user_model.IsErrEmailCharIsNotSupported(err), user_model.IsErrEmailInvalid(err): + case validation.IsErrEmailCharIsNotSupported(err), validation.IsErrEmailInvalid(err): ctx.Error(http.StatusBadRequest, "EmailInvalid", err) case user_model.IsErrEmailAlreadyUsed(err): ctx.Error(http.StatusBadRequest, "EmailUsed", err) @@ -234,7 +235,7 @@ func EditUser(ctx *context.APIContext) { return } - if !user_model.IsEmailDomainAllowed(*form.Email) { + if !validation.IsEmailDomainAllowed(*form.Email) { ctx.Resp.Header().Add("X-Gitea-Warning", fmt.Sprintf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", *form.Email)) } } diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go index 33aa851a80..1e9d0984df 100644 --- a/routers/api/v1/user/email.go +++ b/routers/api/v1/user/email.go @@ -9,6 +9,7 @@ import ( user_model "code.gitea.io/gitea/models/user" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/convert" @@ -66,12 +67,12 @@ func AddEmail(ctx *context.APIContext) { if err := user_service.AddEmailAddresses(ctx, ctx.Doer, form.Emails); err != nil { if user_model.IsErrEmailAlreadyUsed(err) { ctx.Error(http.StatusUnprocessableEntity, "", "Email address has been used: "+err.(user_model.ErrEmailAlreadyUsed).Email) - } else if user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) { + } else if validation.IsErrEmailCharIsNotSupported(err) || validation.IsErrEmailInvalid(err) { email := "" - if typedError, ok := err.(user_model.ErrEmailInvalid); ok { + if typedError, ok := err.(validation.ErrEmailInvalid); ok { email = typedError.Email } - if typedError, ok := err.(user_model.ErrEmailCharIsNotSupported); ok { + if typedError, ok := err.(validation.ErrEmailCharIsNotSupported); ok { email = typedError.Email } diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index ddd7045eb7..2802ace778 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -23,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/web/explore" user_setting "code.gitea.io/gitea/routers/web/user/setting" @@ -185,7 +186,7 @@ func NewUserPost(ctx *context.Context) { case user_model.IsErrEmailAlreadyUsed(err): ctx.Data["Err_Email"] = true ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplUserNew, &form) - case user_model.IsErrEmailInvalid(err), user_model.IsErrEmailCharIsNotSupported(err): + case validation.IsErrEmailInvalid(err), validation.IsErrEmailCharIsNotSupported(err): ctx.Data["Err_Email"] = true ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplUserNew, &form) case db.IsErrNameReserved(err): @@ -203,7 +204,7 @@ func NewUserPost(ctx *context.Context) { return } - if !user_model.IsEmailDomainAllowed(u.Email) { + if !validation.IsEmailDomainAllowed(u.Email) { ctx.Flash.Warning(ctx.Tr("form.email_domain_is_not_allowed", u.Email)) } @@ -414,7 +415,7 @@ func EditUserPost(ctx *context.Context) { if form.Email != "" { if err := user_service.AdminAddOrSetPrimaryEmailAddress(ctx, u, form.Email); err != nil { switch { - case user_model.IsErrEmailCharIsNotSupported(err), user_model.IsErrEmailInvalid(err): + case validation.IsErrEmailCharIsNotSupported(err), validation.IsErrEmailInvalid(err): ctx.Data["Err_Email"] = true ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplUserEdit, &form) case user_model.IsErrEmailAlreadyUsed(err): @@ -425,7 +426,7 @@ func EditUserPost(ctx *context.Context) { } return } - if !user_model.IsEmailDomainAllowed(form.Email) { + if !validation.IsEmailDomainAllowed(form.Email) { ctx.Flash.Warning(ctx.Tr("form.email_domain_is_not_allowed", form.Email)) } } diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 3f1ed54bda..878f34e983 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -25,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web/middleware" auth_service "code.gitea.io/gitea/services/auth" @@ -575,10 +576,10 @@ func createUserInContext(ctx *context.Context, tpl base.TplName, form any, u *us case user_model.IsErrEmailAlreadyUsed(err): ctx.Data["Err_Email"] = true ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tpl, form) - case user_model.IsErrEmailCharIsNotSupported(err): + case validation.IsErrEmailCharIsNotSupported(err): ctx.Data["Err_Email"] = true ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tpl, form) - case user_model.IsErrEmailInvalid(err): + case validation.IsErrEmailInvalid(err): ctx.Data["Err_Email"] = true ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tpl, form) case db.IsErrNameReserved(err): diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index fd7486cacd..c9313d207a 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -22,6 +22,7 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" shared_user "code.gitea.io/gitea/routers/web/shared/user" "code.gitea.io/gitea/services/context" @@ -131,7 +132,7 @@ func TeamsAction(ctx *context.Context) { u, err = user_model.GetUserByName(ctx, uname) if err != nil { if user_model.IsErrUserNotExist(err) { - if setting.MailService != nil && user_model.ValidateEmail(uname) == nil { + if setting.MailService != nil && validation.ValidateEmail(uname) == nil { if err := org_service.CreateTeamInvite(ctx, ctx.Doer, ctx.Org.Team, uname); err != nil { if org_model.IsErrTeamInviteAlreadyExist(err) { ctx.Flash.Error(ctx.Tr("form.duplicate_invite_to_team")) diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index d2d2d5bc4c..0f811cd2cd 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/auth" "code.gitea.io/gitea/services/auth/source/db" @@ -205,7 +206,7 @@ func EmailPost(ctx *context.Context) { loadAccountData(ctx) ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsAccount, &form) - } else if user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) { + } else if validation.IsErrEmailCharIsNotSupported(err) || validation.IsErrEmailInvalid(err) { loadAccountData(ctx) ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplSettingsAccount, &form) diff --git a/services/auth/source/pam/source_authenticate.go b/services/auth/source/pam/source_authenticate.go index addd1bd2c9..0df0b2bca1 100644 --- a/services/auth/source/pam/source_authenticate.go +++ b/services/auth/source/pam/source_authenticate.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/auth/pam" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/validation" "github.com/google/uuid" ) @@ -39,13 +40,13 @@ func (source *Source) Authenticate(ctx context.Context, user *user_model.User, u if idx > -1 { username = pamLogin[:idx] } - if user_model.ValidateEmail(email) != nil { + if validation.ValidateEmail(email) != nil { if source.EmailDomain != "" { email = fmt.Sprintf("%s@%s", username, source.EmailDomain) } else { email = fmt.Sprintf("%s@%s", username, setting.Service.NoReplyAddress) } - if user_model.ValidateEmail(email) != nil { + if validation.ValidateEmail(email) != nil { email = uuid.New().String() + "@localhost" } } diff --git a/services/doctor/breaking.go b/services/doctor/breaking.go index 77e3d4e8ef..683ec97389 100644 --- a/services/doctor/breaking.go +++ b/services/doctor/breaking.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/validation" "xorm.io/builder" ) @@ -31,7 +32,7 @@ func iterateUserAccounts(ctx context.Context, each func(*user.User) error) error func checkUserEmail(ctx context.Context, logger log.Logger, _ bool) error { // We could use quirky SQL to get all users that start without a [a-zA-Z0-9], but that would mean // DB provider-specific SQL and only works _now_. So instead we iterate through all user accounts - // and use the user.ValidateEmail function to be future-proof. + // and use the validation.ValidateEmail function to be future-proof. var invalidUserCount int64 if err := iterateUserAccounts(ctx, func(u *user.User) error { // Only check for users, skip @@ -39,7 +40,7 @@ func checkUserEmail(ctx context.Context, logger log.Logger, _ bool) error { return nil } - if err := user.ValidateEmail(u.Email); err != nil { + if err := validation.ValidateEmail(u.Email); err != nil { invalidUserCount++ logger.Warn("User[id=%d name=%q] have not a valid e-mail: %v", u.ID, u.Name, err) } diff --git a/services/forms/admin.go b/services/forms/admin.go index 7d46904440..d71fc076fc 100644 --- a/services/forms/admin.go +++ b/services/forms/admin.go @@ -18,7 +18,7 @@ type AdminCreateUserForm struct { LoginType string `binding:"Required"` LoginName string UserName string `binding:"Required;Username;MaxSize(40)"` - Email string `binding:"Required;Email;MaxSize(254)"` + Email string `binding:"Required;EmailForAdmin;MaxSize(254)"` Password string `binding:"MaxSize(255)"` SendNotify bool MustChangePassword bool @@ -37,7 +37,7 @@ type AdminEditUserForm struct { UserName string `binding:"Username;MaxSize(40)"` LoginName string FullName string `binding:"MaxSize(100)"` - Email string `binding:"Required;Email;MaxSize(254)"` + Email string `binding:"Required;EmailForAdmin;MaxSize(254)"` Password string `binding:"MaxSize(255)"` Website string `binding:"ValidUrl;MaxSize(255)"` Location string `binding:"MaxSize(50)"` diff --git a/services/forms/user_form.go b/services/forms/user_form.go index cc93b27e2a..67c8f00715 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -10,9 +10,9 @@ import ( "strings" auth_model "code.gitea.io/gitea/models/auth" - user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/services/context" @@ -110,7 +110,7 @@ func (f *RegisterForm) Validate(req *http.Request, errs binding.Errors) binding. // domains in the whitelist or if it doesn't match any of // domains in the blocklist, if any such list is not empty. func (f *RegisterForm) IsEmailDomainAllowed() bool { - return user_model.IsEmailDomainAllowed(f.Email) + return validation.IsEmailDomainAllowed(f.Email) } // MustChangePasswordForm form for updating your password after account creation @@ -258,7 +258,7 @@ const ( type AvatarForm struct { Source string Avatar *multipart.FileHeader - Gravatar string `binding:"OmitEmpty;Email;MaxSize(254)"` + Gravatar string `binding:"OmitEmpty;EmailWithAllowedDomain;MaxSize(254)"` Federavatar bool } @@ -270,7 +270,7 @@ func (f *AvatarForm) Validate(req *http.Request, errs binding.Errors) binding.Er // AddEmailForm form for adding new email type AddEmailForm struct { - Email string `binding:"Required;Email;MaxSize(254)"` + Email string `binding:"Required;EmailWithAllowedDomain;MaxSize(254)"` } // Validate validates the fields diff --git a/services/forms/user_form_auth_openid.go b/services/forms/user_form_auth_openid.go index ca1c77e320..595bfecad9 100644 --- a/services/forms/user_form_auth_openid.go +++ b/services/forms/user_form_auth_openid.go @@ -27,7 +27,7 @@ func (f *SignInOpenIDForm) Validate(req *http.Request, errs binding.Errors) bind // SignUpOpenIDForm form for signin up with OpenID type SignUpOpenIDForm struct { UserName string `binding:"Required;Username;MaxSize(40)"` - Email string `binding:"Required;Email;MaxSize(254)"` + Email string `binding:"Required;EmailWithAllowedDomain;MaxSize(254)"` } // Validate validates the fields diff --git a/services/user/email.go b/services/user/email.go index e8725267f4..31404aadaa 100644 --- a/services/user/email.go +++ b/services/user/email.go @@ -12,6 +12,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/services/mailer" ) @@ -21,7 +22,7 @@ func AdminAddOrSetPrimaryEmailAddress(ctx context.Context, u *user_model.User, e return nil } - if err := user_model.ValidateEmailForAdmin(emailStr); err != nil { + if err := validation.ValidateEmailForAdmin(emailStr); err != nil { return err } @@ -74,7 +75,7 @@ func ReplacePrimaryEmailAddress(ctx context.Context, u *user_model.User, emailSt return nil } - if err := user_model.ValidateEmail(emailStr); err != nil { + if err := validation.ValidateEmail(emailStr); err != nil { return err } @@ -119,7 +120,7 @@ func ReplacePrimaryEmailAddress(ctx context.Context, u *user_model.User, emailSt func AddEmailAddresses(ctx context.Context, u *user_model.User, emails []string) error { for _, emailStr := range emails { - if err := user_model.ValidateEmail(emailStr); err != nil { + if err := validation.ValidateEmail(emailStr); err != nil { return err } From e4134f0a81ea67c9f6776ba1e6eb021213fd4f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Piliszek?= Date: Fri, 6 Sep 2024 11:54:14 +0000 Subject: [PATCH 002/443] Makefile: support gotestsum gotestsum [1] is a tool that brings sanity to human-powered analysis of test results, supporting handy summaries of results and more. This implementation allows for the use of `USE_GOTESTSUM=yes` to switch the implementation from raw `go test` to `gotestsum`. It also gives general flexibility in choice of go tests runner. The PREFIX-SUFFIX play is needed for compiled tests and may be subject to modification depending on the outcome of #5248 [1] https://pkg.go.dev/gotest.tools/gotestsum --- Makefile | 84 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index 455bf16bce..1dcfbd7083 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,16 @@ HAS_GO := $(shell hash $(GO) > /dev/null 2>&1 && echo yes) COMMA := , DIFF ?= diff --unified +ifeq ($(USE_GOTESTSUM), yes) + GOTEST ?= gotestsum -- + GOTESTCOMPILEDRUNPREFIX ?= gotestsum --raw-command -- go tool test2json -t + GOTESTCOMPILEDRUNSUFFIX ?= -test.v=test2json +else + GOTEST ?= $(GO) test + GOTESTCOMPILEDRUNPREFIX ?= + GOTESTCOMPILEDRUNSUFFIX ?= +endif + XGO_VERSION := go-1.21.x AIR_PACKAGE ?= github.com/air-verse/air@v1 # renovate: datasource=go @@ -534,12 +544,12 @@ test: test-frontend test-backend .PHONY: test-backend test-backend: @echo "Running go test with $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." - @$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' $(GO_TEST_PACKAGES) + @$(GOTEST) $(GOTESTFLAGS) -tags='$(TEST_TAGS)' $(GO_TEST_PACKAGES) .PHONY: test-remote-cacher test-remote-cacher: @echo "Running go test with $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." - @$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' $(GO_TEST_REMOTE_CACHER_PACKAGES) + @$(GOTEST) $(GOTESTFLAGS) -tags='$(TEST_TAGS)' $(GO_TEST_REMOTE_CACHER_PACKAGES) .PHONY: test-frontend test-frontend: node_modules @@ -564,7 +574,7 @@ test-check: .PHONY: test\#% test\#%: @echo "Running go test with -tags '$(TEST_TAGS)'..." - @$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_TEST_PACKAGES) + @$(GOTEST) $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_TEST_PACKAGES) .PHONY: coverage coverage: @@ -575,7 +585,7 @@ coverage: .PHONY: unit-test-coverage unit-test-coverage: @echo "Running unit-test-coverage $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." - @$(GO) test $(GOTESTFLAGS) -timeout=20m -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_TEST_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1 + @$(GOTEST) $(GOTESTFLAGS) -timeout=20m -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_TEST_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1 .PHONY: tidy tidy: @@ -608,11 +618,11 @@ generate-ini-sqlite: .PHONY: test-sqlite test-sqlite: integrations.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTESTCOMPILEDRUNPREFIX) ./integrations.sqlite.test $(GOTESTCOMPILEDRUNSUFFIX) .PHONY: test-sqlite\#% test-sqlite\#%: integrations.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*) + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTESTCOMPILEDRUNPREFIX) ./integrations.sqlite.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run $(subst .,/,$*) .PHONY: test-sqlite-migration test-sqlite-migration: migrations.sqlite.test migrations.individual.sqlite.test @@ -629,11 +639,11 @@ generate-ini-mysql: .PHONY: test-mysql test-mysql: integrations.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GOTESTCOMPILEDRUNPREFIX) ./integrations.mysql.test $(GOTESTCOMPILEDRUNSUFFIX) .PHONY: test-mysql\#% test-mysql\#%: integrations.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*) + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GOTESTCOMPILEDRUNPREFIX) ./integrations.mysql.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run $(subst .,/,$*) .PHONY: test-mysql-migration test-mysql-migration: migrations.mysql.test migrations.individual.mysql.test @@ -651,11 +661,11 @@ generate-ini-pgsql: .PHONY: test-pgsql test-pgsql: integrations.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTESTCOMPILEDRUNPREFIX) ./integrations.pgsql.test $(GOTESTCOMPILEDRUNSUFFIX) .PHONY: test-pgsql\#% test-pgsql\#%: integrations.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*) + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTESTCOMPILEDRUNPREFIX) ./integrations.pgsql.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run $(subst .,/,$*) .PHONY: test-pgsql-migration test-pgsql-migration: migrations.pgsql.test migrations.individual.pgsql.test @@ -674,31 +684,31 @@ test-e2e: test-e2e-sqlite .PHONY: test-e2e-sqlite test-e2e-sqlite: playwright e2e.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./e2e.sqlite.test -test.run TestE2e + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTESTCOMPILEDRUNPREFIX) ./e2e.sqlite.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run TestE2e .PHONY: test-e2e-sqlite\#% test-e2e-sqlite\#%: playwright e2e.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./e2e.sqlite.test -test.run TestE2e/$* + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTESTCOMPILEDRUNPREFIX) ./e2e.sqlite.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run TestE2e/$* .PHONY: test-e2e-sqlite-firefox\#% test-e2e-sqlite-firefox\#%: playwright e2e.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini PLAYWRIGHT_PROJECT=firefox ./e2e.sqlite.test -test.run TestE2e/$* + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini PLAYWRIGHT_PROJECT=firefox $(GOTESTCOMPILEDRUNPREFIX) ./e2e.sqlite.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run TestE2e/$* .PHONY: test-e2e-mysql test-e2e-mysql: playwright e2e.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test -test.run TestE2e + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GOTESTCOMPILEDRUNPREFIX) ./e2e.mysql.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run TestE2e .PHONY: test-e2e-mysql\#% test-e2e-mysql\#%: playwright e2e.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./e2e.mysql.test -test.run TestE2e/$* + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GOTESTCOMPILEDRUNPREFIX) ./e2e.mysql.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run TestE2e/$* .PHONY: test-e2e-pgsql test-e2e-pgsql: playwright e2e.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test -test.run TestE2e + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTESTCOMPILEDRUNPREFIX) ./e2e.pgsql.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run TestE2e .PHONY: test-e2e-pgsql\#% test-e2e-pgsql\#%: playwright e2e.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./e2e.pgsql.test -test.run TestE2e/$* + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTESTCOMPILEDRUNPREFIX) ./e2e.pgsql.test $(GOTESTCOMPILEDRUNSUFFIX) -test.run TestE2e/$* .PHONY: test-e2e-debugserver test-e2e-debugserver: e2e.sqlite.test generate-ini-sqlite @@ -726,73 +736,73 @@ integration-test-coverage-sqlite: integrations.cover.sqlite.test generate-ini-sq GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.cover.sqlite.test -test.coverprofile=integration.coverage.out integrations.mysql.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql.test + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.mysql.test integrations.pgsql.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.pgsql.test + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.pgsql.test integrations.sqlite.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.sqlite.test -tags '$(TEST_TAGS)' + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.sqlite.test -tags '$(TEST_TAGS)' integrations.cover.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.test + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.test integrations.cover.sqlite.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.sqlite.test -tags '$(TEST_TAGS)' + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.sqlite.test -tags '$(TEST_TAGS)' .PHONY: migrations.mysql.test migrations.mysql.test: $(GO_SOURCES) generate-ini-mysql - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.mysql.test + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GOTESTCOMPILEDRUNPREFIX) ./migrations.mysql.test $(GOTESTCOMPILEDRUNSUFFIX) .PHONY: migrations.pgsql.test migrations.pgsql.test: $(GO_SOURCES) generate-ini-pgsql - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.pgsql.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./migrations.pgsql.test + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.pgsql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTESTCOMPILEDRUNPREFIX) ./migrations.pgsql.test $(GOTESTCOMPILEDRUNSUFFIX) .PHONY: migrations.sqlite.test migrations.sqlite.test: $(GO_SOURCES) generate-ini-sqlite - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)' - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.sqlite.test + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)' + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTESTCOMPILEDRUNPREFIX) ./migrations.sqlite.test $(GOTESTCOMPILEDRUNSUFFIX) .PHONY: migrations.individual.mysql.test migrations.individual.mysql.test: $(GO_SOURCES) for pkg in $(MIGRATION_PACKAGES); do \ - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg || exit 1; \ + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg || exit 1; \ done .PHONY: migrations.individual.sqlite.test\#% migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* .PHONY: migrations.individual.pgsql.test migrations.individual.pgsql.test: $(GO_SOURCES) for pkg in $(MIGRATION_PACKAGES); do \ - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg || exit 1;\ + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg || exit 1;\ done .PHONY: migrations.individual.pgsql.test\#% migrations.individual.pgsql.test\#%: $(GO_SOURCES) generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* .PHONY: migrations.individual.sqlite.test migrations.individual.sqlite.test: $(GO_SOURCES) generate-ini-sqlite for pkg in $(MIGRATION_PACKAGES); do \ - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg || exit 1; \ + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg || exit 1; \ done .PHONY: migrations.individual.sqlite.test\#% migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GOTEST) $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* e2e.mysql.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql.test + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql.test e2e.pgsql.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.pgsql.test + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.pgsql.test e2e.sqlite.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.sqlite.test -tags '$(TEST_TAGS)' + $(GOTEST) $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.sqlite.test -tags '$(TEST_TAGS)' .PHONY: check check: test From 5bf0af1aaf0e8ffc521b0992bb6560da6739c658 Mon Sep 17 00:00:00 2001 From: Otto Richter Date: Wed, 11 Sep 2024 20:45:14 +0200 Subject: [PATCH 003/443] tests(e2e): Refactor branch protection test - ensuring the afterEach hook runs should reduce flakiness and allow retries - the hook cleans up a rule if it exists or does nothing if not --- tests/e2e/repo-settings.test.e2e.js | 45 +++++++++++++++++------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/tests/e2e/repo-settings.test.e2e.js b/tests/e2e/repo-settings.test.e2e.js index b7b0884b26..3ec57a8a3c 100644 --- a/tests/e2e/repo-settings.test.e2e.js +++ b/tests/e2e/repo-settings.test.e2e.js @@ -25,24 +25,33 @@ test('repo webhook settings', async ({browser}, workerInfo) => { await expect(page.locator('.hide-unless-checked')).toBeHidden(); }); -test('repo branch protection settings', async ({browser}, workerInfo) => { - test.skip(workerInfo.project.name === 'Mobile Safari', 'Cannot get it to work - as usual'); - const page = await login({browser}, workerInfo); - const response = await page.goto('/user2/repo1/settings/branches/edit'); - await expect(response?.status()).toBe(200); +test.describe('repo branch protection settings', () => { + test('form', async ({browser}, workerInfo) => { + test.skip(workerInfo.project.name === 'Mobile Safari', 'Cannot get it to work - as usual'); + const page = await login({browser}, workerInfo); + const response = await page.goto('/user2/repo1/settings/branches/edit'); + await expect(response?.status()).toBe(200); - await validate_form({page}, 'fieldset'); + await validate_form({page}, 'fieldset'); - // verify header is new - await expect(page.locator('h4')).toContainText('new'); - await page.locator('input[name="rule_name"]').fill('testrule'); - await page.getByText('Save rule').click(); - // verify header is in edit mode - await page.waitForLoadState('networkidle'); - await page.getByText('Edit').click(); - await expect(page.locator('h4')).toContainText('Protection rules for branch'); - // delete the rule for the next test - await page.goBack(); - await page.getByText('Delete rule').click(); - await page.getByText('Yes').click(); + // verify header is new + await expect(page.locator('h4')).toContainText('new'); + await page.locator('input[name="rule_name"]').fill('testrule'); + await page.getByText('Save rule').click(); + // verify header is in edit mode + await page.waitForLoadState('domcontentloaded'); + await page.getByText('Edit').click(); + await expect(page.locator('h4')).toContainText('Protection rules for branch'); + }); + + test.afterEach(async ({browser}, workerInfo) => { + const page = await login({browser}, workerInfo); + // delete the rule for the next test + await page.goto('/user2/repo1/settings/branches/'); + await page.waitForLoadState('domcontentloaded'); + test.skip(await page.getByText('Delete rule').isHidden(), 'Nothing to delete at this time'); + await page.getByText('Delete rule').click(); + await page.getByText('Yes').click(); + await page.waitForLoadState('load'); + }); }); From 6d6116857ca4d8167d2d4e34f65d96bc23cf6bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Piliszek?= Date: Mon, 12 Aug 2024 20:57:42 +0200 Subject: [PATCH 004/443] git-grep: support regexp --- modules/git/grep.go | 19 +++++++++++-- modules/git/grep_test.go | 31 +++++++++++++++++++++ routers/web/repo/search.go | 57 ++++++++++++++++++++++++++++++++++---- services/wiki/wiki.go | 2 +- 4 files changed, 99 insertions(+), 10 deletions(-) diff --git a/modules/git/grep.go b/modules/git/grep.go index 5572bd994f..1e34f0275c 100644 --- a/modules/git/grep.go +++ b/modules/git/grep.go @@ -27,12 +27,20 @@ type GrepResult struct { HighlightedRanges [][3]int } +type grepMode int + +const ( + FixedGrepMode grepMode = iota + FixedAnyGrepMode + RegExpGrepMode +) + type GrepOptions struct { RefName string MaxResultLimit int MatchesPerFile int ContextLineNumber int - IsFuzzy bool + Mode grepMode PathSpec []setting.Glob } @@ -75,11 +83,16 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO // -I skips binary files cmd := NewCommand(ctx, "grep", "-I", "--null", "--break", "--heading", "--column", - "--fixed-strings", "--line-number", "--ignore-case", "--full-name") + "--line-number", "--ignore-case", "--full-name") + if opts.Mode == RegExpGrepMode { + cmd.AddArguments("--perl-regexp") + } else { + cmd.AddArguments("--fixed-strings") + } cmd.AddOptionValues("--context", fmt.Sprint(opts.ContextLineNumber)) cmd.AddOptionValues("--max-count", fmt.Sprint(opts.MatchesPerFile)) words := []string{search} - if opts.IsFuzzy { + if opts.Mode == FixedAnyGrepMode { words = strings.Fields(search) } for _, word := range words { diff --git a/modules/git/grep_test.go b/modules/git/grep_test.go index 3ba7a6efcb..835f441b19 100644 --- a/modules/git/grep_test.go +++ b/modules/git/grep_test.go @@ -201,3 +201,34 @@ func TestGrepRefs(t *testing.T) { assert.Len(t, res, 1) assert.Equal(t, "A", res[0].LineCodes[0]) } + +func TestGrepCanHazRegexOnDemand(t *testing.T) { + tmpDir := t.TempDir() + + err := InitRepository(DefaultContext, tmpDir, false, Sha1ObjectFormat.Name()) + require.NoError(t, err) + + gitRepo, err := openRepositoryWithDefaultContext(tmpDir) + require.NoError(t, err) + defer gitRepo.Close() + + require.NoError(t, os.WriteFile(path.Join(tmpDir, "matching"), []byte("It's a match!"), 0o666)) + require.NoError(t, os.WriteFile(path.Join(tmpDir, "not-matching"), []byte("Orisitamatch?"), 0o666)) + + err = AddChanges(tmpDir, true) + require.NoError(t, err) + + err = CommitChanges(tmpDir, CommitChangesOptions{Message: "Add fixtures for regexp test"}) + require.NoError(t, err) + + // should find nothing by default... + res, err := GrepSearch(context.Background(), gitRepo, "\\bmatch\\b", GrepOptions{}) + require.NoError(t, err) + assert.Empty(t, res) + + // ... unless configured explicitly + res, err = GrepSearch(context.Background(), gitRepo, "\\bmatch\\b", GrepOptions{Mode: RegExpGrepMode}) + require.NoError(t, err) + assert.Len(t, res, 1) + assert.Equal(t, "matching", res[0].Filename) +} diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go index c4f9f9afd1..9a033c0f1b 100644 --- a/routers/web/repo/search.go +++ b/routers/web/repo/search.go @@ -17,16 +17,55 @@ import ( const tplSearch base.TplName = "repo/search" +type searchMode int + +const ( + ExactSearchMode searchMode = iota + FuzzySearchMode + RegExpSearchMode +) + +func searchModeFromString(s string) searchMode { + switch s { + case "fuzzy": + return FuzzySearchMode + case "regexp": + return RegExpSearchMode + default: + return ExactSearchMode + } +} + +func (m searchMode) String() string { + switch m { + case ExactSearchMode: + return "exact" + case FuzzySearchMode: + return "fuzzy" + case RegExpSearchMode: + return "regexp" + default: + panic("cannot happen") + } +} + // Search render repository search page func Search(ctx *context.Context) { language := ctx.FormTrim("l") keyword := ctx.FormTrim("q") - isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) + mode := ExactSearchMode + if modeStr := ctx.FormString("mode"); len(modeStr) > 0 { + mode = searchModeFromString(modeStr) + } else if ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) { // for backward compatibility in links + mode = FuzzySearchMode + } ctx.Data["Keyword"] = keyword ctx.Data["Language"] = language - ctx.Data["IsFuzzy"] = isFuzzy + ctx.Data["IsFuzzy"] = mode == FuzzySearchMode + ctx.Data["IsRegExp"] = mode == RegExpSearchMode + ctx.Data["SearchMode"] = mode.String() ctx.Data["PageIsViewCode"] = true if keyword == "" { @@ -47,7 +86,7 @@ func Search(ctx *context.Context) { total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{ RepoIDs: []int64{ctx.Repo.Repository.ID}, Keyword: keyword, - IsKeywordFuzzy: isFuzzy, + IsKeywordFuzzy: mode == FuzzySearchMode, Language: language, Paginator: &db.ListOptions{ Page: page, @@ -64,11 +103,17 @@ func Search(ctx *context.Context) { ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx) } } else { - res, err := git.GrepSearch(ctx, ctx.Repo.GitRepo, keyword, git.GrepOptions{ + grepOpt := git.GrepOptions{ ContextLineNumber: 1, - IsFuzzy: isFuzzy, RefName: ctx.Repo.RefName, - }) + } + switch mode { + case FuzzySearchMode: + grepOpt.Mode = git.FixedAnyGrepMode + case RegExpSearchMode: + grepOpt.Mode = git.RegExpGrepMode + } + res, err := git.GrepSearch(ctx, ctx.Repo.GitRepo, keyword, grepOpt) if err != nil { ctx.ServerError("GrepSearch", err) return diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go index 24779d41e0..e1b37d1e7f 100644 --- a/services/wiki/wiki.go +++ b/services/wiki/wiki.go @@ -417,7 +417,7 @@ func SearchWikiContents(ctx context.Context, repo *repo_model.Repository, keywor return git.GrepSearch(ctx, gitRepo, keyword, git.GrepOptions{ ContextLineNumber: 0, - IsFuzzy: true, + Mode: git.FixedAnyGrepMode, RefName: repo.GetWikiBranchName(), MaxResultLimit: 10, MatchesPerFile: 3, From 663e957d3d83a760e03d14c12d53c3aefa97d20e Mon Sep 17 00:00:00 2001 From: Shiny Nematoda Date: Fri, 16 Aug 2024 13:23:25 +0000 Subject: [PATCH 005/443] ui(git-grep): expose regexp mode in dropdown --- modules/git/grep.go | 4 ++-- options/locale/locale_en-US.ini | 2 ++ routers/web/explore/code.go | 13 ++++++++++++- routers/web/repo/search.go | 7 +++++-- routers/web/user/code.go | 13 ++++++++++++- templates/shared/search/code/search.tmpl | 7 ++++--- templates/shared/search/combo_multi.tmpl | 24 ++++++++++++++++++++++++ templates/shared/search/fuzzy.tmpl | 16 +++++----------- 8 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 templates/shared/search/combo_multi.tmpl diff --git a/modules/git/grep.go b/modules/git/grep.go index 1e34f0275c..3aa1442d29 100644 --- a/modules/git/grep.go +++ b/modules/git/grep.go @@ -82,12 +82,12 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO var results []*GrepResult // -I skips binary files cmd := NewCommand(ctx, "grep", - "-I", "--null", "--break", "--heading", "--column", + "-I", "--null", "--break", "--heading", "--line-number", "--ignore-case", "--full-name") if opts.Mode == RegExpGrepMode { cmd.AddArguments("--perl-regexp") } else { - cmd.AddArguments("--fixed-strings") + cmd.AddArguments("--fixed-strings", "--column") } cmd.AddOptionValues("--context", fmt.Sprint(opts.ContextLineNumber)) cmd.AddOptionValues("--max-count", fmt.Sprint(opts.MatchesPerFile)) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1631c90ba2..625f85fac3 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -173,6 +173,8 @@ union = Union union_tooltip = Include results that match any of the whitespace seperated keywords exact = Exact exact_tooltip = Include only results that match the exact search term +regexp = RegExp +regexp_tooltip = Include results that match the regular expression repo_kind = Search repos... user_kind = Search users... org_kind = Search orgs... diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go index f61b832572..4db41fd726 100644 --- a/routers/web/explore/code.go +++ b/routers/web/explore/code.go @@ -35,11 +35,22 @@ func Code(ctx *context.Context) { language := ctx.FormTrim("l") keyword := ctx.FormTrim("q") - isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) + isFuzzy := true + if mode := ctx.FormTrim("mode"); len(mode) > 0 { + isFuzzy = mode == "fuzzy" + } else { + isFuzzy = ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) + } ctx.Data["Keyword"] = keyword ctx.Data["Language"] = language + ctx.Data["CodeSearchOptions"] = []string{"exact", "fuzzy"} ctx.Data["IsFuzzy"] = isFuzzy + if isFuzzy { + ctx.Data["CodeSearchMode"] = "fuzzy" + } else { + ctx.Data["CodeSearchMode"] = "exact" + } ctx.Data["PageIsViewCode"] = true if keyword == "" { diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go index 9a033c0f1b..724bb82612 100644 --- a/routers/web/repo/search.go +++ b/routers/web/repo/search.go @@ -27,7 +27,7 @@ const ( func searchModeFromString(s string) searchMode { switch s { - case "fuzzy": + case "fuzzy", "union": return FuzzySearchMode case "regexp": return RegExpSearchMode @@ -65,7 +65,7 @@ func Search(ctx *context.Context) { ctx.Data["Language"] = language ctx.Data["IsFuzzy"] = mode == FuzzySearchMode ctx.Data["IsRegExp"] = mode == RegExpSearchMode - ctx.Data["SearchMode"] = mode.String() + ctx.Data["CodeSearchMode"] = mode.String() ctx.Data["PageIsViewCode"] = true if keyword == "" { @@ -102,6 +102,7 @@ func Search(ctx *context.Context) { } else { ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx) } + ctx.Data["CodeSearchOptions"] = []string{"exact", "fuzzy"} } else { grepOpt := git.GrepOptions{ ContextLineNumber: 1, @@ -110,6 +111,7 @@ func Search(ctx *context.Context) { switch mode { case FuzzySearchMode: grepOpt.Mode = git.FixedAnyGrepMode + ctx.Data["CodeSearchMode"] = "union" case RegExpSearchMode: grepOpt.Mode = git.RegExpGrepMode } @@ -133,6 +135,7 @@ func Search(ctx *context.Context) { Lines: code_indexer.HighlightSearchResultCode(r.Filename, r.LineNumbers, r.HighlightedRanges, strings.Join(r.LineCodes, "\n")), }) } + ctx.Data["CodeSearchOptions"] = []string{"exact", "union", "regexp"} } ctx.Data["CodeIndexerDisabled"] = !setting.Indexer.RepoIndexerEnabled diff --git a/routers/web/user/code.go b/routers/web/user/code.go index e2e8f25661..9e8614cb04 100644 --- a/routers/web/user/code.go +++ b/routers/web/user/code.go @@ -40,11 +40,22 @@ func CodeSearch(ctx *context.Context) { language := ctx.FormTrim("l") keyword := ctx.FormTrim("q") - isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) + isFuzzy := true + if mode := ctx.FormTrim("mode"); len(mode) > 0 { + isFuzzy = mode == "fuzzy" + } else { + isFuzzy = ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) + } ctx.Data["Keyword"] = keyword ctx.Data["Language"] = language + ctx.Data["CodeSearchOptions"] = []string{"exact", "fuzzy"} ctx.Data["IsFuzzy"] = isFuzzy + if isFuzzy { + ctx.Data["CodeSearchMode"] = "fuzzy" + } else { + ctx.Data["CodeSearchMode"] = "exact" + } ctx.Data["IsCodePage"] = true if keyword == "" { diff --git a/templates/shared/search/code/search.tmpl b/templates/shared/search/code/search.tmpl index 6a52bb9462..b81c6c8f36 100644 --- a/templates/shared/search/code/search.tmpl +++ b/templates/shared/search/code/search.tmpl @@ -1,11 +1,12 @@
- {{template "shared/search/combo_fuzzy" + {{template "shared/search/combo_multi" dict "Value" .Keyword "Disabled" .CodeIndexerUnavailable - "IsFuzzy" .IsFuzzy "Placeholder" (ctx.Locale.Tr "search.code_kind") - "CodeIndexerDisabled" $.CodeIndexerDisabled}} + "CodeIndexerDisabled" $.CodeIndexerDisabled + "Selected" $.CodeSearchMode + "Options" $.CodeSearchOptions}}
diff --git a/templates/shared/search/combo_multi.tmpl b/templates/shared/search/combo_multi.tmpl new file mode 100644 index 0000000000..23c4b4d406 --- /dev/null +++ b/templates/shared/search/combo_multi.tmpl @@ -0,0 +1,24 @@ +{{/* Value - value of the search field (for search results page) */}} +{{/* Disabled (optional) - if search field/button has to be disabled */}} +{{/* Placeholder (optional) - placeholder text to be used */}} +{{/* Selected - the currently selected option */}} +{{/* Options - options available to choose from */}} +{{/* Tooltip (optional) - a tooltip to be displayed on button hover */}} +
+ {{template "shared/search/input" dict "Value" .Value "Disabled" .Disabled "Placeholder" .Placeholder}} + + {{template "shared/search/button" dict "Disabled" .Disabled "Tooltip" .Tooltip}} +
diff --git a/templates/shared/search/fuzzy.tmpl b/templates/shared/search/fuzzy.tmpl index 25cfc5762c..f0344c32b7 100644 --- a/templates/shared/search/fuzzy.tmpl +++ b/templates/shared/search/fuzzy.tmpl @@ -1,21 +1,15 @@ {{/* Disabled (optional) - if dropdown has to be disabled */}} {{/* IsFuzzy - state of the fuzzy search toggle */}} - {{else if eq .Type 11}} @@ -339,10 +339,11 @@ {{svg "octicon-plus"}} + {{$strTitle := RenderRefIssueTitle $.Context .DependentIssue.Title}} {{if eq .DependentIssue.RepoID .Issue.RepoID}} - #{{.DependentIssue.Index}} {{.DependentIssue.Title}} + #{{.DependentIssue.Index}} {{$strTitle}} {{else}} - {{.DependentIssue.Repo.FullName}}#{{.DependentIssue.Index}} - {{.DependentIssue.Title}} + {{.DependentIssue.Repo.FullName}}#{{.DependentIssue.Index}} - {{$strTitle}} {{end}} @@ -362,10 +363,11 @@ {{svg "octicon-trash"}} + {{$strTitle := RenderRefIssueTitle $.Context .DependentIssue.Title}} {{if eq .DependentIssue.RepoID .Issue.RepoID}} - #{{.DependentIssue.Index}} {{.DependentIssue.Title}} + #{{.DependentIssue.Index}} {{$strTitle}} {{else}} - {{.DependentIssue.Repo.FullName}}#{{.DependentIssue.Index}} - {{.DependentIssue.Title}} + {{.DependentIssue.Repo.FullName}}#{{.DependentIssue.Index}} - {{$strTitle}} {{end}} diff --git a/templates/repo/issue/view_content/sidebar/dependencies.tmpl b/templates/repo/issue/view_content/sidebar/dependencies.tmpl index 791bd5c4a1..6a9b651e7d 100644 --- a/templates/repo/issue/view_content/sidebar/dependencies.tmpl +++ b/templates/repo/issue/view_content/sidebar/dependencies.tmpl @@ -19,8 +19,8 @@ {{range .BlockingDependencies}}
- - #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}} + + #{{.Issue.Index}} {{RenderRefIssueTitle $.Context .Issue.Title}}}
{{.Repository.OwnerName}}/{{.Repository.Name}} @@ -51,8 +51,9 @@ {{range .BlockedByDependencies}}
- - #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}} + {{$title := RenderRefIssueTitle $.Context .Issue.Title}} + + #{{.Issue.Index}} {{RenderRefIssueTitle $.Context .Issue.Title}}
{{.Repository.OwnerName}}/{{.Repository.Name}} @@ -73,8 +74,8 @@
{{svg "octicon-lock" 16}} - - #{{.Issue.Index}} {{.Issue.Title | RenderEmoji $.Context}} + + #{{.Issue.Index}} {{RenderRefIssueTitle $.Context .DependentIssue.Title}}
diff --git a/templates/repo/issue/view_title.tmpl b/templates/repo/issue/view_title.tmpl index db21adae2c..f60d958a1c 100644 --- a/templates/repo/issue/view_title.tmpl +++ b/templates/repo/issue/view_title.tmpl @@ -7,8 +7,7 @@ {{$canEditIssueTitle := and (or .HasIssuesOrPullsWritePermission .IsIssuePoster) (not .Repository.IsArchived)}}

- {{RenderIssueTitle $.Context .Issue.Title ($.Repository.ComposeMetas ctx) | RenderCodeBlock}} - #{{.Issue.Index}} + {{RenderIssueTitle $.Context .Issue.Title ($.Repository.ComposeMetas ctx)}} #{{.Issue.Index}}

{{if $canEditIssueTitle}} diff --git a/templates/repo/pulse.tmpl b/templates/repo/pulse.tmpl index 0494883a85..3554cf6a19 100644 --- a/templates/repo/pulse.tmpl +++ b/templates/repo/pulse.tmpl @@ -153,7 +153,7 @@ {{range .Activity.MergedPRs}}

{{ctx.Locale.Tr "repo.activity.merged_prs_label"}} - #{{.Index}} {{.Issue.Title | RenderEmoji $.Context | RenderCodeBlock}} + #{{.Index}} {{RenderRefIssueTitle $.Context .Issue.Title}} {{TimeSinceUnix .MergedUnix ctx.Locale}}

{{end}} @@ -172,7 +172,7 @@ {{range .Activity.OpenedPRs}}

{{ctx.Locale.Tr "repo.activity.opened_prs_label"}} - #{{.Index}} {{.Issue.Title | RenderEmoji $.Context | RenderCodeBlock}} + #{{.Index}} {{RenderRefIssueTitle $.Context .Issue.Title}} {{TimeSinceUnix .Issue.CreatedUnix ctx.Locale}}

{{end}} @@ -191,7 +191,7 @@ {{range .Activity.ClosedIssues}}

{{ctx.Locale.Tr "repo.activity.closed_issue_label"}} - #{{.Index}} {{.Title | RenderEmoji $.Context | RenderCodeBlock}} + #{{.Index}} {{RenderRefIssueTitle $.Context .Title}} {{TimeSinceUnix .ClosedUnix ctx.Locale}}

{{end}} @@ -210,7 +210,7 @@ {{range .Activity.OpenedIssues}}

{{ctx.Locale.Tr "repo.activity.new_issue_label"}} - #{{.Index}} {{.Title | RenderEmoji $.Context | RenderCodeBlock}} + #{{.Index}} {{RenderRefIssueTitle $.Context .Title}} {{TimeSinceUnix .CreatedUnix ctx.Locale}}

{{end}} @@ -228,9 +228,9 @@ {{ctx.Locale.Tr "repo.activity.unresolved_conv_label"}} #{{.Index}} {{if .IsPull}} - {{.Title | RenderEmoji $.Context | RenderCodeBlock}} + {{RenderRefIssueTitle $.Context .Title}} {{else}} - {{.Title | RenderEmoji $.Context | RenderCodeBlock}} + {{RenderRefIssueTitle $.Context .Title}} {{end}} {{TimeSinceUnix .UpdatedUnix ctx.Locale}}

diff --git a/templates/user/notification/notification_div.tmpl b/templates/user/notification/notification_div.tmpl index 4329ffdb7a..5c27ba8b41 100644 --- a/templates/user/notification/notification_div.tmpl +++ b/templates/user/notification/notification_div.tmpl @@ -58,7 +58,7 @@
{{if .Issue}} - {{.Issue.Title | RenderEmoji $.Context | RenderCodeBlock}} + {{RenderRefIssueTitle $.Context .Issue.Title}} {{else}} {{.Repository.FullName}} {{end}} diff --git a/tests/integration/repo_issue_title_test.go b/tests/integration/repo_issue_title_test.go new file mode 100644 index 0000000000..5199be91bc --- /dev/null +++ b/tests/integration/repo_issue_title_test.go @@ -0,0 +1,162 @@ +// Copyright 2024 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package integration + +import ( + "net/http" + "net/url" + "strings" + "testing" + "time" + + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" + issue_service "code.gitea.io/gitea/services/issue" + pull_service "code.gitea.io/gitea/services/pull" + files_service "code.gitea.io/gitea/services/repository/files" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestIssueTitles(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + repo, _, f := tests.CreateDeclarativeRepo(t, user, "issue-titles", nil, nil, nil) + defer f() + + session := loginUser(t, user.LoginName) + + title := "Title :+1: `code`" + issue1 := createIssue(t, user, repo, title, "Test issue") + issue2 := createIssue(t, user, repo, title, "Ref #1") + + titleHTML := []string{ + "Title", + `👍`, + `code`, + } + + t.Run("Main issue title", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + html := extractHTML(t, session, issue1, "div.issue-title-header > * > h1") + assertContainsAll(t, titleHTML, html) + }) + + t.Run("Referenced issue comment", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + html := extractHTML(t, session, issue1, "div.timeline > div.timeline-item:nth-child(3) > div.detail > * > a") + assertContainsAll(t, titleHTML, html) + }) + + t.Run("Dependent issue comment", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + err := issues_model.CreateIssueDependency(db.DefaultContext, user, issue1, issue2) + require.NoError(t, err) + + html := extractHTML(t, session, issue1, "div.timeline > div:nth-child(3) > div.detail > * > a") + assertContainsAll(t, titleHTML, html) + }) + + t.Run("Dependent issue sidebar", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + html := extractHTML(t, session, issue1, "div.item.dependency > * > a.title") + assertContainsAll(t, titleHTML, html) + }) + + t.Run("Referenced pull comment", func(t *testing.T) { + _, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, user, &files_service.ChangeRepoFilesOptions{ + Files: []*files_service.ChangeRepoFile{ + { + Operation: "update", + TreePath: "README.md", + ContentReader: strings.NewReader("Update README"), + }, + }, + Message: "Update README", + OldBranch: "main", + NewBranch: "branch", + Author: &files_service.IdentityOptions{ + Name: user.Name, + Email: user.Email, + }, + Committer: &files_service.IdentityOptions{ + Name: user.Name, + Email: user.Email, + }, + Dates: &files_service.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }) + + require.NoError(t, err) + + pullIssue := &issues_model.Issue{ + RepoID: repo.ID, + Title: title, + Content: "Closes #1", + PosterID: user.ID, + Poster: user, + IsPull: true, + } + + pullRequest := &issues_model.PullRequest{ + HeadRepoID: repo.ID, + BaseRepoID: repo.ID, + HeadBranch: "branch", + BaseBranch: "main", + HeadRepo: repo, + BaseRepo: repo, + Type: issues_model.PullRequestGitea, + } + + err = pull_service.NewPullRequest(git.DefaultContext, repo, pullIssue, nil, nil, pullRequest, nil) + require.NoError(t, err) + + html := extractHTML(t, session, issue1, "div.timeline > div:nth-child(4) > div.detail > * > a") + assertContainsAll(t, titleHTML, html) + }) + }) +} + +func createIssue(t *testing.T, user *user_model.User, repo *repo_model.Repository, title, content string) *issues_model.Issue { + issue := &issues_model.Issue{ + RepoID: repo.ID, + Title: title, + Content: content, + PosterID: user.ID, + Poster: user, + } + + err := issue_service.NewIssue(db.DefaultContext, repo, issue, nil, nil, nil) + require.NoError(t, err) + + return issue +} + +func extractHTML(t *testing.T, session *TestSession, issue *issues_model.Issue, query string) string { + req := NewRequest(t, "GET", issue.HTMLURL()) + resp := session.MakeRequest(t, req, http.StatusOK) + doc := NewHTMLParser(t, resp.Body) + res, err := doc.doc.Find(query).Html() + require.NoError(t, err) + + return res +} + +func assertContainsAll(t *testing.T, expected []string, actual string) { + for i := range expected { + assert.Contains(t, actual, expected[i]) + } +} diff --git a/vitest.config.js b/vitest.config.js index ea0fafeee8..776247c5ee 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -1,6 +1,7 @@ import {defineConfig} from 'vitest/config'; import vuePlugin from '@vitejs/plugin-vue'; import {stringPlugin} from 'vite-string-plugin'; +import {resolve} from 'node:path'; export default defineConfig({ test: { @@ -13,6 +14,9 @@ export default defineConfig({ passWithNoTests: true, globals: true, watch: false, + alias: { + 'monaco-editor': resolve(import.meta.dirname, '/node_modules/monaco-editor/esm/vs/editor/editor.api'), + }, }, plugins: [ stringPlugin(), diff --git a/web_src/js/features/repo-issue.js b/web_src/js/features/repo-issue.js index ff8faa94f6..feba449c16 100644 --- a/web_src/js/features/repo-issue.js +++ b/web_src/js/features/repo-issue.js @@ -8,6 +8,7 @@ import {toAbsoluteUrl} from '../utils.js'; import {initDropzone} from './common-global.js'; import {POST, GET} from '../modules/fetch.js'; import {showErrorToast} from '../modules/toast.js'; +import {emojiHTML} from './emoji.js'; const {appSubUrl} = window.config; @@ -124,7 +125,7 @@ export function initRepoIssueSidebarList() { return; } filteredResponse.results.push({ - name: `#${issue.number} ${htmlEscape(issue.title) + name: `#${issue.number} ${issueTitleHTML(htmlEscape(issue.title)) }
${htmlEscape(issue.repository.full_name)}
`, value: issue.id, }); @@ -731,3 +732,9 @@ export function initArchivedLabelHandler() { toggleElem(label, label.classList.contains('checked')); } } + +// Render the issue's title. It converts emojis and code blocks syntax into their respective HTML equivalent. +export function issueTitleHTML(title) { + return title.replaceAll(/:[-+\w]+:/g, (emoji) => emojiHTML(emoji.substring(1, emoji.length - 1))) + .replaceAll(/`[^`]+`/g, (code) => `${code.substring(1, code.length - 1)}`); +} diff --git a/web_src/js/features/repo-issue.test.js b/web_src/js/features/repo-issue.test.js new file mode 100644 index 0000000000..8c9734b0c6 --- /dev/null +++ b/web_src/js/features/repo-issue.test.js @@ -0,0 +1,24 @@ +import {vi} from 'vitest'; + +import {issueTitleHTML} from './repo-issue.js'; + +// monaco-editor does not have any exports fields, which trips up vitest +vi.mock('./comp/ComboMarkdownEditor.js', () => ({})); +// jQuery is missing +vi.mock('./common-global.js', () => ({})); + +test('Convert issue title to html', () => { + expect(issueTitleHTML('')).toEqual(''); + expect(issueTitleHTML('issue title')).toEqual('issue title'); + + const expected_thumbs_up = `👍`; + expect(issueTitleHTML(':+1:')).toEqual(expected_thumbs_up); + expect(issueTitleHTML(':invalid emoji:')).toEqual(':invalid emoji:'); + + const expected_code_block = `code`; + expect(issueTitleHTML('`code`')).toEqual(expected_code_block); + expect(issueTitleHTML('`invalid code')).toEqual('`invalid code'); + expect(issueTitleHTML('invalid code`')).toEqual('invalid code`'); + + expect(issueTitleHTML('issue title :+1: `code`')).toEqual(`issue title ${expected_thumbs_up} ${expected_code_block}`); +}); From dc9a268d3c23d19e42fabd936c9846828f94a6e4 Mon Sep 17 00:00:00 2001 From: Otto Richter Date: Sun, 22 Sep 2024 21:21:54 +0200 Subject: [PATCH 018/443] i18n: UX improvements: Team permissions and issue closing Change word order for issue comment actions - An attempt to address https://codeberg.org/forgejo/forgejo/issues/2650 Org team permissions improvements - consistency: added missing dot - clarity: explain what external units mean - use dedicated keys to explain the permissions. - split in read/write permissions - use explicit labels for accessibility - ext_wiki.desc and ext_issues.desc are no longer in use. --- models/unit/unit.go | 11 +++++++++++ options/locale/locale_en-US.ini | 32 +++++++++++++++++++++++++------- templates/org/team/new.tmpl | 17 +++++++++-------- tests/e2e/shared/forms.js | 14 ++++++++++++++ 4 files changed, 59 insertions(+), 15 deletions(-) diff --git a/models/unit/unit.go b/models/unit/unit.go index 3beee6a572..5a8b9114f2 100644 --- a/models/unit/unit.go +++ b/models/unit/unit.go @@ -245,6 +245,7 @@ func (u *Type) CanBeDefault() bool { // Unit is a section of one repository type Unit struct { Type Type + Name string NameKey string URI string DescKey string @@ -272,6 +273,7 @@ func (u Unit) MaxPerm() perm.AccessMode { var ( UnitCode = Unit{ TypeCode, + "code", "repo.code", "/", "repo.code.desc", @@ -281,6 +283,7 @@ var ( UnitIssues = Unit{ TypeIssues, + "issues", "repo.issues", "/issues", "repo.issues.desc", @@ -290,6 +293,7 @@ var ( UnitExternalTracker = Unit{ TypeExternalTracker, + "ext_issues", "repo.ext_issues", "/issues", "repo.ext_issues.desc", @@ -299,6 +303,7 @@ var ( UnitPullRequests = Unit{ TypePullRequests, + "pulls", "repo.pulls", "/pulls", "repo.pulls.desc", @@ -308,6 +313,7 @@ var ( UnitReleases = Unit{ TypeReleases, + "releases", "repo.releases", "/releases", "repo.releases.desc", @@ -317,6 +323,7 @@ var ( UnitWiki = Unit{ TypeWiki, + "wiki", "repo.wiki", "/wiki", "repo.wiki.desc", @@ -326,6 +333,7 @@ var ( UnitExternalWiki = Unit{ TypeExternalWiki, + "ext_wiki", "repo.ext_wiki", "/wiki", "repo.ext_wiki.desc", @@ -335,6 +343,7 @@ var ( UnitProjects = Unit{ TypeProjects, + "projects", "repo.projects", "/projects", "repo.projects.desc", @@ -344,6 +353,7 @@ var ( UnitPackages = Unit{ TypePackages, + "packages", "repo.packages", "/packages", "packages.desc", @@ -353,6 +363,7 @@ var ( UnitActions = Unit{ TypeActions, + "actions", "repo.actions", "/actions", "actions.unit.desc", diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1631c90ba2..6b732fb121 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1441,8 +1441,7 @@ commitstatus.failure = Failure commitstatus.pending = Pending commitstatus.success = Success -ext_issues = Access to external issues -ext_issues.desc = Link to an external issue tracker. +ext_issues = External issues projects = Projects projects.desc = Manage issues and pulls in project boards. @@ -1619,9 +1618,9 @@ issues.no_content = No description provided. issues.close = Close issue issues.comment_pull_merged_at = merged commit %[1]s into %[2]s %[3]s issues.comment_manually_pull_merged_at = manually merged commit %[1]s into %[2]s %[3]s -issues.close_comment_issue = Comment and close +issues.close_comment_issue = Close with comment issues.reopen_issue = Reopen -issues.reopen_comment_issue = Comment and reopen +issues.reopen_comment_issue = Reopen with comment issues.create_comment = Comment issues.closed_at = `closed this issue %[2]s` issues.reopened_at = `reopened this issue %[2]s` @@ -2025,8 +2024,7 @@ signing.wont_sign.commitssigned = The merge will not be signed as all the associ signing.wont_sign.approved = The merge will not be signed as the PR is not approved. signing.wont_sign.not_signed_in = You are not signed in. -ext_wiki = Access to external Wiki -ext_wiki.desc = Link to an external wiki. +ext_wiki = External Wiki wiki = Wiki wiki.welcome = Welcome to the Wiki. @@ -2766,6 +2764,26 @@ error.csv.unexpected = Can't render this file because it contains an unexpected error.csv.invalid_field_count = Can't render this file because it has a wrong number of fields in line %d. error.broken_git_hook = Git hooks of this repository seem to be broken. Please follow the documentation to fix them, then push some commits to refresh the status. +[repo.permissions] +code.read = Read: Access and clone the code of the repository. +code.write = Write: Push to the repository, create branches and tags. +issues.read = Read: Read and create issues and comments. +issues.write = Write: Close issues and manage metadata like labels, milestones, assignees, due dates and dependencies. +pulls.read = Read: Reading and create pull requests. +pulls.write = Write: Close pull requests and manage metadata like labels, milestones, assignees, due dates and dependencies. +releases.read = Read: View and download releases. +releases.write = Write: Publish, edit and delete releases and their assets. +wiki.read = Read: Read the integrated wiki and it's history. +wiki.write = Write: Create, update and delete pages in the integrated wiki. +projects.read = Read: Access repository project boards. +projects.write = Write: Create projects and columns and edit them. +packages.read = Read: View and download packages assigned to the repository. +packages.write = Write: Publish and delete packages assigned to the repository. +actions.read = Read: View integrated CI/CD pipelines and their logs. +actions.write = Write: Manually trigger, restart, cancel or approve pending CI/CD pipelines. +ext_issues = Access the link to an external issue tracker. The permissions are managed externally. +ext_wiki = Access the link to an external wiki. The permissions are managed externally. + [graphs] component_loading = Loading %s... component_loading_failed = Could not load %s @@ -3733,7 +3751,7 @@ management = Manage secrets [actions] actions = Actions -unit.desc = Manage integrated CI/CD pipelines with Forgejo Actions +unit.desc = Manage integrated CI/CD pipelines with Forgejo Actions. status.unknown = Unknown status.waiting = Waiting diff --git a/templates/org/team/new.tmpl b/templates/org/team/new.tmpl index 1776f5e3ae..ed9cb9893a 100644 --- a/templates/org/team/new.tmpl +++ b/templates/org/team/new.tmpl @@ -65,8 +65,8 @@ {{ctx.Locale.Tr "units.unit"}} {{ctx.Locale.Tr "org.teams.none_access"}} - {{ctx.Locale.Tr "org.teams.read_access"}} - {{ctx.Locale.Tr "org.teams.write_access"}} + {{ctx.Locale.Tr "org.teams.read_access"}} + {{ctx.Locale.Tr "org.teams.write_access"}} @@ -75,25 +75,26 @@ @@ -108,7 +109,7 @@ {{end}} {{end}} diff --git a/tests/e2e/shared/forms.js b/tests/e2e/shared/forms.js index 586dd0ca38..7340dc60ff 100644 --- a/tests/e2e/shared/forms.js +++ b/tests/e2e/shared/forms.js @@ -21,10 +21,24 @@ export async function validate_form({page}, scope) { await expect(b).toHaveCSS('margin-top', '0px'); await expect(b).toHaveCSS('vertical-align', 'baseline'); } + // assert no (trailing) colon is used in labels // might be necessary to adjust in case colons are strictly necessary in help text for (const l of await page.locator('label').all()) { const str = await l.textContent(); await expect(str.split('\n')[0]).not.toContain(':'); } + + // check that multiple help text are correctly aligned to each other + // used for example to separate read/write permissions in team permission matrix + for (const l of await page.locator('label:has(.help + .help)').all()) { + const helpLabels = await l.locator('.help').all(); + const boxes = await Promise.all(helpLabels.map((help) => help.boundingBox())); + for (let i = 1; i < boxes.length; i++) { + // help texts vertically aligned on top of each other + await expect(boxes[i].x).toBe(boxes[0].x); + // help texts don't horizontally intersect each other + await expect(boxes[i].y + boxes[i].height).toBeGreaterThanOrEqual(boxes[i - 1].y + boxes[i - 1].height); + } + } } From c54ebb8bc74e459ad1454da9866bbbaec4f4fde5 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Tue, 24 Sep 2024 22:02:34 +0000 Subject: [PATCH 019/443] Replace dependency eslint-plugin-vitest with @vitest/eslint-plugin 1.0.0 --- package-lock.json | 51 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index f2aea12a85..876e6bef7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,6 +68,7 @@ "@stylistic/stylelint-plugin": "3.0.1", "@vitejs/plugin-vue": "5.1.3", "@vitest/coverage-v8": "2.1.1", + "@vitest/eslint-plugin": "1.0.0", "@vue/test-utils": "2.4.6", "eslint": "8.57.1", "eslint-plugin-array-func": "4.0.0", @@ -79,7 +80,6 @@ "eslint-plugin-regexp": "2.6.0", "eslint-plugin-sonarjs": "2.0.2", "eslint-plugin-unicorn": "55.0.0", - "eslint-plugin-vitest": "0.5.4", "eslint-plugin-vitest-globals": "1.5.0", "eslint-plugin-vue": "9.28.0", "eslint-plugin-vue-scoped-css": "2.8.1", @@ -5149,6 +5149,30 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/@vitest/eslint-plugin": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.0.0.tgz", + "integrity": "sha512-YQSFGYrD+eAa2QqdL8v4WAG3yYhcfW3LGlPdNRcjbF1etX0xUfI4isE+U+tYjQuVVzHG4KccRg1F8UuveFVdfg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@typescript-eslint/utils": ">= 7.8 || 8.0.0", + "eslint": ">= 8.57.0", + "typescript": ">= 5.0.0", + "vitest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/utils": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, "node_modules/@vitest/expect": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.1.tgz", @@ -9311,31 +9335,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-vitest": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.5.4.tgz", - "integrity": "sha512-um+odCkccAHU53WdKAw39MY61+1x990uXjSPguUCq3VcEHdqJrOb8OTMrbYlY6f9jAKx7x98kLVlIe3RJeJqoQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^7.7.1" - }, - "engines": { - "node": "^18.0.0 || >= 20.0.0" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "vitest": "*" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "vitest": { - "optional": true - } - } - }, "node_modules/eslint-plugin-vitest-globals": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/eslint-plugin-vitest-globals/-/eslint-plugin-vitest-globals-1.5.0.tgz", diff --git a/package.json b/package.json index 7a7ed6687c..99e014f057 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "eslint-plugin-regexp": "2.6.0", "eslint-plugin-sonarjs": "2.0.2", "eslint-plugin-unicorn": "55.0.0", - "eslint-plugin-vitest": "0.5.4", + "@vitest/eslint-plugin": "1.0.0", "eslint-plugin-vitest-globals": "1.5.0", "eslint-plugin-vue": "9.28.0", "eslint-plugin-vue-scoped-css": "2.8.1", From a8f141f6d13546f716b9eded84f76c2a89bdd09c Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Wed, 25 Sep 2024 08:34:57 +0200 Subject: [PATCH 020/443] chore: migrate eslint config --- .eslintrc.yaml | 100 ++++++++++++++++++++++++------------------------- package.json | 2 +- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 6600ae189b..db85b143dd 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -13,6 +13,7 @@ parserOptions: plugins: - "@eslint-community/eslint-plugin-eslint-comments" - "@stylistic/eslint-plugin-js" + - "@vitest" - eslint-plugin-array-func - eslint-plugin-github - eslint-plugin-i @@ -21,7 +22,6 @@ plugins: - eslint-plugin-regexp - eslint-plugin-sonarjs - eslint-plugin-unicorn - - eslint-plugin-vitest - eslint-plugin-vitest-globals - eslint-plugin-wc @@ -50,55 +50,55 @@ overrides: env: vitest-globals/env: true rules: - vitest/consistent-test-filename: [0] - vitest/consistent-test-it: [0] - vitest/expect-expect: [0] - vitest/max-expects: [0] - vitest/max-nested-describe: [0] - vitest/no-alias-methods: [0] - vitest/no-commented-out-tests: [0] - vitest/no-conditional-expect: [0] - vitest/no-conditional-in-test: [0] - vitest/no-conditional-tests: [0] - vitest/no-disabled-tests: [0] - vitest/no-done-callback: [0] - vitest/no-duplicate-hooks: [0] - vitest/no-focused-tests: [0] - vitest/no-hooks: [0] - vitest/no-identical-title: [2] - vitest/no-interpolation-in-snapshots: [0] - vitest/no-large-snapshots: [0] - vitest/no-mocks-import: [0] - vitest/no-restricted-matchers: [0] - vitest/no-restricted-vi-methods: [0] - vitest/no-standalone-expect: [0] - vitest/no-test-prefixes: [0] - vitest/no-test-return-statement: [0] - vitest/prefer-called-with: [0] - vitest/prefer-comparison-matcher: [0] - vitest/prefer-each: [0] - vitest/prefer-equality-matcher: [0] - vitest/prefer-expect-resolves: [0] - vitest/prefer-hooks-in-order: [0] - vitest/prefer-hooks-on-top: [2] - vitest/prefer-lowercase-title: [0] - vitest/prefer-mock-promise-shorthand: [0] - vitest/prefer-snapshot-hint: [0] - vitest/prefer-spy-on: [0] - vitest/prefer-strict-equal: [0] - vitest/prefer-to-be: [0] - vitest/prefer-to-be-falsy: [0] - vitest/prefer-to-be-object: [0] - vitest/prefer-to-be-truthy: [0] - vitest/prefer-to-contain: [0] - vitest/prefer-to-have-length: [0] - vitest/prefer-todo: [0] - vitest/require-hook: [0] - vitest/require-to-throw-message: [0] - vitest/require-top-level-describe: [0] - vitest/valid-describe-callback: [2] - vitest/valid-expect: [2] - vitest/valid-title: [2] + "@vitest/consistent-test-filename": [0] + "@vitest/consistent-test-it": [0] + "@vitest/expect-expect": [0] + "@vitest/max-expects": [0] + "@vitest/max-nested-describe": [0] + "@vitest/no-alias-methods": [0] + "@vitest/no-commented-out-tests": [0] + "@vitest/no-conditional-expect": [0] + "@vitest/no-conditional-in-test": [0] + "@vitest/no-conditional-tests": [0] + "@vitest/no-disabled-tests": [0] + "@vitest/no-done-callback": [0] + "@vitest/no-duplicate-hooks": [0] + "@vitest/no-focused-tests": [0] + "@vitest/no-hooks": [0] + "@vitest/no-identical-title": [2] + "@vitest/no-interpolation-in-snapshots": [0] + "@vitest/no-large-snapshots": [0] + "@vitest/no-mocks-import": [0] + "@vitest/no-restricted-matchers": [0] + "@vitest/no-restricted-vi-methods": [0] + "@vitest/no-standalone-expect": [0] + "@vitest/no-test-prefixes": [0] + "@vitest/no-test-return-statement": [0] + "@vitest/prefer-called-with": [0] + "@vitest/prefer-comparison-matcher": [0] + "@vitest/prefer-each": [0] + "@vitest/prefer-equality-matcher": [0] + "@vitest/prefer-expect-resolves": [0] + "@vitest/prefer-hooks-in-order": [0] + "@vitest/prefer-hooks-on-top": [2] + "@vitest/prefer-lowercase-title": [0] + "@vitest/prefer-mock-promise-shorthand": [0] + "@vitest/prefer-snapshot-hint": [0] + "@vitest/prefer-spy-on": [0] + "@vitest/prefer-strict-equal": [0] + "@vitest/prefer-to-be": [0] + "@vitest/prefer-to-be-falsy": [0] + "@vitest/prefer-to-be-object": [0] + "@vitest/prefer-to-be-truthy": [0] + "@vitest/prefer-to-contain": [0] + "@vitest/prefer-to-have-length": [0] + "@vitest/prefer-todo": [0] + "@vitest/require-hook": [0] + "@vitest/require-to-throw-message": [0] + "@vitest/require-top-level-describe": [0] + "@vitest/valid-describe-callback": [2] + "@vitest/valid-expect": [2] + "@vitest/valid-title": [2] - files: ["web_src/js/modules/fetch.js", "web_src/js/standalone/**/*"] rules: no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression] diff --git a/package.json b/package.json index 99e014f057..c22a9af1e2 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "@stylistic/stylelint-plugin": "3.0.1", "@vitejs/plugin-vue": "5.1.3", "@vitest/coverage-v8": "2.1.1", + "@vitest/eslint-plugin": "1.0.0", "@vue/test-utils": "2.4.6", "eslint": "8.57.1", "eslint-plugin-array-func": "4.0.0", @@ -78,7 +79,6 @@ "eslint-plugin-regexp": "2.6.0", "eslint-plugin-sonarjs": "2.0.2", "eslint-plugin-unicorn": "55.0.0", - "@vitest/eslint-plugin": "1.0.0", "eslint-plugin-vitest-globals": "1.5.0", "eslint-plugin-vue": "9.28.0", "eslint-plugin-vue-scoped-css": "2.8.1", From 9f64769b6da33565f0039ca5677420b5942350b8 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Wed, 25 Sep 2024 09:35:53 +0200 Subject: [PATCH 021/443] docs: add link to the v9.0.0 release notes --- RELEASE-NOTES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index f86e10c21a..e05288335f 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -6,6 +6,10 @@ A [patch or minor release](https://semver.org/spec/v2.0.0.html) (e.g. upgrading The release notes of each release [are available in the corresponding milestone](https://codeberg.org/forgejo/forgejo/milestones), starting with [Forgejo 7.0.7](https://codeberg.org/forgejo/forgejo/milestone/7683) and [Forgejo 8.0.1](https://codeberg.org/forgejo/forgejo/milestone/7682). +## 9.0.0 + +The Forgejo v9.0.0 release notes are [available in the v9.0.0 milestone](https://codeberg.org/forgejo/forgejo/milestone/7235). + ## 8.0.3 The Forgejo v8.0.3 release notes are [available in the v8.0.3 milestone](https://codeberg.org/forgejo/forgejo/milestone/8231). From c2797ecfc1d9d2e97b03b29b1ce6550e04d1812c Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 25 Sep 2024 08:03:04 +0000 Subject: [PATCH 022/443] Update dependency vue to v3.5.8 --- package-lock.json | 108 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/package-lock.json b/package-lock.json index 876e6bef7f..d00f0044e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,7 @@ "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", - "vue": "3.5.6", + "vue": "3.5.8", "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", @@ -5325,39 +5325,39 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.6.tgz", - "integrity": "sha512-r+gNu6K4lrvaQLQGmf+1gc41p3FO2OUJyWmNqaIITaJU6YFiV5PtQSFZt8jfztYyARwqhoCayjprC7KMvT3nRA==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.8.tgz", + "integrity": "sha512-Uzlxp91EPjfbpeO5KtC0KnXPkuTfGsNDeaKQJxQN718uz+RqDYarEf7UhQJGK+ZYloD2taUbHTI2J4WrUaZQNA==", "license": "MIT", "dependencies": { "@babel/parser": "^7.25.3", - "@vue/shared": "3.5.6", + "@vue/shared": "3.5.8", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.6.tgz", - "integrity": "sha512-xRXqxDrIqK8v8sSScpistyYH0qYqxakpsIvqMD2e5sV/PXQ1mTwtXp4k42yHK06KXxKSmitop9e45Ui/3BrTEw==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.8.tgz", + "integrity": "sha512-GUNHWvoDSbSa5ZSHT9SnV5WkStWfzJwwTd6NMGzilOE/HM5j+9EB9zGXdtu/fCNEmctBqMs6C9SvVPpVPuk1Eg==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/compiler-core": "3.5.8", + "@vue/shared": "3.5.8" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.6.tgz", - "integrity": "sha512-pjWJ8Kj9TDHlbF5LywjVso+BIxCY5wVOLhkEXRhuCHDxPFIeX1zaFefKs8RYoHvkSMqRWt93a0f2gNJVJixHwg==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.8.tgz", + "integrity": "sha512-taYpngQtSysrvO9GULaOSwcG5q821zCoIQBtQQSx7Uf7DxpR6CIHR90toPr9QfDD2mqHQPCSgoWBvJu0yV9zjg==", "license": "MIT", "dependencies": { "@babel/parser": "^7.25.3", - "@vue/compiler-core": "3.5.6", - "@vue/compiler-dom": "3.5.6", - "@vue/compiler-ssr": "3.5.6", - "@vue/shared": "3.5.6", + "@vue/compiler-core": "3.5.8", + "@vue/compiler-dom": "3.5.8", + "@vue/compiler-ssr": "3.5.8", + "@vue/shared": "3.5.8", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", @@ -5374,63 +5374,63 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.6.tgz", - "integrity": "sha512-VpWbaZrEOCqnmqjE83xdwegtr5qO/2OPUC6veWgvNqTJ3bYysz6vY3VqMuOijubuUYPRpG3OOKIh9TD0Stxb9A==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.8.tgz", + "integrity": "sha512-W96PtryNsNG9u0ZnN5Q5j27Z/feGrFV6zy9q5tzJVyJaLiwYxvC0ek4IXClZygyhjm+XKM7WD9pdKi/wIRVC/Q==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/compiler-dom": "3.5.8", + "@vue/shared": "3.5.8" } }, "node_modules/@vue/reactivity": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.6.tgz", - "integrity": "sha512-shZ+KtBoHna5GyUxWfoFVBCVd7k56m6lGhk5e+J9AKjheHF6yob5eukssHRI+rzvHBiU1sWs/1ZhNbLExc5oYQ==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.8.tgz", + "integrity": "sha512-mlgUyFHLCUZcAYkqvzYnlBRCh0t5ZQfLYit7nukn1GR96gc48Bp4B7OIcSfVSvlG1k3BPfD+p22gi1t2n9tsXg==", "license": "MIT", "dependencies": { - "@vue/shared": "3.5.6" + "@vue/shared": "3.5.8" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.6.tgz", - "integrity": "sha512-FpFULR6+c2lI+m1fIGONLDqPQO34jxV8g6A4wBOgne8eSRHP6PQL27+kWFIx5wNhhjkO7B4rgtsHAmWv7qKvbg==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.8.tgz", + "integrity": "sha512-fJuPelh64agZ8vKkZgp5iCkPaEqFJsYzxLk9vSC0X3G8ppknclNDr61gDc45yBGTaN5Xqc1qZWU3/NoaBMHcjQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/reactivity": "3.5.8", + "@vue/shared": "3.5.8" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.6.tgz", - "integrity": "sha512-SDPseWre45G38ENH2zXRAHL1dw/rr5qp91lS4lt/nHvMr0MhsbCbihGAWLXNB/6VfFOJe2O+RBRkXU+CJF7/sw==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.8.tgz", + "integrity": "sha512-DpAUz+PKjTZPUOB6zJgkxVI3GuYc2iWZiNeeHQUw53kdrparSTG6HeXUrYDjaam8dVsCdvQxDz6ZWxnyjccUjQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.6", - "@vue/runtime-core": "3.5.6", - "@vue/shared": "3.5.6", + "@vue/reactivity": "3.5.8", + "@vue/runtime-core": "3.5.8", + "@vue/shared": "3.5.8", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.6.tgz", - "integrity": "sha512-zivnxQnOnwEXVaT9CstJ64rZFXMS5ZkKxCjDQKiMSvUhXRzFLWZVbaBiNF4HGDqGNNsTgmjcCSmU6TB/0OOxLA==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.8.tgz", + "integrity": "sha512-7AmC9/mEeV9mmXNVyUIm1a1AjUhyeeGNbkLh39J00E7iPeGks8OGRB5blJiMmvqSh8SkaS7jkLWSpXtxUCeagA==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/compiler-ssr": "3.5.8", + "@vue/shared": "3.5.8" }, "peerDependencies": { - "vue": "3.5.6" + "vue": "3.5.8" } }, "node_modules/@vue/shared": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.6.tgz", - "integrity": "sha512-eidH0HInnL39z6wAt6SFIwBrvGOpDWsDxlw3rCgo1B+CQ1781WzQUSU3YjxgdkcJo9Q8S6LmXTkvI+cLHGkQfA==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.8.tgz", + "integrity": "sha512-mJleSWbAGySd2RJdX1RBtcrUBX6snyOc0qHpgk3lGi4l9/P/3ny3ELqFWqYdkXIwwNN/kdm8nD9ky8o6l/Lx2A==", "license": "MIT" }, "node_modules/@vue/test-utils": { @@ -16343,16 +16343,16 @@ "license": "MIT" }, "node_modules/vue": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.6.tgz", - "integrity": "sha512-zv+20E2VIYbcJOzJPUWp03NOGFhMmpCKOfSxVTmCYyYFFko48H9tmuQFzYj7tu4qX1AeXlp9DmhIP89/sSxxhw==", + "version": "3.5.8", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.8.tgz", + "integrity": "sha512-hvuvuCy51nP/1fSRvrrIqTLSvrSyz2Pq+KQ8S8SXCxTWVE0nMaOnSDnSOxV1eYmGfvK7mqiwvd1C59CEEz7dAQ==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.6", - "@vue/compiler-sfc": "3.5.6", - "@vue/runtime-dom": "3.5.6", - "@vue/server-renderer": "3.5.6", - "@vue/shared": "3.5.6" + "@vue/compiler-dom": "3.5.8", + "@vue/compiler-sfc": "3.5.8", + "@vue/runtime-dom": "3.5.8", + "@vue/server-renderer": "3.5.8", + "@vue/shared": "3.5.8" }, "peerDependencies": { "typescript": "*" diff --git a/package.json b/package.json index c22a9af1e2..fd083ea6f4 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", - "vue": "3.5.6", + "vue": "3.5.8", "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", From 69b01eb911b18002d78332125aca2ac3f9d5bea7 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 16 Sep 2024 02:03:29 +0000 Subject: [PATCH 023/443] Lock file maintenance --- package-lock.json | 1614 +++++++++++++--------------- poetry.lock | 191 ++-- web_src/fomantic/package-lock.json | 73 +- 3 files changed, 881 insertions(+), 997 deletions(-) diff --git a/package-lock.json b/package-lock.json index 876e6bef7f..e3d759c01f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -275,13 +275,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.5.tgz", - "integrity": "sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.25.4", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -290,19 +290,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", @@ -347,16 +334,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -622,14 +599,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" @@ -709,12 +686,6 @@ "node": ">=4" } }, - "node_modules/@babel/highlight/node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -728,12 +699,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.4.tgz", - "integrity": "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "license": "MIT", "dependencies": { - "@babel/types": "^7.25.4" + "@babel/types": "^7.25.6" }, "bin": { "parser": "bin/babel-parser.js" @@ -925,13 +896,13 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", - "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.6.tgz", + "integrity": "sha512-aABl0jHw9bZ2karQ/uUD6XP4u0SG22SJrOHFoL6XB1R7dTovOP4TzTlsxOYC5yQ1pdscVK2JTUnF6QL3ARoAiQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -941,13 +912,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -2205,9 +2176,9 @@ "license": "MIT" }, "node_modules/@babel/runtime": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", - "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", + "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -2232,17 +2203,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.4.tgz", - "integrity": "sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.4", - "@babel/parser": "^7.25.4", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", "@babel/template": "^7.25.0", - "@babel/types": "^7.25.4", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2261,9 +2232,9 @@ } }, "node_modules/@babel/types": { - "version": "7.25.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.4.tgz", - "integrity": "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.24.8", @@ -3263,9 +3234,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "license": "MIT", "engines": { "node": ">=12" @@ -3690,9 +3661,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.0.tgz", - "integrity": "sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.3.tgz", + "integrity": "sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==", "cpu": [ "arm" ], @@ -3704,9 +3675,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.0.tgz", - "integrity": "sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.3.tgz", + "integrity": "sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==", "cpu": [ "arm64" ], @@ -3718,9 +3689,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.0.tgz", - "integrity": "sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.3.tgz", + "integrity": "sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==", "cpu": [ "arm64" ], @@ -3732,9 +3703,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.0.tgz", - "integrity": "sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.3.tgz", + "integrity": "sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==", "cpu": [ "x64" ], @@ -3746,9 +3717,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.0.tgz", - "integrity": "sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.3.tgz", + "integrity": "sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==", "cpu": [ "arm" ], @@ -3760,9 +3731,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.0.tgz", - "integrity": "sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.3.tgz", + "integrity": "sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==", "cpu": [ "arm" ], @@ -3774,9 +3745,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.0.tgz", - "integrity": "sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.3.tgz", + "integrity": "sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==", "cpu": [ "arm64" ], @@ -3788,9 +3759,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.0.tgz", - "integrity": "sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.3.tgz", + "integrity": "sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==", "cpu": [ "arm64" ], @@ -3802,9 +3773,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.0.tgz", - "integrity": "sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.3.tgz", + "integrity": "sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==", "cpu": [ "ppc64" ], @@ -3816,9 +3787,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.0.tgz", - "integrity": "sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.3.tgz", + "integrity": "sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==", "cpu": [ "riscv64" ], @@ -3830,9 +3801,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.0.tgz", - "integrity": "sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.3.tgz", + "integrity": "sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==", "cpu": [ "s390x" ], @@ -3844,9 +3815,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.0.tgz", - "integrity": "sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.3.tgz", + "integrity": "sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==", "cpu": [ "x64" ], @@ -3858,9 +3829,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.0.tgz", - "integrity": "sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.3.tgz", + "integrity": "sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==", "cpu": [ "x64" ], @@ -3872,9 +3843,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.0.tgz", - "integrity": "sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.3.tgz", + "integrity": "sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==", "cpu": [ "arm64" ], @@ -3886,9 +3857,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.0.tgz", - "integrity": "sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.3.tgz", + "integrity": "sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==", "cpu": [ "ia32" ], @@ -3900,9 +3871,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.0.tgz", - "integrity": "sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.3.tgz", + "integrity": "sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==", "cpu": [ "x64" ], @@ -3913,6 +3884,13 @@ "win32" ] }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, "node_modules/@stoplight/better-ajv-errors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz", @@ -3931,9 +3909,9 @@ } }, "node_modules/@stoplight/json": { - "version": "3.21.6", - "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.6.tgz", - "integrity": "sha512-KGisXfNigoYdWIj1jA4p3IAAIW5YFpU9BdoECdjyDLBbhWGGHzs77e0STSCBmXQ/K3ApxfED2R7mQ79ymjzlvQ==", + "version": "3.21.7", + "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.7.tgz", + "integrity": "sha512-xcJXgKFqv/uCEgtGlPxy3tPA+4I+ZI4vAuMJ885+ThkTHFVkC+0Fm58lA9NlsyjnkpxFh4YiQWpH+KefHdbA0A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4076,9 +4054,9 @@ } }, "node_modules/@stoplight/spectral-core": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.18.3.tgz", - "integrity": "sha512-YY8x7X2SWJIhGTLPol+eFiQpWPz0D0mJdkK2i4A0QJG68KkNhypP6+JBC7/Kz3XWjqr0L/RqAd+N5cQLPOKZGQ==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.19.1.tgz", + "integrity": "sha512-YiWhXdjyjn4vCl3102ywzwCEJzncxapFcj4dxcj1YP/bZ62DFeGJ8cEaMP164vSw2kI3rX7EMMzI/c8XOUnTfQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4086,12 +4064,12 @@ "@stoplight/json": "~3.21.0", "@stoplight/path": "1.3.2", "@stoplight/spectral-parsers": "^1.0.0", - "@stoplight/spectral-ref-resolver": "^1.0.0", + "@stoplight/spectral-ref-resolver": "^1.0.4", "@stoplight/spectral-runtime": "^1.0.0", "@stoplight/types": "~13.6.0", "@types/es-aggregate-error": "^1.0.2", "@types/json-schema": "^7.0.11", - "ajv": "^8.6.0", + "ajv": "^8.17.1", "ajv-errors": "~3.0.0", "ajv-formats": "~2.1.0", "es-aggregate-error": "^1.0.7", @@ -4163,9 +4141,9 @@ } }, "node_modules/@stoplight/spectral-formatters": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-formatters/-/spectral-formatters-1.3.0.tgz", - "integrity": "sha512-ryuMwlzbPUuyn7ybSEbFYsljYmvTaTyD51wyCQs4ROzgfm3Yo5QDD0IsiJUzUpKK/Ml61ZX8ebgiPiRFEJtBpg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-formatters/-/spectral-formatters-1.4.0.tgz", + "integrity": "sha512-nxYQldDzVg32pxQ4cMX27eMtB1A39ea+GSf0wIJ20mqkSBfIgLnRZ+GKkBxhgF9JzSolc4YtweydsubGQGd7ag==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4173,9 +4151,11 @@ "@stoplight/spectral-core": "^1.15.1", "@stoplight/spectral-runtime": "^1.1.0", "@stoplight/types": "^13.15.0", + "@types/markdown-escape": "^1.1.3", "chalk": "4.1.2", "cliui": "7.0.4", "lodash": "^4.17.21", + "markdown-escape": "^2.0.0", "node-sarif-builder": "^2.0.3", "strip-ansi": "6.0", "text-table": "^0.2.0", @@ -4186,18 +4166,18 @@ } }, "node_modules/@stoplight/spectral-functions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.8.0.tgz", - "integrity": "sha512-ZrAkYA/ZGbuQ6EyG1gisF4yQ5nWP/+glcqVoGmS6kH6ekaynz2Yp6FL0oIamWj3rWedFUN7ppwTRUdo+9f/uCw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.9.0.tgz", + "integrity": "sha512-T+xl93ji8bpus4wUsTq8Qr2DSu2X9PO727rbxW61tTCG0s17CbsXOLYI+Ezjg5P6aaQlgXszGX8khtc57xk8Yw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "^3.17.1", "@stoplight/spectral-core": "^1.7.0", - "@stoplight/spectral-formats": "^1.0.0", + "@stoplight/spectral-formats": "^1.7.0", "@stoplight/spectral-runtime": "^1.1.0", - "ajv": "^8.6.3", + "ajv": "^8.17.1", "ajv-draft-04": "~1.0.0", "ajv-errors": "~3.0.0", "ajv-formats": "~2.1.0", @@ -4333,9 +4313,9 @@ "license": "Apache-2.0" }, "node_modules/@stoplight/spectral-rulesets": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.19.1.tgz", - "integrity": "sha512-rfGK87Y1JJCEeLC8MVdLkjUkRH+Y6VnSF388D+UWihfU9xuq2eNB9phWpTFkG+AG4HLRyGx963BmO6PyM9dBag==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.20.1.tgz", + "integrity": "sha512-LrJ9lm/Jy9uUrPyBVO03zOkRVRVB2EfzrbtMegTiGs6ju02YGH/0mPu0DKJy+749aKGiSjpXTiLZgsbDJniEew==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4343,12 +4323,12 @@ "@stoplight/better-ajv-errors": "1.0.3", "@stoplight/json": "^3.17.0", "@stoplight/spectral-core": "^1.8.1", - "@stoplight/spectral-formats": "^1.5.0", + "@stoplight/spectral-formats": "^1.7.0", "@stoplight/spectral-functions": "^1.5.1", "@stoplight/spectral-runtime": "^1.1.1", "@stoplight/types": "^13.6.0", "@types/json-schema": "^7.0.7", - "ajv": "^8.12.0", + "ajv": "^8.17.1", "ajv-formats": "~2.1.0", "json-schema-traverse": "^1.0.0", "leven": "3.1.0", @@ -4518,19 +4498,6 @@ "@types/node": "*" } }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, "node_modules/@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", @@ -4550,6 +4517,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/markdown-escape": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/markdown-escape/-/markdown-escape-1.1.3.tgz", + "integrity": "sha512-JIc1+s3y5ujKnt/+N+wq6s/QdL2qZ11fP79MijrVXsAAnzSxCbT2j/3prHRouJdZ2yFLN3vkP0HytfnoCczjOw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/marked": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.3.2.tgz", @@ -4557,9 +4531,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.0.tgz", - "integrity": "sha512-49AbMDwYUz7EXxKU/r7mXOsxwFr4BYbvB7tWYxVuLdb2ibd30ijjXINSMAHiEEZk5PCRBmW1gUeisn2VMKt3cQ==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", "license": "MIT", "dependencies": { "undici-types": "~6.19.2" @@ -4596,32 +4570,32 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", - "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.5.0.tgz", + "integrity": "sha512-lHS5hvz33iUFQKuPFGheAB84LwcJ60G8vKnEhnfcK1l8kGVLro2SFYW6K0/tj8FUhRJ0VHyg1oAfg50QGbPPHw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/type-utils": "7.16.1", - "@typescript-eslint/utils": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/scope-manager": "8.5.0", + "@typescript-eslint/type-utils": "8.5.0", + "@typescript-eslint/utils": "8.5.0", + "@typescript-eslint/visitor-keys": "8.5.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -4629,92 +4603,28 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.5.0.tgz", + "integrity": "sha512-gF77eNv0Xz2UJg/NbpWJ0kqAm35UMsvZf1GHj8D9MRFTj/V3tAciIWXfmPLsAAF/vUlpWPvUDyH1jjsr0cMVWw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/scope-manager": "8.5.0", + "@typescript-eslint/types": "8.5.0", + "@typescript-eslint/typescript-estree": "8.5.0", + "@typescript-eslint/visitor-keys": "8.5.0", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -4723,18 +4633,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.5.0.tgz", + "integrity": "sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" + "@typescript-eslint/types": "8.5.0", + "@typescript-eslint/visitor-keys": "8.5.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4742,65 +4651,19 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", - "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.5.0.tgz", + "integrity": "sha512-N1K8Ix+lUM+cIDhL2uekVn/ZD7TZW+9/rwz8DclQpcQ9rk4sIL5CAlBC0CugWKREmDjBzI/kQqU4wkg46jWLYA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/typescript-estree": "8.5.0", + "@typescript-eslint/utils": "8.5.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4812,62 +4675,14 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.5.0.tgz", + "integrity": "sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4875,24 +4690,23 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.5.0.tgz", + "integrity": "sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/types": "8.5.0", + "@typescript-eslint/visitor-keys": "8.5.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4910,7 +4724,6 @@ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4922,149 +4735,40 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", - "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.5.0.tgz", + "integrity": "sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1" + "@typescript-eslint/scope-manager": "8.5.0", + "@typescript-eslint/types": "8.5.0", + "@typescript-eslint/typescript-estree": "8.5.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.5.0.tgz", + "integrity": "sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/types": "8.5.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -5077,7 +4781,6 @@ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "license": "Apache-2.0", - "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -5835,13 +5538,13 @@ "license": "Python-2.0" }, "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", "dev": true, "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" + "engines": { + "node": ">= 0.4" } }, "node_modules/array-buffer-byte-length": { @@ -6083,9 +5786,9 @@ } }, "node_modules/astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", "dev": true, "license": "MIT", "bin": { @@ -6132,13 +5835,13 @@ } }, "node_modules/axobject-query": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", - "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" + "engines": { + "node": ">= 0.4" } }, "node_modules/babel-plugin-polyfill-corejs2": { @@ -6409,9 +6112,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001651", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", - "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "version": "1.0.30001660", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz", + "integrity": "sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==", "funding": [ { "type": "opencollective", @@ -6784,9 +6487,9 @@ "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.38.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.0.tgz", - "integrity": "sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz", + "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==", "dev": true, "license": "MIT", "dependencies": { @@ -7578,12 +7281,12 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -7719,16 +7422,6 @@ "node": ">= 0.6.0" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -7906,9 +7599,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.11", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.11.tgz", - "integrity": "sha512-R1CccCDYqndR25CaXFd6hp/u9RaaMcftMkphmvuepXr5b1vfLkRml6aWVeBhXJ7rbevHkKEMJtz8XqPf7ffmew==", + "version": "1.5.23", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.23.tgz", + "integrity": "sha512-mBhODedOXg4v5QWwl21DjM5amzjmI1zw9EPrPK/5Wx7C8jt33bpZNrC7OhHUG3pxRtbLpr3W2dXT+Ph1SsfRZA==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -7961,9 +7654,9 @@ } }, "node_modules/envinfo": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", - "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", + "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", "license": "MIT", "bin": { "envinfo": "dist/cli.js" @@ -8254,9 +7947,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -8395,9 +8088,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.0.tgz", + "integrity": "sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8526,225 +8219,6 @@ "eslint": "^8.0.1" } }, - "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.5.0.tgz", - "integrity": "sha512-lHS5hvz33iUFQKuPFGheAB84LwcJ60G8vKnEhnfcK1l8kGVLro2SFYW6K0/tj8FUhRJ0VHyg1oAfg50QGbPPHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.5.0", - "@typescript-eslint/type-utils": "8.5.0", - "@typescript-eslint/utils": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/parser": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.5.0.tgz", - "integrity": "sha512-gF77eNv0Xz2UJg/NbpWJ0kqAm35UMsvZf1GHj8D9MRFTj/V3tAciIWXfmPLsAAF/vUlpWPvUDyH1jjsr0cMVWw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "8.5.0", - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/typescript-estree": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/scope-manager": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.5.0.tgz", - "integrity": "sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/type-utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.5.0.tgz", - "integrity": "sha512-N1K8Ix+lUM+cIDhL2uekVn/ZD7TZW+9/rwz8DclQpcQ9rk4sIL5CAlBC0CugWKREmDjBzI/kQqU4wkg46jWLYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "8.5.0", - "@typescript-eslint/utils": "8.5.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/types": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.5.0.tgz", - "integrity": "sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.5.0.tgz", - "integrity": "sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/visitor-keys": "8.5.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.5.0.tgz", - "integrity": "sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.5.0", - "@typescript-eslint/types": "8.5.0", - "@typescript-eslint/typescript-estree": "8.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-github/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.5.0.tgz", - "integrity": "sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.5.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-github/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-github/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/eslint-plugin-i": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/eslint-plugin-i/-/eslint-plugin-i-2.29.1.tgz", @@ -8806,27 +8280,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", + "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", "dev": true, "license": "MIT", "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", "array.prototype.flat": "^1.3.2", "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "eslint-module-utils": "^2.9.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", "semver": "^6.3.1", "tsconfig-paths": "^3.15.0" }, @@ -8895,9 +8370,9 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", - "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.0.tgz", + "integrity": "sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==", "dev": true, "license": "MIT", "dependencies": { @@ -8905,8 +8380,8 @@ "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", - "axe-core": "^4.9.1", - "axobject-query": "~3.1.1", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "es-iterator-helpers": "^1.0.19", @@ -8922,7 +8397,7 @@ "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { @@ -9052,9 +8527,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.35.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", - "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", + "version": "7.36.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz", + "integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==", "dev": true, "license": "MIT", "dependencies": { @@ -9219,6 +8694,373 @@ "eslint": "^8.0.0 || ^9.0.0" } }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/type-utils": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/utils": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@typescript-eslint/visitor-keys/node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/eslint-plugin-sonarjs/node_modules/eslint-scope": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz", @@ -9236,6 +9078,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-plugin-sonarjs/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint-plugin-sonarjs/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -9335,6 +9190,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/eslint-plugin-vitest-globals": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/eslint-plugin-vitest-globals/-/eslint-plugin-vitest-globals-1.5.0.tgz", @@ -10001,9 +9869,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", - "integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -10339,6 +10207,16 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/hpagent": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", @@ -10705,9 +10583,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -11314,10 +11192,9 @@ "license": "MIT" }, "node_modules/js-tokens": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", - "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/js-types": { @@ -11363,16 +11240,16 @@ } }, "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=6" + "node": ">=4" } }, "node_modules/json-buffer": { @@ -11806,13 +11683,6 @@ "loose-envify": "cli.js" } }, - "node_modules/loose-envify/node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, "node_modules/loupe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", @@ -11834,13 +11704,13 @@ } }, "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "license": "ISC", - "engines": { - "node": ">=12" + "dependencies": { + "yallist": "^3.0.2" } }, "node_modules/magic-string": { @@ -11854,14 +11724,14 @@ } }, "node_modules/magicast": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz", - "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.24.4", - "@babel/types": "^7.24.0", + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, @@ -11881,6 +11751,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-escape": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-escape/-/markdown-escape-2.0.0.tgz", + "integrity": "sha512-Trz4v0+XWlwy68LJIyw3bLbsJiC8XAbRCKF9DbEtZjyndKOGVx6n+wNB0VfoRmY2LKboQLeniap3xrb6LGSJ8A==", + "dev": true, + "license": "MIT" + }, "node_modules/markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -12262,9 +12139,9 @@ "license": "BSD-3-Clause" }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/mz": { @@ -13048,6 +12925,13 @@ "node": "^12 || >=14" } }, + "node_modules/postcss-html/node_modules/js-tokens": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", + "dev": true, + "license": "MIT" + }, "node_modules/postcss-import": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", @@ -13808,9 +13692,9 @@ "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dev": true, "license": "MIT", "dependencies": { @@ -14461,9 +14345,9 @@ } }, "node_modules/solid-js": { - "version": "1.8.21", - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.21.tgz", - "integrity": "sha512-FHUGdoo7GVa1BTpGh/4UtwIISde0vSXoqNB6KFpHiTgkIY959tmCJ7NYQAWDfScBfnpoMGZR8lFz0DiwW/gFlw==", + "version": "1.8.22", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.22.tgz", + "integrity": "sha512-VBzN5j+9Y4rqIKEnK301aBk+S7fvFSTs9ljg+YEdFxjNjH0hkjXPiQRcws9tE5fUzMznSS6KToL5hwMfHDgpLA==", "license": "MIT", "dependencies": { "csstype": "^3.1.0", @@ -14573,9 +14457,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", "dev": true, "license": "CC0-1.0" }, @@ -14977,9 +14861,9 @@ } }, "node_modules/stylelint/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, "license": "MIT", "engines": { @@ -15077,9 +14961,9 @@ } }, "node_modules/stylis": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", - "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", + "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==", "license": "MIT" }, "node_modules/stylus": { @@ -15388,9 +15272,9 @@ "license": "ISC" }, "node_modules/terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "version": "5.32.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.32.0.tgz", + "integrity": "sha512-v3Gtw3IzpBJ0ugkxEX8U0W6+TnPKRRCWGh1jC/iM/e3Ki5+qvO1L1EAZ56bZasc64aXHwRHNIQEzm6//i5cemQ==", "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -15603,9 +15487,9 @@ "license": "MIT" }, "node_modules/tinypool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz", - "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", "dev": true, "license": "MIT", "engines": { @@ -15745,9 +15629,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true, "license": "0BSD" }, @@ -15855,9 +15739,9 @@ } }, "node_modules/typescript": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", - "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "devOptional": true, "license": "Apache-2.0", "bin": { @@ -15910,15 +15794,15 @@ } }, "node_modules/undici-types": { - "version": "6.19.6", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.6.tgz", - "integrity": "sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, "license": "MIT", "engines": { @@ -15940,9 +15824,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "dev": true, "license": "MIT", "engines": { @@ -16072,15 +15956,15 @@ "license": "MIT" }, "node_modules/vite": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.1.tgz", - "integrity": "sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.5.tgz", + "integrity": "sha512-pXqR0qtb2bTwLkev4SE3r4abCNioP3GkjvIDLlzziPpXtHgiJIjuKl+1GN6ESOT3wMjG3JTeARopj2SwYaHTOA==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.41", - "rollup": "^4.13.0" + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -16183,9 +16067,9 @@ } }, "node_modules/vite/node_modules/rollup": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz", - "integrity": "sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.3.tgz", + "integrity": "sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==", "dev": true, "license": "MIT", "dependencies": { @@ -16199,22 +16083,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.21.0", - "@rollup/rollup-android-arm64": "4.21.0", - "@rollup/rollup-darwin-arm64": "4.21.0", - "@rollup/rollup-darwin-x64": "4.21.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.21.0", - "@rollup/rollup-linux-arm-musleabihf": "4.21.0", - "@rollup/rollup-linux-arm64-gnu": "4.21.0", - "@rollup/rollup-linux-arm64-musl": "4.21.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.21.0", - "@rollup/rollup-linux-riscv64-gnu": "4.21.0", - "@rollup/rollup-linux-s390x-gnu": "4.21.0", - "@rollup/rollup-linux-x64-gnu": "4.21.0", - "@rollup/rollup-linux-x64-musl": "4.21.0", - "@rollup/rollup-win32-arm64-msvc": "4.21.0", - "@rollup/rollup-win32-ia32-msvc": "4.21.0", - "@rollup/rollup-win32-x64-msvc": "4.21.0", + "@rollup/rollup-android-arm-eabi": "4.21.3", + "@rollup/rollup-android-arm64": "4.21.3", + "@rollup/rollup-darwin-arm64": "4.21.3", + "@rollup/rollup-darwin-x64": "4.21.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.3", + "@rollup/rollup-linux-arm-musleabihf": "4.21.3", + "@rollup/rollup-linux-arm64-gnu": "4.21.3", + "@rollup/rollup-linux-arm64-musl": "4.21.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.3", + "@rollup/rollup-linux-riscv64-gnu": "4.21.3", + "@rollup/rollup-linux-s390x-gnu": "4.21.3", + "@rollup/rollup-linux-x64-gnu": "4.21.3", + "@rollup/rollup-linux-x64-musl": "4.21.3", + "@rollup/rollup-win32-arm64-msvc": "4.21.3", + "@rollup/rollup-win32-ia32-msvc": "4.21.3", + "@rollup/rollup-win32-x64-msvc": "4.21.3", "fsevents": "~2.3.2" } }, @@ -16374,9 +16258,9 @@ } }, "node_modules/vue-component-type-helpers": { - "version": "2.0.29", - "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.0.29.tgz", - "integrity": "sha512-58i+ZhUAUpwQ+9h5Hck0D+jr1qbYl4voRt5KffBx8qzELViQ4XdT/Tuo+mzq8u63teAG8K0lLaOiL5ofqW38rg==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.1.6.tgz", + "integrity": "sha512-ng11B8B/ZADUMMOsRbqv0arc442q7lifSubD0v8oDXIFoMg/mXwAPUunrroIDkY+mcD0dHKccdaznSVp8EoX3w==", "dev": true, "license": "MIT" }, @@ -16888,9 +16772,9 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "license": "MIT", "engines": { "node": ">=12" @@ -16912,9 +16796,9 @@ } }, "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", "license": "MIT" }, "node_modules/wrap-ansi/node_modules/string-width": { @@ -16998,9 +16882,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", - "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", "license": "ISC", "bin": { "yaml": "bin.mjs" diff --git a/poetry.lock b/poetry.lock index a486f961ea..886dfe53d8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -214,104 +214,105 @@ files = [ [[package]] name = "regex" -version = "2023.12.25" +version = "2024.9.11" description = "Alternative regular expression module, to replace re." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, - {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, - {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, - {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, - {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, - {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, - {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, - {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, - {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, - {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, - {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, - {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, - {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, - {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, - {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, - {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, - {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, - {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, - {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, - {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, - {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, - {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, - {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, - {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, - {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, - {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, - {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, - {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, - {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, - {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, - {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, - {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, - {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, - {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, - {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, - {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, - {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, - {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, - {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, - {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, - {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, + {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408"}, + {file = "regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d"}, + {file = "regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5"}, + {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c"}, + {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8"}, + {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35"}, + {file = "regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71"}, + {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8"}, + {file = "regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a"}, + {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d"}, + {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137"}, + {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6"}, + {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca"}, + {file = "regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a"}, + {file = "regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0"}, + {file = "regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623"}, + {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df"}, + {file = "regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268"}, + {file = "regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad"}, + {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679"}, + {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4"}, + {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664"}, + {file = "regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50"}, + {file = "regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199"}, + {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4"}, + {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd"}, + {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f"}, + {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96"}, + {file = "regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1"}, + {file = "regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9"}, + {file = "regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf"}, + {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"}, + {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231"}, + {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"}, + {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64"}, + {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42"}, + {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766"}, + {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"}, + {file = "regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9"}, + {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d"}, + {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822"}, + {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0"}, + {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a"}, + {file = "regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a"}, + {file = "regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776"}, + {file = "regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009"}, + {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784"}, + {file = "regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36"}, + {file = "regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92"}, + {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86"}, + {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85"}, + {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963"}, + {file = "regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6"}, + {file = "regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802"}, + {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29"}, + {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8"}, + {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84"}, + {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554"}, + {file = "regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8"}, + {file = "regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8"}, + {file = "regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f"}, + {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:35f4a6f96aa6cb3f2f7247027b07b15a374f0d5b912c0001418d1d55024d5cb4"}, + {file = "regex-2024.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:55b96e7ce3a69a8449a66984c268062fbaa0d8ae437b285428e12797baefce7e"}, + {file = "regex-2024.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb130fccd1a37ed894824b8c046321540263013da72745d755f2d35114b81a60"}, + {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:323c1f04be6b2968944d730e5c2091c8c89767903ecaa135203eec4565ed2b2b"}, + {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be1c8ed48c4c4065ecb19d882a0ce1afe0745dfad8ce48c49586b90a55f02366"}, + {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5b029322e6e7b94fff16cd120ab35a253236a5f99a79fb04fda7ae71ca20ae8"}, + {file = "regex-2024.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6fff13ef6b5f29221d6904aa816c34701462956aa72a77f1f151a8ec4f56aeb"}, + {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:587d4af3979376652010e400accc30404e6c16b7df574048ab1f581af82065e4"}, + {file = "regex-2024.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:079400a8269544b955ffa9e31f186f01d96829110a3bf79dc338e9910f794fca"}, + {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f9268774428ec173654985ce55fc6caf4c6d11ade0f6f914d48ef4719eb05ebb"}, + {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:23f9985c8784e544d53fc2930fc1ac1a7319f5d5332d228437acc9f418f2f168"}, + {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2941333154baff9838e88aa71c1d84f4438189ecc6021a12c7573728b5838e"}, + {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e93f1c331ca8e86fe877a48ad64e77882c0c4da0097f2212873a69bbfea95d0c"}, + {file = "regex-2024.9.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:846bc79ee753acf93aef4184c040d709940c9d001029ceb7b7a52747b80ed2dd"}, + {file = "regex-2024.9.11-cp38-cp38-win32.whl", hash = "sha256:c94bb0a9f1db10a1d16c00880bdebd5f9faf267273b8f5bd1878126e0fbde771"}, + {file = "regex-2024.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:2b08fce89fbd45664d3df6ad93e554b6c16933ffa9d55cb7e01182baaf971508"}, + {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:07f45f287469039ffc2c53caf6803cd506eb5f5f637f1d4acb37a738f71dd066"}, + {file = "regex-2024.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4838e24ee015101d9f901988001038f7f0d90dc0c3b115541a1365fb439add62"}, + {file = "regex-2024.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6edd623bae6a737f10ce853ea076f56f507fd7726bee96a41ee3d68d347e4d16"}, + {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c69ada171c2d0e97a4b5aa78fbb835e0ffbb6b13fc5da968c09811346564f0d3"}, + {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02087ea0a03b4af1ed6ebab2c54d7118127fee8d71b26398e8e4b05b78963199"}, + {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69dee6a020693d12a3cf892aba4808fe168d2a4cef368eb9bf74f5398bfd4ee8"}, + {file = "regex-2024.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297f54910247508e6e5cae669f2bc308985c60540a4edd1c77203ef19bfa63ca"}, + {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecea58b43a67b1b79805f1a0255730edaf5191ecef84dbc4cc85eb30bc8b63b9"}, + {file = "regex-2024.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eab4bb380f15e189d1313195b062a6aa908f5bd687a0ceccd47c8211e9cf0d4a"}, + {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0cbff728659ce4bbf4c30b2a1be040faafaa9eca6ecde40aaff86f7889f4ab39"}, + {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:54c4a097b8bc5bb0dfc83ae498061d53ad7b5762e00f4adaa23bee22b012e6ba"}, + {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:73d6d2f64f4d894c96626a75578b0bf7d9e56dcda8c3d037a2118fdfe9b1c664"}, + {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e53b5fbab5d675aec9f0c501274c467c0f9a5d23696cfc94247e1fb56501ed89"}, + {file = "regex-2024.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0ffbcf9221e04502fc35e54d1ce9567541979c3fdfb93d2c554f0ca583a19b35"}, + {file = "regex-2024.9.11-cp39-cp39-win32.whl", hash = "sha256:e4c22e1ac1f1ec1e09f72e6c44d8f2244173db7eb9629cc3a346a8d7ccc31142"}, + {file = "regex-2024.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:faa3c142464efec496967359ca99696c896c591c56c53506bac1ad465f66e919"}, + {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"}, ] [[package]] diff --git a/web_src/fomantic/package-lock.json b/web_src/fomantic/package-lock.json index f3d6d42d17..2401294105 100644 --- a/web_src/fomantic/package-lock.json +++ b/web_src/fomantic/package-lock.json @@ -44,9 +44,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "license": "MIT", "engines": { "node": ">=12" @@ -492,9 +492,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.0.tgz", - "integrity": "sha512-49AbMDwYUz7EXxKU/r7mXOsxwFr4BYbvB7tWYxVuLdb2ibd30ijjXINSMAHiEEZk5PCRBmW1gUeisn2VMKt3cQ==", + "version": "22.5.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", + "integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", "license": "MIT", "dependencies": { "undici-types": "~6.19.2" @@ -1219,9 +1219,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001651", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", - "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "version": "1.0.30001660", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz", + "integrity": "sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==", "funding": [ { "type": "opencollective", @@ -1277,7 +1277,6 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", "license": "MIT", "dependencies": { "anymatch": "^2.0.0", @@ -1962,9 +1961,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.11", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.11.tgz", - "integrity": "sha512-R1CccCDYqndR25CaXFd6hp/u9RaaMcftMkphmvuepXr5b1vfLkRml6aWVeBhXJ7rbevHkKEMJtz8XqPf7ffmew==", + "version": "1.5.23", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.23.tgz", + "integrity": "sha512-mBhODedOXg4v5QWwl21DjM5amzjmI1zw9EPrPK/5Wx7C8jt33bpZNrC7OhHUG3pxRtbLpr3W2dXT+Ph1SsfRZA==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -2078,9 +2077,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -2700,9 +2699,9 @@ } }, "node_modules/get-stream/node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -4105,9 +4104,9 @@ } }, "node_modules/gulp-uglify/node_modules/uglify-js": { - "version": "3.19.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.2.tgz", - "integrity": "sha512-S8KA6DDI47nQXJSi2ctQ629YzwOVs+bQML6DAtvy0wgNdpi+0ySpQK0g2pxBq2xfF2z3YCscu7NNA8nXT9PlIQ==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "license": "BSD-2-Clause", "bin": { "uglifyjs": "bin/uglifyjs" @@ -4620,9 +4619,9 @@ "license": "MIT" }, "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -5836,9 +5835,9 @@ } }, "node_modules/native-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.0.tgz", - "integrity": "sha512-uZ5rQaeRn15XmpgE0xoPL8YWqcX90VtCFglYwAgkvKM5e8fog+vePLAhHxuuv/gRkrQxIeh5U3q9sMNUrENqWw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.2.tgz", + "integrity": "sha512-/etjwrK0J4Ebbcnt35VMWnfiUX/B04uwGJxyJInagxDqf2z5drSt/lsOvEMWGYunz1kaLZAFrV4NDAbOoDKvAQ==", "license": "MIT", "optional": true }, @@ -7415,9 +7414,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", "license": "CC0-1.0" }, "node_modules/split-string": { @@ -8132,9 +8131,9 @@ } }, "node_modules/undici-types": { - "version": "6.19.6", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.6.tgz", - "integrity": "sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "license": "MIT" }, "node_modules/union-value": { @@ -8260,9 +8259,9 @@ } }, "node_modules/update-browserslist-db/node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "license": "ISC" }, "node_modules/urix": { From 1e5f7d211653372fa8b262623d14b04c91be9c2e Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Mon, 16 Sep 2024 08:33:39 +0200 Subject: [PATCH 024/443] chore: fix lint error --- tests/e2e/shared/forms.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/shared/forms.js b/tests/e2e/shared/forms.js index 7340dc60ff..0ffd6eef2d 100644 --- a/tests/e2e/shared/forms.js +++ b/tests/e2e/shared/forms.js @@ -1,5 +1,5 @@ import {expect} from '@playwright/test'; -import AxeBuilder from '@axe-core/playwright'; +import {AxeBuilder} from '@axe-core/playwright'; export async function validate_form({page}, scope) { scope ??= 'form'; From e1a9ad600b31c1c2af563720423e282baa60f707 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 25 Sep 2024 09:03:00 +0000 Subject: [PATCH 025/443] Update dependency tailwindcss to v3.4.13 (forgejo) (#5345) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5345 Reviewed-by: Michael Kriese Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe848ce5ad..e23a87edc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "pretty-ms": "9.0.0", "sortablejs": "1.15.3", "swagger-ui-dist": "5.17.14", - "tailwindcss": "3.4.11", + "tailwindcss": "3.4.13", "temporal-polyfill": "0.2.4", "throttle-debounce": "5.0.0", "tinycolor2": "1.6.0", @@ -15211,9 +15211,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.11.tgz", - "integrity": "sha512-qhEuBcLemjSJk5ajccN9xJFtM/h0AVCPaA6C92jNP+M2J8kX+eMJHI7R2HFKUvvAsMpcfLILMCFYSeDwpMmlUg==", + "version": "3.4.13", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz", + "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", diff --git a/package.json b/package.json index fd083ea6f4..b29f80de50 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "pretty-ms": "9.0.0", "sortablejs": "1.15.3", "swagger-ui-dist": "5.17.14", - "tailwindcss": "3.4.11", + "tailwindcss": "3.4.13", "temporal-polyfill": "0.2.4", "throttle-debounce": "5.0.0", "tinycolor2": "1.6.0", From e1566d2a1f4c3030ff10071d79bf37e4b0a6e016 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 25 Sep 2024 09:03:29 +0000 Subject: [PATCH 026/443] Update dependency mermaid to v11.2.1 (forgejo) (#5338) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5338 Reviewed-by: Michael Kriese Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index e23a87edc5..0c92ceff22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "idiomorph": "0.3.0", "jquery": "3.7.1", "katex": "0.16.11", - "mermaid": "11.2.0", + "mermaid": "11.2.1", "mini-css-extract-plugin": "2.9.1", "minimatch": "10.0.1", "monaco-editor": "0.50.0", @@ -11952,9 +11952,9 @@ } }, "node_modules/mermaid": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.2.0.tgz", - "integrity": "sha512-ZinOa063lk81lujX8vkINNqmFaNMk1A95Z4kCL7fE6QLAi01CxeiUJVw+tpXU+lAM73utO39G+2PLjxS2GYS/w==", + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.2.1.tgz", + "integrity": "sha512-F8TEaLVVyxTUmvKswVFyOkjPrlJA5h5vNR1f7ZnSWSpqxgEZG1hggtn/QCa7znC28bhlcrNh10qYaIiill7q4A==", "license": "MIT", "dependencies": { "@braintree/sanitize-url": "^7.0.1", diff --git a/package.json b/package.json index b29f80de50..3bba4b8ab7 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "idiomorph": "0.3.0", "jquery": "3.7.1", "katex": "0.16.11", - "mermaid": "11.2.0", + "mermaid": "11.2.1", "mini-css-extract-plugin": "2.9.1", "minimatch": "10.0.1", "monaco-editor": "0.50.0", From 68cade5b1d7861e53cfc1f3a2bb71995463fbd29 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 25 Sep 2024 09:04:07 +0000 Subject: [PATCH 027/443] Update dependency @vitejs/plugin-vue to v5.1.4 (forgejo) (#5350) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5350 Reviewed-by: Michael Kriese Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0c92ceff22..7dd1cba03a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,7 +66,7 @@ "@stoplight/spectral-cli": "6.13.1", "@stylistic/eslint-plugin-js": "2.8.0", "@stylistic/stylelint-plugin": "3.0.1", - "@vitejs/plugin-vue": "5.1.3", + "@vitejs/plugin-vue": "5.1.4", "@vitest/coverage-v8": "2.1.1", "@vitest/eslint-plugin": "1.0.0", "@vue/test-utils": "2.4.6", @@ -4796,9 +4796,9 @@ "license": "ISC" }, "node_modules/@vitejs/plugin-vue": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.3.tgz", - "integrity": "sha512-3xbWsKEKXYlmX82aOHufFQVnkbMC/v8fLpWwh6hWOUrK5fbbtBh9Q/WWse27BFgSy2/e2c0fz5Scgya9h2GLhw==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz", + "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 3bba4b8ab7..12c6a05c12 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@stoplight/spectral-cli": "6.13.1", "@stylistic/eslint-plugin-js": "2.8.0", "@stylistic/stylelint-plugin": "3.0.1", - "@vitejs/plugin-vue": "5.1.3", + "@vitejs/plugin-vue": "5.1.4", "@vitest/coverage-v8": "2.1.1", "@vitest/eslint-plugin": "1.0.0", "@vue/test-utils": "2.4.6", From f0dab9cc0597dc357ed723438a3e9cfd238b917d Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 25 Sep 2024 09:10:00 +0000 Subject: [PATCH 028/443] Update module code.forgejo.org/forgejo/act to v1.21.3 (forgejo) (#5333) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5333 Reviewed-by: Michael Kriese Co-authored-by: Renovate Bot Co-committed-by: Renovate Bot --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9566af1d37..3f7bb9d7ce 100644 --- a/go.mod +++ b/go.mod @@ -293,6 +293,6 @@ replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 -replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.21.2 +replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.21.3 replace github.com/mholt/archiver/v3 => code.forgejo.org/forgejo/archiver/v3 v3.5.1 diff --git a/go.sum b/go.sum index bdfde0a499..a8f4ff066f 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ code.forgejo.org/f3/gof3/v3 v3.7.0 h1:ZfuCP8CGm8ZJbWmL+V0pUu3E0X4FCAA7GfRDy/y5/K code.forgejo.org/f3/gof3/v3 v3.7.0/go.mod h1:oNhOeqD4DZYjVcNjQXIOdDX9b/1tqxi9ITLS8H9/Csw= code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251 h1:HTZl3CBk3ABNYtFI6TPLvJgGKFIhKT5CBk0sbOtkDKU= code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:PphB88CPbx601QrWPMZATeorACeVmQlyv3u+uUMbSaM= -code.forgejo.org/forgejo/act v1.21.2 h1:LERMtDNZDFXOYYYSU7Yduyyz7sN0t/Xnc1wFlupweiE= -code.forgejo.org/forgejo/act v1.21.2/go.mod h1:+PcvJ9iv+NTFeJSh79ra9Jbk9l0vvyA9D9me5/dbxYM= +code.forgejo.org/forgejo/act v1.21.3 h1:EeJbrz0aar2QhIcBlOW5gjK1rjrQxcAvQSPpG/R1h5w= +code.forgejo.org/forgejo/act v1.21.3/go.mod h1:+PcvJ9iv+NTFeJSh79ra9Jbk9l0vvyA9D9me5/dbxYM= code.forgejo.org/forgejo/archiver/v3 v3.5.1 h1:UmmbA7D5550uf71SQjarmrn6yKwOGxtEjb3jaYYtmSE= code.forgejo.org/forgejo/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= code.forgejo.org/forgejo/reply v1.0.2 h1:dMhQCHV6/O3L5CLWNTol+dNzDAuyCK88z4J/lCdgFuQ= From cd7f92797b6ce3191ffec9524d7e2e979f94b812 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Wed, 25 Sep 2024 11:10:39 +0200 Subject: [PATCH 029/443] start of the v10.0 development branch --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 2edc449177..0c4becacc4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -

Welcome to Forgejo

From a9f9b94478970725c15d339e4287469f55b085c9 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 26 Sep 2024 00:04:54 +0000 Subject: [PATCH 030/443] Update citation-js monorepo --- package-lock.json | 16 ++++++++-------- package.json | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7dd1cba03a..616a2caf65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,8 +5,8 @@ "packages": { "": { "dependencies": { - "@citation-js/core": "0.7.11", - "@citation-js/plugin-bibtex": "0.7.11", + "@citation-js/core": "0.7.14", + "@citation-js/plugin-bibtex": "0.7.16", "@citation-js/plugin-software-formats": "0.6.1", "@github/markdown-toolbar-element": "2.2.3", "@github/relative-time-element": "4.4.3", @@ -2298,9 +2298,9 @@ "license": "Apache-2.0" }, "node_modules/@citation-js/core": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.11.tgz", - "integrity": "sha512-evQtyzeW+Gbmq+xWciIq9sbcvXXDbm8q32orD/HDd5ay6RQFKoW/BKxBLp+Nmpxgspb9sxTJn3iFK7+jxOTNTw==", + "version": "0.7.14", + "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.14.tgz", + "integrity": "sha512-dgeGqYDSQmn2MtnWZkwPGpJQPh43yr1lAAr9jl1NJ9pIY1RXUQxtlAUZVur0V9PHdbfQC+kkvB1KC3VpgVV3MA==", "license": "MIT", "dependencies": { "@citation-js/date": "^0.5.0", @@ -2331,9 +2331,9 @@ } }, "node_modules/@citation-js/plugin-bibtex": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.11.tgz", - "integrity": "sha512-G4vEmLjrQUxgBIp3ffWN5dDOlwjPsrRSi/uTyxDJuFgKBD8GR1eO7Y/ZcePNAOHMqUxG7lxhhBbZJwcJZNVHYw==", + "version": "0.7.16", + "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.16.tgz", + "integrity": "sha512-Udeli19VAoFjOw0H1bB1KgmekRoW6XP5cdR3OQF5c2Mt1tZatXWcSQVdq+FeLKzodRocZXG5NFRvjyUZjVbV6A==", "license": "MIT", "dependencies": { "@citation-js/date": "^0.5.0", diff --git a/package.json b/package.json index 12c6a05c12..7195994cb2 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "node": ">= 18.0.0" }, "dependencies": { - "@citation-js/core": "0.7.11", - "@citation-js/plugin-bibtex": "0.7.11", + "@citation-js/core": "0.7.14", + "@citation-js/plugin-bibtex": "0.7.16", "@citation-js/plugin-software-formats": "0.6.1", "@github/markdown-toolbar-element": "2.2.3", "@github/relative-time-element": "4.4.3", From ed656ca0f301b748aa141ba882f9474fe8e7c7bf Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 26 Sep 2024 00:05:12 +0000 Subject: [PATCH 031/443] Update dependency @github/text-expander-element to v2.7.2 --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7dd1cba03a..d44168a89d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "@citation-js/plugin-software-formats": "0.6.1", "@github/markdown-toolbar-element": "2.2.3", "@github/relative-time-element": "4.4.3", - "@github/text-expander-element": "2.7.1", + "@github/text-expander-element": "2.7.2", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.9.0", "ansi_up": "6.0.2", @@ -3124,13 +3124,13 @@ "license": "MIT" }, "node_modules/@github/text-expander-element": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.7.1.tgz", - "integrity": "sha512-CWxfYxJRkeWVCUhJveproLs6pHsPrWtK8TsjL8ByYVcSCs8CJmNzF8b7ZawrUgfai0F2jb4aIdw2FoBTykj9XA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.7.2.tgz", + "integrity": "sha512-eTIOUQKoBxe+e0yHKHQHoo4x61Erb7m0lhi2vMRHZS7TwI6OCGSj/3YydAr3obbQbZjevF9wPihLf1wADu3A9g==", "license": "MIT", "dependencies": { "@github/combobox-nav": "^2.0.2", - "dom-input-range": "^1.1.6" + "dom-input-range": "^1.2.0" } }, "node_modules/@humanwhocodes/config-array": { @@ -7461,9 +7461,9 @@ } }, "node_modules/dom-input-range": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/dom-input-range/-/dom-input-range-1.1.6.tgz", - "integrity": "sha512-4o/SkTpscD0n81BeErrrtmE58lG8vTks++92vk//ld0NmkQTb4AVJ2rexh2yor6rtBf5IMte26u+fF3EgCppPQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dom-input-range/-/dom-input-range-1.2.0.tgz", + "integrity": "sha512-8HVA5Oy5Vt872S7IXsjjp6/5Hqsm5YZLhurxwwQXp80T9qVsj8/mEUH3sQlFujLLUoWfxiaThHHuJ3/q1MHVuA==", "license": "MIT", "workspaces": [ "demos" diff --git a/package.json b/package.json index 12c6a05c12..b7310d05c4 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "@citation-js/plugin-software-formats": "0.6.1", "@github/markdown-toolbar-element": "2.2.3", "@github/relative-time-element": "4.4.3", - "@github/text-expander-element": "2.7.1", + "@github/text-expander-element": "2.7.2", "@mcaptcha/vanilla-glue": "0.1.0-alpha-3", "@primer/octicons": "19.9.0", "ansi_up": "6.0.2", From 7fbe6b4dc391e984e476a07dc8955ee93944c734 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 26 Sep 2024 02:03:41 +0000 Subject: [PATCH 032/443] Update module github.com/klauspost/compress to v1.17.10 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3f7bb9d7ce..7fe2490193 100644 --- a/go.mod +++ b/go.mod @@ -66,7 +66,7 @@ require ( github.com/jhillyerd/enmime v1.3.0 github.com/json-iterator/go v1.1.12 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 - github.com/klauspost/compress v1.17.9 + github.com/klauspost/compress v1.17.10 github.com/klauspost/cpuid/v2 v2.2.8 github.com/lib/pq v1.10.9 github.com/markbates/goth v1.80.0 diff --git a/go.sum b/go.sum index a8f4ff066f..97663e3fd9 100644 --- a/go.sum +++ b/go.sum @@ -448,8 +448,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= +github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= From 76c6b342702f76061fe6549546204d6207b3a7df Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 26 Sep 2024 02:03:56 +0000 Subject: [PATCH 033/443] Update module github.com/minio/minio-go/v7 to v7.0.77 --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 3f7bb9d7ce..87ccc0669b 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/meilisearch/meilisearch-go v0.28.0 github.com/mholt/archiver/v3 v3.5.1 github.com/microcosm-cc/bluemonday v1.0.27 - github.com/minio/minio-go/v7 v7.0.74 + github.com/minio/minio-go/v7 v7.0.77 github.com/msteinert/pam v1.2.0 github.com/nektos/act v0.2.52 github.com/niklasfasching/go-org v1.7.0 @@ -250,7 +250,7 @@ require ( github.com/rhysd/actionlint v1.6.27 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect - github.com/rs/xid v1.5.0 // indirect + github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect diff --git a/go.sum b/go.sum index a8f4ff066f..f5e0e87bd5 100644 --- a/go.sum +++ b/go.sum @@ -502,8 +502,8 @@ github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.74 h1:fTo/XlPBTSpo3BAMshlwKL5RspXRv9us5UeHEGYCFe0= -github.com/minio/minio-go/v7 v7.0.74/go.mod h1:qydcVzV8Hqtj1VtEocfxbmVFa2siu6HGa+LDEPogjD8= +github.com/minio/minio-go/v7 v7.0.77 h1:GaGghJRg9nwDVlNbwYjSDJT1rqltQkBFDsypWX1v3Bw= +github.com/minio/minio-go/v7 v7.0.77/go.mod h1:AVM3IUN6WwKzmwBxVdjzhH8xq+f57JSbbvzqvUzR6eg= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -599,8 +599,8 @@ github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4 github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= From d00099390539621317cd39f0ca2c100467ade4b5 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 27 Sep 2024 00:04:48 +0000 Subject: [PATCH 034/443] Update dependency @stylistic/stylelint-plugin to v3.1.0 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a537c3fc0..3e4c8451fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,7 +65,7 @@ "@playwright/test": "1.47.2", "@stoplight/spectral-cli": "6.13.1", "@stylistic/eslint-plugin-js": "2.8.0", - "@stylistic/stylelint-plugin": "3.0.1", + "@stylistic/stylelint-plugin": "3.1.0", "@vitejs/plugin-vue": "5.1.4", "@vitest/coverage-v8": "2.1.1", "@vitest/eslint-plugin": "1.0.0", @@ -4441,15 +4441,15 @@ } }, "node_modules/@stylistic/stylelint-plugin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.0.1.tgz", - "integrity": "sha512-j3mH8HSw2Rob/KJFWZ627w3CQ8gQqVHtzCdPeEffUg5vOgpz4rgrR+Xw2kU0OQCDcdW8Y1nKfdXKKjM5Rn8X0g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.0.tgz", + "integrity": "sha512-NU2XR6i1x163KdyDj3zqblA13890fBzHNZYqZ13aor/sB3Yq8kU/0NKCudv5pfl9Kb/UAteo/D7vKMHtaror/A==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.0", - "@csstools/css-tokenizer": "^3.0.0", - "@csstools/media-query-list-parser": "^3.0.0", + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", "is-plain-object": "^5.0.0", "postcss-selector-parser": "^6.1.2", "postcss-value-parser": "^4.2.0", diff --git a/package.json b/package.json index 085d10dfca..22290825d8 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@playwright/test": "1.47.2", "@stoplight/spectral-cli": "6.13.1", "@stylistic/eslint-plugin-js": "2.8.0", - "@stylistic/stylelint-plugin": "3.0.1", + "@stylistic/stylelint-plugin": "3.1.0", "@vitejs/plugin-vue": "5.1.4", "@vitest/coverage-v8": "2.1.1", "@vitest/eslint-plugin": "1.0.0", From 757080addd67397d474470fdd1c7ec7723cb894d Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 27 Sep 2024 02:03:09 +0000 Subject: [PATCH 035/443] Update dependency @vitest/eslint-plugin to v1.1.4 --- package-lock.json | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a537c3fc0..14df46c898 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,7 +68,7 @@ "@stylistic/stylelint-plugin": "3.0.1", "@vitejs/plugin-vue": "5.1.4", "@vitest/coverage-v8": "2.1.1", - "@vitest/eslint-plugin": "1.0.0", + "@vitest/eslint-plugin": "1.1.4", "@vue/test-utils": "2.4.6", "eslint": "8.57.1", "eslint-plugin-array-func": "4.0.0", @@ -4853,13 +4853,13 @@ } }, "node_modules/@vitest/eslint-plugin": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.0.0.tgz", - "integrity": "sha512-YQSFGYrD+eAa2QqdL8v4WAG3yYhcfW3LGlPdNRcjbF1etX0xUfI4isE+U+tYjQuVVzHG4KccRg1F8UuveFVdfg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.4.tgz", + "integrity": "sha512-kudjgefmJJ7xQ2WfbUU6pZbm7Ou4gLYRaao/8Ynide3G0QhVKHd978sDyWX4KOH0CCMH9cyrGAkFd55eGzJ48Q==", "dev": true, "license": "MIT", "peerDependencies": { - "@typescript-eslint/utils": ">= 7.8 || 8.0.0", + "@typescript-eslint/utils": ">= 8.0", "eslint": ">= 8.57.0", "typescript": ">= 5.0.0", "vitest": "*" diff --git a/package.json b/package.json index 085d10dfca..9c995c84b0 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "@stylistic/stylelint-plugin": "3.0.1", "@vitejs/plugin-vue": "5.1.4", "@vitest/coverage-v8": "2.1.1", - "@vitest/eslint-plugin": "1.0.0", + "@vitest/eslint-plugin": "1.1.4", "@vue/test-utils": "2.4.6", "eslint": "8.57.1", "eslint-plugin-array-func": "4.0.0", From 70014a7bc913cdd100bcf13d3f33c20718cd327c Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Fri, 27 Sep 2024 02:03:21 +0000 Subject: [PATCH 036/443] Update dependency markdownlint-cli to v0.42.0 --- package-lock.json | 113 ++++++++++++++++++++++++++++++++-------------- package.json | 2 +- 2 files changed, 79 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a537c3fc0..d045caeb93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,7 +86,7 @@ "eslint-plugin-wc": "2.1.1", "happy-dom": "15.7.4", "license-checker-rseidelsohn": "4.4.2", - "markdownlint-cli": "0.41.0", + "markdownlint-cli": "0.42.0", "postcss-html": "1.7.0", "stylelint": "16.9.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0", @@ -11777,14 +11777,14 @@ } }, "node_modules/markdownlint": { - "version": "0.34.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz", - "integrity": "sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.35.0.tgz", + "integrity": "sha512-wgp8yesWjFBL7bycA3hxwHRdsZGJhjhyP1dSxKVKrza0EPFYtn+mHtkVy6dvP1kGSjovyG5B8yNP6Frj0UFUJg==", "dev": true, "license": "MIT", "dependencies": { "markdown-it": "14.1.0", - "markdownlint-micromark": "0.1.9" + "markdownlint-micromark": "0.1.10" }, "engines": { "node": ">=18" @@ -11794,23 +11794,23 @@ } }, "node_modules/markdownlint-cli": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.41.0.tgz", - "integrity": "sha512-kp29tKrMKdn+xonfefjp3a/MsNzAd9c5ke0ydMEI9PR98bOjzglYN4nfMSaIs69msUf1DNkgevAIAPtK2SeX0Q==", + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.42.0.tgz", + "integrity": "sha512-AjkzhhZa3TmEGi/CE2Wpmny69x1IrzqK2gPB0k8SmNMRgnSAJfyEO5FgZdWTHtJ6Nrdv5FWt5c4C5pkG6Dk30A==", "dev": true, "license": "MIT", "dependencies": { "commander": "~12.1.0", "get-stdin": "~9.0.0", - "glob": "~10.4.1", - "ignore": "~5.3.1", + "glob": "~11.0.0", + "ignore": "~6.0.2", "js-yaml": "^4.1.0", - "jsonc-parser": "~3.2.1", + "jsonc-parser": "~3.3.1", "jsonpointer": "5.0.1", - "markdownlint": "~0.34.0", - "minimatch": "~9.0.4", + "markdownlint": "~0.35.0", + "minimatch": "~10.0.1", "run-con": "~1.3.2", - "smol-toml": "~1.2.0" + "smol-toml": "~1.3.0" }, "bin": { "markdownlint": "markdownlint.js" @@ -11830,53 +11830,93 @@ } }, "node_modules/markdownlint-cli/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/markdownlint-cli/node_modules/ignore": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/markdownlint-cli/node_modules/jackspeak": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", + "integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/markdownlint-cli/node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", "dev": true, "license": "MIT" }, - "node_modules/markdownlint-cli/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/markdownlint-cli/node_modules/lru-cache": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.1.tgz", + "integrity": "sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==", "dev": true, "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/markdownlint-cli/node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/markdownlint-micromark": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.9.tgz", - "integrity": "sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.10.tgz", + "integrity": "sha512-no5ZfdqAdWGxftCLlySHSgddEjyW4kui4z7amQcGsSKfYC5v/ou+8mIQVyg9KQMeEZLNtz9OPDTj7nnTnoR4FQ==", "dev": true, "license": "MIT", "engines": { @@ -14335,13 +14375,16 @@ } }, "node_modules/smol-toml": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.2.2.tgz", - "integrity": "sha512-fVEjX2ybKdJKzFL46VshQbj9PuA4IUKivalgp48/3zwS9vXzyykzQ6AX92UxHSvWJagziMRLeHMgEzoGO7A8hQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.0.tgz", + "integrity": "sha512-tWpi2TsODPScmi48b/OQZGi2lgUmBCHy6SZrhi/FdnnHiU1GwebbCfuQuxsC3nHaLwtYeJGPrDZDIeodDOc4pA==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" } }, "node_modules/solid-js": { diff --git a/package.json b/package.json index 085d10dfca..18d522f094 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "eslint-plugin-wc": "2.1.1", "happy-dom": "15.7.4", "license-checker-rseidelsohn": "4.4.2", - "markdownlint-cli": "0.41.0", + "markdownlint-cli": "0.42.0", "postcss-html": "1.7.0", "stylelint": "16.9.0", "stylelint-declaration-block-no-ignored-properties": "2.8.0", From 1bdf334844f398d0a2adafc4499cef15f95df6d8 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sun, 22 Sep 2024 09:28:20 +0200 Subject: [PATCH 037/443] feat: add IfZero utility function (cherry picked from commit 43de021ac1ca017212ec75fd88a8a80a9db27c4c) --- modules/util/util.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/util/util.go b/modules/util/util.go index 0444680228..dcd7cf4f29 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -225,6 +225,15 @@ func Iif[T any](condition bool, trueVal, falseVal T) T { return falseVal } +// IfZero returns "def" if "v" is a zero value, otherwise "v" +func IfZero[T comparable](v, def T) T { + var zero T + if v == zero { + return def + } + return v +} + func ReserveLineBreakForTextarea(input string) string { // Since the content is from a form which is a textarea, the line endings are \r\n. // It's a standard behavior of HTML. From 1ae3b127fc74906f0722caf6486890cf32d23715 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 18 Sep 2024 15:17:25 +0800 Subject: [PATCH 038/443] Refactor CSRF protector (#32057) Remove unused CSRF options, decouple "new csrf protector" and "prepare" logic, do not redirect to home page if CSRF validation falis (it shouldn't happen in daily usage, if it happens, redirecting to home doesn't help either but just makes the problem more complex for "fetch") (cherry picked from commit 1fede04b83288d8a91304a83b7601699bb5cba04) Conflicts: options/locale/locale_en-US.ini tests/integration/repo_branch_test.go trivial context conflicts --- options/locale/locale_en-US.ini | 1 - routers/web/web.go | 2 + services/context/context.go | 6 +- services/context/csrf.go | 192 ++++++++------------------ tests/integration/attachment_test.go | 3 +- tests/integration/csrf_test.go | 26 +--- tests/integration/repo_branch_test.go | 12 +- 7 files changed, 71 insertions(+), 171 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1631c90ba2..2512fe8b55 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -231,7 +231,6 @@ string.desc = Z - A [error] occurred = An error occurred report_message = If you believe that this is a Forgejo bug, please search for issues on Codeberg or open a new issue if necessary. -invalid_csrf = Bad Request: invalid CSRF token not_found = The target couldn't be found. network_error = Network error server_internal = Internal server error diff --git a/routers/web/web.go b/routers/web/web.go index d174b4e251..39116b882d 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -132,6 +132,8 @@ func webAuth(authMethod auth_service.Method) func(*context.Context) { // ensure the session uid is deleted _ = ctx.Session.Delete("uid") } + + ctx.Csrf.PrepareForSessionUser(ctx) } } diff --git a/services/context/context.go b/services/context/context.go index c0819ab11e..91e7b1849d 100644 --- a/services/context/context.go +++ b/services/context/context.go @@ -127,10 +127,8 @@ func Contexter() func(next http.Handler) http.Handler { csrfOpts := CsrfOptions{ Secret: hex.EncodeToString(setting.GetGeneralTokenSigningSecret()), Cookie: setting.CSRFCookieName, - SetCookie: true, Secure: setting.SessionConfig.Secure, CookieHTTPOnly: setting.CSRFCookieHTTPOnly, - Header: "X-Csrf-Token", CookieDomain: setting.SessionConfig.Domain, CookiePath: setting.SessionConfig.CookiePath, SameSite: setting.SessionConfig.SameSite, @@ -156,7 +154,7 @@ func Contexter() func(next http.Handler) http.Handler { ctx.Base.AppendContextValue(WebContextKey, ctx) ctx.Base.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo }) - ctx.Csrf = PrepareCSRFProtector(csrfOpts, ctx) + ctx.Csrf = NewCSRFProtector(csrfOpts) // Get the last flash message from cookie lastFlashCookie := middleware.GetSiteCookie(ctx.Req, CookieNameFlash) @@ -193,8 +191,6 @@ func Contexter() func(next http.Handler) http.Handler { ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) ctx.Data["SystemConfig"] = setting.Config() - ctx.Data["CsrfToken"] = ctx.Csrf.GetToken() - ctx.Data["CsrfTokenHtml"] = template.HTML(``) // FIXME: do we really always need these setting? There should be someway to have to avoid having to always set these ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations diff --git a/services/context/csrf.go b/services/context/csrf.go index 57c55e6550..5890d53f42 100644 --- a/services/context/csrf.go +++ b/services/context/csrf.go @@ -20,64 +20,42 @@ package context import ( - "encoding/base32" - "fmt" + "html/template" "net/http" "strconv" "time" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - "code.gitea.io/gitea/modules/web/middleware" +) + +const ( + CsrfHeaderName = "X-Csrf-Token" + CsrfFormName = "_csrf" ) // CSRFProtector represents a CSRF protector and is used to get the current token and validate the token. type CSRFProtector interface { - // GetHeaderName returns HTTP header to search for token. - GetHeaderName() string - // GetFormName returns form value to search for token. - GetFormName() string - // GetToken returns the token. - GetToken() string - // Validate validates the token in http context. + // PrepareForSessionUser prepares the csrf protector for the current session user. + PrepareForSessionUser(ctx *Context) + // Validate validates the csrf token in http context. Validate(ctx *Context) - // DeleteCookie deletes the cookie + // DeleteCookie deletes the csrf cookie DeleteCookie(ctx *Context) } type csrfProtector struct { opt CsrfOptions - // Token generated to pass via header, cookie, or hidden form value. - Token string - // This value must be unique per user. - ID string -} - -// GetHeaderName returns the name of the HTTP header for csrf token. -func (c *csrfProtector) GetHeaderName() string { - return c.opt.Header -} - -// GetFormName returns the name of the form value for csrf token. -func (c *csrfProtector) GetFormName() string { - return c.opt.Form -} - -// GetToken returns the current token. This is typically used -// to populate a hidden form in an HTML template. -func (c *csrfProtector) GetToken() string { - return c.Token + // id must be unique per user. + id string + // token is the valid one which wil be used by end user and passed via header, cookie, or hidden form value. + token string } // CsrfOptions maintains options to manage behavior of Generate. type CsrfOptions struct { // The global secret value used to generate Tokens. Secret string - // HTTP header used to set and get token. - Header string - // Form value used to set and get token. - Form string // Cookie value used to set and get token. Cookie string // Cookie domain. @@ -87,103 +65,64 @@ type CsrfOptions struct { CookieHTTPOnly bool // SameSite set the cookie SameSite type SameSite http.SameSite - // Key used for getting the unique ID per user. - SessionKey string - // oldSessionKey saves old value corresponding to SessionKey. - oldSessionKey string - // If true, send token via X-Csrf-Token header. - SetHeader bool - // If true, send token via _csrf cookie. - SetCookie bool // Set the Secure flag to true on the cookie. Secure bool - // Disallow Origin appear in request header. - Origin bool - // Cookie lifetime. Default is 0 - CookieLifeTime int + // sessionKey is the key used for getting the unique ID per user. + sessionKey string + // oldSessionKey saves old value corresponding to sessionKey. + oldSessionKey string } -func prepareDefaultCsrfOptions(opt CsrfOptions) CsrfOptions { - if opt.Secret == "" { - randBytes, err := util.CryptoRandomBytes(8) - if err != nil { - // this panic can be handled by the recover() in http handlers - panic(fmt.Errorf("failed to generate random bytes: %w", err)) - } - opt.Secret = base32.StdEncoding.EncodeToString(randBytes) - } - if opt.Header == "" { - opt.Header = "X-Csrf-Token" - } - if opt.Form == "" { - opt.Form = "_csrf" - } - if opt.Cookie == "" { - opt.Cookie = "_csrf" - } - if opt.CookiePath == "" { - opt.CookiePath = "/" - } - if opt.SessionKey == "" { - opt.SessionKey = "uid" - } - if opt.CookieLifeTime == 0 { - opt.CookieLifeTime = int(CsrfTokenTimeout.Seconds()) - } - - opt.oldSessionKey = "_old_" + opt.SessionKey - return opt -} - -func newCsrfCookie(c *csrfProtector, value string) *http.Cookie { +func newCsrfCookie(opt *CsrfOptions, value string) *http.Cookie { return &http.Cookie{ - Name: c.opt.Cookie, + Name: opt.Cookie, Value: value, - Path: c.opt.CookiePath, - Domain: c.opt.CookieDomain, - MaxAge: c.opt.CookieLifeTime, - Secure: c.opt.Secure, - HttpOnly: c.opt.CookieHTTPOnly, - SameSite: c.opt.SameSite, + Path: opt.CookiePath, + Domain: opt.CookieDomain, + MaxAge: int(CsrfTokenTimeout.Seconds()), + Secure: opt.Secure, + HttpOnly: opt.CookieHTTPOnly, + SameSite: opt.SameSite, } } -// PrepareCSRFProtector returns a CSRFProtector to be used for every request. -// Additionally, depending on options set, generated tokens will be sent via Header and/or Cookie. -func PrepareCSRFProtector(opt CsrfOptions, ctx *Context) CSRFProtector { - opt = prepareDefaultCsrfOptions(opt) - x := &csrfProtector{opt: opt} - - if opt.Origin && len(ctx.Req.Header.Get("Origin")) > 0 { - return x +func NewCSRFProtector(opt CsrfOptions) CSRFProtector { + if opt.Secret == "" { + panic("CSRF secret is empty but it must be set") // it shouldn't happen because it is always set in code } + opt.Cookie = util.IfZero(opt.Cookie, "_csrf") + opt.CookiePath = util.IfZero(opt.CookiePath, "/") + opt.sessionKey = "uid" + opt.oldSessionKey = "_old_" + opt.sessionKey + return &csrfProtector{opt: opt} +} - x.ID = "0" - uidAny := ctx.Session.Get(opt.SessionKey) - if uidAny != nil { +func (c *csrfProtector) PrepareForSessionUser(ctx *Context) { + c.id = "0" + if uidAny := ctx.Session.Get(c.opt.sessionKey); uidAny != nil { switch uidVal := uidAny.(type) { case string: - x.ID = uidVal + c.id = uidVal case int64: - x.ID = strconv.FormatInt(uidVal, 10) + c.id = strconv.FormatInt(uidVal, 10) default: log.Error("invalid uid type in session: %T", uidAny) } } - oldUID := ctx.Session.Get(opt.oldSessionKey) - uidChanged := oldUID == nil || oldUID.(string) != x.ID - cookieToken := ctx.GetSiteCookie(opt.Cookie) + oldUID := ctx.Session.Get(c.opt.oldSessionKey) + uidChanged := oldUID == nil || oldUID.(string) != c.id + cookieToken := ctx.GetSiteCookie(c.opt.Cookie) needsNew := true if uidChanged { - _ = ctx.Session.Set(opt.oldSessionKey, x.ID) + _ = ctx.Session.Set(c.opt.oldSessionKey, c.id) } else if cookieToken != "" { // If cookie token presents, reuse existing unexpired token, else generate a new one. if issueTime, ok := ParseCsrfToken(cookieToken); ok { dur := time.Since(issueTime) // issueTime is not a monotonic-clock, the server time may change a lot to an early time. if dur >= -CsrfTokenRegenerationInterval && dur <= CsrfTokenRegenerationInterval { - x.Token = cookieToken + c.token = cookieToken needsNew = false } } @@ -191,42 +130,33 @@ func PrepareCSRFProtector(opt CsrfOptions, ctx *Context) CSRFProtector { if needsNew { // FIXME: actionId. - x.Token = GenerateCsrfToken(x.opt.Secret, x.ID, "POST", time.Now()) - if opt.SetCookie { - cookie := newCsrfCookie(x, x.Token) - ctx.Resp.Header().Add("Set-Cookie", cookie.String()) - } + c.token = GenerateCsrfToken(c.opt.Secret, c.id, "POST", time.Now()) + cookie := newCsrfCookie(&c.opt, c.token) + ctx.Resp.Header().Add("Set-Cookie", cookie.String()) } - if opt.SetHeader { - ctx.Resp.Header().Add(opt.Header, x.Token) - } - return x + ctx.Data["CsrfToken"] = c.token + ctx.Data["CsrfTokenHtml"] = template.HTML(``) } func (c *csrfProtector) validateToken(ctx *Context, token string) { - if !ValidCsrfToken(token, c.opt.Secret, c.ID, "POST", time.Now()) { + if !ValidCsrfToken(token, c.opt.Secret, c.id, "POST", time.Now()) { c.DeleteCookie(ctx) - if middleware.IsAPIPath(ctx.Req) { - // currently, there should be no access to the APIPath with CSRF token. because templates shouldn't use the `/api/` endpoints. - http.Error(ctx.Resp, "Invalid CSRF token.", http.StatusBadRequest) - } else { - ctx.Flash.Error(ctx.Tr("error.invalid_csrf")) - ctx.Redirect(setting.AppSubURL + "/") - } + // currently, there should be no access to the APIPath with CSRF token. because templates shouldn't use the `/api/` endpoints. + // FIXME: distinguish what the response is for: HTML (web page) or JSON (fetch) + http.Error(ctx.Resp, "Invalid CSRF token.", http.StatusBadRequest) } } // Validate should be used as a per route middleware. It attempts to get a token from an "X-Csrf-Token" // HTTP header and then a "_csrf" form value. If one of these is found, the token will be validated. -// If this validation fails, custom Error is sent in the reply. -// If neither a header nor form value is found, http.StatusBadRequest is sent. +// If this validation fails, http.StatusBadRequest is sent. func (c *csrfProtector) Validate(ctx *Context) { - if token := ctx.Req.Header.Get(c.GetHeaderName()); token != "" { + if token := ctx.Req.Header.Get(CsrfHeaderName); token != "" { c.validateToken(ctx, token) return } - if token := ctx.Req.FormValue(c.GetFormName()); token != "" { + if token := ctx.Req.FormValue(CsrfFormName); token != "" { c.validateToken(ctx, token) return } @@ -234,9 +164,7 @@ func (c *csrfProtector) Validate(ctx *Context) { } func (c *csrfProtector) DeleteCookie(ctx *Context) { - if c.opt.SetCookie { - cookie := newCsrfCookie(c, "") - cookie.MaxAge = -1 - ctx.Resp.Header().Add("Set-Cookie", cookie.String()) - } + cookie := newCsrfCookie(&c.opt, "") + cookie.MaxAge = -1 + ctx.Resp.Header().Add("Set-Cookie", cookie.String()) } diff --git a/tests/integration/attachment_test.go b/tests/integration/attachment_test.go index 95c9c9f753..7cbc2545d5 100644 --- a/tests/integration/attachment_test.go +++ b/tests/integration/attachment_test.go @@ -60,7 +60,8 @@ func createAttachment(t *testing.T, session *TestSession, repoURL, filename stri func TestCreateAnonymousAttachment(t *testing.T) { defer tests.PrepareTestEnv(t)() session := emptyTestSession(t) - createAttachment(t, session, "user2/repo1", "image.png", generateImg(), http.StatusSeeOther) + // this test is not right because it just doesn't pass the CSRF validation + createAttachment(t, session, "user2/repo1", "image.png", generateImg(), http.StatusBadRequest) } func TestCreateIssueAttachment(t *testing.T) { diff --git a/tests/integration/csrf_test.go b/tests/integration/csrf_test.go index a789859889..fcb9661b8a 100644 --- a/tests/integration/csrf_test.go +++ b/tests/integration/csrf_test.go @@ -5,12 +5,10 @@ package integration import ( "net/http" - "strings" "testing" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" @@ -25,28 +23,12 @@ func TestCsrfProtection(t *testing.T) { req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ "_csrf": "fake_csrf", }) - session.MakeRequest(t, req, http.StatusSeeOther) - - resp := session.MakeRequest(t, req, http.StatusSeeOther) - loc := resp.Header().Get("Location") - assert.Equal(t, setting.AppSubURL+"/", loc) - resp = session.MakeRequest(t, NewRequest(t, "GET", loc), http.StatusOK) - htmlDoc := NewHTMLParser(t, resp.Body) - assert.Equal(t, "Bad Request: invalid CSRF token", - strings.TrimSpace(htmlDoc.doc.Find(".ui.message").Text()), - ) + resp := session.MakeRequest(t, req, http.StatusBadRequest) + assert.Contains(t, resp.Body.String(), "Invalid CSRF token") // test web form csrf via header. TODO: should use an UI api to test req = NewRequest(t, "POST", "/user/settings") req.Header.Add("X-Csrf-Token", "fake_csrf") - session.MakeRequest(t, req, http.StatusSeeOther) - - resp = session.MakeRequest(t, req, http.StatusSeeOther) - loc = resp.Header().Get("Location") - assert.Equal(t, setting.AppSubURL+"/", loc) - resp = session.MakeRequest(t, NewRequest(t, "GET", loc), http.StatusOK) - htmlDoc = NewHTMLParser(t, resp.Body) - assert.Equal(t, "Bad Request: invalid CSRF token", - strings.TrimSpace(htmlDoc.doc.Find(".ui.message").Text()), - ) + resp = session.MakeRequest(t, req, http.StatusBadRequest) + assert.Contains(t, resp.Body.String(), "Invalid CSRF token") } diff --git a/tests/integration/repo_branch_test.go b/tests/integration/repo_branch_test.go index 2aa299479a..df9ea9a97c 100644 --- a/tests/integration/repo_branch_test.go +++ b/tests/integration/repo_branch_test.go @@ -18,7 +18,6 @@ import ( "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/graceful" - "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/translation" repo_service "code.gitea.io/gitea/services/repository" @@ -157,15 +156,8 @@ func TestCreateBranchInvalidCSRF(t *testing.T) { "_csrf": "fake_csrf", "new_branch_name": "test", }) - resp := session.MakeRequest(t, req, http.StatusSeeOther) - loc := resp.Header().Get("Location") - assert.Equal(t, setting.AppSubURL+"/", loc) - resp = session.MakeRequest(t, NewRequest(t, "GET", loc), http.StatusOK) - htmlDoc := NewHTMLParser(t, resp.Body) - assert.Equal(t, - "Bad Request: invalid CSRF token", - strings.TrimSpace(htmlDoc.doc.Find(".ui.message").Text()), - ) + resp := session.MakeRequest(t, req, http.StatusBadRequest) + assert.Contains(t, resp.Body.String(), "Invalid CSRF token") } func TestDatabaseMissingABranch(t *testing.T) { From 6275d1bc5000a09793574696cb18cc5b5c4b07d6 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sun, 22 Sep 2024 12:57:03 +0200 Subject: [PATCH 039/443] Refactor CSRF protector (#32057) (fix forgejo tests) Fix the tests unique to Forgejo that are impacted by the refactor. --- services/context/csrf.go | 7 ++-- tests/integration/links_test.go | 24 +++++++++--- tests/integration/oauth_test.go | 66 ++++++++++++++++++--------------- 3 files changed, 59 insertions(+), 38 deletions(-) diff --git a/services/context/csrf.go b/services/context/csrf.go index 5890d53f42..e0518a499b 100644 --- a/services/context/csrf.go +++ b/services/context/csrf.go @@ -30,8 +30,9 @@ import ( ) const ( - CsrfHeaderName = "X-Csrf-Token" - CsrfFormName = "_csrf" + CsrfHeaderName = "X-Csrf-Token" + CsrfFormName = "_csrf" + CsrfErrorString = "Invalid CSRF token." ) // CSRFProtector represents a CSRF protector and is used to get the current token and validate the token. @@ -144,7 +145,7 @@ func (c *csrfProtector) validateToken(ctx *Context, token string) { c.DeleteCookie(ctx) // currently, there should be no access to the APIPath with CSRF token. because templates shouldn't use the `/api/` endpoints. // FIXME: distinguish what the response is for: HTML (web page) or JSON (fetch) - http.Error(ctx.Resp, "Invalid CSRF token.", http.StatusBadRequest) + http.Error(ctx.Resp, CsrfErrorString, http.StatusBadRequest) } } diff --git a/tests/integration/links_test.go b/tests/integration/links_test.go index 68d7008e02..e9ad933b24 100644 --- a/tests/integration/links_test.go +++ b/tests/integration/links_test.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/test" + forgejo_context "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" @@ -190,11 +191,6 @@ func TestRedirectsWebhooks(t *testing.T) { {from: "/user/settings/hooks/" + kind + "/new", to: "/user/login", verb: "GET"}, {from: "/admin/system-hooks/" + kind + "/new", to: "/user/login", verb: "GET"}, {from: "/admin/default-hooks/" + kind + "/new", to: "/user/login", verb: "GET"}, - {from: "/user2/repo1/settings/hooks/" + kind + "/new", to: "/", verb: "POST"}, - {from: "/admin/system-hooks/" + kind + "/new", to: "/", verb: "POST"}, - {from: "/admin/default-hooks/" + kind + "/new", to: "/", verb: "POST"}, - {from: "/user2/repo1/settings/hooks/1", to: "/", verb: "POST"}, - {from: "/admin/hooks/1", to: "/", verb: "POST"}, } for _, info := range redirects { req := NewRequest(t, info.verb, info.from) @@ -202,6 +198,24 @@ func TestRedirectsWebhooks(t *testing.T) { assert.EqualValues(t, path.Join(setting.AppSubURL, info.to), test.RedirectURL(resp), info.from) } } + + for _, kind := range []string{"forgejo", "gitea"} { + csrf := []struct { + from string + verb string + }{ + {from: "/user2/repo1/settings/hooks/" + kind + "/new", verb: "POST"}, + {from: "/admin/hooks/1", verb: "POST"}, + {from: "/admin/system-hooks/" + kind + "/new", verb: "POST"}, + {from: "/admin/default-hooks/" + kind + "/new", verb: "POST"}, + {from: "/user2/repo1/settings/hooks/1", verb: "POST"}, + } + for _, info := range csrf { + req := NewRequest(t, info.verb, info.from) + resp := MakeRequest(t, req, http.StatusBadRequest) + assert.Contains(t, resp.Body.String(), forgejo_context.CsrfErrorString) + } + } } func TestRepoLinks(t *testing.T) { diff --git a/tests/integration/oauth_test.go b/tests/integration/oauth_test.go index 0d5e9a0472..f385b99e46 100644 --- a/tests/integration/oauth_test.go +++ b/tests/integration/oauth_test.go @@ -11,6 +11,7 @@ import ( "fmt" "io" "net/http" + "net/http/httptest" "net/url" "strings" "testing" @@ -24,6 +25,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/routers/web/auth" + forgejo_context "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/tests" "github.com/markbates/goth" @@ -803,6 +805,16 @@ func TestOAuthIntrospection(t *testing.T) { }) } +func requireCookieCSRF(t *testing.T, resp http.ResponseWriter) string { + for _, c := range resp.(*httptest.ResponseRecorder).Result().Cookies() { + if c.Name == "_csrf" { + return c.Value + } + } + require.True(t, false, "_csrf not found in cookies") + return "" +} + func TestOAuth_GrantScopesReadUser(t *testing.T) { defer tests.PrepareTestEnv(t)() @@ -840,19 +852,18 @@ func TestOAuth_GrantScopesReadUser(t *testing.T) { authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther) authcode := strings.Split(strings.Split(authorizeResp.Body.String(), "?code=")[1], "&")[0] - htmlDoc := NewHTMLParser(t, authorizeResp.Body) grantReq := NewRequestWithValues(t, "POST", "/login/oauth/grant", map[string]string{ - "_csrf": htmlDoc.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "client_id": app.ClientID, "redirect_uri": "a", "state": "thestate", "granted": "true", }) - grantResp := ctx.MakeRequest(t, grantReq, http.StatusSeeOther) - htmlDocGrant := NewHTMLParser(t, grantResp.Body) + grantResp := ctx.MakeRequest(t, grantReq, http.StatusBadRequest) + assert.NotContains(t, grantResp.Body.String(), forgejo_context.CsrfErrorString) accessTokenReq := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{ - "_csrf": htmlDocGrant.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "grant_type": "authorization_code", "client_id": app.ClientID, "client_secret": app.ClientSecret, @@ -921,19 +932,18 @@ func TestOAuth_GrantScopesFailReadRepository(t *testing.T) { authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther) authcode := strings.Split(strings.Split(authorizeResp.Body.String(), "?code=")[1], "&")[0] - htmlDoc := NewHTMLParser(t, authorizeResp.Body) grantReq := NewRequestWithValues(t, "POST", "/login/oauth/grant", map[string]string{ - "_csrf": htmlDoc.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "client_id": app.ClientID, "redirect_uri": "a", "state": "thestate", "granted": "true", }) - grantResp := ctx.MakeRequest(t, grantReq, http.StatusSeeOther) - htmlDocGrant := NewHTMLParser(t, grantResp.Body) + grantResp := ctx.MakeRequest(t, grantReq, http.StatusBadRequest) + assert.NotContains(t, grantResp.Body.String(), forgejo_context.CsrfErrorString) accessTokenReq := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{ - "_csrf": htmlDocGrant.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "grant_type": "authorization_code", "client_id": app.ClientID, "client_secret": app.ClientSecret, @@ -1000,19 +1010,18 @@ func TestOAuth_GrantScopesReadRepository(t *testing.T) { authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther) authcode := strings.Split(strings.Split(authorizeResp.Body.String(), "?code=")[1], "&")[0] - htmlDoc := NewHTMLParser(t, authorizeResp.Body) grantReq := NewRequestWithValues(t, "POST", "/login/oauth/grant", map[string]string{ - "_csrf": htmlDoc.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "client_id": app.ClientID, "redirect_uri": "a", "state": "thestate", "granted": "true", }) - grantResp := ctx.MakeRequest(t, grantReq, http.StatusSeeOther) - htmlDocGrant := NewHTMLParser(t, grantResp.Body) + grantResp := ctx.MakeRequest(t, grantReq, http.StatusBadRequest) + assert.NotContains(t, grantResp.Body.String(), forgejo_context.CsrfErrorString) accessTokenReq := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{ - "_csrf": htmlDocGrant.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "grant_type": "authorization_code", "client_id": app.ClientID, "client_secret": app.ClientSecret, @@ -1082,19 +1091,18 @@ func TestOAuth_GrantScopesReadPrivateGroups(t *testing.T) { authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther) authcode := strings.Split(strings.Split(authorizeResp.Body.String(), "?code=")[1], "&")[0] - htmlDoc := NewHTMLParser(t, authorizeResp.Body) grantReq := NewRequestWithValues(t, "POST", "/login/oauth/grant", map[string]string{ - "_csrf": htmlDoc.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "client_id": app.ClientID, "redirect_uri": "a", "state": "thestate", "granted": "true", }) - grantResp := ctx.MakeRequest(t, grantReq, http.StatusSeeOther) - htmlDocGrant := NewHTMLParser(t, grantResp.Body) + grantResp := ctx.MakeRequest(t, grantReq, http.StatusBadRequest) + assert.NotContains(t, grantResp.Body.String(), forgejo_context.CsrfErrorString) accessTokenReq := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{ - "_csrf": htmlDocGrant.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "grant_type": "authorization_code", "client_id": app.ClientID, "client_secret": app.ClientSecret, @@ -1164,19 +1172,18 @@ func TestOAuth_GrantScopesReadOnlyPublicGroups(t *testing.T) { authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther) authcode := strings.Split(strings.Split(authorizeResp.Body.String(), "?code=")[1], "&")[0] - htmlDoc := NewHTMLParser(t, authorizeResp.Body) grantReq := NewRequestWithValues(t, "POST", "/login/oauth/grant", map[string]string{ - "_csrf": htmlDoc.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "client_id": app.ClientID, "redirect_uri": "a", "state": "thestate", "granted": "true", }) - grantResp := ctx.MakeRequest(t, grantReq, http.StatusSeeOther) - htmlDocGrant := NewHTMLParser(t, grantResp.Body) + grantResp := ctx.MakeRequest(t, grantReq, http.StatusBadRequest) + assert.NotContains(t, grantResp.Body.String(), forgejo_context.CsrfErrorString) accessTokenReq := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{ - "_csrf": htmlDocGrant.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "grant_type": "authorization_code", "client_id": app.ClientID, "client_secret": app.ClientSecret, @@ -1260,19 +1267,18 @@ func TestOAuth_GrantScopesReadPublicGroupsWithTheReadScope(t *testing.T) { authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther) authcode := strings.Split(strings.Split(authorizeResp.Body.String(), "?code=")[1], "&")[0] - htmlDoc := NewHTMLParser(t, authorizeResp.Body) grantReq := NewRequestWithValues(t, "POST", "/login/oauth/grant", map[string]string{ - "_csrf": htmlDoc.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "client_id": app.ClientID, "redirect_uri": "a", "state": "thestate", "granted": "true", }) - grantResp := ctx.MakeRequest(t, grantReq, http.StatusSeeOther) - htmlDocGrant := NewHTMLParser(t, grantResp.Body) + grantResp := ctx.MakeRequest(t, grantReq, http.StatusBadRequest) + assert.NotContains(t, grantResp.Body.String(), forgejo_context.CsrfErrorString) accessTokenReq := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{ - "_csrf": htmlDocGrant.GetCSRF(), + "_csrf": requireCookieCSRF(t, authorizeResp), "grant_type": "authorization_code", "client_id": app.ClientID, "client_secret": app.ClientSecret, From 526054332acb221e061d3900bba2dc6e012da52d Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Fri, 20 Sep 2024 21:00:39 +0200 Subject: [PATCH 040/443] Fix incorrect `/tokens` api (#32085) Fixes #32078 - Add missing scopes output. - Disallow empty scope. --------- Co-authored-by: Lunny Xiao (cherry picked from commit 08adbc468f8875fd4763c3656b334203c11adc0a) --- routers/api/v1/user/app.go | 5 +++++ tests/integration/api_token_test.go | 31 ++++++++++------------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index b61ebac7d0..d5b20f7703 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -118,6 +118,10 @@ func CreateAccessToken(ctx *context.APIContext) { ctx.Error(http.StatusBadRequest, "AccessTokenScope.Normalize", fmt.Errorf("invalid access token scope provided: %w", err)) return } + if scope == "" { + ctx.Error(http.StatusBadRequest, "AccessTokenScope", "access token must have a scope") + return + } t.Scope = scope if err := auth_model.NewAccessToken(ctx, t); err != nil { @@ -129,6 +133,7 @@ func CreateAccessToken(ctx *context.APIContext) { Token: t.Token, ID: t.ID, TokenLastEight: t.TokenLastEight, + Scopes: t.Scope.StringSlice(), }) } diff --git a/tests/integration/api_token_test.go b/tests/integration/api_token_test.go index 9c7bf37330..01d18ef6f1 100644 --- a/tests/integration/api_token_test.go +++ b/tests/integration/api_token_test.go @@ -23,10 +23,10 @@ func TestAPICreateAndDeleteToken(t *testing.T) { defer tests.PrepareTestEnv(t)() user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - newAccessToken := createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user, nil) + newAccessToken := createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll}) deleteAPIAccessToken(t, newAccessToken, user) - newAccessToken = createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user, nil) + newAccessToken = createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll}) deleteAPIAccessToken(t, newAccessToken, user) } @@ -72,19 +72,19 @@ func TestAPIDeleteTokensPermission(t *testing.T) { user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // admin can delete tokens for other users - createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user2, nil) + createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user2, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll}) req := NewRequest(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-1"). AddBasicAuth(admin.Name) MakeRequest(t, req, http.StatusNoContent) // non-admin can delete tokens for himself - createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user2, nil) + createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user2, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll}) req = NewRequest(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-2"). AddBasicAuth(user2.Name) MakeRequest(t, req, http.StatusNoContent) // non-admin can't delete tokens for other users - createAPIAccessTokenWithoutCleanUp(t, "test-key-3", user2, nil) + createAPIAccessTokenWithoutCleanUp(t, "test-key-3", user2, []auth_model.AccessTokenScope{auth_model.AccessTokenScopeAll}) req = NewRequest(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-3"). AddBasicAuth(user4.Name) MakeRequest(t, req, http.StatusForbidden) @@ -520,7 +520,7 @@ func runTestCase(t *testing.T, testCase *requiredScopeTestCase, user *user_model unauthorizedScopes = append(unauthorizedScopes, cateogoryUnauthorizedScopes...) } - accessToken := createAPIAccessTokenWithoutCleanUp(t, "test-token", user, &unauthorizedScopes) + accessToken := createAPIAccessTokenWithoutCleanUp(t, "test-token", user, unauthorizedScopes) defer deleteAPIAccessToken(t, accessToken, user) // Request the endpoint. Verify that permission is denied. @@ -532,20 +532,12 @@ func runTestCase(t *testing.T, testCase *requiredScopeTestCase, user *user_model // createAPIAccessTokenWithoutCleanUp Create an API access token and assert that // creation succeeded. The caller is responsible for deleting the token. -func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *user_model.User, scopes *[]auth_model.AccessTokenScope) api.AccessToken { +func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *user_model.User, scopes []auth_model.AccessTokenScope) api.AccessToken { payload := map[string]any{ - "name": tokenName, - } - if scopes != nil { - for _, scope := range *scopes { - scopes, scopesExists := payload["scopes"].([]string) - if !scopesExists { - scopes = make([]string, 0) - } - scopes = append(scopes, string(scope)) - payload["scopes"] = scopes - } + "name": tokenName, + "scopes": scopes, } + log.Debug("Requesting creation of token with scopes: %v", scopes) req := NewRequestWithJSON(t, "POST", "/api/v1/users/"+user.LoginName+"/tokens", payload). AddBasicAuth(user.Name) @@ -563,8 +555,7 @@ func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *us return newAccessToken } -// createAPIAccessTokenWithoutCleanUp Delete an API access token and assert that -// deletion succeeded. +// deleteAPIAccessToken deletes an API access token and assert that deletion succeeded. func deleteAPIAccessToken(t *testing.T, accessToken api.AccessToken, user *user_model.User) { req := NewRequestf(t, "DELETE", "/api/v1/users/"+user.LoginName+"/tokens/%d", accessToken.ID). AddBasicAuth(user.Name) From 2675a24649af2fff34f5c7e416d6ff78591d8d9c Mon Sep 17 00:00:00 2001 From: Timon van der Berg Date: Sat, 21 Sep 2024 20:57:01 +0200 Subject: [PATCH 041/443] Repo Activity: count new issues that were closed (#31776) I'm new to go and contributing to gitea, your guidance is much appreciated. This is meant to solve https://github.com/go-gitea/gitea/issues/13309 Previously, closed issues would not be shown under new issues in the activity tab, even if they were newly created. changes: * Split out newlyCreatedIssues from issuesForActivityStatement to count both currently open and closed issues. * Use a seperate function to count active issues to prevent double-counting issues after the above change. Result is that new issues that have been closed are shown both under "new" and "closed". Signed-off-by: Timon van der Berg (cherry picked from commit ebfde845294cc681de6b1fe1adcf27e35f61b89b) --- models/activities/repo_activity.go | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/models/activities/repo_activity.go b/models/activities/repo_activity.go index ba5e4959f0..3ffad035b7 100644 --- a/models/activities/repo_activity.go +++ b/models/activities/repo_activity.go @@ -34,6 +34,7 @@ type ActivityStats struct { OpenedPRAuthorCount int64 MergedPRs issues_model.PullRequestList MergedPRAuthorCount int64 + ActiveIssues issues_model.IssueList OpenedIssues issues_model.IssueList OpenedIssueAuthorCount int64 ClosedIssues issues_model.IssueList @@ -172,7 +173,7 @@ func (stats *ActivityStats) MergedPRPerc() int { // ActiveIssueCount returns total active issue count func (stats *ActivityStats) ActiveIssueCount() int { - return stats.OpenedIssueCount() + stats.ClosedIssueCount() + return len(stats.ActiveIssues) } // OpenedIssueCount returns open issue count @@ -285,13 +286,21 @@ func (stats *ActivityStats) FillIssues(ctx context.Context, repoID int64, fromTi stats.ClosedIssueAuthorCount = count // New issues - sess = issuesForActivityStatement(ctx, repoID, fromTime, false, false) + sess = newlyCreatedIssues(ctx, repoID, fromTime) sess.OrderBy("issue.created_unix ASC") stats.OpenedIssues = make(issues_model.IssueList, 0) if err = sess.Find(&stats.OpenedIssues); err != nil { return err } + // Active issues + sess = activeIssues(ctx, repoID, fromTime) + sess.OrderBy("issue.created_unix ASC") + stats.ActiveIssues = make(issues_model.IssueList, 0) + if err = sess.Find(&stats.ActiveIssues); err != nil { + return err + } + // Opened issue authors sess = issuesForActivityStatement(ctx, repoID, fromTime, false, false) if _, err = sess.Select("count(distinct issue.poster_id) as `count`").Table("issue").Get(&count); err != nil { @@ -317,6 +326,23 @@ func (stats *ActivityStats) FillUnresolvedIssues(ctx context.Context, repoID int return sess.Find(&stats.UnresolvedIssues) } +func newlyCreatedIssues(ctx context.Context, repoID int64, fromTime time.Time) *xorm.Session { + sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID). + And("issue.is_pull = ?", false). // Retain the is_pull check to exclude pull requests + And("issue.created_unix >= ?", fromTime.Unix()) // Include all issues created after fromTime + + return sess +} + +func activeIssues(ctx context.Context, repoID int64, fromTime time.Time) *xorm.Session { + sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID). + And("issue.is_pull = ?", false). + And("issue.created_unix >= ?", fromTime.Unix()). + Or("issue.closed_unix >= ?", fromTime.Unix()) + + return sess +} + func issuesForActivityStatement(ctx context.Context, repoID int64, fromTime time.Time, closed, unresolved bool) *xorm.Session { sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID). And("issue.is_closed = ?", closed) From f709de24039ab7e605d3e09e3b61240836381603 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 22 Sep 2024 05:56:25 +0800 Subject: [PATCH 042/443] Fix wrong last modify time (#32102) (cherry picked from commit a802508f88e546bf18990559e44bf27a09c869ee) --- modules/httpcache/httpcache.go | 3 ++- modules/httplib/serve.go | 1 + routers/api/packages/maven/maven.go | 4 +++- routers/web/repo/githttp.go | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go index b4af371541..30ce0a4a03 100644 --- a/modules/httpcache/httpcache.go +++ b/modules/httpcache/httpcache.go @@ -76,7 +76,8 @@ func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag s w.Header().Set("Etag", etag) } if lastModified != nil && !lastModified.IsZero() { - w.Header().Set("Last-Modified", lastModified.Format(http.TimeFormat)) + // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat + w.Header().Set("Last-Modified", lastModified.UTC().Format(http.TimeFormat)) } if len(etag) > 0 { diff --git a/modules/httplib/serve.go b/modules/httplib/serve.go index 6e147d76f5..2e3e6a7c42 100644 --- a/modules/httplib/serve.go +++ b/modules/httplib/serve.go @@ -79,6 +79,7 @@ func ServeSetHeaders(w http.ResponseWriter, opts *ServeHeaderOptions) { httpcache.SetCacheControlInHeader(header, duration) if !opts.LastModified.IsZero() { + // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat header.Set("Last-Modified", opts.LastModified.UTC().Format(http.TimeFormat)) } } diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index 58271e1d43..4181577454 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -117,7 +117,9 @@ func serveMavenMetadata(ctx *context.Context, params parameters) { xmlMetadataWithHeader := append([]byte(xml.Header), xmlMetadata...) latest := pds[len(pds)-1] - ctx.Resp.Header().Set("Last-Modified", latest.Version.CreatedUnix.Format(http.TimeFormat)) + // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat + lastModifed := latest.Version.CreatedUnix.AsTime().UTC().Format(http.TimeFormat) + ctx.Resp.Header().Set("Last-Modified", lastModifed) ext := strings.ToLower(filepath.Ext(params.Filename)) if isChecksumExtension(ext) { diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index 9f3b63698a..a082498dfd 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -395,7 +395,8 @@ func (h *serviceHandler) sendFile(ctx *context.Context, contentType, file string ctx.Resp.Header().Set("Content-Type", contentType) ctx.Resp.Header().Set("Content-Length", fmt.Sprintf("%d", fi.Size())) - ctx.Resp.Header().Set("Last-Modified", fi.ModTime().Format(http.TimeFormat)) + // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat + ctx.Resp.Header().Set("Last-Modified", fi.ModTime().UTC().Format(http.TimeFormat)) http.ServeFile(ctx.Resp, ctx.Req, reqFile) } From 9d3473119893ffde0ab36d98e7a0e41c5d0ba9a3 Mon Sep 17 00:00:00 2001 From: Jamie Schouten Date: Sun, 22 Sep 2024 00:42:17 +0200 Subject: [PATCH 043/443] Add bin to Composer Metadata (#32099) This PR addresses the missing `bin` field in Composer metadata, which currently causes vendor-provided binaries to not be symlinked to `vendor/bin` during installation. In the current implementation, running `composer install` does not publish the binaries, leading to issues where expected binaries are not available. By properly declaring the `bin` field, this PR ensures that binaries are correctly symlinked upon installation, as described in the [Composer documentation](https://getcomposer.org/doc/articles/vendor-binaries.md). (cherry picked from commit d351a42494e71b5e2da63302c2f9b46c78e6dbde) --- modules/packages/composer/metadata.go | 1 + tests/integration/api_packages_composer_test.go | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/packages/composer/metadata.go b/modules/packages/composer/metadata.go index 2c2e9ebf27..6035eae8ca 100644 --- a/modules/packages/composer/metadata.go +++ b/modules/packages/composer/metadata.go @@ -48,6 +48,7 @@ type Metadata struct { Homepage string `json:"homepage,omitempty"` License Licenses `json:"license,omitempty"` Authors []Author `json:"authors,omitempty"` + Bin []string `json:"bin,omitempty"` Autoload map[string]any `json:"autoload,omitempty"` AutoloadDev map[string]any `json:"autoload-dev,omitempty"` Extra map[string]any `json:"extra,omitempty"` diff --git a/tests/integration/api_packages_composer_test.go b/tests/integration/api_packages_composer_test.go index 9cdcd07e37..9d25cc4d64 100644 --- a/tests/integration/api_packages_composer_test.go +++ b/tests/integration/api_packages_composer_test.go @@ -37,6 +37,7 @@ func TestPackageComposer(t *testing.T) { packageType := "composer-plugin" packageAuthor := "Gitea Authors" packageLicense := "MIT" + packageBin := "./bin/script" var buf bytes.Buffer archive := zip.NewWriter(&buf) @@ -50,6 +51,9 @@ func TestPackageComposer(t *testing.T) { { "name": "` + packageAuthor + `" } + ], + "bin": [ + "` + packageBin + `" ] }`)) archive.Close() @@ -211,6 +215,8 @@ func TestPackageComposer(t *testing.T) { assert.Len(t, pkgs[0].Authors, 1) assert.Equal(t, packageAuthor, pkgs[0].Authors[0].Name) assert.Equal(t, "zip", pkgs[0].Dist.Type) - assert.Equal(t, "7b40bfd6da811b2b78deec1e944f156dbb2c747b", pkgs[0].Dist.Checksum) + assert.Equal(t, "4f5fa464c3cb808a1df191dbf6cb75363f8b7072", pkgs[0].Dist.Checksum) + assert.Len(t, pkgs[0].Bin, 1) + assert.Equal(t, packageBin, pkgs[0].Bin[0]) }) } From 2ffb08bb888bb950b6ed4ff12a4cf4bacc337e18 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 21 Sep 2024 17:50:54 +0800 Subject: [PATCH 044/443] Use camo.Always instead of camo.Allways (#32097) Fix #31575 https://gitea.com/gitea/docs/pulls/73 (cherry picked from commit 8e2dd5d3ddfb442937c79f05df88d18b856952cb) --- custom/conf/app.example.ini | 3 ++- modules/markup/camo.go | 2 +- modules/markup/camo_test.go | 2 +- modules/setting/camo.go | 14 ++++++++++++-- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 9cb5a67172..2eff51fe98 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -529,7 +529,8 @@ INTERNAL_TOKEN = ;; HMAC to encode urls with, it **is required** if camo is enabled. ;HMAC_KEY = ;; Set to true to use camo for https too lese only non https urls are proxyed -;ALLWAYS = false +;; ALLWAYS is deprecated and will be removed in the future +;ALWAYS = false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/modules/markup/camo.go b/modules/markup/camo.go index e93797de2b..7e2583469d 100644 --- a/modules/markup/camo.go +++ b/modules/markup/camo.go @@ -38,7 +38,7 @@ func camoHandleLink(link string) string { if setting.Camo.Enabled { lnkURL, err := url.Parse(link) if err == nil && lnkURL.IsAbs() && !strings.HasPrefix(link, setting.AppURL) && - (setting.Camo.Allways || lnkURL.Scheme != "https") { + (setting.Camo.Always || lnkURL.Scheme != "https") { return CamoEncode(link) } } diff --git a/modules/markup/camo_test.go b/modules/markup/camo_test.go index ba58835221..3c5d40afa0 100644 --- a/modules/markup/camo_test.go +++ b/modules/markup/camo_test.go @@ -28,7 +28,7 @@ func TestCamoHandleLink(t *testing.T) { "https://image.proxy/eivin43gJwGVIjR9MiYYtFIk0mw/aHR0cDovL3Rlc3RpbWFnZXMub3JnL2ltZy5qcGc", camoHandleLink("http://testimages.org/img.jpg")) - setting.Camo.Allways = true + setting.Camo.Always = true assert.Equal(t, "https://gitea.com/img.jpg", camoHandleLink("https://gitea.com/img.jpg")) diff --git a/modules/setting/camo.go b/modules/setting/camo.go index 366e9a116c..608ecf8363 100644 --- a/modules/setting/camo.go +++ b/modules/setting/camo.go @@ -3,18 +3,28 @@ package setting -import "code.gitea.io/gitea/modules/log" +import ( + "strconv" + + "code.gitea.io/gitea/modules/log" +) var Camo = struct { Enabled bool ServerURL string `ini:"SERVER_URL"` HMACKey string `ini:"HMAC_KEY"` - Allways bool + Always bool }{} func loadCamoFrom(rootCfg ConfigProvider) { mustMapSetting(rootCfg, "camo", &Camo) if Camo.Enabled { + oldValue := rootCfg.Section("camo").Key("ALLWAYS").MustString("") + if oldValue != "" { + log.Warn("camo.ALLWAYS is deprecated, use camo.ALWAYS instead") + Camo.Always, _ = strconv.ParseBool(oldValue) + } + if Camo.ServerURL == "" || Camo.HMACKey == "" { log.Fatal(`Camo settings require "SERVER_URL" and HMAC_KEY`) } From e3deb88a8d2494e386f221b9dc743a6a1710837d Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sun, 22 Sep 2024 10:01:43 +0200 Subject: [PATCH 045/443] chore(release-notes): weekly cherry-pick week 2024-39 --- release-notes/5372.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 release-notes/5372.md diff --git a/release-notes/5372.md b/release-notes/5372.md new file mode 100644 index 0000000000..fccb305f34 --- /dev/null +++ b/release-notes/5372.md @@ -0,0 +1,5 @@ +feat: [commit](https://codeberg.org/forgejo/forgejo/commit/9d3473119893ffde0ab36d98e7a0e41c5d0ba9a3) Add bin to Composer Metadata. +fix: [commit](https://codeberg.org/forgejo/forgejo/commit/f709de24039ab7e605d3e09e3b61240836381603) Fix wrong last modify time. +fix: [commit](https://codeberg.org/forgejo/forgejo/commit/2675a24649af2fff34f5c7e416d6ff78591d8d9c) Repo Activity: count new issues that were closed. +fix: [commit](https://codeberg.org/forgejo/forgejo/commit/526054332acb221e061d3900bba2dc6e012da52d) Fix incorrect /tokens api. +fix: [commit](https://codeberg.org/forgejo/forgejo/commit/0cafec4c7a2faf810953e9d522faf5dc019e1522) Do not escape relative path in RPM primary index. From 89742c49135e47372e272596bd536d5d1244721f Mon Sep 17 00:00:00 2001 From: Exploding Dragon Date: Fri, 27 Sep 2024 08:21:22 +0000 Subject: [PATCH 046/443] feat: add architecture-specific removal support for arch package (#5351) - [x] add architecture-specific removal support - [x] Fix upload competition - [x] Fix not checking input when downloading docs: https://codeberg.org/forgejo/docs/pulls/874 ### Release notes - [ ] I do not want this change to show in the release notes. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5351 Reviewed-by: Earl Warren Co-authored-by: Exploding Dragon Co-committed-by: Exploding Dragon --- modules/packages/arch/metadata.go | 69 ++++++++++----------- routers/api/packages/api.go | 12 ++-- routers/api/packages/arch/arch.go | 47 +++++++++----- services/packages/arch/repository.go | 65 ++++++++++--------- templates/package/content/arch.tmpl | 4 +- templates/package/metadata/arch.tmpl | 4 +- tests/integration/api_packages_arch_test.go | 50 ++++++++++++--- 7 files changed, 151 insertions(+), 100 deletions(-) diff --git a/modules/packages/arch/metadata.go b/modules/packages/arch/metadata.go index 0e08670311..6cdde75cdc 100644 --- a/modules/packages/arch/metadata.go +++ b/modules/packages/arch/metadata.go @@ -39,8 +39,8 @@ const ( var ( reName = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+$`) reVer = regexp.MustCompile(`^[a-zA-Z0-9:_.+]+-+[0-9]+$`) - reOptDep = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+([<>]?=?[a-zA-Z0-9@._+-]+)?(:.*)?$`) - rePkgVer = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+([<>]?=?[a-zA-Z0-9@._+-]+)?$`) + reOptDep = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+([<>]?=?([0-9]+:)?[a-zA-Z0-9@._+-]+)?(:.*)?$`) + rePkgVer = regexp.MustCompile(`^[a-zA-Z0-9@._+-]+([<>]?=?([0-9]+:)?[a-zA-Z0-9@._+-]+)?$`) magicZSTD = []byte{0x28, 0xB5, 0x2F, 0xFD} magicXZ = []byte{0xFD, 0x37, 0x7A, 0x58, 0x5A} @@ -71,7 +71,7 @@ type VersionMetadata struct { Conflicts []string `json:"conflicts,omitempty"` Replaces []string `json:"replaces,omitempty"` Backup []string `json:"backup,omitempty"` - Xdata []string `json:"xdata,omitempty"` + XData []string `json:"xdata,omitempty"` } // FileMetadata Metadata related to specific package file. @@ -125,7 +125,7 @@ func ParsePackage(r *packages.HashedBuffer) (*Package, error) { defer tarball.Close() var pkg *Package - var mtree bool + var mTree bool for { f, err := tarball.Read() @@ -135,24 +135,24 @@ func ParsePackage(r *packages.HashedBuffer) (*Package, error) { if err != nil { return nil, err } - defer f.Close() - switch f.Name() { case ".PKGINFO": pkg, err = ParsePackageInfo(tarballType, f) if err != nil { + _ = f.Close() return nil, err } case ".MTREE": - mtree = true + mTree = true } + _ = f.Close() } if pkg == nil { return nil, util.NewInvalidArgumentErrorf(".PKGINFO file not found") } - if !mtree { + if !mTree { return nil, util.NewInvalidArgumentErrorf(".MTREE file not found") } @@ -220,7 +220,7 @@ func ParsePackageInfo(compressType string, r io.Reader) (*Package, error) { case "replaces": p.VersionMetadata.Replaces = append(p.VersionMetadata.Replaces, value) case "xdata": - p.VersionMetadata.Xdata = append(p.VersionMetadata.Xdata, value) + p.VersionMetadata.XData = append(p.VersionMetadata.XData, value) case "builddate": bd, err := strconv.ParseInt(value, 10, 64) if err != nil { @@ -260,48 +260,43 @@ func ValidatePackageSpec(p *Package) error { return util.NewInvalidArgumentErrorf("invalid project URL") } } - for _, cd := range p.VersionMetadata.CheckDepends { - if !rePkgVer.MatchString(cd) { - return util.NewInvalidArgumentErrorf("invalid check dependency: %s", cd) + for _, checkDepend := range p.VersionMetadata.CheckDepends { + if !rePkgVer.MatchString(checkDepend) { + return util.NewInvalidArgumentErrorf("invalid check dependency: %s", checkDepend) } } - for _, d := range p.VersionMetadata.Depends { - if !rePkgVer.MatchString(d) { - return util.NewInvalidArgumentErrorf("invalid dependency: %s", d) + for _, depend := range p.VersionMetadata.Depends { + if !rePkgVer.MatchString(depend) { + return util.NewInvalidArgumentErrorf("invalid dependency: %s", depend) } } - for _, md := range p.VersionMetadata.MakeDepends { - if !rePkgVer.MatchString(md) { - return util.NewInvalidArgumentErrorf("invalid make dependency: %s", md) + for _, makeDepend := range p.VersionMetadata.MakeDepends { + if !rePkgVer.MatchString(makeDepend) { + return util.NewInvalidArgumentErrorf("invalid make dependency: %s", makeDepend) } } - for _, p := range p.VersionMetadata.Provides { - if !rePkgVer.MatchString(p) { - return util.NewInvalidArgumentErrorf("invalid provides: %s", p) + for _, provide := range p.VersionMetadata.Provides { + if !rePkgVer.MatchString(provide) { + return util.NewInvalidArgumentErrorf("invalid provides: %s", provide) } } - for _, p := range p.VersionMetadata.Conflicts { - if !rePkgVer.MatchString(p) { - return util.NewInvalidArgumentErrorf("invalid conflicts: %s", p) + for _, conflict := range p.VersionMetadata.Conflicts { + if !rePkgVer.MatchString(conflict) { + return util.NewInvalidArgumentErrorf("invalid conflicts: %s", conflict) } } - for _, p := range p.VersionMetadata.Replaces { - if !rePkgVer.MatchString(p) { - return util.NewInvalidArgumentErrorf("invalid replaces: %s", p) + for _, replace := range p.VersionMetadata.Replaces { + if !rePkgVer.MatchString(replace) { + return util.NewInvalidArgumentErrorf("invalid replaces: %s", replace) } } - for _, p := range p.VersionMetadata.Replaces { - if !rePkgVer.MatchString(p) { - return util.NewInvalidArgumentErrorf("invalid xdata: %s", p) + for _, optDepend := range p.VersionMetadata.OptDepends { + if !reOptDep.MatchString(optDepend) { + return util.NewInvalidArgumentErrorf("invalid optional dependency: %s", optDepend) } } - for _, od := range p.VersionMetadata.OptDepends { - if !reOptDep.MatchString(od) { - return util.NewInvalidArgumentErrorf("invalid optional dependency: %s", od) - } - } - for _, bf := range p.VersionMetadata.Backup { - if strings.HasPrefix(bf, "/") { + for _, b := range p.VersionMetadata.Backup { + if strings.HasPrefix(b, "/") { return util.NewInvalidArgumentErrorf("backup file contains leading forward slash") } } diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index 76a8fd4714..c72f812704 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -175,18 +175,20 @@ func CommonRoutes() *web.Route { arch.PushPackage(ctx) return } else if isDelete { - if groupLen < 2 { + if groupLen < 3 { ctx.Status(http.StatusBadRequest) return } - if groupLen == 2 { + if groupLen == 3 { ctx.SetParams("group", "") ctx.SetParams("package", pathGroups[0]) ctx.SetParams("version", pathGroups[1]) + ctx.SetParams("arch", pathGroups[2]) } else { - ctx.SetParams("group", strings.Join(pathGroups[:groupLen-2], "/")) - ctx.SetParams("package", pathGroups[groupLen-2]) - ctx.SetParams("version", pathGroups[groupLen-1]) + ctx.SetParams("group", strings.Join(pathGroups[:groupLen-3], "/")) + ctx.SetParams("package", pathGroups[groupLen-3]) + ctx.SetParams("version", pathGroups[groupLen-2]) + ctx.SetParams("arch", pathGroups[groupLen-1]) } reqPackageAccess(perm.AccessModeWrite)(ctx) if ctx.Written() { diff --git a/routers/api/packages/arch/arch.go b/routers/api/packages/arch/arch.go index 2d3481a33f..15fcc37c70 100644 --- a/routers/api/packages/arch/arch.go +++ b/routers/api/packages/arch/arch.go @@ -9,12 +9,14 @@ import ( "fmt" "io" "net/http" + "path/filepath" "regexp" "strings" packages_model "code.gitea.io/gitea/models/packages" packages_module "code.gitea.io/gitea/modules/packages" arch_module "code.gitea.io/gitea/modules/packages/arch" + "code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" "code.gitea.io/gitea/services/context" @@ -25,6 +27,8 @@ import ( var ( archPkgOrSig = regexp.MustCompile(`^.*\.pkg\.tar\.\w+(\.sig)*$`) archDBOrSig = regexp.MustCompile(`^.*.db(\.tar\.gz)*(\.sig)*$`) + + locker = sync.NewExclusivePool() ) func apiError(ctx *context.Context, status int, obj any) { @@ -33,6 +37,14 @@ func apiError(ctx *context.Context, status int, obj any) { }) } +func refreshLocker(ctx *context.Context, group string) func() { + key := fmt.Sprintf("pkg_%d_arch_pkg_%s", ctx.Package.Owner.ID, group) + locker.CheckIn(key) + return func() { + locker.CheckOut(key) + } +} + func GetRepositoryKey(ctx *context.Context) { _, pub, err := arch_service.GetOrCreateKeyPair(ctx, ctx.Package.Owner.ID) if err != nil { @@ -48,7 +60,8 @@ func GetRepositoryKey(ctx *context.Context) { func PushPackage(ctx *context.Context) { group := ctx.Params("group") - + releaser := refreshLocker(ctx, group) + defer releaser() upload, needToClose, err := ctx.UploadStream() if err != nil { apiError(ctx, http.StatusInternalServerError, err) @@ -154,6 +167,7 @@ func PushPackage(ctx *context.Context) { }) if err != nil { apiError(ctx, http.StatusInternalServerError, err) + return } if err = arch_service.BuildPacmanDB(ctx, ctx.Package.Owner.ID, group, p.FileMetadata.Arch); err != nil { apiError(ctx, http.StatusInternalServerError, err) @@ -169,7 +183,7 @@ func GetPackageOrDB(ctx *context.Context) { arch = ctx.Params("arch") ) if archPkgOrSig.MatchString(file) { - pkg, err := arch_service.GetPackageFile(ctx, group, file, ctx.Package.Owner.ID) + pkg, u, pf, err := arch_service.GetPackageFile(ctx, group, file, ctx.Package.Owner.ID) if err != nil { if errors.Is(err, util.ErrNotExist) { apiError(ctx, http.StatusNotFound, err) @@ -178,15 +192,12 @@ func GetPackageOrDB(ctx *context.Context) { } return } - - ctx.ServeContent(pkg, &context.ServeHeaderOptions{ - Filename: file, - }) + helper.ServePackageFile(ctx, pkg, u, pf) return } if archDBOrSig.MatchString(file) { - pkg, err := arch_service.GetPackageDBFile(ctx, group, arch, ctx.Package.Owner.ID, + pkg, u, pf, err := arch_service.GetPackageDBFile(ctx, group, arch, ctx.Package.Owner.ID, strings.HasSuffix(file, ".sig")) if err != nil { if errors.Is(err, util.ErrNotExist) { @@ -196,9 +207,7 @@ func GetPackageOrDB(ctx *context.Context) { } return } - ctx.ServeContent(pkg, &context.ServeHeaderOptions{ - Filename: file, - }) + helper.ServePackageFile(ctx, pkg, u, pf) return } @@ -207,10 +216,13 @@ func GetPackageOrDB(ctx *context.Context) { func RemovePackage(ctx *context.Context) { var ( - group = ctx.Params("group") - pkg = ctx.Params("package") - ver = ctx.Params("version") + group = ctx.Params("group") + pkg = ctx.Params("package") + ver = ctx.Params("version") + pkgArch = ctx.Params("arch") ) + releaser := refreshLocker(ctx, group) + defer releaser() pv, err := packages_model.GetVersionByNameAndVersion( ctx, ctx.Package.Owner.ID, packages_model.TypeArch, pkg, ver, ) @@ -229,7 +241,13 @@ func RemovePackage(ctx *context.Context) { } deleted := false for _, file := range files { - if file.CompositeKey == group { + extName := fmt.Sprintf("-%s.pkg.tar%s", pkgArch, filepath.Ext(file.LowerName)) + if strings.HasSuffix(file.LowerName, ".sig") { + extName = fmt.Sprintf("-%s.pkg.tar%s.sig", pkgArch, + filepath.Ext(strings.TrimSuffix(file.LowerName, filepath.Ext(file.LowerName)))) + } + if file.CompositeKey == group && + strings.HasSuffix(file.LowerName, extName) { deleted = true err := packages_service.RemovePackageFileAndVersionIfUnreferenced(ctx, ctx.ContextUser, file) if err != nil { @@ -242,6 +260,7 @@ func RemovePackage(ctx *context.Context) { err = arch_service.BuildCustomRepositoryFiles(ctx, ctx.Package.Owner.ID, group) if err != nil { apiError(ctx, http.StatusInternalServerError, err) + return } ctx.Status(http.StatusNoContent) } else { diff --git a/services/packages/arch/repository.go b/services/packages/arch/repository.go index de72467421..58433ab5c2 100644 --- a/services/packages/arch/repository.go +++ b/services/packages/arch/repository.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "io" + "net/url" "os" "path/filepath" "sort" @@ -20,6 +21,7 @@ import ( packages_module "code.gitea.io/gitea/modules/packages" arch_module "code.gitea.io/gitea/modules/packages/arch" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/sync" "code.gitea.io/gitea/modules/util" packages_service "code.gitea.io/gitea/services/packages" @@ -28,6 +30,8 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/packet" ) +var locker = sync.NewExclusivePool() + func GetOrCreateRepositoryVersion(ctx context.Context, ownerID int64) (*packages_model.PackageVersion, error) { return packages_service.GetOrCreateInternalPackageVersion(ctx, ownerID, packages_model.TypeArch, arch_module.RepositoryPackage, arch_module.RepositoryVersion) } @@ -101,6 +105,9 @@ func NewFileSign(ctx context.Context, ownerID int64, input io.Reader) (*packages // BuildPacmanDB Create db signature cache func BuildPacmanDB(ctx context.Context, ownerID int64, group, arch string) error { + key := fmt.Sprintf("pkg_%d_arch_db_%s", ownerID, group) + locker.CheckIn(key) + defer locker.CheckOut(key) pv, err := GetOrCreateRepositoryVersion(ctx, ownerID) if err != nil { return err @@ -173,15 +180,18 @@ func createDB(ctx context.Context, ownerID int64, group, arch string) (*packages if err != nil { return nil, err } + defer db.Close() gw := gzip.NewWriter(db) + defer gw.Close() tw := tar.NewWriter(gw) + defer tw.Close() count := 0 for _, pkg := range pkgs { versions, err := packages_model.GetVersionsByPackageName( ctx, ownerID, packages_model.TypeArch, pkg.Name, ) if err != nil { - return nil, errors.Join(tw.Close(), gw.Close(), db.Close(), err) + return nil, err } sort.Slice(versions, func(i, j int) bool { return versions[i].CreatedUnix > versions[j].CreatedUnix @@ -190,7 +200,7 @@ func createDB(ctx context.Context, ownerID int64, group, arch string) (*packages for _, ver := range versions { files, err := packages_model.GetFilesByVersionID(ctx, ver.ID) if err != nil { - return nil, errors.Join(tw.Close(), gw.Close(), db.Close(), err) + return nil, err } var pf *packages_model.PackageFile for _, file := range files { @@ -213,7 +223,7 @@ func createDB(ctx context.Context, ownerID int64, group, arch string) (*packages ctx, packages_model.PropertyTypeFile, pf.ID, arch_module.PropertyDescription, ) if err != nil { - return nil, errors.Join(tw.Close(), gw.Close(), db.Close(), err) + return nil, err } if len(pps) >= 1 { meta := []byte(pps[0].Value) @@ -223,60 +233,50 @@ func createDB(ctx context.Context, ownerID int64, group, arch string) (*packages Mode: int64(os.ModePerm), } if err = tw.WriteHeader(header); err != nil { - return nil, errors.Join(tw.Close(), gw.Close(), db.Close(), err) + return nil, err } if _, err := tw.Write(meta); err != nil { - return nil, errors.Join(tw.Close(), gw.Close(), db.Close(), err) + return nil, err } count++ break } } } - defer gw.Close() - defer tw.Close() if count == 0 { - return nil, errors.Join(db.Close(), io.EOF) + return nil, io.EOF } return db, nil } // GetPackageFile Get data related to provided filename and distribution, for package files // update download counter. -func GetPackageFile(ctx context.Context, group, file string, ownerID int64) (io.ReadSeekCloser, error) { - pf, err := getPackageFile(ctx, group, file, ownerID) - if err != nil { - return nil, err +func GetPackageFile(ctx context.Context, group, file string, ownerID int64) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) { + fileSplit := strings.Split(file, "-") + if len(fileSplit) <= 3 { + return nil, nil, nil, errors.New("invalid file format, need ---.pkg.") } - - filestream, _, _, err := packages_service.GetPackageFileStream(ctx, pf) - return filestream, err -} - -// Ejects parameters required to get package file property from file name. -func getPackageFile(ctx context.Context, group, file string, ownerID int64) (*packages_model.PackageFile, error) { var ( - splt = strings.Split(file, "-") - pkgname = strings.Join(splt[0:len(splt)-3], "-") - vername = splt[len(splt)-3] + "-" + splt[len(splt)-2] + pkgName = strings.Join(fileSplit[0:len(fileSplit)-3], "-") + pkgVer = fileSplit[len(fileSplit)-3] + "-" + fileSplit[len(fileSplit)-2] ) - - version, err := packages_model.GetVersionByNameAndVersion(ctx, ownerID, packages_model.TypeArch, pkgname, vername) + version, err := packages_model.GetVersionByNameAndVersion(ctx, ownerID, packages_model.TypeArch, pkgName, pkgVer) if err != nil { - return nil, err + return nil, nil, nil, err } - pkgfile, err := packages_model.GetFileForVersionByName(ctx, version.ID, file, group) + pkgFile, err := packages_model.GetFileForVersionByName(ctx, version.ID, file, group) if err != nil { - return nil, err + return nil, nil, nil, err } - return pkgfile, nil + + return packages_service.GetPackageFileStream(ctx, pkgFile) } -func GetPackageDBFile(ctx context.Context, group, arch string, ownerID int64, signFile bool) (io.ReadSeekCloser, error) { +func GetPackageDBFile(ctx context.Context, group, arch string, ownerID int64, signFile bool) (io.ReadSeekCloser, *url.URL, *packages_model.PackageFile, error) { pv, err := GetOrCreateRepositoryVersion(ctx, ownerID) if err != nil { - return nil, err + return nil, nil, nil, err } fileName := fmt.Sprintf("%s.db", arch) if signFile { @@ -284,10 +284,9 @@ func GetPackageDBFile(ctx context.Context, group, arch string, ownerID int64, si } file, err := packages_model.GetFileForVersionByName(ctx, pv.ID, fileName, group) if err != nil { - return nil, err + return nil, nil, nil, err } - filestream, _, _, err := packages_service.GetPackageFileStream(ctx, file) - return filestream, err + return packages_service.GetPackageFileStream(ctx, file) } // GetOrCreateKeyPair gets or creates the PGP keys used to sign repository metadata files diff --git a/templates/package/content/arch.tmpl b/templates/package/content/arch.tmpl index bcc24b585b..6138b1d698 100644 --- a/templates/package/content/arch.tmpl +++ b/templates/package/content/arch.tmpl @@ -16,11 +16,11 @@ pacman-key --lsign-key '{{$.SignMail}}'

 {{- if gt (len $.Groups) 1 -}}
-# {{ctx.Locale.Tr "packages.arch.pacman.repo.multi"  $.PackageDescriptor.Package.LowerName}}
+# {{ctx.Locale.Tr "packages.arch.pacman.repo.multi" $.PackageDescriptor.Package.LowerName}}
 
 {{end -}}
 {{- $GroupSize := (len .Groups) -}}
-{{-  range $i,$v :=  .Groups -}}
+{{-  range $i,$v := .Groups -}}
 {{- if gt $i 0}}
 {{end -}}{{- if gt $GroupSize 1 -}}
 # {{ctx.Locale.Tr "packages.arch.pacman.repo.multi.item" .}}
diff --git a/templates/package/metadata/arch.tmpl b/templates/package/metadata/arch.tmpl
index 822973eb7d..89001b979c 100644
--- a/templates/package/metadata/arch.tmpl
+++ b/templates/package/metadata/arch.tmpl
@@ -1,4 +1,4 @@
 {{if eq .PackageDescriptor.Package.Type "arch"}}
-	{{range .PackageDescriptor.Metadata.License}}
{{svg "octicon-law" 16 "gt-mr-3"}} {{.}}
{{end}} - {{if .PackageDescriptor.Metadata.ProjectURL}}
{{svg "octicon-link-external" 16 "mr-3"}} {{ctx.Locale.Tr "packages.details.project_site"}}
{{end}} + {{if .PackageDescriptor.Metadata.ProjectURL}}
{{svg "octicon-link-external" 16 "tw-mr-2"}} {{ctx.Locale.Tr "packages.details.project_site"}}
{{end}} + {{range .PackageDescriptor.Metadata.License}}
{{svg "octicon-law" 16 "tw-mr-2"}} {{.}}
{{end}} {{end}} diff --git a/tests/integration/api_packages_arch_test.go b/tests/integration/api_packages_arch_test.go index af275de442..2cf0186416 100644 --- a/tests/integration/api_packages_arch_test.go +++ b/tests/integration/api_packages_arch_test.go @@ -14,6 +14,7 @@ import ( "io" "net/http" "strings" + "sync" "testing" "testing/fstest" @@ -258,11 +259,15 @@ HMhNSS1IzUsBcpJAPFAwwUXSM0u4BjoaR8EoGAWjgGQAAILFeyQADAAA AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) - req = NewRequestWithBody(t, "DELETE", rootURL+"/base/notfound/1.0.0-1", nil). + req = NewRequestWithBody(t, "DELETE", rootURL+"/base/notfound/1.0.0-1/any", nil). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestWithBody(t, "DELETE", groupURL+"/test/1.0.0-1", nil). + req = NewRequestWithBody(t, "DELETE", groupURL+"/test/1.0.0-1/x86_64", nil). + AddBasicAuth(user.Name) + MakeRequest(t, req, http.StatusNoContent) + + req = NewRequestWithBody(t, "DELETE", groupURL+"/test/1.0.0-1/any", nil). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) @@ -270,12 +275,22 @@ HMhNSS1IzUsBcpJAPFAwwUXSM0u4BjoaR8EoGAWjgGQAAILFeyQADAAA respPkg := MakeRequest(t, req, http.StatusOK) files, err := listTarGzFiles(respPkg.Body.Bytes()) require.NoError(t, err) - require.Len(t, files, 1) // other pkg in L225 + require.Len(t, files, 1) - req = NewRequestWithBody(t, "DELETE", groupURL+"/test2/1.0.0-1", nil). + req = NewRequestWithBody(t, "DELETE", groupURL+"/test2/1.0.0-1/any", nil). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", groupURL+"/x86_64/base.db") + + req = NewRequest(t, "GET", groupURL+"/x86_64/base.db"). + AddBasicAuth(user.Name) + MakeRequest(t, req, http.StatusNotFound) + + req = NewRequestWithBody(t, "DELETE", groupURL+"/test/1.0.0-1/aarch64", nil). + AddBasicAuth(user.Name) + MakeRequest(t, req, http.StatusNoContent) + + req = NewRequest(t, "GET", groupURL+"/aarch64/base.db"). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) }) @@ -294,12 +309,33 @@ HMhNSS1IzUsBcpJAPFAwwUXSM0u4BjoaR8EoGAWjgGQAAILFeyQADAAA resp := MakeRequest(t, req, http.StatusOK) require.Equal(t, pkgs[key], resp.Body.Bytes()) - req = NewRequestWithBody(t, "DELETE", groupURL+"/test2/1.0.0-1", nil). + req = NewRequestWithBody(t, "DELETE", groupURL+"/test2/1.0.0-1/any", nil). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) }) } } + t.Run("Concurrent Upload", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + var wg sync.WaitGroup + + targets := []string{"any", "aarch64", "x86_64"} + for _, tag := range targets { + wg.Add(1) + go func(i string) { + defer wg.Done() + req := NewRequestWithBody(t, "PUT", rootURL, bytes.NewReader(pkgs[i])). + AddBasicAuth(user.Name) + MakeRequest(t, req, http.StatusCreated) + }(tag) + } + wg.Wait() + for _, target := range targets { + req := NewRequestWithBody(t, "DELETE", rootURL+"/test/1.0.0-1/"+target, nil). + AddBasicAuth(user.Name) + MakeRequest(t, req, http.StatusNoContent) + } + }) } func getProperty(data, key string) string { @@ -318,10 +354,10 @@ func getProperty(data, key string) string { func listTarGzFiles(data []byte) (fstest.MapFS, error) { reader, err := gzip.NewReader(bytes.NewBuffer(data)) - defer reader.Close() if err != nil { return nil, err } + defer reader.Close() tarRead := tar.NewReader(reader) files := make(fstest.MapFS) for { From 5b847561370fe768775390afc0c82cb7302f3f80 Mon Sep 17 00:00:00 2001 From: Otto Richter Date: Fri, 27 Sep 2024 20:44:22 +0200 Subject: [PATCH 047/443] Split env preparation boilerplate --- .../workflows/composite/setup-env/action.yaml | 11 ++++ .forgejo/workflows/testing.yml | 51 +++---------------- 2 files changed, 18 insertions(+), 44 deletions(-) create mode 100644 .forgejo/workflows/composite/setup-env/action.yaml diff --git a/.forgejo/workflows/composite/setup-env/action.yaml b/.forgejo/workflows/composite/setup-env/action.yaml new file mode 100644 index 0000000000..30e78dbb71 --- /dev/null +++ b/.forgejo/workflows/composite/setup-env/action.yaml @@ -0,0 +1,11 @@ +runs: + using: "composite" + steps: + - uses: https://code.forgejo.org/actions/setup-go@v4 + with: + go-version-file: "go.mod" + - name: setup user and permissions + run: | + git config --add safe.directory '*' + adduser --quiet --comment forgejo --disabled-password forgejo + chown -R forgejo:forgejo . diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml index 725cd242ee..d5c7b86abb 100644 --- a/.forgejo/workflows/testing.yml +++ b/.forgejo/workflows/testing.yml @@ -20,9 +20,7 @@ jobs: ${{ toJSON(github) }} EOF - uses: https://code.forgejo.org/actions/checkout@v3 - - uses: https://code.forgejo.org/actions/setup-go@v4 - with: - go-version-file: "go.mod" + - uses: ./.forgejo/workflows/composite/setup-env - run: make deps-backend deps-tools - run: make --always-make -j$(nproc) lint-backend tidy-check swagger-check fmt-check swagger-validate # ensure the "go-licenses" make target runs - run: | @@ -67,13 +65,7 @@ jobs: MINIO_ROOT_PASSWORD: 12345678 steps: - uses: https://code.forgejo.org/actions/checkout@v3 - - uses: https://code.forgejo.org/actions/setup-go@v4 - with: - go-version-file: "go.mod" - - run: | - git config --add safe.directory '*' - adduser --quiet --comment forgejo --disabled-password forgejo - chown -R forgejo:forgejo . + - uses: ./.forgejo/workflows/composite/setup-env - name: install git >= 2.42 run: | export DEBIAN_FRONTEND=noninteractive @@ -132,13 +124,7 @@ jobs: options: ${{ matrix.cacher.options }} steps: - uses: https://code.forgejo.org/actions/checkout@v3 - - uses: https://code.forgejo.org/actions/setup-go@v4 - with: - go-version-file: "go.mod" - - run: | - git config --add safe.directory '*' - adduser --quiet --comment forgejo --disabled-password forgejo - chown -R forgejo:forgejo . + - uses: ./.forgejo/workflows/composite/setup-env - name: install git >= 2.42 run: | export DEBIAN_FRONTEND=noninteractive @@ -184,9 +170,7 @@ jobs: MYSQL_EXTRA_FLAGS: --innodb-adaptive-flushing=OFF --innodb-buffer-pool-size=4G --innodb-log-buffer-size=128M --innodb-flush-log-at-trx-commit=0 --innodb-flush-log-at-timeout=30 --innodb-flush-method=nosync --innodb-fsync-threshold=1000000000 steps: - uses: https://code.forgejo.org/actions/checkout@v3 - - uses: https://code.forgejo.org/actions/setup-go@v4 - with: - go-version-file: "go.mod" + - uses: ./.forgejo/workflows/composite/setup-env - name: install dependencies & git >= 2.42 run: | export DEBIAN_FRONTEND=noninteractive @@ -195,11 +179,6 @@ jobs: apt-get install --no-install-recommends -qq -y git git-lfs rm /etc/apt/sources.list.d/testing.list apt-get update -qq - - name: setup user and permissions - run: | - git config --add safe.directory '*' - adduser --quiet --comment forgejo --disabled-password forgejo - chown -R forgejo:forgejo . - run: | su forgejo -c 'make deps-backend' - uses: actions/cache/restore@v4 @@ -238,9 +217,7 @@ jobs: POSTGRES_PASSWORD: postgres steps: - uses: https://code.forgejo.org/actions/checkout@v3 - - uses: https://code.forgejo.org/actions/setup-go@v4 - with: - go-version-file: "go.mod" + - uses: ./.forgejo/workflows/composite/setup-env - name: install dependencies & git >= 2.42 run: | export DEBIAN_FRONTEND=noninteractive @@ -249,11 +226,6 @@ jobs: apt-get install --no-install-recommends -qq -y git git-lfs rm /etc/apt/sources.list.d/testing.list apt-get update -qq - - name: setup user and permissions - run: | - git config --add safe.directory '*' - adduser --quiet --comment forgejo --disabled-password forgejo - chown -R forgejo:forgejo . - run: | su forgejo -c 'make deps-backend' - uses: actions/cache/restore@v4 @@ -281,9 +253,7 @@ jobs: image: 'code.forgejo.org/oci/node:20-bookworm' steps: - uses: https://code.forgejo.org/actions/checkout@v3 - - uses: https://code.forgejo.org/actions/setup-go@v4 - with: - go-version-file: "go.mod" + - uses: ./.forgejo/workflows/composite/setup-env - name: install dependencies & git >= 2.42 run: | export DEBIAN_FRONTEND=noninteractive @@ -292,11 +262,6 @@ jobs: apt-get install --no-install-recommends -qq -y git git-lfs rm /etc/apt/sources.list.d/testing.list apt-get update -qq - - name: setup user and permissions - run: | - git config --add safe.directory '*' - adduser --quiet --comment forgejo --disabled-password forgejo - chown -R forgejo:forgejo . - run: | su forgejo -c 'make deps-backend' - uses: actions/cache/restore@v4 @@ -330,8 +295,6 @@ jobs: image: 'code.forgejo.org/oci/node:20-bookworm' steps: - uses: https://code.forgejo.org/actions/checkout@v3 - - uses: https://code.forgejo.org/actions/setup-go@v4 - with: - go-version-file: "go.mod" + - uses: ./.forgejo/workflows/composite/setup-env - run: make deps-backend deps-tools - run: make security-check From c0b17a06ef53d122644304dd8a85a01a3c842ade Mon Sep 17 00:00:00 2001 From: Otto Richter Date: Fri, 27 Sep 2024 20:47:09 +0200 Subject: [PATCH 048/443] Split backend building boilerplate --- .../composite/build-backend/action.yaml | 15 ++++ .forgejo/workflows/testing.yml | 78 ++----------------- 2 files changed, 23 insertions(+), 70 deletions(-) create mode 100644 .forgejo/workflows/composite/build-backend/action.yaml diff --git a/.forgejo/workflows/composite/build-backend/action.yaml b/.forgejo/workflows/composite/build-backend/action.yaml new file mode 100644 index 0000000000..193ff911e1 --- /dev/null +++ b/.forgejo/workflows/composite/build-backend/action.yaml @@ -0,0 +1,15 @@ +runs: + using: "composite" + steps: + - run: | + su forgejo -c 'make deps-backend' + - uses: actions/cache@v4 + id: cache-backend + with: + path: '/workspace/forgejo/forgejo/gitea' + key: backend-build-${{ github.sha }} + - if: steps.cache-backend.outputs.cache-hit != 'true' + run: | + su forgejo -c 'make backend' + env: + TAGS: bindata diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml index d5c7b86abb..5f7a1e351a 100644 --- a/.forgejo/workflows/testing.yml +++ b/.forgejo/workflows/testing.yml @@ -21,16 +21,9 @@ jobs: EOF - uses: https://code.forgejo.org/actions/checkout@v3 - uses: ./.forgejo/workflows/composite/setup-env - - run: make deps-backend deps-tools - - run: make --always-make -j$(nproc) lint-backend tidy-check swagger-check fmt-check swagger-validate # ensure the "go-licenses" make target runs - - run: | - make backend - env: - TAGS: bindata - - uses: actions/cache@v4 - with: - path: '/workspace/forgejo/forgejo/gitea' - key: backend-build-${{ github.sha }} + - run: su forgejo -c 'make deps-backend deps-tools' + - run: su forgejo -c 'make --always-make -j$(nproc) lint-backend tidy-check swagger-check fmt-check swagger-validate' # ensure the "go-licenses" make target runs + - uses: ./.forgejo/workflows/composite/build-backend frontend-checks: if: ${{ !startsWith(vars.ROLE, 'forgejo-') }} runs-on: docker @@ -78,18 +71,7 @@ jobs: run: | apt-get -q install -qq -y jq ./release-notes-assistant.sh test_main - - run: | - su forgejo -c 'make deps-backend' - - uses: actions/cache/restore@v4 - id: cache-backend - with: - path: '/workspace/forgejo/forgejo/gitea' - key: backend-build-${{ github.sha }} - - if: steps.cache-backend.outputs.cache-hit != 'true' - run: | - su forgejo -c 'make backend' - env: - TAGS: bindata + - uses: ./.forgejo/workflows/composite/build-backend - run: | su forgejo -c 'make test-backend test-check' timeout-minutes: 50 @@ -133,18 +115,7 @@ jobs: apt-get -q install -qq -y git rm /etc/apt/sources.list.d/testing.list apt-get update -qq - - run: | - su forgejo -c 'make deps-backend' - - uses: actions/cache/restore@v4 - id: cache-backend - with: - path: '/workspace/forgejo/forgejo/gitea' - key: backend-build-${{ github.sha }} - - if: steps.cache-backend.outputs.cache-hit != 'true' - run: | - su forgejo -c 'make backend' - env: - TAGS: bindata + - uses: ./.forgejo/workflows/composite/build-backend - run: | su forgejo -c 'make test-remote-cacher test-check' timeout-minutes: 50 @@ -179,18 +150,7 @@ jobs: apt-get install --no-install-recommends -qq -y git git-lfs rm /etc/apt/sources.list.d/testing.list apt-get update -qq - - run: | - su forgejo -c 'make deps-backend' - - uses: actions/cache/restore@v4 - id: cache-backend - with: - path: '/workspace/forgejo/forgejo/gitea' - key: backend-build-${{ github.sha }} - - if: steps.cache-backend.outputs.cache-hit != 'true' - run: | - su forgejo -c 'make backend' - env: - TAGS: bindata + - uses: ./.forgejo/workflows/composite/build-backend - run: | su forgejo -c 'make test-mysql-migration test-mysql' timeout-minutes: 50 @@ -226,18 +186,7 @@ jobs: apt-get install --no-install-recommends -qq -y git git-lfs rm /etc/apt/sources.list.d/testing.list apt-get update -qq - - run: | - su forgejo -c 'make deps-backend' - - uses: actions/cache/restore@v4 - id: cache-backend - with: - path: '/workspace/forgejo/forgejo/gitea' - key: backend-build-${{ github.sha }} - - if: steps.cache-backend.outputs.cache-hit != 'true' - run: | - su forgejo -c 'make backend' - env: - TAGS: bindata + - uses: ./.forgejo/workflows/composite/build-backend - run: | su forgejo -c 'make test-pgsql-migration test-pgsql' timeout-minutes: 50 @@ -262,18 +211,7 @@ jobs: apt-get install --no-install-recommends -qq -y git git-lfs rm /etc/apt/sources.list.d/testing.list apt-get update -qq - - run: | - su forgejo -c 'make deps-backend' - - uses: actions/cache/restore@v4 - id: cache-backend - with: - path: '/workspace/forgejo/forgejo/gitea' - key: backend-build-${{ github.sha }} - - if: steps.cache-backend.outputs.cache-hit != 'true' - run: | - su forgejo -c 'make backend' - env: - TAGS: bindata sqlite sqlite_unlock_notify + - uses: ./.forgejo/workflows/composite/build-backend - run: | su forgejo -c 'make test-sqlite-migration test-sqlite' timeout-minutes: 50 From 735bcf978f4d98399b1e05008911a1f8670fcacd Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 28 Sep 2024 00:02:39 +0000 Subject: [PATCH 049/443] Update dependency webpack to v5.95.0 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 156a76f3ce..b6edb9d5a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.94.0", + "webpack": "5.95.0", "webpack-cli": "5.1.4", "wrap-ansi": "9.0.0" }, @@ -16422,9 +16422,9 @@ } }, "node_modules/webpack": { - "version": "5.94.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", - "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "version": "5.95.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", + "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.5", @@ -16537,9 +16537,9 @@ } }, "node_modules/webpack/node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "license": "MIT" }, "node_modules/webpack/node_modules/ajv": { diff --git a/package.json b/package.json index b3daef53f0..24e3bd3eb9 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.94.0", + "webpack": "5.95.0", "webpack-cli": "5.1.4", "wrap-ansi": "9.0.0" }, From e40554f89baa79d12a1ff89b434041b297afff02 Mon Sep 17 00:00:00 2001 From: Codeberg Translate Date: Sat, 28 Sep 2024 09:40:29 +0000 Subject: [PATCH 050/443] i18n: update of translations from Codeberg Translate (#5355) Co-authored-by: earl-warren Co-authored-by: Vaclovas Intas Co-authored-by: Zughy Co-authored-by: aleksi Co-authored-by: Application-Maker Co-authored-by: Salif Mehmed Co-authored-by: 0ko <0ko@users.noreply.translate.codeberg.org> Co-authored-by: Fjuro Co-authored-by: Panagiotis \"Ivory\" Vasilopoulos Co-authored-by: claudep Co-authored-by: vri Co-authored-by: nicokaiser Co-authored-by: Outbreak2096 Co-authored-by: robines Co-authored-by: nazrin Co-authored-by: Kaede Fujisaki Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5355 Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Codeberg Translate Co-committed-by: Codeberg Translate --- options/locale/locale_bg.ini | 25 +++- options/locale/locale_cs-CZ.ini | 38 +++-- options/locale/locale_de-DE.ini | 32 ++++- options/locale/locale_el-GR.ini | 242 ++++++++++++++++---------------- options/locale/locale_fi-FI.ini | 5 + options/locale/locale_fr-FR.ini | 58 +++++--- options/locale/locale_is-IS.ini | 8 +- options/locale/locale_it-IT.ini | 23 +++ options/locale/locale_ja-JP.ini | 7 + options/locale/locale_lt.ini | 77 +++++++++- options/locale/locale_nb_NO.ini | 113 ++++++++++++++- options/locale/locale_ru-RU.ini | 16 ++- options/locale/locale_zh-CN.ini | 34 ++++- 13 files changed, 505 insertions(+), 173 deletions(-) diff --git a/options/locale/locale_bg.ini b/options/locale/locale_bg.ini index 01fb84c3c6..2207129cfa 100644 --- a/options/locale/locale_bg.ini +++ b/options/locale/locale_bg.ini @@ -168,6 +168,7 @@ versions.view_all = Вижте всички dependencies = Зависимости published_by_in = Публикуван %[1]s от %[3]s в %[5]s published_by = Публикуван %[1]s от %[3]s +generic.download = Изтеглете пакета от командния ред: [tool] hours = %d часа @@ -1020,7 +1021,7 @@ pulls.title_desc_one = иска да слее %[1]d подаване от pulls.showing_specified_commit_range = Показани са само промените между %[1]s..%[2]s pulls.merged_title_desc_one = сля %[1]d подаване от %[2]s в %[3]s %[4]s pulls.no_merge_access = Не сте упълномощени за сливане на тази заявка за сливане. -activity.navbar.code_frequency = Честота на кода +activity.navbar.code_frequency = Честота на промените activity.git_stats_pushed_1 = е изтласкал activity.git_stats_push_to_branch = към %s и contributors.contribution_type.commits = Подавания @@ -1183,6 +1184,15 @@ diff.hide_file_tree = Скриване на файловото дърво tag.ahead.target = в %s след този маркер diff.file_image_width = Широчина activity.unresolved_conv_label = Отворено +invisible_runes_line = `Този ред съдържа невидими Уникод знаци` +code.desc = Достъп до програмния код, файловете, подаванията и клоновете. +settings.branches.update_default_branch = Обновяване на стандартния клон +settings.default_branch_desc = Изберете стандартен клон за хранилището, за заявки за сливане и подавания на код: +settings.transfer.button = Прехвърляне на притежанието +settings.transfer.modal.title = Прехвърляне на притежанието +ambiguous_runes_line = `Този ред съдържа двусмислени Уникод знаци` +ambiguous_character = `%[1]c [U+%04[1]X] може да бъде объркан с %[2]c [U+%04[2]X]` +invisible_runes_header = `Този файл съдържа невидими Уникод знаци` [modal] confirm = Потвърждаване @@ -1279,6 +1289,7 @@ members.member = Участник members.private_helper = Да е видим teams.no_desc = Този екип няма описание settings.delete_org_desc = Тази организация ще бъде изтрита перманентно. Продължаване? +open_dashboard = Отваряне на таблото [install] admin_password = Парола @@ -1378,6 +1389,7 @@ followers.title.few = Последователи followers.title.one = Последовател following.title.one = Следван following.title.few = Следвани +public_activity.visibility_hint.self_public = Вашата дейност е видима за всички, с изключение на взаимодействията в частни пространства. Конфигуриране. [home] filter = Други филтри @@ -1544,6 +1556,8 @@ push_tag = изтласка маркер %[3]s към %[3]s#%[2]s` reject_pull_request = `предложи промени за %[3]s#%[2]s` compare_branch = Сравняване +compare_commits_general = Сравняване на подавания +compare_commits = Сравнете %d подавания [auth] tab_openid = OpenID @@ -1572,6 +1586,12 @@ tab_signin = Влизане tab_signup = Регистриране password_pwned = Паролата, която сте избрали, е в списък с откраднати пароли, разкрити преди това при публични пробиви на данни. Моля, опитайте отново с различна парола. confirmation_mail_sent_prompt = Ново ел. писмо за потвърждение е изпратено до %s. За да завършите процеса на регистрация, моля, проверете входящата си кутия и последвайте предоставената връзка в рамките на следващите %s. Ако адресът за ел. поща е неправилен, можете да влезете и да поискате друго ел. писмо за потвърждение да бъде изпратено на различен адрес. +hint_login = Вече имате акаунт? Влезте! +hint_register = Нуждаете се от акаунт? Регистрирайте се. +sign_up_button = Регистрирайте се. +back_to_sign_in = Назад към Вход +sign_in_openid = Продължаване с OpenID +send_reset_mail = Изпращане на ел. писмо за възстановяване [aria] footer.software = Относно този софтуер @@ -1582,7 +1602,7 @@ footer = Долен колонтитул install = Лесен за инсталиране lightweight = Лек license = Отворен код -install_desc = Просто стартирайте двоичния файл за вашата платформа, използвайте Docker, или го получете пакетирано. +install_desc = Просто стартирайте двоичния файл за вашата платформа, използвайте Docker, или го получете пакетиран. app_desc = Безпроблемна Git услуга със самостоятелен хостинг platform = Междуплатформен lightweight_desc = Forgejo има ниски минимални изисквания и може да работи на икономичен Raspberry Pi. Спестете енергията на вашата машина! @@ -1670,6 +1690,7 @@ contributors.what = приноси recent_commits.what = скорошни подавания component_loading = Зареждане на %s... component_loading_info = Това може да отнеме известно време… +code_frequency.what = честота на промените [projects] type-1.display_name = Индивидуален проект diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 9ca8c6b387..4fa19b80f2 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -842,8 +842,8 @@ add_key=Přidat klíč ssh_desc=Tyto veřejné klíče SSH jsou propojeny s vaším účtem. Odpovídající soukromé klíče umožní plný přístup k vašim repozitářům. Klíče SSH, které byly ověřeny, mohou být použity pro ověření Git commitů podepsaných přes SSH. principal_desc=Tyto SSH Principal certifikáty jsou přidruženy k vašemu účtu a umožňují plný přístup do vašich repozitářů. gpg_desc=Tyto veřejné klíče GPG jsou propojeny s vaším účtem a používají se k ověření vašich commitů. Uložte je na bezpečné místo, jelikož umožňují podepsat commity vaší identitou. -ssh_helper=Potřebujete pomoct? Podívejte se do příručky GitHubu na to vytvoření vlastních klíčů SSH nebo vyřešte běžné problémy, se kterými se můžete potkat při použití SSH. -gpg_helper=Potřebujete pomoct? Podívejte se do příručky GitHubu o GPG. +ssh_helper=Potřebujete pomoct? Podívejte se do příručky, jak vytvořit vlastní klíče SSH nebo vyřešte běžné problémy, se kterými se můžete potkat při použití SSH. +gpg_helper=Potřebujete pomoct? Podívejte se do příručky o GPG. add_new_key=Přidat klíč SSH add_new_gpg_key=Přidat klíč GPG key_content_ssh_placeholder=Začíná s „ssh-ed25519“, „ssh-rsa“, „ecdsa-sha2-nistp256“, „ecdsa-sha2-nistp384“, „ecdsa-sha2-nistp521“, „sk-ecdsa-sha2-nistp256@openssh.com“ nebo „sk-ssh-ed25519@openssh.com“ @@ -1427,7 +1427,7 @@ commitstatus.failure=Chyba commitstatus.pending=Čekající commitstatus.success=Úspěch -ext_issues=Přístup k externím problémům +ext_issues=Externí problémy ext_issues.desc=Odkaz na externí systém problémů. projects=Projekty @@ -1608,9 +1608,9 @@ issues.no_content=K dispozici není žádný popis. issues.close=Zavřít problém issues.comment_pull_merged_at=sloučený commit %[1]s do %[2]s %[3]s issues.comment_manually_pull_merged_at=ručně sloučený commit %[1]s do %[2]s %[3]s -issues.close_comment_issue=Okomentovat a zavřít +issues.close_comment_issue=Zavřít s komentářem issues.reopen_issue=Znovu otevřít -issues.reopen_comment_issue=Okomentovat a znovu otevřít +issues.reopen_comment_issue=Znovu otevřít s komentářem issues.create_comment=Okomentovat issues.closed_at=`uzavřel/a tento problém %[2]s` issues.reopened_at=`znovu otevřel/a tento problém %[2]s` @@ -1995,7 +1995,7 @@ signing.wont_sign.commitssigned=Sloučení nebude podepsáno, protože všechny signing.wont_sign.approved=Sloučení nebude podepsáno, protože požadavek na natažení není schválen. signing.wont_sign.not_signed_in=Nejste přihlášeni. -ext_wiki=Přístup k externí Wiki +ext_wiki=Externí wiki ext_wiki.desc=Odkaz do externí Wiki. wiki=Wiki @@ -2436,7 +2436,7 @@ settings.protect_branch_name_pattern=Vzor jména chráněné větve settings.protect_branch_name_pattern_desc=Vzory názvů chráněných větví. Pro vzorovou syntaxi viz dokumentace. Příklady: main, release/** settings.protect_patterns=Vzory settings.protect_protected_file_patterns=Vzory chráněných souborů (oddělené středníkem „;“) -settings.protect_protected_file_patterns_desc=Chráněné soubory, které nemají povoleno být měněny přímo, i když uživatel má právo přidávat, upravovat nebo mazat soubory v této větvi. Více vzorů lze oddělit pomocí středníku („;“). Podívejte se na github.com/gobwas/glob dokumentaci pro syntaxi vzoru. Příklady: .drone.yml, /docs/**/*.txt. +settings.protect_protected_file_patterns_desc=Chráněné soubory, které nemají povoleno být měněny přímo, i když uživatel má právo přidávat, upravovat nebo mazat soubory v této větvi. Více vzorů lze oddělit pomocí středníku („;“). Podívejte se na dokumentaci %[2]s pro syntaxi vzoru. Příklady: .drone.yml, /docs/**/*.txt. settings.protect_unprotected_file_patterns=Vzory nechráněných souborů (oddělené středníkem „;“) settings.protect_unprotected_file_patterns_desc=Nechráněné soubory, které je možné měnit přímo, pokud má uživatel právo zápisu, čímž se obejde omezení push. Více vzorů lze oddělit pomocí středníku („;“). Podívejte se na %[2]s dokumentaci pro syntaxi vzoru. Příklady: .drone.yml, /docs/**/*.txt. settings.add_protected_branch=Zapnout ochranu @@ -3822,7 +3822,7 @@ management=Správa tajných klíčů [actions] actions=Akce -unit.desc=Spravovat integrované pipeliny CI/CD pomocí funkce Forgejo Actions +unit.desc=Spravovat integrované pipeliny CI/CD pomocí funkce Forgejo Actions. status.unknown=Neznámý status.waiting=Čekání @@ -3987,4 +3987,24 @@ eib = EiB [translation_meta] -test = diky vsem za pomoc :) \ No newline at end of file +test = diky vsem za pomoc :) + +[repo.permissions] +pulls.write = Zapisovat: Zavírat žádosti o sloučení a spravovat metadata jako štítky, milníky, zpracovatele, data dokončení a závislosti. +packages.write = Zapisovat: Zveřejňovat a mazat balíčky připojené k repozitáři. +projects.read = Číst: Přístup k projektovým nástěnkám repozitáře. +code.write = Zapisovat: Odesílat změny do repozitáře, vytvářet větve a značky. +issues.write = Zapisovat: Zavírat problémy a spravovat metadata jako štítky, milníky, zpracovatele, data dokončení a závislosti. +pulls.read = Číst: Číst a vytvářet žádosti o sloučení. +releases.read = Číst: Zobrazovat a stahovat vydání. +releases.write = Zapisovat: Zveřejňovat, upravovat a mazat vydání a jejich soubory. +wiki.read = Číst: Číst integrovanou wiki a její historii. +wiki.write = Zapisovat: Vytvářet, aktualizovat a mazat stránky v integrované wiki. +projects.write = Zapisovat: Vytvářet projekty a sloupce a upravovat je. +packages.read = Číst: Zobrazovat a stahovat balíčky připojené k repozitáři. +actions.read = Číst: Zobrazovat integrované pipeliny CI/CD a jejich protokoly. +actions.write = Zapisovat: Ručně spouštět, restartovat, rušit nebo schvalovat čekající pipeliny CI/CD. +ext_wiki = Přístup k odkazu v externí wiki. Oprávnění jsou spravována externě. +code.read = Číst: Přístup a klonování kódu v repozitáři. +issues.read = Číst: Číst a vytvářet problémy a komentáře. +ext_issues = Přístup k odkazu v externím sledovacím systému problémů. Oprávnění jsou spravována externě. \ No newline at end of file diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 39b3596aa7..b112ec82c3 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -1420,7 +1420,7 @@ commitstatus.failure=Fehler commitstatus.pending=Ausstehend commitstatus.success=Erfolg -ext_issues=Zugriff auf Externe Issues +ext_issues=Externe Issues ext_issues.desc=Link zu externem Issuetracker. projects=Projekte @@ -1601,9 +1601,9 @@ issues.no_content=Keine Beschreibung angegeben. issues.close=Issue schließen issues.comment_pull_merged_at=hat Commit %[1]s in %[2]s %[3]s zusammengeführt issues.comment_manually_pull_merged_at=hat Commit %[1]s in %[2]s %[3]s manuell zusammengeführt -issues.close_comment_issue=Kommentieren und schließen +issues.close_comment_issue=Mit Kommentar schließen issues.reopen_issue=Wieder öffnen -issues.reopen_comment_issue=Kommentieren und wieder öffnen +issues.reopen_comment_issue=Mit Kommentar wieder öffnen issues.create_comment=Kommentieren issues.closed_at=`hat diesen Issue %[2]s geschlossen` issues.reopened_at=`hat dieses Issue %[2]s wieder geöffnet` @@ -1984,7 +1984,7 @@ signing.wont_sign.commitssigned=Der Merge-Commit wird nicht signiert werden, da signing.wont_sign.approved=Der Merge-Commit wird nicht signiert werden, da der Pull-Request nicht genehmigt wurde. signing.wont_sign.not_signed_in=Du bist nicht eingeloggt. -ext_wiki=Zugriff auf externes Wiki +ext_wiki=Externes Wiki ext_wiki.desc=Verweis auf externes Wiki. wiki=Wiki @@ -3792,7 +3792,7 @@ management=Secrets verwalten [actions] actions=Actions -unit.desc=Integrierte CI/CD-Pipelines mit Forgejo-Actions verwalten +unit.desc=Integrierte CI/CD-Pipelines mit Forgejo-Actions verwalten. status.unknown=Unbekannt status.waiting=Wartend @@ -3964,4 +3964,24 @@ eib = EiB [translation_meta] -test = ok \ No newline at end of file +test = ok + +[repo.permissions] +code.write = Schreiben: In das Repository pushen, Branches und Tags erstellen. +code.read = Lesen: Zugriff auf das Repository und Klonen. +issues.read = Lesen: Issues und Kommentare lesen und erstellen. +issues.write = Schreiben: Issues schließen und Metadaten wie Labels, Meilensteine, Zuweisungen, Fälligkeitsdaten und Abhängigkeiten verwalten. +pulls.read = Lesen: Pull-Requests lesen und erstellen. +releases.read = Lesen: Releases ansehen und herunterladen. +releases.write = Schreiben: Releases und ihre Assets veröffentlichen, bearbeiten und löschen. +wiki.read = Read: Das integrierte Wiki und seine Historie lesen. +wiki.write = Schreiben: Seiten im integrierten Wiki erstellen, aktualisieren und löschen. +projects.read = Lesen: Zugriff auf Projektboards des Repositories. +projects.write = Schreiben: Projekte und Spalten erstellen und bearbeiten. +packages.read = Lesen: Pakete dieses Repositories betrachten und herunterladen. +packages.write = Schreiben: Pakete dieses Repositories veröffentlichen und löschen. +actions.read = Lesen: Integrierte CI/CD-Pipelines und ihre Logs betrachten. +actions.write = Schreiben: Ausstehende CI/CD-Pipelines manuell auslösen, neustarten, abbrechen oder genehmigen. +ext_issues = Zugriff auf den Link zu einem externen Issue-Tracker. Die Berechtigungen werden extern verwaltet. +ext_wiki = Zugriff auf den Link zu einem externen Wiki. Die Berechtigungen werden extern verwaltet. +pulls.write = Schreiben: Pull-Requests schließen und Metadaten wie Labels, Meilensteine, Zuweisungen, Fälligkeitsdaten und Abhängigkeiten verwalten. \ No newline at end of file diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 55478dacf2..2df8dce95d 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -51,7 +51,7 @@ webauthn_error_empty=Πρέπει να ορίσετε ένα όνομα για webauthn_error_timeout=Το χρονικό όριο έφτασε πριν το κλειδί να διαβαστεί. Παρακαλώ ανανεώστε τη σελίδα και προσπαθήστε ξανά. webauthn_reload=Ανανέωση -repository=Αποθετήριο +repository=Repository organization=Οργανισμός mirror=Αντίγραφο new_repo=Νέο αποθετήριο @@ -129,7 +129,7 @@ archived=Αρχειοθετήθηκε concept_system_global=Γενικό concept_user_individual=Ατομικό -concept_code_repository=Αποθετήριο +concept_code_repository=Repository concept_user_organization=Οργανισμός show_timestamps=Εμφάνιση χρονοσημάνσεων @@ -160,11 +160,11 @@ invalid_data = Τα δεδομένα δεν είναι έγκυρα: %v test = Τεστ copy_generic = Αντιγραφή στο πρόχειρο error413 = Έχετε εξαντλήσει τους διαθέσιμους πόρους σας. -new_repo.link = Νέο αποθετήριο +new_repo.link = Νέο repository new_migrate.link = Νέα μεταφορά new_org.link = Νέος οργανισμός new_migrate.title = Νέα μεταφορά -new_repo.title = Νέο αποθετήριο +new_repo.title = Νέο repository new_org.title = Νέος οργανισμός [aria] @@ -504,8 +504,8 @@ reset_password.text=Εφόσον το αίτημα δημιουργήθηκε α register_success=Η εγγραφή ολοκληρώθηκε επιτυχώς -issue_assigned.pull=Ο/Η @%[1]s σας έχει αναθέσει στο pull request %[2]s στο αποθετήριο %[3]s. -issue_assigned.issue=Ο/Η @%[1]s σας ανέθεσε το ζήτημα %[2]s στο αποθετήριο %[3]s. +issue_assigned.pull=Ο/Η @%[1]s σας έχει αναθέσει στο pull request %[2]s στο repository %[3]s. +issue_assigned.issue=Ο/Η @%[1]s σας ανέθεσε το ζήτημα %[2]s στο repository %[3]s. issue.x_mentioned_you=Ο/Η @%s σας ανέφερε: issue.action.force_push=Ο/Η %[1]s έκανε force-push το %[2]s από %[3]s σε %[4]s. @@ -530,13 +530,13 @@ release.downloads=Λήψεις: release.download.zip=Πηγαίος Κώδικας (ZIP) release.download.targz=Πηγαίος Κώδικας (TAR.GZ) -repo.transfer.subject_to=Ο/Η %s θα ήθελε να μεταφέρει το αποθετήριο «%s» σε %s -repo.transfer.subject_to_you=Ο/Η %s θα ήθελε να σας μεταφέρει το αποθετήριο «%s» +repo.transfer.subject_to=Ο/Η %s θα ήθελε να μεταφέρει το repository «%s» στο %s +repo.transfer.subject_to_you=Ο/Η %s θα ήθελε να σας μεταφέρει το repository «%s» repo.transfer.to_you=εσάς repo.transfer.body=Για να αποδεχτείτε ή να απορρίψετε το αίτημα αυτό, επισκεφθείτε το %s ή απλά αγνοήστε το. repo.collaborator.added.subject=Ο/Η %s σας πρόσθεσε στο %s ως συνεργάτη -repo.collaborator.added.text=Είστε πλέον συνεργάτης στο αποθετήριο: +repo.collaborator.added.text=Είστε πλέον συνεργάτης στο repository: team_invite.subject=Ο/Η %[1]s σας προσκάλεσε να συμμετέχετε στον οργανισμό %[2]s team_invite.text_1=Ο/Η %[1]s σας προσκάλεσε να συμμετέχετε στην ομάδα %[2]s του οργανισμού %[3]s. @@ -615,10 +615,10 @@ username_change_not_local_user=Δεν επιτρέπεται στους μη τ username_has_not_been_changed=Το όνομα χρήστη δεν άλλαξε repo_name_been_taken=Το όνομα του αποθετηρίου χρησιμοποιείται ήδη. repository_force_private=Η επιλογή Μόνο Ιδιωτικά είναι ενεργοποιημένη: τα ιδιωτικά αποθετήρια δεν μπορούν να δημοσιευθούν. -repository_files_already_exist=Αρχεία υπάρχουν ήδη για αυτό το αποθετήριο. Επικοινωνήστε με το διαχειριστή του συστήματος. -repository_files_already_exist.adopt=Αρχεία υπάρχουν ήδη για αυτό το αποθετήριο και μπορούν να Υιοθετηθούν μόνο. -repository_files_already_exist.delete=Τα αρχεία υπάρχουν ήδη για αυτόν το αποθετήριο. Πρέπει να τα διαγράψετε. -repository_files_already_exist.adopt_or_delete=Τα αρχεία υπάρχουν ήδη για αυτόν το αποθετήριο. Είτε υιοθετήστε τα είτε διαγράψτε τα. +repository_files_already_exist=Αρχεία υπάρχουν ήδη για αυτό το repository. Επικοινωνήστε με το διαχειριστή του συστήματος. +repository_files_already_exist.adopt=Αρχεία υπάρχουν ήδη για αυτό το repository και μπορούν μόνο να υιοθετηθούν. +repository_files_already_exist.delete=Τα αρχεία υπάρχουν ήδη για αυτόν το repository. Πρέπει να τα διαγράψετε. +repository_files_already_exist.adopt_or_delete=Υπάρχουν ήδη τα αρχεία για αυτό το repository. Πρέπει να τα υιοθετήσετε ή να τα διαγράψετε. visit_rate_limit=Συναντήθηκε το όριο ρυθμού κατά την απομακρυσμένη πρόσβαση. 2fa_auth_required=Απαιτήθηκε ταυτοποίηση δύο παραγόντων κατά την απομακρυσμένη πρόσβαση. org_name_been_taken=Το όνομα του οργανισμού χρησιμοποιείται ήδη. @@ -925,7 +925,7 @@ access_token_deletion_cancel_action=Άκυρο access_token_deletion_confirm_action=Διαγραφή access_token_deletion_desc=Η διαγραφή ενός διακριτικού θα ανακαλέσει οριστικά την πρόσβαση στο λογαριασμό σας για εφαρμογές που το χρησιμοποιούν. Συνέχεια; delete_token_success=Το διακριτικό έχει διαγραφεί. Οι εφαρμογές που το χρησιμοποιούν δεν έχουν πλέον πρόσβαση στο λογαριασμό σας. -repo_and_org_access=Πρόσβαση στο Αποθετήριο και Οργανισμό +repo_and_org_access=Πρόσβαση στο repository και οργανισμό permissions_public_only=Δημόσια μόνο permissions_access_all=Όλα (δημόσια, ιδιωτικά, και περιορισμένα) select_permissions=Επιλογή δικαιωμάτων @@ -1005,7 +1005,7 @@ remove_account_link_success=Ο συνδεδεμένος λογαριασμός hooks.desc=Προσθήκη webhooks που θα ενεργοποιούνται για όλα τα αποθετήρια που σας ανήκουν. orgs_none=Δεν είστε μέλος σε κάποιο οργανισμό. -repos_none=Δεν σας ανήκει κανένα κάποιο αποθετήριο. +repos_none=Δεν υπάρχει κάποιο repository που σας ανήκει. delete_account=Διαγραφή του λογαριασμού σας delete_prompt=Αυτή η ενέργεια θα διαγράψει μόνιμα το λογαριασμό σας. ΔΕΝ ΘΑ ΜΠΟΡΕΙ να επανέλθει. @@ -1047,7 +1047,7 @@ language.localization_project = Βοηθήστε μας να μεταφράσο language.description = Από εδώ και στο εξής, αυτή η γλώσσα θα χρησιμοποιείται από προεπιλογή για τον λογαριασμό σας. [repo] -new_repo_helper=Ένα αποθετήριο περιέχει όλα τα αρχεία έργου, συμπεριλαμβανομένου του ιστορικού εκδόσεων. Ήδη φιλοξενείται αλλού; Μετεγκατάσταση αποθετηρίου. +new_repo_helper=Ένα repository περιέχει όλα τα αρχεία έργου, συμπεριλαμβανομένου του ιστορικού εκδόσεων. Έχετε ήδη ένα που φιλοξενείται κάπου αλλού; Μεταφορά αποθετηρίου. owner=Ιδιοκτήτης owner_helper=Ορισμένοι οργανισμοί ενδέχεται να μην εμφανίζονται στο αναπτυσσόμενο μενού λόγω του μέγιστου αριθμού αποθετηρίων. repo_name=Όνομα αποθετηρίου @@ -1055,7 +1055,7 @@ repo_name_helper=Τα καλά ονόματα αποθετηρίων χρησι repo_size=Μέγεθος Αποθετηρίου template=Πρότυπο template_select=Επιλέξτε ένα πρότυπο -template_helper=Μετατροπή σε πρότυπο αποθετήριο +template_helper=Μετατροπή σε πρότυπο repository template_description=Τα πρότυπα αποθετήρια επιτρέπουν στους χρήστες να δημιουργήσουν νέα αποθετήρια με την ίδια δομή, αρχεία και προαιρετικές ρυθμίσεις. visibility=Ορατότητα visibility_description=Μόνο ο ιδιοκτήτης ή τα μέλη του οργανισμού εάν έχουν δικαιώματα, θα είναι σε θέση να το δουν. @@ -1070,7 +1070,7 @@ fork_to_different_account=Fork σε διαφορετικό λογαριασμό fork_visibility_helper=Η ορατότητα ενός fork αποθετηρίου δεν μπορεί να αλλάξει. fork_branch=Κλάδος που θα κλωνοποιηθεί στο fork all_branches=Όλοι οι κλάδοι -fork_no_valid_owners=Αυτό το αποθετήριο δεν μπορεί να γίνει fork επειδή δεν υπάρχουν έγκυροι ιδιοκτήτες. +fork_no_valid_owners=Αυτό το repository δεν μπορεί να γίνει fork, επειδή δεν υπάρχουν έγκυροι ιδιοκτήτες. use_template=Χρήση αυτού του πρότυπου clone_in_vsc=Κλωνοποίηση στο VS Code download_zip=Λήψη ZIP @@ -1120,7 +1120,7 @@ mirror_password_blank_placeholder=(Μη ορισμένο) mirror_password_help=Αλλάξτε το όνομα χρήστη για να διαγράψετε έναν αποθηκευμένο κωδικό πρόσβασης. watchers=Παρατηρητές stargazers=Θαυμαστές -stars_remove_warning=Αυτό θα αφαιρέσει όλα τα αστέρια από αυτό το αποθετήριο. +stars_remove_warning=Αυτό θα αφαιρέσει όλα τα αστέρια από αυτό το repository. forks=Forks reactions_more=και %d περισσότερα unit_disabled=Ο διαχειριστής του ιστότοπου έχει απενεργοποιήσει αυτήν την ενότητα αποθετηρίου. @@ -1129,7 +1129,7 @@ adopt_search=Εισάγετε όνομα χρήστη για αναζήτηση adopt_preexisting_label=Υιοθέτηση αρχείων adopt_preexisting=Υιοθετήστε τα προϋπάρχοντα αρχεία adopt_preexisting_content=Δημιουργία αποθετηρίου από %s -adopt_preexisting_success=Υιοθετήθηκαν αρχεία και δημιουργήθηκε το αποθετήριο από %s +adopt_preexisting_success=Υιοθετήθηκαν αρχεία και δημιουργήθηκε το repository από %s delete_preexisting_label=Διαγραφή delete_preexisting=Διαγραφή αρχείων που προϋπήρχαν delete_preexisting_content=Διαγραφή αρχείων στο %s @@ -1159,17 +1159,17 @@ desc.archived=Αρχειοθετημένο template.items=Αντικείμενα προτύπου template.git_content=Περιεχόμενο Git (Προεπιλεγμένος κλάδος) template.git_hooks=Git hooks -template.git_hooks_tooltip=Δεν θα μπορέσετε να αφαιρέσετε ή να τροποποιήσετε τα Git hook αφού τα έχετε προσθέσει. Επιλέξτε την ρύθμιση αυτή μόνο αν εμπιστεύεστε το πρότυπο αποθετήριο. +template.git_hooks_tooltip=Δεν θα μπορέσετε να αφαιρέσετε ή να τροποποιήσετε τα Git hook αφού τα έχετε προσθέσει. Επιλέξτε την ρύθμιση αυτή μόνο αν εμπιστεύεστε το πρότυπο repository. template.webhooks=Webhooks template.topics=Θέματα template.avatar=Εικόνα template.issue_labels=Ταμπέλες ζητημάτων template.one_item=Πρέπει να επιλέξετε τουλάχιστον ένα αντικείμενο στο πρότυπο -template.invalid=Πρέπει να επιλέξετε ένα πρότυπο αποθετήριο +template.invalid=Πρέπει να επιλέξετε ένα πρότυπο repository archive.title=Αυτό το αποθετήρειο αρχειοθετήθηκε. Μπορείτε να προβάλετε αρχεία και να τα κλωνοποιήσετε, αλλά δεν μπορείτε να ωθήσετε ή να ανοίξετε ζητήματα ή pull requests. -archive.title_date=Αυτό το αποθετήριο έχει αρχειοθετηθεί στο %s. Μπορείτε να προβάλετε αρχεία και να κλωνοποιήσετε, αλλά δεν μπορείτε να ωθήσετε ή να ανοίξετε ζητήματα ή pull requests. -archive.issue.nocomment=Αυτό το αποθετήριο αρχειοθετήθηκε. Δεν μπορείτε να σχολιάσετε σε ζητήματα. +archive.title_date=Αυτό το repository αρχειοθετήθηκε στις %s. Μπορείτε να δείτε τα αρχεία του και να το κλωνοποιήσετε, αλλά δεν μπορείτε να κάνετε push, να ανοίξετε ζητήματα ή pull requests. +archive.issue.nocomment=Αυτό το repository έχει αρχειοθετηθεί. Δεν μπορείτε να σχολιάσετε σε ζητήματα. archive.pull.nocomment=Αυτό το repo αρχειοθετήθηκε. Δεν μπορείτε να σχολιάσετε στα pull requests. form.reach_limit_of_creation_1=Έχετε ήδη συμπληρώσει το όριο του %d αποθετηρίου. @@ -1180,7 +1180,7 @@ form.name_pattern_not_allowed=Το μοτίβο «%s» δεν επιτρέπετ need_auth=Εξουσιοδότηση migrate_options=Ρυθμίσεις μεταφοράς migrate_service=Υπηρεσία Μεταφοράς -migrate_options_mirror_helper=Αυτό το αποθετήριο θα είναι είδωλο +migrate_options_mirror_helper=Αυτό το repository θα είναι είδωλο migrate_options_lfs=Μεταφορά αρχείων LFS migrate_options_lfs_endpoint.label=Άκρο LFS migrate_options_lfs_endpoint.description=Η μεταφορά θα προσπαθήσει να χρησιμοποιήσει το Git remote για να καθορίσει τον διακομιστή LFS. Μπορείτε επίσης να καθορίσετε ένα δικό σας endpoint αν τα δεδομένα LFS του αποθετηρίου αποθηκεύονται κάπου αλλού. @@ -1233,10 +1233,10 @@ migrate.cancel_migrating_confirm=Θέλετε να ακυρώσετε αυτή mirror_from=είδωλο του forked_from=forked από generated_from=παραγμένο από -fork_from_self=Δεν μπορείτε να κάνετε fork σε ένα αποθετήριο που κατέχετε. -fork_guest_user=Συνδεθείτε για να κάνετε fork αυτό το αποθετήριο. -watch_guest_user=Συνδεθείτε για να παρακολουθήσετε αυτό το αποθετήριο. -star_guest_user=Συνδεθείτε για να δώσετε ένα αστέρι σε αυτό το αποθετήριο. +fork_from_self=Δεν μπορείτε να κάνετε fork ένα repository που σας ανήκει. +fork_guest_user=Συνδεθείτε για να κάνετε fork αυτό το repository. +watch_guest_user=Συνδεθείτε για να παρακολουθήσετε αυτό το repository. +star_guest_user=Συνδεθείτε για να δώσετε ένα αστέρι σε αυτό το repository. unwatch=Παύση ακολούθησης watch=Παρακολούθηση unstar=Αφαίρεση αστεριού @@ -1248,11 +1248,11 @@ more_operations=Περισσότερες λειτουργίες no_desc=Χωρίς περιγραφή quick_guide=Γρήγορος οδηγός clone_this_repo=Κλωνοποίηση αυτού του αποθετηρίου -cite_this_repo=Αναφορά σε αυτό το αποθετήριο +cite_this_repo=Αναφορά σε αυτό το repository create_new_repo_command=Δημιουργία νέου αποθετηρίου στη γραμμή εντολών push_exist_repo=Προώθηση ενός υπάρχοντος αποθετηρίου από τη γραμμή εντολών -empty_message=Αυτό το αποθετήριο δεν έχει περιεχόμενο. -broken_message=Τα δεδομένα Git που διέπουν αυτό το αποθετήριο δεν μπορούν να διαβαστούν. Επικοινωνήστε με το διαχειριστή ή διαγράψτε αυτό το αποθετήριο. +empty_message=Αυτό το repository δεν έχει περιεχόμενο. +broken_message=Τα δεδομένα Git που διέπουν αυτό το αποθετήριο δεν μπορούν να διαβαστούν. Επικοινωνήστε με το διαχειριστή ή διαγράψτε αυτό το repository. code=Κώδικας code.desc=Πρόσβαση στον πηγαίο κώδικα, αρχεία, υποβολές και κλάδους. @@ -1330,7 +1330,7 @@ editor.cannot_edit_non_text_files=Τα δυαδικά αρχεία δεν μπο editor.edit_this_file=Επεξεργασία αρχείου editor.this_file_locked=Το αρχείο είναι κλειδωμένο editor.must_be_on_a_branch=Πρέπει να βρίσκεστε σε έναν κλάδο για να κάνετε ή να προτείνετε αλλαγές σε αυτό το αρχείο. -editor.fork_before_edit=Πρέπει να κάνετε fork αυτό το αποθετήριο για να κάνετε ή να προτείνετε αλλαγές σε αυτό το αρχείο. +editor.fork_before_edit=Πρέπει να κάνετε fork αυτό το repository για να κάνετε ή να προτείνετε αλλαγές σε αυτό το αρχείο. editor.delete_this_file=Διαγραφή αρχείου editor.must_have_write_access=Πρέπει να έχετε πρόσβαση εγγραφής για να κάνετε ή να προτείνετε αλλαγές σε αυτό το αρχείο. editor.file_delete_success=Το αρχείο «%s» έχει διαγραφεί. @@ -1359,15 +1359,15 @@ editor.new_branch_name_desc=Όνομα νέου κλάδου… editor.cancel=Ακύρωση editor.filename_cannot_be_empty=Το όνομα αρχείου δεν μπορεί να είναι κενό. editor.filename_is_invalid=Το όνομα αρχείου δεν είναι έγκυρο: "%s". -editor.branch_does_not_exist=Ο κλάδος "%s" δεν υπάρχει σε αυτό το αποθετήριο. -editor.branch_already_exists=Ο κλάδος «%s» υπάρχει ήδη σε αυτό το αποθετήριο. -editor.directory_is_a_file=Το όνομα φακέλου «%s» χρησιμοποιείται ήδη ως όνομα αρχείου σε αυτό το αποθετήριο. +editor.branch_does_not_exist=Ο κλάδος "%s" δεν υπάρχει σε αυτό το repository. +editor.branch_already_exists=Ο κλάδος «%s» υπάρχει ήδη σε αυτό το repository. +editor.directory_is_a_file=Το όνομα φακέλου «%s» χρησιμοποιείται ήδη ως όνομα αρχείου σε αυτό το repository. editor.file_is_a_symlink=`Το «%s» είναι συμβολικός σύνδεσμος. Οι συμβολικοί σύνδεσμοι δεν μπορούν να επεξεργαστούν στην ενσωματωμένη εφαρμογή` -editor.filename_is_a_directory=Το όνομα αρχείου «%s» χρησιμοποιείται ήδη ως όνομα φακέλου σε αυτό το αποθετήριο. -editor.file_editing_no_longer_exists=Το αρχείο «%s», το οποίο επεξεργάζεστε, δεν υπάρχει πλέον σε αυτό το αποθετήριο. -editor.file_deleting_no_longer_exists=Το αρχείο «%s», το οποίο διαγράφεται, δεν υπάρχει πλέον σε αυτό το αποθετήριο. +editor.filename_is_a_directory=Το όνομα αρχείου «%s» χρησιμοποιείται ήδη ως όνομα φακέλου σε αυτό το repository. +editor.file_editing_no_longer_exists=Το αρχείο «%s», το οποίο επεξεργάζεστε, δεν υπάρχει πλέον σε αυτό το repository. +editor.file_deleting_no_longer_exists=Το αρχείο «%s», το οποίο διαγράφεται, δεν υπάρχει πλέον σε αυτό το repository. editor.file_changed_while_editing=Προέκυψαν κάποιες αλλαγές στα περιεχόμενα του αρχείου από τότε που ξεκινήσατε να τα επεξεργάζεστε. Κάντε κλικ εδώ για να τα δείτε ή ξανακάντε μία υποβολή των αλλαγών σας για να τις αντικαταστήσετε. -editor.file_already_exists=Υπάρχει ήδη ένα αρχείο με το όνομα «%s» σε αυτό το αποθετήριο. +editor.file_already_exists=Υπάρχει ήδη ένα αρχείο με το όνομα «%s» σε αυτό το repository. editor.commit_empty_file_header=Υποβολή ενός κενού αρχείου editor.commit_empty_file_text=Το αρχείο που πρόκειται να υποβληθεί είναι κενό. Συνέχεια; editor.no_changes_to_show=Δεν υπάρχουν αλλαγές για εμφάνιση. @@ -1620,13 +1620,13 @@ issues.author_helper=Αυτός ο χρήστης είναι ο συγγραφέ issues.role.owner=Ιδιοκτήτης issues.role.owner_helper=Αυτός ο χρήστης είναι ο ιδιοκτήτης αυτού του αποθετηρίου. issues.role.member=Μέλος -issues.role.member_helper=Αυτός ο χρήστης είναι μέλος του οργανισμού, του οποίου ανήκει το αποθετήριο. +issues.role.member_helper=Αυτός ο χρήστης είναι μέλος του οργανισμού, του οποίου ανήκει το repository. issues.role.collaborator=Συνεργάτης -issues.role.collaborator_helper=Ο χρήστης έλαβε πρόσκληση συνεργασίας στο αποθετήριο. +issues.role.collaborator_helper=Ο χρήστης έλαβε πρόσκληση συνεργασίας στο repository. issues.role.first_time_contributor=Συντελεστής για πρώτη φορά -issues.role.first_time_contributor_helper=Αυτή είναι η πρώτη συνεισφορά αυτού του χρήστη στο αποθετήριο. +issues.role.first_time_contributor_helper=Αυτή είναι η πρώτη συνεισφορά αυτού του χρήστη στο repository. issues.role.contributor=Συντελεστής -issues.role.contributor_helper=Αυτός ο χρήστης έχει προηγούμενές υποβολές (commits) στο αποθετήριο. +issues.role.contributor_helper=Αυτός ο χρήστης έχει προηγούμενές υποβολές (commits) στο repository. issues.re_request_review=Επαναίτηση ανασκόπησης issues.is_stale=Έχουν υπάρξει αλλαγές σε αυτό το PR από αυτή την αναθεώρηση issues.remove_request_review=Αφαίρεση αιτήματος αναθεώρησης @@ -1678,7 +1678,7 @@ issues.unlock_comment=: ξεκλείδωσε αυτή τη συνομιλία %s issues.lock_confirm=Κλείδωμα issues.unlock_confirm=Ξεκλείδωμα issues.lock.notice_1=- Άλλοι χρήστες δεν μπορούν να αφήσουν νέα σχόλια σε αυτό το ζήτημα. -issues.lock.notice_2=- Εσείς και άλλοι συνεργάτες που έχουν πρόσβαση στο αποθετήριο θα μπορείτε ακόμα να αφήσετε σχόλια που θα είναι ορατά σε άλλους. +issues.lock.notice_2=- Εσείς, μαζί με τους συνεργάτες σας που έχουν πρόσβαση στο repository, θα μπορείτε ακόμα να αφήσετε σχόλια που θα μπορούν να βλέπουν και άλλοι. issues.lock.notice_3=- Θα μπορείτε να ξεκλειδώσετε αυτό το ζήτημα πιο μετά. issues.unlock.notice_1=- Όλοι θα βρίσκονται πάλι σε θέση να αφήσουν σχόλιο σε αυτό το ζήτημα. issues.unlock.notice_2=- Θα μπορείτε πάντα να ξανακλειδώσετε αυτό το ζήτημα πιο μετά. @@ -1759,7 +1759,7 @@ issues.dependency.add_error_dep_issue_not_exist=Εξαρτώμενο ζήτημ issues.dependency.add_error_dep_not_exist=Δεν υπάρχει η Εξάρτηση. issues.dependency.add_error_dep_exists=Η Εξάρτηση υπάρχει ήδη. issues.dependency.add_error_cannot_create_circular=Δεν μπορείτε να δημιουργήσετε μια εξάρτηση με δύο ζητήματα που μπλοκάρουν το ένα το άλλο. -issues.dependency.add_error_dep_not_same_repo=Και τα δύο ζητήματα πρέπει να βρίσκονται στο ίδιο αποθετήριο. +issues.dependency.add_error_dep_not_same_repo=Και τα δύο ζητήματα πρέπει να βρίσκονται στο ίδιο repository. issues.review.self.approval=Δεν μπορείτε να εγκρίνετε το δικό σας pull request. issues.review.self.rejection=Δεν μπορείτε να ζητήσετε αλλαγές στο δικό σας pull request. issues.review.approve=ενέκρινε τις αλλαγές %s @@ -1922,7 +1922,7 @@ pulls.closed_at=`έκλεισε αυτό το pull request %[2]s` pulls.cmd_instruction_hint=Προβολή οδηγιών γραμμής εντολών pulls.cmd_instruction_checkout_title=Έλεγχος -pulls.cmd_instruction_checkout_desc=Από το αποθετήριο του έργου σας, ελέγξτε έναν νέο κλάδο και δοκιμάστε τις αλλαγές. +pulls.cmd_instruction_checkout_desc=Από το repository του έργου σας, ελέγξτε έναν νέο κλάδο και δοκιμάστε τις αλλαγές. pulls.cmd_instruction_merge_title=Συγχώνευση pulls.cmd_instruction_merge_desc=Συγχώνευση των αλλαγών και ενημέρωση στο Gitea. pulls.clear_merge_message=Εκκαθάριση μηνύματος συγχώνευσης @@ -2101,8 +2101,8 @@ search.code_no_results=Δεν βρέθηκε πηγαίος κώδικας πο search.code_search_unavailable=Η αναζήτηση κώδικα δεν είναι διαθέσιμη αυτή τη στιγμή. Παρακαλώ επικοινωνήστε με το διαχειριστή. settings=Ρυθμίσεις -settings.desc=Στις Ρυθμίσεις μπορείτε να διαχειριστείτε τις ρυθμίσεις για το αποθετήριο -settings.options=Αποθετήριο +settings.desc=Στις Ρυθμίσεις μπορείτε να διαχειριστείτε τις ρυθμίσεις για το repository +settings.options=Repository settings.collaboration=Συνεργάτες settings.collaboration.admin=Διαχειριστής settings.collaboration.write=Εγγραφή @@ -2113,18 +2113,18 @@ settings.hooks=Webhooks settings.githooks=Git hooks settings.basic_settings=Βασικές ρυθμίσεις settings.mirror_settings=Ρυθμίσεις ειδώλου -settings.mirror_settings.docs=Ρυθμίστε τον αυτόματο συγχρονισμό των υποβολών, ετικετών και κλάδων του αποθετηρίου σας σε ένα άλλο αποθετήριο. -settings.mirror_settings.docs.disabled_pull_mirror.instructions=Ρυθμίστε τον αυτόματο συγχρονισμό των υποβολών, ετικετών και κλάδων του έργου σας με ένα άλλο αποθετήριο. Τα είδωλα τύπου λήψης έχουν απενεργοποιηθεί από τον διαχειριστή σας. -settings.mirror_settings.docs.disabled_push_mirror.instructions=Ρυθμίστε την αυτόματη λήψη υποβολών, ετικετών και κλάδων από ένα άλλο αποθετήριο. +settings.mirror_settings.docs=Ρυθμίστε τον αυτόματο συγχρονισμό των commit, ετικετών και κλάδων του αποθετηρίου σας σε ένα άλλο repository. +settings.mirror_settings.docs.disabled_pull_mirror.instructions=Ρυθμίστε τον αυτόματο συγχρονισμό των commit, ετικετών και κλάδων του έργου σας με ένα άλλο repository. Τα είδωλα τύπου λήψης έχουν απενεργοποιηθεί από τον διαχειριστή σας. +settings.mirror_settings.docs.disabled_push_mirror.instructions=Ρυθμίστε την αυτόματη λήψη υποβολών, ετικετών και κλάδων από ένα άλλο repository. settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=Αυτή τη στιγμή, αυτό μπορεί να γίνει μόνο στο μενού "Νέα Μεταφορά". Για περισσότερες πληροφορίες, συμβουλευτείτε το: settings.mirror_settings.docs.disabled_push_mirror.info=Τα είδωλα ώθησης έχουν απενεργοποιηθεί από το διαχειριστή σας. -settings.mirror_settings.docs.no_new_mirrors=Το αποθετήριο σας αντιγράφει τις αλλαγές προς ή από ένα άλλο αποθετήριο. Λάβετε υπόψη ότι δεν μπορείτε να δημιουργήσετε νέα είδωλα αυτή τη στιγμή. +settings.mirror_settings.docs.no_new_mirrors=Το repository σας αντιγράφει τις αλλαγές προς ή από ένα άλλο repository. Λάβετε υπόψη ότι δεν μπορείτε να δημιουργήσετε νέα είδωλα αυτή τη στιγμή. settings.mirror_settings.docs.can_still_use=Αν και δεν μπορείτε να τροποποιήσετε τα υπάρχοντα είδωλα ή να δημιουργήσετε νέα, μπορείτε να χρησιμοποιείται ακόμα το υπάρχων είδωλο. settings.mirror_settings.docs.pull_mirror_instructions=Για να ορίσετε έναν είδωλο έλξης, παρακαλούμε συμβουλευθείτε: settings.mirror_settings.docs.more_information_if_disabled=Μπορείτε να μάθετε περισσότερα για τα είδωλα ώθησης και έλξης εδώ: settings.mirror_settings.docs.doc_link_title=Πώς μπορώ να αντιγράψω αποθετήρια; settings.mirror_settings.docs.doc_link_pull_section=το κεφάλαιο "Pulling from a remote repository" της τεκμηρίωσης. -settings.mirror_settings.docs.pulling_remote_title=Έλξη από ένα απομακρυσμένο αποθετήριο +settings.mirror_settings.docs.pulling_remote_title=Pull από ένα απομακρυσμένο repository settings.mirror_settings.mirrored_repository=Είδωλο αποθετηρίου settings.mirror_settings.direction=Κατεύθυνση settings.mirror_settings.direction.pull=Pull @@ -2188,33 +2188,33 @@ settings.reindex_button=Προσθήκη στην ουρά Reindex settings.reindex_requested=Αιτήθηκε reindex settings.admin_enable_close_issues_via_commit_in_any_branch=Κλείσιμο ενός ζητήματος μέσω μιας υποβολής που έγινε σε έναν μη προεπιλεγμένο κλάδο settings.danger_zone=Ζώνη κινδύνου -settings.new_owner_has_same_repo=Ο νέος ιδιοκτήτης έχει ήδη ένα αποθετήριο με το ίδιο όνομα. Παρακαλώ επιλέξτε ένα άλλο όνομα. -settings.convert=Μετατροπή σε κανονικό αποθετήριο -settings.convert_desc=Μπορείτε να μετατρέψετε αυτόν το είδωλο σε κανονικό αποθετήριο. Αυτό δεν μπορεί να αναιρεθεί. -settings.convert_notices_1=Αυτή η λειτουργία θα μετατρέψει το είδωλο σε ένα κανονικό αποθετήριο και δεν μπορεί να αναιρεθεί. +settings.new_owner_has_same_repo=Ο νέος ιδιοκτήτης έχει ήδη ένα repository με το ίδιο όνομα. Παρακαλώ επιλέξτε ένα άλλο όνομα. +settings.convert=Μετατροπή σε κανονικό repository +settings.convert_desc=Μπορείτε να μετατρέψετε αυτόν το είδωλο σε κανονικό repository. Αυτό δεν μπορεί να αναιρεθεί. +settings.convert_notices_1=Αυτή η λειτουργία θα μετατρέψει το είδωλο σε ένα κανονικό repository και δεν μπορεί να αναιρεθεί. settings.convert_confirm=Μετατροπή αποθετηρίου -settings.convert_succeed=Το είδωλο έχει μετατραπεί σε κανονικό αποθετήριο. -settings.convert_fork=Μετατροπή σε κανονικό αποθετήριο -settings.convert_fork_desc=Μπορείτε να μετατρέψετε αυτό το fork σε κανονικό αποθετήριο. Αυτό δεν μπορεί να αναιρεθεί. -settings.convert_fork_notices_1=Αυτή η λειτουργία θα μετατρέψει το fork σε ένα κανονικό αποθετήριο και δεν μπορεί να αναιρεθεί. +settings.convert_succeed=Το είδωλο έχει μετατραπεί σε κανονικό repository. +settings.convert_fork=Μετατροπή σε κανονικό repository +settings.convert_fork_desc=Μπορείτε να μετατρέψετε αυτό το fork σε κανονικό repository. Αυτό δεν μπορεί να αναιρεθεί. +settings.convert_fork_notices_1=Αυτή η λειτουργία θα μετατρέψει το fork σε ένα κανονικό repository και δεν μπορεί να αναιρεθεί. settings.convert_fork_confirm=Μετατροπή αποθετηρίου -settings.convert_fork_succeed=Το fork έχει μετατραπεί σε κανονικό αποθετήριο. +settings.convert_fork_succeed=Το fork έχει μετατραπεί σε κανονικό repository. settings.transfer.title=Μεταβίβαση ιδιοκτησίας settings.transfer.rejected=Η μεταβίβαση του αποθετηρίου απορρίφθηκε. settings.transfer.success=Η μεταβίβαση του αποθετηρίου ήταν επιτυχής. settings.transfer_abort=Ακύρωση μεταβίβασης settings.transfer_abort_invalid=Δεν μπορείτε να ακυρώσετε μια ανύπαρκτη μεταβίβαση αποθετηρίου. settings.transfer_abort_success=Η μεταφορά αποθετηρίου στο %s ακυρώθηκε με επιτυχία. -settings.transfer_desc=Μεταβιβάστε αυτό το αποθετήριο σε έναν χρήστη ή σε έναν οργανισμό για τον οποίο έχετε δικαιώματα διαχειριστή. +settings.transfer_desc=Μεταβιβάστε αυτό το repository σε έναν χρήστη ή σε έναν οργανισμό για τον οποίο έχετε δικαιώματα διαχειριστή. settings.transfer_form_title=Εισάγετε το όνομα του αποθετηρίου ως επιβεβαίωση: -settings.transfer_in_progress=Αυτή τη στιγμή υπάρχει μια εν εξελίξει μεταβίβαση. Παρακαλούμε ακυρώστε την αν θέλετε να μεταβιβάσετε αυτό το αποθετήριο σε άλλο χρήστη. -settings.transfer_notices_1=- Θα χάσετε την πρόσβαση στο αποθετήριο αν το μεταβιβάσετε σε έναν μεμονωμένο χρήστη. -settings.transfer_notices_2=- Θα διατηρήσετε την πρόσβαση στο αποθετήριο αν το μεταβιβάσετε σε έναν οργανισμό που είστε (συν)ιδιοκτήτης. -settings.transfer_notices_3=- Εάν το αποθετήριο είναι ιδιωτικό και μεταβιβάζεται σε μεμονωμένο χρήστη, αυτή η ενέργεια εξασφαλίζει ότι ο χρήστης έχει τουλάχιστον άδεια ανάγνωσης (και αλλάζει τα δικαιώματα εάν είναι απαραίτητο). +settings.transfer_in_progress=Αυτή τη στιγμή υπάρχει μια εν εξελίξει μεταβίβαση. Παρακαλούμε ακυρώστε την αν θέλετε να μεταβιβάσετε αυτό το repository σε άλλο χρήστη. +settings.transfer_notices_1=- Θα χάσετε την πρόσβαση στο repository αν το μεταβιβάσετε σε έναν μεμονωμένο χρήστη. +settings.transfer_notices_2=- Θα διατηρήσετε την πρόσβαση στο repository αν το μεταβιβάσετε σε έναν οργανισμό που είστε (συν)ιδιοκτήτης. +settings.transfer_notices_3=- Εάν το repository είναι ιδιωτικό και μεταβιβάζεται σε μεμονωμένο χρήστη, αυτή η ενέργεια εξασφαλίζει ότι ο χρήστης έχει τουλάχιστον άδεια ανάγνωσης (και αλλάζει τα δικαιώματα εάν είναι απαραίτητο). settings.transfer_owner=Νέος ιδιοκτήτης settings.transfer_perform=Εκτέλεση μεταφοράς -settings.transfer_started=`Αυτό το αποθετήριο έχει επισημανθεί για μεταφορά και αναμένει επιβεβαίωση από το "%s"` -settings.transfer_succeed=Το αποθετήριο έχει μεταφερθεί. +settings.transfer_started=`Αυτό το repository έχει επισημανθεί για μεταφορά και αναμένει επιβεβαίωση από το "%s"` +settings.transfer_succeed=Το repository έχει μεταφερθεί. settings.signing_settings=Ρυθμίσεις επαλήθευσης υπογραφών settings.trust_model=Μοντέλο εμπιστοσύνης υπογραφών settings.trust_model.default=Προεπιλεγμένο μοντέλο εμπιστοσύνης @@ -2236,33 +2236,33 @@ settings.wiki_deletion_success=Τα δεδομένα wiki του αποθετη settings.delete=Διαγραφή αυτόυ του αποθετηρίου settings.delete_desc=Η διαγραφή ενός αποθετηρίου είναι μόνιμη και δεν μπορεί να αναιρεθεί. settings.delete_notices_1=- Αυτή η ενέργεια ΔΕΝ ΜΠΟΡΕΙ να αναιρεθεί. -settings.delete_notices_2=- Αυτή η ενέργεια θα διαγράψει μόνιμα το αποθετήριο %s μαζί με τον κώδικα, τα ζητημάτα, τα σχόλια, τα δεδομένα των wiki και τις ρυθμίσεις συνεργατών που βρίσκονται μέσα σε αυτό. +settings.delete_notices_2=- Αυτή η ενέργεια θα διαγράψει μόνιμα το repository %s μαζί με τον κώδικα, τα ζητημάτα, τα σχόλια, τα δεδομένα των wiki και τις ρυθμίσεις συνεργατών που βρίσκονται μέσα σε αυτό. settings.delete_notices_fork_1=- Τα Forks αυτού του αποθετηρίου θα γίνουν ανεξάρτητα μετά τη διαγραφή. -settings.deletion_success=Το αποθετήριο έχει διαγραφεί. +settings.deletion_success=Το repository έχει διαγραφεί. settings.update_settings_success=Οι ρυθμίσεις του αποθετηρίου έχουν ενημερωθεί. -settings.update_settings_no_unit=Το αποθετήριο θα πρέπει να επιτρέπει τουλάχιστον κάποιο είδος αλληλεπίδρασης. +settings.update_settings_no_unit=Το repository θα πρέπει να επιτρέπει τουλάχιστον κάποιο είδος αλληλεπίδρασης. settings.confirm_delete=Διαγραφή αποθετηρίου settings.add_collaborator=Προσθήκη συνεργάτη settings.add_collaborator_success=Ο συνεργάτης προστέθηκε. settings.add_collaborator_inactive_user=Δεν είναι δυνατή η προσθήκη ενός ανενεργού χρήστη ως συνεργάτη. settings.add_collaborator_owner=Δεν είναι δυνατή η προσθήκη ενός ιδιοκτήτη σαν συνεργάτη. -settings.add_collaborator_duplicate=Ο συνεργάτης έχει ήδη προστεθεί σε αυτό το αποθετήριο. +settings.add_collaborator_duplicate=Ο συνεργάτης έχει ήδη προστεθεί σε αυτό το repository. settings.delete_collaborator=Κατάργηση settings.collaborator_deletion=Κατάργηση συνεργάτη -settings.collaborator_deletion_desc=Η κατάργηση ενός συνεργάτη θα αφαιρέσει και την πρόσβασή του στο αποθετήριο. Είστε βέβαιοι; +settings.collaborator_deletion_desc=Η κατάργηση ενός συνεργάτη θα αφαιρέσει και την πρόσβασή του στο repository. Είστε βέβαιοι; settings.remove_collaborator_success=Ο συνεργάτης έχει καταργηθεί. settings.search_user_placeholder=Αναζήτηση χρήστη… settings.org_not_allowed_to_be_collaborator=Δεν μπορείτε να προσθέσετε έναν οργανισμό ως συνεργάτη. -settings.change_team_access_not_allowed=Η αλλαγή της πρόσβασης ομάδας για το αποθετήριο έχει περιοριστεί στον ιδιοκτήτη του οργανισμού -settings.team_not_in_organization=Η ομάδα δεν είναι στον ίδιο οργανισμό με το αποθετήριο +settings.change_team_access_not_allowed=Η αλλαγή της πρόσβασης ομάδας για το repository έχει περιοριστεί στον ιδιοκτήτη του οργανισμού +settings.team_not_in_organization=Η ομάδα δεν είναι στον ίδιο οργανισμό με το repository settings.teams=Ομάδες settings.add_team=Προσθήκη ομάδας -settings.add_team_duplicate=Η ομάδα έχει ήδη το αποθετήριο -settings.add_team_success=Η ομάδα έχει πλέον πρόσβαση στο αποθετήριο. +settings.add_team_duplicate=Η ομάδα έχει ήδη το repository +settings.add_team_success=Η ομάδα έχει πλέον πρόσβαση στο repository. settings.search_team=Αναζήτηση Ομάδας… -settings.change_team_permission_tip=Τα δικαιώματα της ομάδας έχουν οριστεί στη σελίδα ρυθμίσεων της ομάδας και δεν μπορούν να αλλάξουν ανά αποθετήριο +settings.change_team_permission_tip=Τα δικαιώματα της ομάδας έχουν οριστεί στη σελίδα ρυθμίσεων της ομάδας και δεν μπορούν να αλλάξουν ανά repository settings.delete_team_tip=Αυτή η ομάδα έχει πρόσβαση σε όλα τα αποθετήρια και δεν μπορεί να αφαιρεθεί -settings.remove_team_success=Έχει αφαιρεθεί η πρόσβαση της ομάδας στο αποθετήριο. +settings.remove_team_success=Έχει αφαιρεθεί η πρόσβαση της ομάδας στο repository. settings.add_webhook=Προσθήκη webhook settings.add_webhook.invalid_channel_name=Το όνομα του καναλιού Webhook δεν μπορεί να είναι κενό και δεν μπορεί να περιέχει μόνο έναν χαρακτήρα #. settings.hooks_desc=Τα Webhooks κάνουν αυτόματα αιτήσεις HTTP POST σε ένα διακομιστή όταν ενεργοποιούνται ορισμένα γεγονότα στο Forgejo. Διαβάστε περισσότερα στον οδηγό webhooks. @@ -2305,15 +2305,15 @@ settings.event_create_desc=Ο κλάδος ή η ετικέτα δημιουργ settings.event_delete=Διαγραφή settings.event_delete_desc=Ο κλάδος ή η ετικέτα διαγράφηκε. settings.event_fork=Fork -settings.event_fork_desc=Το αποθετήριο έγινε fork. +settings.event_fork_desc=Το repository έγινε fork. settings.event_wiki=Wiki settings.event_wiki_desc=Η σελίδα Wiki δημιουργήθηκε, μετονομάστηκε, επεξεργάστηκε ή διαγράφηκε. settings.event_release=Κυκλοφορία settings.event_release_desc=Η έκδοση δημοσιεύτηκε, ενημερώθηκε ή διαγράφηκε από ένα αποθετήριο. settings.event_push=Push -settings.event_push_desc=Git push σε ένα αποθετήριο. -settings.event_repository=Αποθετήριο -settings.event_repository_desc=Το αποθετήριο δημιουργήθηκε ή διαγράφηκε. +settings.event_push_desc=Git push σε ένα repository. +settings.event_repository=Repository +settings.event_repository_desc=Το repository δημιουργήθηκε ή διαγράφηκε. settings.event_header_issue=Συμβάντα ζητημάτων settings.event_issues=Ζητήματα settings.event_issues_desc=Το ζήτημα άνοιξε, έκλεισε, ανοίχθηκε εκ νέου ή επεξεργάστηκε. @@ -2345,7 +2345,7 @@ settings.event_pull_request_review_request_desc=Ζητήθηκε η αξιολό settings.event_pull_request_approvals=Εγκρίσεις pull request settings.event_pull_request_merge=Συγχώνευση pull request settings.event_package=Πακέτο -settings.event_package_desc=Το πακέτο δημιουργήθηκε ή διαγράφηκε σε ένα αποθετήριο. +settings.event_package_desc=Το πακέτο δημιουργήθηκε ή διαγράφηκε σε ένα repository. settings.branch_filter=Φίλτρο κλάδου settings.branch_filter_desc=Λίστα επιτρεπόμενων κλάδων για ωθήσεις, δημιουργία κλάδων και γεγονότα διαγραφής κλάδων, που ορίζονται ως μοτίβο glob. Εάν είναι κενό ή *, αναφέρονται συμβάντα για όλους τους κλάδους. Δείτε τη τεκμηρίωση%[2]s για σύνταξη. Παραδείγματα: master, {master,release*}. settings.authorization_header=Κεφαλίδα authorization @@ -2361,7 +2361,7 @@ settings.hook_type=Είδος hook settings.slack_token=Διακριτικό settings.slack_domain=Domain settings.slack_channel=Κανάλι -settings.add_web_hook_desc=Ενσωμάτωσε το %s στο αποθετήριο σας. +settings.add_web_hook_desc=Ενσωμάτωσε το %s στο repository σας. settings.web_hook_name_gitea=Gitea settings.web_hook_name_forgejo = Forgejo settings.web_hook_name_gogs=Gogs @@ -2381,9 +2381,9 @@ settings.packagist_api_token=Διακριτικό API settings.packagist_package_url=URL πακέτων Packagist settings.deploy_keys=Κλειδιά διάθεσης settings.add_deploy_key=Προσθήκη κλειδιού διάθεσης -settings.deploy_key_desc=Τα κλειδιά διάθεσης έχουν πρόσβαση μόνο-ανάγνωσης στο αποθετήριο. +settings.deploy_key_desc=Τα κλειδιά διάθεσης έχουν πρόσβαση μόνο-ανάγνωσης στο repository. settings.is_writable=Ενεργοποίηση πρόσβασης εγγραφής -settings.is_writable_info=Επιτρέψτε σε αυτό το κλειδί διάθεσης να ωθήσει στο αποθετήριο. +settings.is_writable_info=Επιτρέψτε σε αυτό το κλειδί διάθεσης να ωθήσει στο repository. settings.no_deploy_keys=Δεν υπάρχουν ακόμα κλειδιά διάθεσης. settings.title=Τίτλος settings.deploy_key_content=Περιεχόμενο @@ -2391,7 +2391,7 @@ settings.key_been_used=Ένα κλειδί διάθεσης με το ίδιο settings.key_name_used=Ένα κλειδί διάθεσης με το ίδιο όνομα υπάρχει ήδη. settings.add_key_success=Το κλειδί διάθεσης «%s» προστέθηκε. settings.deploy_key_deletion=Αφαίρεση κλειδιού διάθεσης -settings.deploy_key_deletion_desc=Η κατάργηση ενός κλειδί διάθεσης θα ανακαλέσει την πρόσβασή του σε αυτό το αποθετήριο. Συνέχεια; +settings.deploy_key_deletion_desc=Η κατάργηση ενός κλειδί διάθεσης θα ανακαλέσει την πρόσβασή του σε αυτό το repository. Συνέχεια; settings.deploy_key_deletion_success=Το κλειδί διάθεσης έχει αφαιρεθεί. settings.branches=Κλάδοι settings.protected_branch=Προστασία κλάδου @@ -2424,7 +2424,7 @@ settings.protect_check_status_contexts=Ενεργοποίηση ελέγχου settings.protect_status_check_patterns=Μοτίβα ελέγχου κατάστασης: settings.protect_status_check_patterns_desc=Ορίστε μοτίβα για να καθορίσετε ποιοι έλεγχοι κατάστασης πρέπει να περάσουν πριν οι κλάδοι να μπορούν να συγχωνευτούν σε έναν κλάδο που ταιριάζει με αυτόν τον κανόνα. Κάθε γραμμή καθορίζει ένα μοτίβο. Τα μοτίβα δεν μπορούν να είναι κενά. settings.protect_check_status_contexts_desc=Απαιτείται έλεγχος κατάστασης για να περάσει το pull request πριν από τη συγχώνευση. Επιλέξτε ποιοι έλεγχοι κατάστασης πρέπει να περάσουν πριν κλάδοι μπορούν να συγχωνευτούν σε έναν κλάδο που ταιριάζει με αυτόν τον κανόνα. Όταν είναι ενεργοποιημένο, οι υποβολές πρέπει πρώτα να γίνονται push σε άλλο κλάδο, στη συνέχεια, να συγχωνεύονται ή γίνονται push απευθείας σε ένα κλάδο που ταιριάζει με αυτόν τον κανόνα, αφού έχουν ολοκληρωθεί οι έλεγχοι κατάστασης. Αν δεν επιλεχθεί κανένα πλαίσιο, η τελευταία υποβολή πρέπει να είναι επιτυχής ανεξάρτητα από το πλαίσιο. -settings.protect_check_status_contexts_list=Έλεγχοι κατάστασης που βρέθηκαν την τελευταία εβδομάδα για αυτό το αποθετήριο +settings.protect_check_status_contexts_list=Έλεγχοι κατάστασης που βρέθηκαν την τελευταία εβδομάδα για αυτό το repository settings.protect_status_check_matched=Ταιριάζει settings.protect_invalid_status_check_pattern=Μη έγκυρο μοτίβο ελέγχου κατάστασης: "%s". settings.protect_no_valid_status_check_patterns=Μη έγκυρα μοτίβα ελέγχου κατάστασης. @@ -2486,20 +2486,20 @@ settings.matrix.message_type=Είδος μηνύματος settings.archive.button=Αρχειοθέτηση αποθετηρίου settings.archive.header=Αρχειοθέτηση αποθετηρίου settings.archive.text=Η αρχειοθέτηση του αποθετηρίου θα το αλλάξει σε μόνο για ανάγνωση. Δε θα φαίνεται στον αρχικό πίνακα. Κανείς (ακόμα και εσείς!) δε θα μπορεί να κάνει νέες υποβολές, ή να ανοίξει ζητήματα ή pull request. -settings.archive.success=Το αποθετήριο αρχειοθετήθηκε με επιτυχία. +settings.archive.success=Το repository αρχειοθετήθηκε με επιτυχία. settings.archive.error=Παρουσιάστηκε σφάλμα κατά την προσπάθεια αρχειοθέτησης του αποθετηρίου. Δείτε το αρχείο καταγραφής για περισσότερες λεπτομέρειες. settings.archive.error_ismirror=Δε μπορείτε να αρχειοθετήσετε ένα είδωλο αποθετηρίου. -settings.archive.branchsettings_unavailable=Οι ρυθμίσεις του κλάδου δεν είναι διαθέσιμες αν το αποθετήριο είναι αρχειοθετημένο. -settings.archive.tagsettings_unavailable=Οι ρυθμίσεις της ετικέτας δεν είναι διαθέσιμες αν το αποθετήριο είναι αρχειοθετημένο. +settings.archive.branchsettings_unavailable=Οι ρυθμίσεις του κλάδου δεν είναι διαθέσιμες αν το repository είναι αρχειοθετημένο. +settings.archive.tagsettings_unavailable=Οι ρυθμίσεις της ετικέτας δεν είναι διαθέσιμες αν το repository είναι αρχειοθετημένο. settings.unarchive.button=Αναίρεση αρχειοθέτησης αποθετηρίου settings.unarchive.header=Απο-Αρχειοθέτηση του αποθετηρίου settings.unarchive.text=Η απο-αρχειοθέτηση του αποθετηρίου θα αποκαταστήσει την ικανότητά του να λαμβάνει υποβολές και ωθήσεις, καθώς και νέα ζητήματα και pull-requests. -settings.unarchive.success=Το αποθετήριο απο-αρχειοθετήθηκε με επιτυχία. +settings.unarchive.success=Το repository απο-αρχειοθετήθηκε με επιτυχία. settings.unarchive.error=Παρουσιάστηκε σφάλμα κατά την προσπάθεια απο-αρχειοθέτησης του αποθετηρίου. Δείτε τις καταγραφές για περισσότερες λεπτομέρειες. settings.update_avatar_success=Η εικόνα του αποθετηρίου έχει ενημερωθεί. settings.lfs=LFS -settings.lfs_filelist=Αρχεία LFS σε αυτό το αποθετήριο -settings.lfs_no_lfs_files=Δεν υπάρχουν αρχεία LFS σε αυτό το αποθετήριο +settings.lfs_filelist=Αρχεία LFS σε αυτό το repository +settings.lfs_no_lfs_files=Δεν υπάρχουν αρχεία LFS σε αυτό το repository settings.lfs_findcommits=Εύρεση υποβολών settings.lfs_lfs_file_no_commits=Δεν βρέθηκαν υποβολές για αυτό το αρχείο LFS settings.lfs_noattribute=Αυτή η διαδρομή δεν έχει λειτουργία κλειδώματος στον προεπιλεγμένο κλάδο @@ -2518,7 +2518,7 @@ settings.lfs_force_unlock=Εξαγκαναστικό ξεκλείδωμα settings.lfs_pointers.found=Βρέθηκαν %d δείκτης(ες) blob - %d συσχετίστηκαν, %d δεν συσχετίστηκαν (%d λείπουν από το χώρο αποθήκευσης) settings.lfs_pointers.sha=Blob hash settings.lfs_pointers.oid=OID -settings.lfs_pointers.inRepo=Στο αποθετήριο +settings.lfs_pointers.inRepo=Στο repository settings.lfs_pointers.exists=Υπάρχει στο χώρο αποθήκευσης settings.lfs_pointers.accessible=Προσβάσιμο στον χρήστη settings.lfs_pointers.associateAccessible=Συσχετισμός προσιτών %d OID @@ -2621,7 +2621,7 @@ release.delete_tag=Διαγραφή ετικέτας release.deletion=Διαγραφή κυκλοφορίας release.deletion_desc=Διαγράφοντας μια κυκλοφορία, αυτή αφαιρείται μόνο από το Gitea. Δε θα επηρεάσει την ετικέτα Git, τα περιεχόμενα του αποθετηρίου σας ή το ιστορικό της. Συνέχεια; release.deletion_success=Η κυκλοφορία έχει διαγραφεί. -release.deletion_tag_desc=Θα διαγράψει αυτή την ετικέτα από το αποθετήριο. Τα περιεχόμενα του αποθετηρίου και το ιστορικό παραμένουν αμετάβλητα. Συνέχεια; +release.deletion_tag_desc=Θα διαγράψει αυτή την ετικέτα από το repository. Τα περιεχόμενα του repository και το ιστορικό δεν θα πειραχτούν. Να γίνει συνέχεια; release.deletion_tag_success=Η ετικέτα έχει διαγραφεί. release.tag_name_already_exist=Υπάρχει ήδη μια έκδοση με αυτό το όνομα ετικέτας. release.tag_name_invalid=Το όνομα της ετικέτας δεν είναι έγκυρο. @@ -2646,7 +2646,7 @@ branch.delete_branch_has_new_commits=Ο κλάδος «%s» δεν μπορεί branch.create_branch=Δημιουργία κλάδου %s branch.create_from=`από το «%s»` branch.create_success=Ο κλάδος «%s» δημιουργήθηκε. -branch.branch_already_exists=Ο κλάδος «%s» υπάρχει ήδη σε αυτό το αποθετήριο. +branch.branch_already_exists=Ο κλάδος «%s» υπάρχει ήδη σε αυτό το repository. branch.branch_name_conflict=Το όνομα του κλάδου «%s» συγκρούεται με το ήδη υπάρχον κλάδο «%s». branch.tag_collision=Ο κλάδος «%s» δεν μπορεί να δημιουργηθεί επειδή μια ετικέτα με το ίδιο όνομα υπάρχει ήδη στο αποθετήριο. branch.deleted_by=Διαγράφηκε από %s @@ -2691,7 +2691,7 @@ error.csv.invalid_field_count=Δεν είναι δυνατή η απόδοση commits.renamed_from = Μετονομάστηκε από %σ settings.wiki_rename_branch_main_desc = Ο κλάδος, ο οποίος χρησιμοποιείται εσωτερικά από το wiki, θα μετονομαστεί (μόνιμα και μη αναστράψιμα) σε «%s». issues.comment.blocked_by_user = Δεν μπορείτε να αφήσετε σχόλιο σε αυτό το ζήτημα, επειδή ο κάτοχος του αποθετηρίου ή το άτομο που δημιούργησε το ζήτημα σας έχει αποκλείσει. -pulls.blocked_by_user = Δεν μπορείτε να δημιουργήσετε pull request σε αυτό το αποθετήριο, επειδή ο κάτοχος του αποθετηρίου σας έχει αποκλείσει. +pulls.blocked_by_user = Δεν μπορείτε να δημιουργήσετε pull request σε αυτό το repository, επειδή ο κάτοχος του repository σας έχει αποκλείσει. pulls.made_using_agit = AGit wiki.cancel = Ακύρωση settings.units.add_more = Προσθήκη μονάδων... @@ -2710,13 +2710,13 @@ rss.must_be_on_branch = Για να αποκτήσετε ένα RSS feed, πρέ clone_in_vscodium = Κλωνοποίηση στο VSCodium editor.invalid_commit_mail = Αυτή η διεύθυνση email δεν είναι έγκυρη για την δημιουργία μίας υποβολής. pulls.nothing_to_compare_have_tag = Ο επιλεγμένος κλάδος/tag είναι όμοιος. -issues.blocked_by_user = Δεν μπορείτε να δημιουργήσετε ζητήματα σε αυτό το αποθετήριο, επειδή ο κάτοχος του αποθετηρίου σας έχει αποκλείσει. +issues.blocked_by_user = Δεν μπορείτε να δημιουργήσετε ζητήματα σε αυτό το repository, επειδή ο κάτοχος του repository σας έχει αποκλείσει. pulls.agit_explanation = Δημιουργημένο μέσω του AGit. Το AGit επιτρέπει σε συνεισφέροντες να προτείνουν αλλαγές χρησιμοποιώντας την εντολή «git push», χωρίς την δημιουργία fork ή έναν νέο κλάδο. activity.navbar.recent_commits = Πρόσφατες υποβολές settings.wiki_globally_editable = Να επιτρέπεται η επεξεργασία του wiki σε όλους admin.manage_flags = Διαχείριση σημάνσεων -admin.enabled_flags = Το αποθετήριο έχει τις εξής σημάνσεις: -settings.mirror_settings.pushed_repository = Προοριζόμενο αποθετήριο +admin.enabled_flags = Το repository έχει τις εξής σημάνσεις: +settings.mirror_settings.pushed_repository = Προοριζόμενο repository admin.flags_replaced = Οι σημάνσεις του αποθετηρίου αντικαταστάθηκαν activity.navbar.code_frequency = Συχνότητα κώδικα settings.wiki_branch_rename_success = Το όνομα κλάδου wiki του αποθετηρίου κανονικοποιήθηκε επιτυχώς. @@ -2767,7 +2767,7 @@ editor.commit_id_not_matching = Το αρχείο άλλαξε όσο το επ settings.sourcehut_builds.visibility = Ορατότητα εργασιών object_format = Μορφή αντικειμένων («object format») settings.ignore_stale_approvals_desc = Οι εγκρίσεις, οι οποίες αναφέρονται σε παλαιότερες υποβολές, δεν θα προσμετρούνται στο σύνολο των απαιτούμενων εγκρίσεων του pull request. Εφόσον αυτές οι εγκρίσεις έχουν ήδη ανακληθεί, τότε αυτή η ρύθμιση δεν θα παίξει κάποιον ρόλο. -settings.archive.mirrors_unavailable = Οι λειτουργίες ειδώλου δεν είναι διαθέσιμες εφόσον το αποθετήριο έχει αρχειοθετηθεί. +settings.archive.mirrors_unavailable = Οι λειτουργίες ειδώλου δεν είναι διαθέσιμες εφόσον το repository έχει αρχειοθετηθεί. settings.web_hook_name_sourcehut_builds = SourceHut Builds settings.enforce_on_admins = Εφαρμογή κανόνα σε διαχειριστές του αποθετηρίου object_format_helper = Η μορφή αντικειμένων («object format») του αποθετηρίου. Δεν θα μπορείτε να το αλλάξετε μεταγενέστερα. Η πιο συμβατή μορφή είναι η SHA1. @@ -2805,7 +2805,7 @@ release.type_attachment = Συνημμένο activity.published_prerelease_label = Προδημοσίευση activity.published_tag_label = Ετικέτα settings.pull_mirror_sync_quota_exceeded = Έχετε υπερβεί τους διαθέσιμους πόρους σας, για αυτό δεν θα γίνει λήψη των πιο πρόσφατων αλλαγών. -settings.transfer_quota_exceeded = Ο νέος ιδιοκτήτης (%s) έχει υπερβεί τους διαθέσιμους πόρους του. Το αποθετήριο δεν μπορεί να μεταφερθεί. +settings.transfer_quota_exceeded = Ο νέος ιδιοκτήτης (%s) έχει υπερβεί τους διαθέσιμους πόρους του. Το repository δεν μπορεί να μεταφερθεί. release.asset_name = Όνομα αρχείου release.asset_external_url = Εξωτερικό URL release.invalid_external_url = Μη έγκυρο εξωτερικό URL: «%s» @@ -2901,7 +2901,7 @@ teams.join=Συμμετοχή teams.leave=Αποχώρηση teams.leave.detail=Σίγουρα θέλετε να αποχωρήσετε από την ομάδα %s; teams.can_create_org_repo=Δημιουργία αποθετηρίων -teams.can_create_org_repo_helper=Τα μέλη μπορούν να δημιουργήσουν νέα αποθετήρια στον οργανισμό. Ο δημιουργός θα αποκτήσει πρόσβαση διαχειριστή στο νέο αποθετήριο. +teams.can_create_org_repo_helper=Τα μέλη μπορούν να δημιουργήσουν νέα αποθετήρια στον οργανισμό. Ο δημιουργός θα αποκτήσει πρόσβαση διαχειριστή στο νέο repository. teams.none_access=Καμία πρόσβαση teams.none_access_helper=Τα μέλη δεν μπορούν να δουν ή να κάνουν οποιαδήποτε άλλη ενέργεια σε αυτή τη μονάδα. teams.general_access=Γενική πρόσβαση @@ -2922,7 +2922,7 @@ teams.add_team_member=Προσθήκη μέλους ομάδας teams.invite_team_member=Πρόσκληση στην ομάδα %s teams.invite_team_member.list=Εκκρεμείς προσκλήσεις teams.delete_team_title=Διαγραφή ομάδας -teams.delete_team_desc=Η διαγραφή μιας ομάδας ανακαλεί τη πρόσβαση στο αποθετήριο από τα μέλη της. Συνέχεια; +teams.delete_team_desc=Η διαγραφή μιας ομάδας ανακαλεί τη πρόσβαση στο repository από τα μέλη της. Συνέχεια; teams.delete_team_success=Η ομάδα έχει διαγραφεί. teams.read_permission_desc=Αυτή η ομάδα χορηγεί πρόσβαση Ανάγνωσης: τα μέλη μπορούν να δουν και να κλωνοποιήσουν τα αποθετήρια της ομάδας. teams.write_permission_desc=Αυτή η ομάδα χορηγεί πρόσβαση Εγγραφής: τα μέλη μπορούν να διαβάσουν και να κάνουν push στα αποθετήρια της ομάδας. @@ -2934,9 +2934,9 @@ teams.remove_all_repos_title=Αφαίρεση όλων των αποθετηρί teams.remove_all_repos_desc=Αυτό θα αφαιρέσει όλα τα αποθετήρια από την ομάδα. teams.add_all_repos_title=Προσθήκη όλων των αποθετηρίων teams.add_all_repos_desc=Αυτό θα προσθέσει όλα τα αποθετήρια του οργανισμού στην ομάδα. -teams.add_nonexistent_repo=Το αποθετήριο που προσπαθείτε να προσθέσετε δεν υπάρχει, παρακαλώ δημιουργήστε το πρώτα. +teams.add_nonexistent_repo=Το repository που προσπαθείτε να προσθέσετε δεν υπάρχει, παρακαλώ δημιουργήστε το πρώτα. teams.add_duplicate_users=Ο χρήστης είναι ήδη μέλος της ομάδας. -teams.repos.none=Αυτή η ομάδα δεν έχει πρόσβαση σε κανένα αποθετήριο. +teams.repos.none=Αυτή η ομάδα δεν έχει πρόσβαση σε κανένα repository. teams.members.none=Δεν υπάρχουν μέλη σε αυτήν την ομάδα. teams.specific_repositories=Συγκεκριμένα αποθετήρια teams.specific_repositories_helper=Τα μέλη θα έχουν πρόσβαση μόνο σε αποθετήρια που προστίθενται ρητά στην ομάδα. Επιλέγοντας το δεν θα θα αφαιρεθούν αυτόματα τα αποθετήρια που έχουν ήδη προστεθεί με το Όλα τα αποθετήρια. @@ -3154,7 +3154,7 @@ packages.creator=Δημιουργός packages.name=Όνομα packages.version=Έκδοση packages.type=Τύπος -packages.repository=Αποθετήριο +packages.repository=Repository packages.size=Μέγεθος packages.published=Δημοσιευμένα @@ -3473,7 +3473,7 @@ notices.inverse_selection=Αντιστροφή επιλογής notices.delete_selected=Διαγραφή επιλεγμένων notices.delete_all=Διαγραφή όλων των ειδοποιήσεων notices.type=Τύπος -notices.type_1=Αποθετήριο +notices.type_1=Repository notices.type_2=Εργασία notices.desc=Περιγραφή notices.op=Λειτ. @@ -3511,7 +3511,7 @@ users.organization_creation.description = Να επιτρέπεται η δημ [action] create_repo=δημιούργησε το αποθετήριο %s -rename_repo=μετονόμασε το αποθετήριο από %[1]s σε %[3]s +rename_repo=μετονόμασε το repository από %[1]s σε %[3]s commit_repo=έκανε push στο %[3]s του %[4]s create_issue=`άνοιξε το ζήτημα %[3]s#%[2]s` close_issue=`έκλεισε το ζήτημα %[3]s#%[2]s` @@ -3523,7 +3523,7 @@ comment_issue=`άφησε σχόλιο στο ζήτημα %[3]s comment_pull=`σχολίασε στο pull request %[3]s#%[2]s` merge_pull_request=`συγχώνευσε το pull request %[3]s#%[2]s` auto_merge_pull_request=`αυτόματη συγχώνευση του pull request %[3]s#%[2]s` -transfer_repo=μετέφερε το αποθετήριο %s σε %s +transfer_repo=μετέφερε το repository %s σε %s push_tag=ώθησε την ετικέτα %[3]s σε %[4]s delete_tag=διέγραψε την ετικέτα %[2]s από %[3]s delete_branch=διέγραψε το κλάδο %[2]s από %[3]s @@ -3603,7 +3603,7 @@ title=Πακέτα desc=Διαχείριση πακέτων μητρώου. empty=Δεν υπάρχουν πακέτα ακόμα. empty.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο πακέτων, συμβουλευτείτε τον οδηγό. -empty.repo=Μήπως ανεβάσατε ένα πακέτο, αλλά δεν εμφανίζεται εδώ; Πηγαίνετε στις ρυθμίσεις πακέτων και συνδέστε το σε αυτό το αποθετήριο. +empty.repo=Μήπως ανεβάσατε ένα πακέτο, αλλά δεν εμφανίζεται εδώ; Πηγαίνετε στις ρυθμίσεις πακέτων και συνδέστε το σε αυτό το repository. registry.documentation=Για περισσότερες πληροφορίες σχετικά με το μητρώο %s, συμβουλευτείτε τον οδηγό. filter.type=Τύπος filter.type.all=Όλα @@ -3644,10 +3644,10 @@ composer.registry=Ρυθμίστε αυτό το μητρώο στο αρχεί composer.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το Composer, εκτελέστε την ακόλουθη εντολή: composer.dependencies=Εξαρτήσεις composer.dependencies.development=Εξαρτήσεις Ανάπτυξης -conan.details.repository=Αποθετήριο +conan.details.repository=Repository conan.registry=Ρυθμίστε αυτό το μητρώο από τη γραμμή εντολών: conan.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το Conan, εκτελέστε την ακόλουθη εντολή: -conda.registry=Ρυθμίστε αυτό το μητρώο ως αποθετήριο Conda στο αρχείο .condarc: +conda.registry=Ρυθμίστε αυτό το μητρώο ως repository Conda στο αρχείο .condarc: conda.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το Conda, εκτελέστε την ακόλουθη εντολή: container.details.type=Τύπος Εικόνας container.details.platform=Πλατφόρμα @@ -3705,8 +3705,8 @@ swift.registry=Ρυθμίστε αυτό το μητρώο από τη γραμ swift.install=Προσθέστε το πακέτο στο αρχείο Package.swift: swift.install2=και εκτελέστε την ακόλουθη εντολή: vagrant.install=Για προσθήκη ενός κυτίου Vagrant, εκτελέστε την ακόλουθη εντολή: -settings.link=Σύνδεση αυτού του πακέτου με ένα αποθετήριο -settings.link.description=Εάν συνδέσετε ένα πακέτο με ένα αποθετήριο, το πακέτο περιλαμβάνεται στη λίστα πακέτων του αποθετηρίου. +settings.link=Σύνδεση αυτού του πακέτου με ένα repository +settings.link.description=Εάν συνδέσετε ένα πακέτο με ένα repository, το πακέτο περιλαμβάνεται στη λίστα πακέτων του repository. settings.link.select=Επιλογή Αποθετηρίου settings.link.button=Ενημέρωση Συνδέσμου Αποθετηρίου settings.link.success=Ο σύνδεσμος αποθετηρίου ενημερώθηκε επιτυχώς. @@ -3718,7 +3718,7 @@ settings.delete.success=Το πακέτο έχει διαγραφεί. settings.delete.error=Αποτυχία διαγραφής του πακέτου. owner.settings.cargo.title=Ευρετήριο μητρώου Cargo owner.settings.cargo.initialize=Αρχικοποίηση ευρετηρίου -owner.settings.cargo.initialize.description=Απαιτείται ένα ειδικό αποθετήριο ευρετηρίου Git για τη χρήση του μητρώου Cargo. Χρησιμοποιώντας αυτή την επιλογή θα δημιουργηθεί ξανά το αποθετήριο και θα ρυθμιστεί αυτόματα. +owner.settings.cargo.initialize.description=Απαιτείται ένα ειδικό repository ευρετηρίου Git για τη χρήση του μητρώου Cargo. Χρησιμοποιώντας αυτή την επιλογή θα δημιουργηθεί ξανά το repository και θα ρυθμιστεί αυτόματα. owner.settings.cargo.initialize.error=Αποτυχία αρχικοποίησης ευρετηρίου Cargo: %v owner.settings.cargo.initialize.success=Ο ευρετήριο Cargo δημιουργήθηκε με επιτυχία. owner.settings.cargo.rebuild=Ανανέωση ευρετηρίου @@ -3811,7 +3811,7 @@ runners.task_list=Πρόσφατες εργασίες στον εκτελεστ runners.task_list.no_tasks=Δεν υπάρχει καμία εργασία ακόμα. runners.task_list.run=Εκτέλεση runners.task_list.status=Κατάσταση -runners.task_list.repository=Αποθετήριο +runners.task_list.repository=Repository runners.task_list.commit=Υποβολή runners.task_list.done_at=Ολοκλήρωσε Στις runners.edit_runner=Επεξεργασία Εκτελεστή diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini index 643a61b456..75ee89b545 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -147,6 +147,11 @@ value = Arvo rerun = Suorita uudelleen filter.clear = Tyhjennä suodattimet invalid_data = Virheellistä dataa: %v +new_repo.title = Uusi repositorio +new_org.title = Uusi organisaatio +new_org.link = Uusi organisaatio +new_repo.link = Uusi repositorio +new_migrate.link = Uusi siirto [aria] footer.links = Linkit diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 656ead34e1..0df97ec31b 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -207,7 +207,7 @@ string.desc=Z - A [error] occurred=Une erreur s’est produite -report_message=Si vous pensez qu'il s'agit d'un bug Forgejo, veuillez consulter notre board Codeberg ou ouvrir un nouveau ticket si nécessaire. +report_message=Si vous pensez qu'il s'agit d'un bug Forgejo, veuillez consulter les tickets de Codeberg ou ouvrir un nouveau ticket si nécessaire. missing_csrf=Requête incorrecte : aucun jeton CSRF présent invalid_csrf=Requête incorrecte : jeton CSRF invalide not_found=La cible n'a pu être trouvée. @@ -223,7 +223,7 @@ platform_desc=Forgejo est confirmé fonctionner sur des systèmes d'exploitation lightweight=Léger lightweight_desc=Forgejo utilise peu de ressources. Il peut même tourner sur un Raspberry Pi très bon marché. Économisez l'énergie de vos serveurs ! license=Open Source -license_desc=Toutes les sources sont sur Forgejo ! Rejoignez-nous et contribuez à rendre ce projet encore meilleur ! +license_desc=Toutes les sources sont sur Forgejo ! Rejoignez-nous et contribuez à rendre ce projet encore meilleur. Ne craignez pas de devenir un·e contributeur·trice ! [install] install=Installation @@ -558,6 +558,11 @@ removed_security_key.subject = Une clé de sécurité a été supprimée totp_disabled.subject = TOTP a été désactivé removed_security_key.no_2fa = Il n'y a plus de méthodes 2FA configurées ce qui signifie qu'il n'est plus nécessaire d'utiliser 2FA pour se connecter à votre compte. account_security_caution.text_1 = Si vous êtes à l’origine de cette action, vous pouvez ignorer ce courriel. +totp_enrolled.text_1.no_webauthn = Vous venez d'activer TOTP pour votre compte. Cela signifie que pour toutes les prochaines connexions à votre compte, vous devrez utiliser TOTP comme méthode 2FA. +totp_enrolled.subject = Vous avez activé TOTP comme méthode 2FA +totp_enrolled.text_1.has_webauthn = Vous venez d'activer TOTP pour votre compte. Cela signifie que pour toutes les prochaines connexions à votre compte, vous pouvez utiliser TOTP comme méthode 2FA ou l'une de vos clés de sécurité. +removed_security_key.text_1 = La clé de sécurité « %[1]s » vient d'être supprimée de votre compte. +account_security_caution.text_2 = S'il ne s'agissait pas de vous, votre compte est compromis. Veuillez contacter les administrateurs du site. [modal] yes=Oui @@ -823,7 +828,7 @@ add_new_email=Ajouter une nouvelle adresse e-mail add_new_openid=Ajouter une nouvelle URI OpenID add_email=Ajouter une adresse courriel add_openid=Ajouter une URI OpenID -add_email_confirmation_sent=Un e-mail de confirmation a été envoyé à "%s". Veuillez vérifier votre boîte de réception dans les %s suivants pour confirmer votre adresse e-mail. +add_email_confirmation_sent=Un courriel de confirmation a été envoyé à « %s ». Pour confirmer votre adresse de courriel, veuillez vérifier votre boîte de réception et suivre le lien indiqué dans les prochains %s. add_email_success=La nouvelle adresse e-mail a été ajoutée. email_preference_set_success=L'e-mail de préférence a été défini avec succès. add_openid_success=La nouvelle adresse OpenID a été ajoutée. @@ -1042,6 +1047,8 @@ pronouns = Pronoms pronouns_unspecified = Non spécifiés language.title = Langue par défaut keep_activity_private.description = Vous seul pourrez voir votre activité publique, ainsi que les administrateurs de l'instance. +language.localization_project = Aidez-nous à traduire Forgejo dans votre langue ! En savoir plus. +language.description = Cette langue sera enregistrée dans votre compte et utilisée comme langue par défaut après votre connexion. [repo] new_repo_helper=Un dépôt contient tous les fichiers d’un projet, ainsi que l’historique de leurs modifications. Vous avez déjà ça ailleurs ? Migrez-le ici. @@ -1421,7 +1428,7 @@ commitstatus.failure=Échec commitstatus.pending=En attente commitstatus.success=Succès -ext_issues=Accès aux tickets externes +ext_issues=Tickets externes ext_issues.desc=Lien vers un gestionnaire de tickets externe. projects=Projets @@ -1602,9 +1609,9 @@ issues.no_content=Sans contenu. issues.close=Fermer le ticket issues.comment_pull_merged_at=a fusionné la révision %[1]s dans %[2]s %[3]s issues.comment_manually_pull_merged_at=a fusionné manuellement la révision %[1]s dans %[2]s %[3]s -issues.close_comment_issue=Commenter et fermer +issues.close_comment_issue=Fermer avec le commentaire issues.reopen_issue=Rouvrir -issues.reopen_comment_issue=Commenter et réouvrir +issues.reopen_comment_issue=Réouvrir avec le commentaire issues.create_comment=Commenter issues.closed_at=`a fermé ce ticket %[2]s.` issues.reopened_at=`a réouvert ce ticket %[2]s.` @@ -1993,7 +2000,7 @@ signing.wont_sign.commitssigned=La fusion ne sera pas signée car ses révisions signing.wont_sign.approved=La fusion ne sera pas signée car la demande d'ajout n'a pas été approuvée. signing.wont_sign.not_signed_in=Vous n'êtes pas connecté. -ext_wiki=Accès au wiki externe +ext_wiki=Wiki externe ext_wiki.desc=Lier un wiki externe. wiki=Wiki @@ -2418,14 +2425,14 @@ settings.protect_enable_merge_desc=Toute personne ayant un accès en écriture s settings.protect_whitelist_committers=Liste blanche des soumissions (push) settings.protect_whitelist_committers_desc=Seuls les utilisateurs ou les équipes autorisés pourront soumettre sur cette branche (sans forcer). settings.protect_whitelist_deploy_keys=Mettez les clés de déploiement sur liste blanche avec accès en écriture pour soumettre. -settings.protect_whitelist_users=Utilisateurs sur liste blanche : +settings.protect_whitelist_users=Utilisateurs sur liste blanche pour pousser settings.protect_whitelist_search_users=Rechercher des utilisateurs… -settings.protect_whitelist_teams=Équipes sur liste blanche : +settings.protect_whitelist_teams=Équipes sur liste blanche pour pousser settings.protect_whitelist_search_teams=Rechercher des équipes… settings.protect_merge_whitelist_committers=Activer la liste blanche pour la fusion settings.protect_merge_whitelist_committers_desc=N'autoriser que les utilisateurs et les équipes en liste blanche d'appliquer les demandes de fusion sur cette branche. -settings.protect_merge_whitelist_users=Utilisateurs en liste blanche de fusion : -settings.protect_merge_whitelist_teams=Équipes en liste blanche de fusion : +settings.protect_merge_whitelist_users=Utilisateurs en liste blanche pour fusionner +settings.protect_merge_whitelist_teams=Équipes en liste blanche pour fusionner settings.protect_check_status_contexts=Activer le contrôle de status settings.protect_status_check_patterns=Motifs de vérification des statuts : settings.protect_status_check_patterns_desc=Entrez des motifs pour spécifier quelles vérifications doivent réussir avant que des branches puissent être fusionnées. Un motif par ligne. Un motif ne peut être vide. @@ -2434,12 +2441,12 @@ settings.protect_check_status_contexts_list=Contrôles qualité trouvés au cour settings.protect_status_check_matched=Correspondant settings.protect_invalid_status_check_pattern=Motif de vérification des statuts incorrect : « %s ». settings.protect_no_valid_status_check_patterns=Aucun motif de vérification des statuts valide. -settings.protect_required_approvals=Minimum d'approbations requis : +settings.protect_required_approvals=Approbations requises settings.protect_required_approvals_desc=Permet de fusionner les demandes d’ajout lorsque suffisamment d’évaluation sont positives. settings.protect_approvals_whitelist_enabled=Restreindre les approbations aux utilisateurs ou aux équipes en liste blanche settings.protect_approvals_whitelist_enabled_desc=Seuls les évaluations des utilisateurs ou des équipes suivantes compteront dans les approbations requises. Si laissé vide, les évaluations de toute personne ayant un accès en écriture seront comptabilisées à la place. -settings.protect_approvals_whitelist_users=Évaluateurs autorisés : -settings.protect_approvals_whitelist_teams=Équipes d’évaluateurs autorisés : +settings.protect_approvals_whitelist_users=Évaluateurs autorisés +settings.protect_approvals_whitelist_teams=Équipes d’évaluateurs autorisés settings.dismiss_stale_approvals=Révoquer automatiquement les approbations périmées settings.dismiss_stale_approvals_desc=Lorsque des nouvelles révisions changent le contenu de la demande d’ajout, les approbations existantes sont révoquées. settings.ignore_stale_approvals=Ignorer les approbations obsolètes @@ -2449,9 +2456,9 @@ settings.require_signed_commits_desc=Rejeter les soumissions sur cette branche l settings.protect_branch_name_pattern=Motif de nom de branche protégé settings.protect_branch_name_pattern_desc=Motifs de nom de branche protégé. Consultez la documentation pour la syntaxe du motif. Exemples : main, release/** settings.protect_patterns=Motifs -settings.protect_protected_file_patterns=Liste des fichiers et motifs protégés (séparés par un point virgule ";") : -settings.protect_protected_file_patterns_desc=Les fichiers protégés ne peuvent être modifiés, même si l'utilisateur a le droit d'ajouter, éditer ou supprimer des fichiers dans cette branche. Plusieurs motifs peuvent être séparés par un point-virgule (";"). Veuillez voir github.com/gobwas/glob la documentation pour la syntaxe des motifs. Exemples : .drone.yml, /docs/**/*.txt. -settings.protect_unprotected_file_patterns=Liste des fichiers et motifs exclus (séparés par un point virgule ";") : +settings.protect_protected_file_patterns=Motifs de fichiers protégés (séparés par un point virgule ";") +settings.protect_protected_file_patterns_desc=Les fichiers protégés ne peuvent être modifiés, même si l'utilisateur a le droit d'ajouter, éditer ou supprimer des fichiers dans cette branche. Plusieurs motifs peuvent être séparés par un point-virgule (";"). Veuillez voir %[2]s la documentation pour la syntaxe des motifs. Exemples : .drone.yml, /docs/**/*.txt. +settings.protect_unprotected_file_patterns=Motifs de fichiers non protégés (séparés par un point virgule ";") settings.protect_unprotected_file_patterns_desc=Les fichiers non-protégés qui peuvent être modifiés si l'utilisateur a le droit d'écriture, prenant le pas sur les restrictions de push. Plusieurs motifs peuvent être séparés par un point-virgule (";"). Veuillez voir %[2]s la documentation pour la syntaxe des motifs. Exemples : .drone.yml, /docs/**/*.txt. settings.add_protected_branch=Activer la protection settings.delete_protected_branch=Désactiver la protection @@ -2811,6 +2818,23 @@ settings.federation_following_repos = Les URL des dépôts suivis séparés par settings.federation_not_enabled = La fédération n'est pas activée pour votre instance. comments.edit.already_changed = Impossible de sauvegarder les changements du commentaire car son contenu a déjà été modifié par un autre utilisateur. Veuillez recharger la page et essayer de l'éditer à nouveau pour éviter d'écraser ses changements settings.federation_apapiurl = URL de fédération de ce dépôt. A copier-coller dans les paramètres de fédérations d'un autre dépôt comme URL d'un dépôt à suivre. +mirror_denied_combination = Il n'est pas possible de combiner une authentification par clé publique et par mot de passe. +mirror_public_key = Clé SSH publique +mirror_use_ssh.text = Utiliser l'authentification SSH +mirror_use_ssh.helper = Forgejo va créer un miroir du dépôt via Git sur SSH et créer une paire de clés pour vous lorsque vous sélectionnez cette option. Vous devez vous assurer que la clé publique générée est autorisée à pousser dans le dépôt de destination. Il n'est pas possible d'utiliser l'autorisation basée sur un mot de passe si vous choisissez cette option. +no_eol.text = Pas d'EOL +mirror_use_ssh.not_available = L'authentification par SSH n'est pas disponible. +no_eol.tooltip = Ce fichier ne contient pas de caractère final de fin de ligne. +release.type_attachment = Pièce jointe +settings.transfer_quota_exceeded = Le nouvel utilisateur (%s) a dépassé son quota. Le dépôt n'a pas été transféré. +settings.pull_mirror_sync_quota_exceeded = Quota dépassé, les modifications ne sont pas tirées. +activity.commit = Activité de commit +settings.mirror_settings.push_mirror.copy_public_key = Copier la clé publique +release.asset_external_url = URL externe +release.invalid_external_url = URL externe non valable : « %s » +milestones.filter_sort.name = Nom +settings.mirror_settings.push_mirror.none_ssh = Aucun +settings.protect_new_rule = Créer une nouvelle règle de protection de branche [graphs] component_loading=Chargement de %s… diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index e34da348a5..0cb6c0f7ab 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -3,7 +3,7 @@ home=Forsíða dashboard=Stjórnborð explore=Vafra help=Hjálp -sign_in=Skrá Inn +sign_in=Skrá inn sign_in_or=eða sign_out=Skrá Út sign_up=Nýskráning @@ -15,9 +15,9 @@ page=Síða template=Sniðmát language=Tungumál notifications=Tilkynningar -active_stopwatch=Virk Tímamæling +active_stopwatch=Virk tímamæling create_new=Skapa… -user_profile_and_more=Notandasíða og Stillingar… +user_profile_and_more=Notandasíða og stillingar… signed_in_as=Skráð(ur) inn sem toc=Efnisyfirlit licenses=Hugbúnaðarleyfi @@ -111,6 +111,8 @@ concept_code_repository=Hugbúnaðarsafn name=Heiti value=Gildi +sign_in_with_provider = Skrá inn með %s +enable_javascript = Þessi síða krefst JavaScript. [aria] diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index 0860176b18..f6fcd5135f 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -471,6 +471,11 @@ openid_signin_desc = Inserisci il tuo URI OpenID. Per esempio: alice.openid.exam password_pwned = La password che hai scelto è in un elenco di password rubate precedentemente esposte a violazioni di dati pubblici. Riprova con una password diversa e valuta di modificare questa password anche altrove. tab_signup = Registrati tab_signin = Accedi +back_to_sign_in = Torna alla schermata d'accesso +sign_in_openid = Procedi con OpenID +hint_login = Hai già un'utenza? Accedi! +hint_register = Non hai un'utenza? Registrati ora. +sign_up_button = Registrati ora. [mail] view_it_on=Visualizza su %s @@ -539,6 +544,21 @@ activate_email.title = %s, verifica il tuo indirizzo email admin.new_user.text = Clicca qui per gestire questo utente dal pannello di amministrazione. team_invite.text_1 = %[1]s ti ha invitato a far parte del team %[2]s nell'organizzazione %[3]s. team_invite.text_3 = Nota: Questo invito è destinato a %[1]s. Se non ti aspettavi questo invito, puoi ignorare questa email. +primary_mail_change.subject = La tua mail principale è stata cambiata +removed_security_key.no_2fa = Non ci sono più altri metodi di autenticazione a due fattori configurati, ergo non c'è più bisogno di accedere alla tua utenza tramite tale autenticazione. +primary_mail_change.text_1 = La mail principale della tua utenza è appena stata cambiata in %[1]s. Ciò significa che questo indirizzo di posta elettronica non riceverà più notifiche mail da quest'utenza. +totp_disabled.subject = La TOTP è stata disabilitata +totp_disabled.no_2fa = Non ci sono più altri metodi d'autenticazione a due fattori configurati, ergo non c'è più bisogno di accedere alla tua utenza con tale autenticazione. +removed_security_key.subject = È stata rimossa una chiave di sicurezza +removed_security_key.text_1 = La chiave di sicurezza "%[1]s" è appena stata rimossa dalla tua utenza. +totp_disabled.text_1 = La password a tempo usa e getta (TOTP) della tua utenza è appena stata disabilitata. +totp_enrolled.subject = Hai attivato la TOTP come metodo d'autenticazione a due fattori +totp_enrolled.text_1.no_webauthn = Hai appena attivato la TOTP per la tua utenza. Ciò significa che dovrai usarla come metodo d'autenticazione a due fattori per tutti i tuoi accessi futuri. +totp_enrolled.text_1.has_webauthn = Hai appena attivato la TOTP per la tua utenza. Ciò significa che dovrai usare come metodo d'autenticazione a due fattori per i tuoi accessi futuri tale TOTP o una delle tue chiavi di sicurezza. +password_change.subject = La tua password è stata modificata +password_change.text_1 = La password della tua utenza è appena stata modificata. +account_security_caution.text_1 = Se sei statə tu, puoi ignorare questa mail. +account_security_caution.text_2 = Se non sei statə tu, la tua utenza è compromessa. Contatta l'amministrazione del sito. [modal] @@ -1022,6 +1042,8 @@ pronouns = Pronomi pronouns_custom = Personalizzato pronouns_unspecified = Non specificato language.title = Lingua predefinita +language.description = Questa lingua verrà salvata nella tua utenza e verrà usata come predefinita ogni volta che farai l'accesso. +language.localization_project = Aiutaci a tradurre Forgejo nella tua lingua! Più informazioni. [repo] owner=Proprietario @@ -3863,6 +3885,7 @@ exact_tooltip = Includi solo i risultati che corrispondono esattamente al termin issue_kind = Cerca segnalazioni... pull_kind = Cerca richieste... exact = Esatto +milestone_kind = Ricerca tappe... [munits.data] gib = GiB diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index f53356ee71..fba7f37808 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -158,6 +158,13 @@ filter.not_template = テンプレートではない invalid_data = 無効なデータ: %v more_items = さらに表示 copy_generic = クリップボードへコピー +new_repo.title = 新しいリポジトリ +new_migrate.title = 新しいマイグレーション +new_org.title = 新しい組織 +new_repo.link = 新しいリポジトリ +new_migrate.link = 新しいマイグレーション +new_org.link = 新しい組織 +test = テスト [aria] navbar=ナビゲーションバー diff --git a/options/locale/locale_lt.ini b/options/locale/locale_lt.ini index 35f56fa4fd..b55a749cb2 100644 --- a/options/locale/locale_lt.ini +++ b/options/locale/locale_lt.ini @@ -159,6 +159,18 @@ fuzzy_tooltip = Įtraukti rezultatus, kurie taip pat labai atitinka paieškos te repo_kind = Ieškoti saugyklų... code_search_unavailable = Kodų paieška šiuo metu nepasiekiama. Kreipkis į svetainės administratorių. org_kind = Ieškoti organizacijų... +union = Bendrinis +code_search_by_git_grep = Dabartiniai kodo paieškos rezultatai pateikiami atliekant „git grep“. Rezultatai gali būti geresni, jei svetainės administratorius įjungs kodo indeksuotoją. +package_kind = Ieškoti paketų... +project_kind = Ieškoti projektų... +commit_kind = Ieškoti įsipareigojimų... +runner_kind = Ieškoti vykdyklių... +no_results = Nerasta atitinkamų rezultatų. +issue_kind = Ieškoti problemų... +branch_kind = Ieškoti šakų... +milestone_kind = Ieškoti gairių... +pull_kind = Ieškoti sujungimų... +keyword_search_unavailable = Ieškoti pagal raktažodį šiuo metu nepasiekiamas. Susisiekite su svetainės administratoriumi. [actions] workflow.disable = Išjungti darbo eigą @@ -171,6 +183,9 @@ runs.empty_commit_message = (tuščias įsipareigojimo pranešimas) submodule = Pomodulis changed_filemode = %[1]s → %[2]s symbolic_link = Virtualusis aplankas +directory = Katalogas +executable_file = Vykdomasis failas +normal_file = Įprastas failas [projects] deleted.display_name = Ištrintas projektas @@ -182,4 +197,64 @@ type-3.display_name = Organizacijos projektas filepreview.truncated = Peržiūra buvo sutrumpinta [mail] -reset_password.text = Jei tai buvote jūs, spustelėkite toliau esančią nuorodą, kad atkurtumėte savo paskyrą per %s: \ No newline at end of file +reset_password.text = Jei tai buvote jūs, spustelėkite toliau esančią nuorodą, kad atkurtumėte savo paskyrą per %s: + +[heatmap] +contributions_one = įnašas +contributions_few = įnašai +less = Mažiau +more = Daugiau +number_of_contributions_in_the_last_12_months = %s įnašų per pastaruosius 12 mėnesių +contributions_zero = Įnašų nėra +contributions_format = {contributions} {year} {month} {day} + +[aria] +navbar = Naršymo juosta +footer = Puslapinė poraštė +footer.software = Apie šią programinę įrangą +footer.links = Nuorodos + +[editor] +buttons.quote.tooltip = Cituoti tekstą +buttons.code.tooltip = Pridėti kodą +buttons.link.tooltip = Pridėti nuorodą +buttons.heading.tooltip = Pridėti antraštę +buttons.bold.tooltip = Pridėti pusjuodį tekstą +buttons.italic.tooltip = Pridėti kursyvinį tekstą + +[error] +network_error = Tinklo klaida +server_internal = Vidinio serverio klaida + +[startpage] +app_desc = Nesudėtinga, savarankiškai teikiama „Git“ paslauga +install = Lengva įdiegti + +[install] +path = Kelias +err_admin_name_is_reserved = Administratoriaus naudotojo vardas netinkamas. Naudotojo vardas yra rezervuotas. +enable_update_checker = Įjungti naujinimų tikrintuvą +env_config_keys = Aplinkos konfigūracija +db_title = Duomenų bazės nustatymai +db_type = Duomenų bazės tipas +user = Naudotojo vardas +password = Slaptažodis +db_name = Duomenų bazės pavadinimas +db_schema = Schema +ssl_mode = SSL +host = Pagrindinis komputeris +general_title = Bendrieji nustatymai +email_title = El. pašto nustatymai +federated_avatar_lookup.description = Ieškokite pseudoportretų naudojant „Libravatar“. +db_schema_helper = Palikite tuščią, jei tai numatytoji duomenų bazė („public“). +err_empty_admin_password = Administratoriaus slaptažodis negali būti tuščias. +err_empty_admin_email = Administratoriaus el. paštas negali būti tuščias. + +[explore] +go_to = Eiti į +code = Kodas + +[auth] +remember_me = Prisiminti šį įrenginį +forgot_password_title = Pamirštas slaptažodis +forgot_password = Pamiršote slaptažodį? \ No newline at end of file diff --git a/options/locale/locale_nb_NO.ini b/options/locale/locale_nb_NO.ini index aae4ae788f..349d56ce13 100644 --- a/options/locale/locale_nb_NO.ini +++ b/options/locale/locale_nb_NO.ini @@ -23,4 +23,115 @@ language = Språk notifications = Varslinger create_new = Opprett… user_profile_and_more = Profil og innstillinger… -signed_in_as = Logget inn som \ No newline at end of file +signed_in_as = Logget inn som +confirm_delete_selected = Bekreft sletting av alle valgte elementer? +dashboard = Dashbord +download_logs = Last ned logger +copy_hash = Kopier hash +more_items = Flere elementer +passcode = Adgangskode +webauthn_insert_key = Skriv inn din sikkerhetsnøkkel +webauthn_use_twofa = Bruk tofaktorkode fra din mobil +organization = Organisasjon +mirror = Speil +new_mirror = Ny speiling +repository = Repositorium +new_project = Nytt prosjekt +new_project_column = Ny kolonne +webauthn_error = Klarte ikke lese sikkerhetsnøkkelen. +webauthn_unsupported_browser = Nettleseren din støtter ikke WebAuthn. +webauthn_error_unknown = En ukjent feil oppstod. Vennligst prøv igjen. +webauthn_error_insecure = WebAuhn støtter kun sikre forbindelser. For testing over HTTP kan du bruke verten "localhost" eller "127.0.0.1" +admin_panel = Nettsideadministrasjon +settings = Innstillinger +your_profile = Profil +your_starred = Stjernemerket +your_settings = Innstillinger +new_repo.title = Nytt repositorium +new_migrate.title = Ny migrasjon +new_org.title = Ny organisasjon +new_repo.link = Nytt repositorium +new_migrate.link = Ny migrasjon +new_org.link = Ny organisasjon +all = Alle +sources = Kilder +mirrors = Speilinger +activities = Aktiviteter +rss_feed = RSS feed +retry = Prøv igjen +rerun = Kjør på nytt +rerun_all = Kjør alle jobber på nytt +save = Lagre +cancel = Avbryt +forks = Forks +milestones = Milepæler +ok = OK +test = Test +loading = Laster inn… +error = Feil +go_back = Gå tilbake +never = Aldri +invalid_data = Ugyldig data: %v +unknown = Ukjent +pin = Pin +artifacts = Artefakter +archived = Arkivert +concept_system_global = Global +add = Legg til +add_all = Legg til alle +remove = Fjern +remove_all = Fjern alle +remove_label_str = Fjern element "%s" +edit = Rediger +view = Vis +enabled = Aktivert +disabled = Deaktivert +locked = Låst +copy = Kopier +copy_generic = Kopier til utklippstavlen +copy_url = Kopier URL +copy_content = Kopier innhold +copy_success = Kopiert! +copy_error = Kopiering mislyktes +copy_type_unsupported = Denne filtypen kan ikke kopieres +write = Skriv +preview = Forhåndsvis +concept_user_individual = Individuell +concept_code_repository = Repositorium +concept_user_organization = Organisasjon +show_timestamps = Vis tidsstempler +show_log_seconds = Vis sekunder +show_full_screen = Vis fullskjerm +name = Navn +value = Verdi +filter = Filter +filter.clear = Tøm filtre +filter.is_archived = Arkivert +filter.not_archived = Ikke arkivert +filter.is_mirror = Speilinger +filter.not_mirror = Ikke speilinger +filter.is_template = Maler +filter.not_template = Ikke maler +filter.public = Offentlig +filter.private = Privat +explore = Utforsk +active_stopwatch = Aktiv tidsregistrering +home = Hjem +help = Hjelp +logo = Logo +sign_in = Logg inn +sign_in_with_provider = Logg inn med %s +sign_in_or = eller +sign_out = Logg ut +sign_up = Opprett konto +confirm_delete_artifact = Er du sikker på at du vil slette artefakten "%s" ? + +[search] +search = Søk... +type_tooltip = Søketype +fuzzy = Fuzzy +union = Union + +[auth] +verify = Bekreft +sign_up_button = Opprett konto nå. \ No newline at end of file diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index 0938d4099c..e13b1341c4 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -1406,7 +1406,7 @@ commitstatus.failure=Неудача commitstatus.pending=Ожидание commitstatus.success=Успешно -ext_issues=Доступ ко внешним задачам +ext_issues=Внешние задачи ext_issues.desc=Ссылка на внешнюю систему отслеживания задач. projects=Проекты @@ -1587,9 +1587,9 @@ issues.no_content=Описание отсутствует. issues.close=Закрыть задачу issues.comment_pull_merged_at=коммит %[1]s был добавлен в %[2]s %[3]s issues.comment_manually_pull_merged_at=коммит %[1]s был вручную добавлен в %[2]s %[3]s -issues.close_comment_issue=Прокомментировать и закрыть +issues.close_comment_issue=Закрыть комментарием issues.reopen_issue=Открыть снова -issues.reopen_comment_issue=Прокомментировать и открыть снова +issues.reopen_comment_issue=Открыть снова комментарием issues.create_comment=Комментировать issues.closed_at=`задача была закрыта %[2]s` issues.reopened_at=`задача была открыта снова %[2]s` @@ -1964,7 +1964,7 @@ signing.wont_sign.commitssigned=Слияние не будет подписан signing.wont_sign.approved=Слияние не будет подписано, так как запрос на слияние не одобрен. signing.wont_sign.not_signed_in=Вы не вошли в систему. -ext_wiki=Доступ ко внешней вики +ext_wiki=Внешняя вики ext_wiki.desc=Ссылка на внешнюю вики. wiki=Вики @@ -3332,7 +3332,7 @@ config.allow_only_external_registration=Регистрация только че config.enable_openid_signup=Саморегистрация через OpenID config.enable_openid_signin=Вход через OpenID config.show_registration_button=Кнопка регистрации -config.require_sign_in_view=Для просмотра содержимого необходима авторизация +config.require_sign_in_view=Требовать авторизацию для просмотра содержимого config.mail_notify=Уведомления по эл. почте config.enable_captcha=CAPTCHA config.active_code_lives=Срок действия кода активации учётной записи @@ -3963,4 +3963,8 @@ filepreview.lines = Строки с %[1]d по %[2]d в %[3]s filepreview.truncated = Предпросмотр был обрезан [translation_meta] -test = хи-хи! \ No newline at end of file +test = хи-хи! + +[repo.permissions] +code.write = Запись: отправка изменений в репозиторий, создание веток и тегов. +code.read = Чтение: доступ к исходному коду репозитория и клонированию. \ No newline at end of file diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 1873b11478..7a1a77c3e5 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -1427,7 +1427,7 @@ commitstatus.failure=失败 commitstatus.pending=待定 commitstatus.success=成功 -ext_issues=访问外部工单 +ext_issues=外部工单 ext_issues.desc=链接到外部工单跟踪系统。 projects=项目 @@ -1608,9 +1608,9 @@ issues.no_content=没有提供说明。 issues.close=关闭工单 issues.comment_pull_merged_at=已合并提交 %[1]s 到 %[2]s %[3]s issues.comment_manually_pull_merged_at=手动合并提交 %[1]s 到 %[2]s %[3]s -issues.close_comment_issue=评论并关闭 +issues.close_comment_issue=关闭评论 issues.reopen_issue=重新开启 -issues.reopen_comment_issue=评论并重新开启 +issues.reopen_comment_issue=重新打开评论 issues.create_comment=评论 issues.closed_at=`于 %[2]s 关闭此工单` issues.reopened_at=`重新打开此问题 %[2]s` @@ -1999,7 +1999,7 @@ signing.wont_sign.commitssigned=合并将不会被签名,因为所有相关的 signing.wont_sign.approved=合并将不会被签名,因为合并请求未被批准。 signing.wont_sign.not_signed_in=您还没有登录。 -ext_wiki=访问外部百科 +ext_wiki=外部百科 ext_wiki.desc=链接到外部 wiki。 wiki=百科 @@ -2330,7 +2330,7 @@ settings.event_repository_desc=创建或删除仓库 settings.event_header_issue=工单事件 settings.event_issues=工单 settings.event_issues_desc=工单已打开、已关闭、已重新打开或已编辑。 -settings.event_issue_assign=工单已分配 +settings.event_issue_assign=工单已指派 settings.event_issue_assign_desc=工单已被指派或取消指派。 settings.event_issue_label=工单已分类 settings.event_issue_label_desc=工单标签被更新或清除。 @@ -3818,7 +3818,7 @@ management=密钥管理 [actions] actions=Actions -unit.desc=使用 Forgejo Actions 管理集成的 CI/CD 管道 +unit.desc=使用 Forgejo Actions 管理集成的 CI/CD 管道。 status.unknown=未知 status.waiting=等待中 @@ -3980,4 +3980,24 @@ filepreview.lines = %[3]s 中的第 %[1]d 到 %[2]d 行 filepreview.truncated = 预览已被截断 [translation_meta] -test = 好的 \ No newline at end of file +test = 好的 + +[repo.permissions] +code.write = 写入:推送到仓库,创建分支和标签。 +code.read = 读取:访问并克隆仓库的代码。 +actions.read = 读取:查看集成的 CI/CD 管道及其日志。 +issues.write = 写入:关闭工单并管理元数据,如标签、里程碑、指派成员、截止日期和依赖。 +releases.write = 写入:发布、编辑和删除版本发布及其资产。 +issues.read = 读取:阅读并创建工单和评论。 +pulls.read = 读取:阅读并创建合并请求。 +releases.read = 读取:查看并下载版本发布。 +wiki.read = 读取:阅读集成的百科及其历史。 +wiki.write = 写入:在集成的百科中创建、更新和删除页面。 +projects.read = 读取:访问仓库项目看板。 +packages.read = 读取:查看并下载指派给仓库的软件包。 +packages.write = 写入:发布并删除指派给仓库的软件包。 +actions.write = 写入:手动触发、重启、取消或批准待处理的 CI/CD 管道。 +ext_issues = 访问外部工单系统的链接。权限由外部管理。 +ext_wiki = 访问外部百科的链接。权限由外部管理。 +projects.write = 写入:创建项目和列并进行编辑。 +pulls.write = 写入:关闭合并请求并管理元数据,如标签、里程碑、指派成员、截止日期和依赖。 \ No newline at end of file From 1fa09d16210f825ea5aee5d87294c957d405a108 Mon Sep 17 00:00:00 2001 From: Otto Richter Date: Sat, 28 Sep 2024 03:39:19 +0200 Subject: [PATCH 051/443] Split Git package installation --- .../composite/apt-install-from/action.yaml | 29 +++++++++++ .forgejo/workflows/testing.yml | 50 ++++++------------- 2 files changed, 44 insertions(+), 35 deletions(-) create mode 100644 .forgejo/workflows/composite/apt-install-from/action.yaml diff --git a/.forgejo/workflows/composite/apt-install-from/action.yaml b/.forgejo/workflows/composite/apt-install-from/action.yaml new file mode 100644 index 0000000000..615e7cb184 --- /dev/null +++ b/.forgejo/workflows/composite/apt-install-from/action.yaml @@ -0,0 +1,29 @@ +inputs: + packages: + description: 'Packages to install' + required: true + release: + description: 'Release to install from' + default: testing + +runs: + using: "composite" + steps: + - name: setup apt package source + run: | + export DEBIAN_FRONTEND=noninteractive + echo "deb http://deb.debian.org/debian/ ${RELEASE} main" > "/etc/apt/sources.list.d/${RELEASE}.list" + env: + RELEASE: ${{inputs.release}} + - name: install packages + run: | + apt-get update -qq + apt-get -q install -qq -y ${PACKAGES} + env: + PACKAGES: ${{inputs.packages}} + - name: remove temporary package list to prevent using it in other steps + run: | + rm "/etc/apt/sources.list.d/${RELEASE}.list" + apt-get update -qq + env: + RELEASE: ${{inputs.release}} diff --git a/.forgejo/workflows/testing.yml b/.forgejo/workflows/testing.yml index 5f7a1e351a..8c1e6d06f8 100644 --- a/.forgejo/workflows/testing.yml +++ b/.forgejo/workflows/testing.yml @@ -60,13 +60,9 @@ jobs: - uses: https://code.forgejo.org/actions/checkout@v3 - uses: ./.forgejo/workflows/composite/setup-env - name: install git >= 2.42 - run: | - export DEBIAN_FRONTEND=noninteractive - echo deb http://deb.debian.org/debian/ testing main > /etc/apt/sources.list.d/testing.list - apt-get update -qq - apt-get -q install -qq -y git - rm /etc/apt/sources.list.d/testing.list - apt-get update -qq + uses: ./.forgejo/workflows/composite/apt-install-from + with: + packages: git - name: test release-notes-assistant.sh run: | apt-get -q install -qq -y jq @@ -108,13 +104,9 @@ jobs: - uses: https://code.forgejo.org/actions/checkout@v3 - uses: ./.forgejo/workflows/composite/setup-env - name: install git >= 2.42 - run: | - export DEBIAN_FRONTEND=noninteractive - echo deb http://deb.debian.org/debian/ testing main > /etc/apt/sources.list.d/testing.list - apt-get update -qq - apt-get -q install -qq -y git - rm /etc/apt/sources.list.d/testing.list - apt-get update -qq + uses: ./.forgejo/workflows/composite/apt-install-from + with: + packages: git - uses: ./.forgejo/workflows/composite/build-backend - run: | su forgejo -c 'make test-remote-cacher test-check' @@ -143,13 +135,9 @@ jobs: - uses: https://code.forgejo.org/actions/checkout@v3 - uses: ./.forgejo/workflows/composite/setup-env - name: install dependencies & git >= 2.42 - run: | - export DEBIAN_FRONTEND=noninteractive - echo deb http://deb.debian.org/debian/ testing main > /etc/apt/sources.list.d/testing.list - apt-get update -qq - apt-get install --no-install-recommends -qq -y git git-lfs - rm /etc/apt/sources.list.d/testing.list - apt-get update -qq + uses: ./.forgejo/workflows/composite/apt-install-from + with: + packages: git git-lfs - uses: ./.forgejo/workflows/composite/build-backend - run: | su forgejo -c 'make test-mysql-migration test-mysql' @@ -179,13 +167,9 @@ jobs: - uses: https://code.forgejo.org/actions/checkout@v3 - uses: ./.forgejo/workflows/composite/setup-env - name: install dependencies & git >= 2.42 - run: | - export DEBIAN_FRONTEND=noninteractive - echo deb http://deb.debian.org/debian/ testing main > /etc/apt/sources.list.d/testing.list - apt-get update -qq - apt-get install --no-install-recommends -qq -y git git-lfs - rm /etc/apt/sources.list.d/testing.list - apt-get update -qq + uses: ./.forgejo/workflows/composite/apt-install-from + with: + packages: git git-lfs - uses: ./.forgejo/workflows/composite/build-backend - run: | su forgejo -c 'make test-pgsql-migration test-pgsql' @@ -204,13 +188,9 @@ jobs: - uses: https://code.forgejo.org/actions/checkout@v3 - uses: ./.forgejo/workflows/composite/setup-env - name: install dependencies & git >= 2.42 - run: | - export DEBIAN_FRONTEND=noninteractive - echo deb http://deb.debian.org/debian/ testing main > /etc/apt/sources.list.d/testing.list - apt-get update -qq - apt-get install --no-install-recommends -qq -y git git-lfs - rm /etc/apt/sources.list.d/testing.list - apt-get update -qq + uses: ./.forgejo/workflows/composite/apt-install-from + with: + packages: git git-lfs - uses: ./.forgejo/workflows/composite/build-backend - run: | su forgejo -c 'make test-sqlite-migration test-sqlite' From 5b17c1d6ebc39ab20327a502bea5bbc39a456846 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sun, 29 Sep 2024 00:29:01 +0200 Subject: [PATCH 052/443] make sqlite3 the default database --- custom/conf/app.example.ini | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 2eff51fe98..7eb4f1c655 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -349,16 +349,25 @@ RUN_USER = ; git ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; Database to use. Either "mysql", "postgres", "mssql" or "sqlite3". +;; Database to use. Either "sqlite3", "mySQL", "postgres" or "mssql". +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; SQLite Configuration +;; +DB_TYPE = sqlite3 +;PATH= ; defaults to data/forgejo.db +;SQLITE_TIMEOUT = ; Query timeout defaults to: 500 +;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; MySQL Configuration ;; -DB_TYPE = mysql -HOST = 127.0.0.1:3306 ; can use socket e.g. /var/run/mysqld/mysqld.sock -NAME = gitea -USER = root +;DB_TYPE = mysql +;HOST = 127.0.0.1:3306 ; can use socket e.g. /var/run/mysqld/mysqld.sock +;NAME = gitea +;USER = root ;PASSWD = ;Use PASSWD = `your password` for quoting if you use special characters in the password. ;SSL_MODE = false ; either "false" (default), "true", or "skip-verify" ;CHARSET_COLLATION = ; Empty as default, Gitea will try to find a case-sensitive collation. Don't change it unless you clearly know what you need. @@ -377,15 +386,6 @@ USER = root ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; SQLite Configuration -;; -;DB_TYPE = sqlite3 -;PATH= ; defaults to data/forgejo.db -;SQLITE_TIMEOUT = ; Query timeout defaults to: 500 -;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; MSSQL Configuration ;; ;DB_TYPE = mssql From 8f0a05a7e47a1ed333bfdde01ee2e4d8580d39d0 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Sun, 22 Sep 2024 13:01:09 +0200 Subject: [PATCH 053/443] Fix artifact v4 upload above 8MB (#31664) Multiple chunks are uploaded with type "block" without using "appendBlock" and eventually out of order for bigger uploads. 8MB seems to be the chunk size This change parses the blockList uploaded after all blocks to get the final artifact size and order them correctly before calculating the sha256 checksum over all blocks Fixes #31354 (cherry picked from commit b594cec2bda6f861effedb2e8e0a7ebba191c0e9) Conflicts: routers/api/actions/artifactsv4.go conflict because of Refactor AppURL usage (#30885) 67c1a07285008cc00036a87cef966c3bd519a50c that was not cherry-picked in Forgejo the resolution consist of removing the extra ctx argument --- routers/api/actions/artifacts_chunks.go | 50 +++++- routers/api/actions/artifactsv4.go | 144 +++++++++++++----- .../api_actions_artifact_v4_test.go | 130 ++++++++++++++++ 3 files changed, 285 insertions(+), 39 deletions(-) diff --git a/routers/api/actions/artifacts_chunks.go b/routers/api/actions/artifacts_chunks.go index b0c96585cb..cdb56584b8 100644 --- a/routers/api/actions/artifacts_chunks.go +++ b/routers/api/actions/artifacts_chunks.go @@ -123,6 +123,54 @@ func listChunksByRunID(st storage.ObjectStorage, runID int64) (map[int64][]*chun return chunksMap, nil } +func listChunksByRunIDV4(st storage.ObjectStorage, runID, artifactID int64, blist *BlockList) ([]*chunkFileItem, error) { + storageDir := fmt.Sprintf("tmpv4%d", runID) + var chunks []*chunkFileItem + chunkMap := map[string]*chunkFileItem{} + dummy := &chunkFileItem{} + for _, name := range blist.Latest { + chunkMap[name] = dummy + } + if err := st.IterateObjects(storageDir, func(fpath string, obj storage.Object) error { + baseName := filepath.Base(fpath) + if !strings.HasPrefix(baseName, "block-") { + return nil + } + // when read chunks from storage, it only contains storage dir and basename, + // no matter the subdirectory setting in storage config + item := chunkFileItem{Path: storageDir + "/" + baseName, ArtifactID: artifactID} + var size int64 + var b64chunkName string + if _, err := fmt.Sscanf(baseName, "block-%d-%d-%s", &item.RunID, &size, &b64chunkName); err != nil { + return fmt.Errorf("parse content range error: %v", err) + } + rchunkName, err := base64.URLEncoding.DecodeString(b64chunkName) + if err != nil { + return fmt.Errorf("failed to parse chunkName: %v", err) + } + chunkName := string(rchunkName) + item.End = item.Start + size - 1 + if _, ok := chunkMap[chunkName]; ok { + chunkMap[chunkName] = &item + } + return nil + }); err != nil { + return nil, err + } + for i, name := range blist.Latest { + chunk, ok := chunkMap[name] + if !ok || chunk.Path == "" { + return nil, fmt.Errorf("missing Chunk (%d/%d): %s", i, len(blist.Latest), name) + } + chunks = append(chunks, chunk) + if i > 0 { + chunk.Start = chunkMap[blist.Latest[i-1]].End + 1 + chunk.End += chunk.Start + } + } + return chunks, nil +} + func mergeChunksForRun(ctx *ArtifactContext, st storage.ObjectStorage, runID int64, artifactName string) error { // read all db artifacts by name artifacts, err := db.Find[actions.ActionArtifact](ctx, actions.FindArtifactsOptions{ @@ -230,7 +278,7 @@ func mergeChunksForArtifact(ctx *ArtifactContext, chunks []*chunkFileItem, st st rawChecksum := hash.Sum(nil) actualChecksum := hex.EncodeToString(rawChecksum) if !strings.HasSuffix(checksum, actualChecksum) { - return fmt.Errorf("update artifact error checksum is invalid") + return fmt.Errorf("update artifact error checksum is invalid %v vs %v", checksum, actualChecksum) } } diff --git a/routers/api/actions/artifactsv4.go b/routers/api/actions/artifactsv4.go index 7b2f9c4360..677e89da2f 100644 --- a/routers/api/actions/artifactsv4.go +++ b/routers/api/actions/artifactsv4.go @@ -24,8 +24,15 @@ package actions // PUT: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75&comp=block // 1.3. Continue Upload Zip Content to Blobstorage (unauthenticated request), repeat until everything is uploaded // PUT: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75&comp=appendBlock -// 1.4. Unknown xml payload to Blobstorage (unauthenticated request), ignored for now +// 1.4. BlockList xml payload to Blobstorage (unauthenticated request) +// Files of about 800MB are parallel in parallel and / or out of order, this file is needed to enshure the correct order // PUT: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75&comp=blockList +// Request +// +// +// blockId1 +// blockId2 +// // 1.5. FinalizeArtifact // Post: /twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact // Request @@ -82,6 +89,7 @@ import ( "crypto/hmac" "crypto/sha256" "encoding/base64" + "encoding/xml" "fmt" "io" "net/http" @@ -153,31 +161,34 @@ func ArtifactsV4Routes(prefix string) *web.Route { return m } -func (r artifactV4Routes) buildSignature(endp, expires, artifactName string, taskID int64) []byte { +func (r artifactV4Routes) buildSignature(endp, expires, artifactName string, taskID, artifactID int64) []byte { mac := hmac.New(sha256.New, setting.GetGeneralTokenSigningSecret()) mac.Write([]byte(endp)) mac.Write([]byte(expires)) mac.Write([]byte(artifactName)) mac.Write([]byte(fmt.Sprint(taskID))) + mac.Write([]byte(fmt.Sprint(artifactID))) return mac.Sum(nil) } -func (r artifactV4Routes) buildArtifactURL(endp, artifactName string, taskID int64) string { +func (r artifactV4Routes) buildArtifactURL(endp, artifactName string, taskID, artifactID int64) string { expires := time.Now().Add(60 * time.Minute).Format("2006-01-02 15:04:05.999999999 -0700 MST") uploadURL := strings.TrimSuffix(setting.AppURL, "/") + strings.TrimSuffix(r.prefix, "/") + - "/" + endp + "?sig=" + base64.URLEncoding.EncodeToString(r.buildSignature(endp, expires, artifactName, taskID)) + "&expires=" + url.QueryEscape(expires) + "&artifactName=" + url.QueryEscape(artifactName) + "&taskID=" + fmt.Sprint(taskID) + "/" + endp + "?sig=" + base64.URLEncoding.EncodeToString(r.buildSignature(endp, expires, artifactName, taskID, artifactID)) + "&expires=" + url.QueryEscape(expires) + "&artifactName=" + url.QueryEscape(artifactName) + "&taskID=" + fmt.Sprint(taskID) + "&artifactID=" + fmt.Sprint(artifactID) return uploadURL } func (r artifactV4Routes) verifySignature(ctx *ArtifactContext, endp string) (*actions.ActionTask, string, bool) { rawTaskID := ctx.Req.URL.Query().Get("taskID") + rawArtifactID := ctx.Req.URL.Query().Get("artifactID") sig := ctx.Req.URL.Query().Get("sig") expires := ctx.Req.URL.Query().Get("expires") artifactName := ctx.Req.URL.Query().Get("artifactName") dsig, _ := base64.URLEncoding.DecodeString(sig) taskID, _ := strconv.ParseInt(rawTaskID, 10, 64) + artifactID, _ := strconv.ParseInt(rawArtifactID, 10, 64) - expecedsig := r.buildSignature(endp, expires, artifactName, taskID) + expecedsig := r.buildSignature(endp, expires, artifactName, taskID, artifactID) if !hmac.Equal(dsig, expecedsig) { log.Error("Error unauthorized") ctx.Error(http.StatusUnauthorized, "Error unauthorized") @@ -272,6 +283,8 @@ func (r *artifactV4Routes) createArtifact(ctx *ArtifactContext) { return } artifact.ContentEncoding = ArtifactV4ContentEncoding + artifact.FileSize = 0 + artifact.FileCompressedSize = 0 if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil { log.Error("Error UpdateArtifactByID: %v", err) ctx.Error(http.StatusInternalServerError, "Error UpdateArtifactByID") @@ -280,7 +293,7 @@ func (r *artifactV4Routes) createArtifact(ctx *ArtifactContext) { respData := CreateArtifactResponse{ Ok: true, - SignedUploadUrl: r.buildArtifactURL("UploadArtifact", artifactName, ctx.ActionTask.ID), + SignedUploadUrl: r.buildArtifactURL("UploadArtifact", artifactName, ctx.ActionTask.ID, artifact.ID), } r.sendProtbufBody(ctx, &respData) } @@ -306,38 +319,77 @@ func (r *artifactV4Routes) uploadArtifact(ctx *ArtifactContext) { comp := ctx.Req.URL.Query().Get("comp") switch comp { case "block", "appendBlock": - // get artifact by name - artifact, err := r.getArtifactByName(ctx, task.Job.RunID, artifactName) - if err != nil { - log.Error("Error artifact not found: %v", err) - ctx.Error(http.StatusNotFound, "Error artifact not found") - return - } + blockid := ctx.Req.URL.Query().Get("blockid") + if blockid == "" { + // get artifact by name + artifact, err := r.getArtifactByName(ctx, task.Job.RunID, artifactName) + if err != nil { + log.Error("Error artifact not found: %v", err) + ctx.Error(http.StatusNotFound, "Error artifact not found") + return + } - if comp == "block" { - artifact.FileSize = 0 - artifact.FileCompressedSize = 0 + _, err = appendUploadChunk(r.fs, ctx, artifact, artifact.FileSize, ctx.Req.ContentLength, artifact.RunID) + if err != nil { + log.Error("Error runner api getting task: task is not running") + ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running") + return + } + artifact.FileCompressedSize += ctx.Req.ContentLength + artifact.FileSize += ctx.Req.ContentLength + if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil { + log.Error("Error UpdateArtifactByID: %v", err) + ctx.Error(http.StatusInternalServerError, "Error UpdateArtifactByID") + return + } + } else { + _, err := r.fs.Save(fmt.Sprintf("tmpv4%d/block-%d-%d-%s", task.Job.RunID, task.Job.RunID, ctx.Req.ContentLength, base64.URLEncoding.EncodeToString([]byte(blockid))), ctx.Req.Body, -1) + if err != nil { + log.Error("Error runner api getting task: task is not running") + ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running") + return + } } - - _, err = appendUploadChunk(r.fs, ctx, artifact, artifact.FileSize, ctx.Req.ContentLength, artifact.RunID) + ctx.JSON(http.StatusCreated, "appended") + case "blocklist": + rawArtifactID := ctx.Req.URL.Query().Get("artifactID") + artifactID, _ := strconv.ParseInt(rawArtifactID, 10, 64) + _, err := r.fs.Save(fmt.Sprintf("tmpv4%d/%d-%d-blocklist", task.Job.RunID, task.Job.RunID, artifactID), ctx.Req.Body, -1) if err != nil { log.Error("Error runner api getting task: task is not running") ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running") return } - artifact.FileCompressedSize += ctx.Req.ContentLength - artifact.FileSize += ctx.Req.ContentLength - if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil { - log.Error("Error UpdateArtifactByID: %v", err) - ctx.Error(http.StatusInternalServerError, "Error UpdateArtifactByID") - return - } - ctx.JSON(http.StatusCreated, "appended") - case "blocklist": ctx.JSON(http.StatusCreated, "created") } } +type BlockList struct { + Latest []string `xml:"Latest"` +} + +type Latest struct { + Value string `xml:",chardata"` +} + +func (r *artifactV4Routes) readBlockList(runID, artifactID int64) (*BlockList, error) { + blockListName := fmt.Sprintf("tmpv4%d/%d-%d-blocklist", runID, runID, artifactID) + s, err := r.fs.Open(blockListName) + if err != nil { + return nil, err + } + + xdec := xml.NewDecoder(s) + blockList := &BlockList{} + err = xdec.Decode(blockList) + + delerr := r.fs.Delete(blockListName) + if delerr != nil { + log.Warn("Failed to delete blockList %s: %v", blockListName, delerr) + } + return blockList, err +} + func (r *artifactV4Routes) finalizeArtifact(ctx *ArtifactContext) { var req FinalizeArtifactRequest @@ -356,18 +408,34 @@ func (r *artifactV4Routes) finalizeArtifact(ctx *ArtifactContext) { ctx.Error(http.StatusNotFound, "Error artifact not found") return } - chunkMap, err := listChunksByRunID(r.fs, runID) + + var chunks []*chunkFileItem + blockList, err := r.readBlockList(runID, artifact.ID) if err != nil { - log.Error("Error merge chunks: %v", err) - ctx.Error(http.StatusInternalServerError, "Error merge chunks") - return - } - chunks, ok := chunkMap[artifact.ID] - if !ok { - log.Error("Error merge chunks") - ctx.Error(http.StatusInternalServerError, "Error merge chunks") - return + log.Warn("Failed to read BlockList, fallback to old behavior: %v", err) + chunkMap, err := listChunksByRunID(r.fs, runID) + if err != nil { + log.Error("Error merge chunks: %v", err) + ctx.Error(http.StatusInternalServerError, "Error merge chunks") + return + } + chunks, ok = chunkMap[artifact.ID] + if !ok { + log.Error("Error merge chunks") + ctx.Error(http.StatusInternalServerError, "Error merge chunks") + return + } + } else { + chunks, err = listChunksByRunIDV4(r.fs, runID, artifact.ID, blockList) + if err != nil { + log.Error("Error merge chunks: %v", err) + ctx.Error(http.StatusInternalServerError, "Error merge chunks") + return + } + artifact.FileSize = chunks[len(chunks)-1].End + 1 + artifact.FileCompressedSize = chunks[len(chunks)-1].End + 1 } + checksum := "" if req.Hash != nil { checksum = req.Hash.Value @@ -468,7 +536,7 @@ func (r *artifactV4Routes) getSignedArtifactURL(ctx *ArtifactContext) { } } if respData.SignedUrl == "" { - respData.SignedUrl = r.buildArtifactURL("DownloadArtifact", artifactName, ctx.ActionTask.ID) + respData.SignedUrl = r.buildArtifactURL("DownloadArtifact", artifactName, ctx.ActionTask.ID, artifact.ID) } r.sendProtbufBody(ctx, &respData) } diff --git a/tests/integration/api_actions_artifact_v4_test.go b/tests/integration/api_actions_artifact_v4_test.go index b2c25a2e70..96668b1ddf 100644 --- a/tests/integration/api_actions_artifact_v4_test.go +++ b/tests/integration/api_actions_artifact_v4_test.go @@ -7,12 +7,14 @@ import ( "bytes" "crypto/sha256" "encoding/hex" + "encoding/xml" "io" "net/http" "strings" "testing" "time" + "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/routers/api/actions" actions_service "code.gitea.io/gitea/services/actions" "code.gitea.io/gitea/tests" @@ -175,6 +177,134 @@ func TestActionsArtifactV4UploadSingleFileWithRetentionDays(t *testing.T) { assert.True(t, finalizeResp.Ok) } +func TestActionsArtifactV4UploadSingleFileWithPotentialHarmfulBlockID(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + token, err := actions_service.CreateAuthorizationToken(48, 792, 193) + assert.NoError(t, err) + + // acquire artifact upload url + req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact", toProtoJSON(&actions.CreateArtifactRequest{ + Version: 4, + Name: "artifactWithPotentialHarmfulBlockID", + WorkflowRunBackendId: "792", + WorkflowJobRunBackendId: "193", + })).AddTokenAuth(token) + resp := MakeRequest(t, req, http.StatusOK) + var uploadResp actions.CreateArtifactResponse + protojson.Unmarshal(resp.Body.Bytes(), &uploadResp) + assert.True(t, uploadResp.Ok) + assert.Contains(t, uploadResp.SignedUploadUrl, "/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact") + + // get upload urls + idx := strings.Index(uploadResp.SignedUploadUrl, "/twirp/") + url := uploadResp.SignedUploadUrl[idx:] + "&comp=block&blockid=%2f..%2fmyfile" + blockListURL := uploadResp.SignedUploadUrl[idx:] + "&comp=blocklist" + + // upload artifact chunk + body := strings.Repeat("A", 1024) + req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body)) + MakeRequest(t, req, http.StatusCreated) + + // verify that the exploit didn't work + _, err = storage.Actions.Stat("myfile") + assert.Error(t, err) + + // upload artifact blockList + blockList := &actions.BlockList{ + Latest: []string{ + "/../myfile", + }, + } + rawBlockList, err := xml.Marshal(blockList) + assert.NoError(t, err) + req = NewRequestWithBody(t, "PUT", blockListURL, bytes.NewReader(rawBlockList)) + MakeRequest(t, req, http.StatusCreated) + + t.Logf("Create artifact confirm") + + sha := sha256.Sum256([]byte(body)) + + // confirm artifact upload + req = NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact", toProtoJSON(&actions.FinalizeArtifactRequest{ + Name: "artifactWithPotentialHarmfulBlockID", + Size: 1024, + Hash: wrapperspb.String("sha256:" + hex.EncodeToString(sha[:])), + WorkflowRunBackendId: "792", + WorkflowJobRunBackendId: "193", + })). + AddTokenAuth(token) + resp = MakeRequest(t, req, http.StatusOK) + var finalizeResp actions.FinalizeArtifactResponse + protojson.Unmarshal(resp.Body.Bytes(), &finalizeResp) + assert.True(t, finalizeResp.Ok) +} + +func TestActionsArtifactV4UploadSingleFileWithChunksOutOfOrder(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + token, err := actions_service.CreateAuthorizationToken(48, 792, 193) + assert.NoError(t, err) + + // acquire artifact upload url + req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact", toProtoJSON(&actions.CreateArtifactRequest{ + Version: 4, + Name: "artifactWithChunksOutOfOrder", + WorkflowRunBackendId: "792", + WorkflowJobRunBackendId: "193", + })).AddTokenAuth(token) + resp := MakeRequest(t, req, http.StatusOK) + var uploadResp actions.CreateArtifactResponse + protojson.Unmarshal(resp.Body.Bytes(), &uploadResp) + assert.True(t, uploadResp.Ok) + assert.Contains(t, uploadResp.SignedUploadUrl, "/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact") + + // get upload urls + idx := strings.Index(uploadResp.SignedUploadUrl, "/twirp/") + block1URL := uploadResp.SignedUploadUrl[idx:] + "&comp=block&blockid=block1" + block2URL := uploadResp.SignedUploadUrl[idx:] + "&comp=block&blockid=block2" + blockListURL := uploadResp.SignedUploadUrl[idx:] + "&comp=blocklist" + + // upload artifact chunks + bodyb := strings.Repeat("B", 1024) + req = NewRequestWithBody(t, "PUT", block2URL, strings.NewReader(bodyb)) + MakeRequest(t, req, http.StatusCreated) + + bodya := strings.Repeat("A", 1024) + req = NewRequestWithBody(t, "PUT", block1URL, strings.NewReader(bodya)) + MakeRequest(t, req, http.StatusCreated) + + // upload artifact blockList + blockList := &actions.BlockList{ + Latest: []string{ + "block1", + "block2", + }, + } + rawBlockList, err := xml.Marshal(blockList) + assert.NoError(t, err) + req = NewRequestWithBody(t, "PUT", blockListURL, bytes.NewReader(rawBlockList)) + MakeRequest(t, req, http.StatusCreated) + + t.Logf("Create artifact confirm") + + sha := sha256.Sum256([]byte(bodya + bodyb)) + + // confirm artifact upload + req = NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact", toProtoJSON(&actions.FinalizeArtifactRequest{ + Name: "artifactWithChunksOutOfOrder", + Size: 2048, + Hash: wrapperspb.String("sha256:" + hex.EncodeToString(sha[:])), + WorkflowRunBackendId: "792", + WorkflowJobRunBackendId: "193", + })). + AddTokenAuth(token) + resp = MakeRequest(t, req, http.StatusOK) + var finalizeResp actions.FinalizeArtifactResponse + protojson.Unmarshal(resp.Body.Bytes(), &finalizeResp) + assert.True(t, finalizeResp.Ok) +} + func TestActionsArtifactV4DownloadSingle(t *testing.T) { defer tests.PrepareTestEnv(t)() From a226064711899da07d6b1455a68ef758f2f3e7e0 Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Sun, 29 Sep 2024 09:58:47 +0200 Subject: [PATCH 054/443] Fix artifact v4 upload above 8MB (#31664) (fix lint errors) --- tests/integration/api_actions_artifact_v4_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/integration/api_actions_artifact_v4_test.go b/tests/integration/api_actions_artifact_v4_test.go index 96668b1ddf..f55250f6c1 100644 --- a/tests/integration/api_actions_artifact_v4_test.go +++ b/tests/integration/api_actions_artifact_v4_test.go @@ -181,7 +181,7 @@ func TestActionsArtifactV4UploadSingleFileWithPotentialHarmfulBlockID(t *testing defer tests.PrepareTestEnv(t)() token, err := actions_service.CreateAuthorizationToken(48, 792, 193) - assert.NoError(t, err) + require.NoError(t, err) // acquire artifact upload url req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact", toProtoJSON(&actions.CreateArtifactRequest{ @@ -208,7 +208,7 @@ func TestActionsArtifactV4UploadSingleFileWithPotentialHarmfulBlockID(t *testing // verify that the exploit didn't work _, err = storage.Actions.Stat("myfile") - assert.Error(t, err) + require.Error(t, err) // upload artifact blockList blockList := &actions.BlockList{ @@ -217,7 +217,7 @@ func TestActionsArtifactV4UploadSingleFileWithPotentialHarmfulBlockID(t *testing }, } rawBlockList, err := xml.Marshal(blockList) - assert.NoError(t, err) + require.NoError(t, err) req = NewRequestWithBody(t, "PUT", blockListURL, bytes.NewReader(rawBlockList)) MakeRequest(t, req, http.StatusCreated) @@ -244,7 +244,7 @@ func TestActionsArtifactV4UploadSingleFileWithChunksOutOfOrder(t *testing.T) { defer tests.PrepareTestEnv(t)() token, err := actions_service.CreateAuthorizationToken(48, 792, 193) - assert.NoError(t, err) + require.NoError(t, err) // acquire artifact upload url req := NewRequestWithBody(t, "POST", "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact", toProtoJSON(&actions.CreateArtifactRequest{ @@ -282,7 +282,7 @@ func TestActionsArtifactV4UploadSingleFileWithChunksOutOfOrder(t *testing.T) { }, } rawBlockList, err := xml.Marshal(blockList) - assert.NoError(t, err) + require.NoError(t, err) req = NewRequestWithBody(t, "PUT", blockListURL, bytes.NewReader(rawBlockList)) MakeRequest(t, req, http.StatusCreated) From 1d5f8e5488da48af763a04783376c57e37fa9198 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 29 Sep 2024 08:03:13 +0000 Subject: [PATCH 055/443] Update dependency vue to v3.5.10 --- package-lock.json | 108 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/package-lock.json b/package-lock.json index b6edb9d5a5..7ba9c262f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,7 @@ "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", - "vue": "3.5.8", + "vue": "3.5.10", "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", @@ -5028,39 +5028,39 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.8.tgz", - "integrity": "sha512-Uzlxp91EPjfbpeO5KtC0KnXPkuTfGsNDeaKQJxQN718uz+RqDYarEf7UhQJGK+ZYloD2taUbHTI2J4WrUaZQNA==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.10.tgz", + "integrity": "sha512-iXWlk+Cg/ag7gLvY0SfVucU8Kh2CjysYZjhhP70w9qI4MvSox4frrP+vDGvtQuzIcgD8+sxM6lZvCtdxGunTAA==", "license": "MIT", "dependencies": { "@babel/parser": "^7.25.3", - "@vue/shared": "3.5.8", + "@vue/shared": "3.5.10", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.8.tgz", - "integrity": "sha512-GUNHWvoDSbSa5ZSHT9SnV5WkStWfzJwwTd6NMGzilOE/HM5j+9EB9zGXdtu/fCNEmctBqMs6C9SvVPpVPuk1Eg==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.10.tgz", + "integrity": "sha512-DyxHC6qPcktwYGKOIy3XqnHRrrXyWR2u91AjP+nLkADko380srsC2DC3s7Y1Rk6YfOlxOlvEQKa9XXmLI+W4ZA==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.8", - "@vue/shared": "3.5.8" + "@vue/compiler-core": "3.5.10", + "@vue/shared": "3.5.10" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.8.tgz", - "integrity": "sha512-taYpngQtSysrvO9GULaOSwcG5q821zCoIQBtQQSx7Uf7DxpR6CIHR90toPr9QfDD2mqHQPCSgoWBvJu0yV9zjg==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.10.tgz", + "integrity": "sha512-to8E1BgpakV7224ZCm8gz1ZRSyjNCAWEplwFMWKlzCdP9DkMKhRRwt0WkCjY7jkzi/Vz3xgbpeig5Pnbly4Tow==", "license": "MIT", "dependencies": { "@babel/parser": "^7.25.3", - "@vue/compiler-core": "3.5.8", - "@vue/compiler-dom": "3.5.8", - "@vue/compiler-ssr": "3.5.8", - "@vue/shared": "3.5.8", + "@vue/compiler-core": "3.5.10", + "@vue/compiler-dom": "3.5.10", + "@vue/compiler-ssr": "3.5.10", + "@vue/shared": "3.5.10", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.47", @@ -5077,63 +5077,63 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.8.tgz", - "integrity": "sha512-W96PtryNsNG9u0ZnN5Q5j27Z/feGrFV6zy9q5tzJVyJaLiwYxvC0ek4IXClZygyhjm+XKM7WD9pdKi/wIRVC/Q==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.10.tgz", + "integrity": "sha512-hxP4Y3KImqdtyUKXDRSxKSRkSm1H9fCvhojEYrnaoWhE4w/y8vwWhnosJoPPe2AXm5sU7CSbYYAgkt2ZPhDz+A==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.8", - "@vue/shared": "3.5.8" + "@vue/compiler-dom": "3.5.10", + "@vue/shared": "3.5.10" } }, "node_modules/@vue/reactivity": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.8.tgz", - "integrity": "sha512-mlgUyFHLCUZcAYkqvzYnlBRCh0t5ZQfLYit7nukn1GR96gc48Bp4B7OIcSfVSvlG1k3BPfD+p22gi1t2n9tsXg==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.10.tgz", + "integrity": "sha512-kW08v06F6xPSHhid9DJ9YjOGmwNDOsJJQk0ax21wKaUYzzuJGEuoKNU2Ujux8FLMrP7CFJJKsHhXN9l2WOVi2g==", "license": "MIT", "dependencies": { - "@vue/shared": "3.5.8" + "@vue/shared": "3.5.10" } }, "node_modules/@vue/runtime-core": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.8.tgz", - "integrity": "sha512-fJuPelh64agZ8vKkZgp5iCkPaEqFJsYzxLk9vSC0X3G8ppknclNDr61gDc45yBGTaN5Xqc1qZWU3/NoaBMHcjQ==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.10.tgz", + "integrity": "sha512-9Q86I5Qq3swSkFfzrZ+iqEy7Vla325M7S7xc1NwKnRm/qoi1Dauz0rT6mTMmscqx4qz0EDJ1wjB+A36k7rl8mA==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.8", - "@vue/shared": "3.5.8" + "@vue/reactivity": "3.5.10", + "@vue/shared": "3.5.10" } }, "node_modules/@vue/runtime-dom": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.8.tgz", - "integrity": "sha512-DpAUz+PKjTZPUOB6zJgkxVI3GuYc2iWZiNeeHQUw53kdrparSTG6HeXUrYDjaam8dVsCdvQxDz6ZWxnyjccUjQ==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.10.tgz", + "integrity": "sha512-t3x7ht5qF8ZRi1H4fZqFzyY2j+GTMTDxRheT+i8M9Ph0oepUxoadmbwlFwMoW7RYCpNQLpP2Yx3feKs+fyBdpA==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.5.8", - "@vue/runtime-core": "3.5.8", - "@vue/shared": "3.5.8", + "@vue/reactivity": "3.5.10", + "@vue/runtime-core": "3.5.10", + "@vue/shared": "3.5.10", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.8.tgz", - "integrity": "sha512-7AmC9/mEeV9mmXNVyUIm1a1AjUhyeeGNbkLh39J00E7iPeGks8OGRB5blJiMmvqSh8SkaS7jkLWSpXtxUCeagA==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.10.tgz", + "integrity": "sha512-IVE97tt2kGKwHNq9yVO0xdh1IvYfZCShvDSy46JIh5OQxP1/EXSpoDqetVmyIzL7CYOWnnmMkVqd7YK2QSWkdw==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.5.8", - "@vue/shared": "3.5.8" + "@vue/compiler-ssr": "3.5.10", + "@vue/shared": "3.5.10" }, "peerDependencies": { - "vue": "3.5.8" + "vue": "3.5.10" } }, "node_modules/@vue/shared": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.8.tgz", - "integrity": "sha512-mJleSWbAGySd2RJdX1RBtcrUBX6snyOc0qHpgk3lGi4l9/P/3ny3ELqFWqYdkXIwwNN/kdm8nD9ky8o6l/Lx2A==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.10.tgz", + "integrity": "sha512-VkkBhU97Ki+XJ0xvl4C9YJsIZ2uIlQ7HqPpZOS3m9VCvmROPaChZU6DexdMJqvz9tbgG+4EtFVrSuailUq5KGQ==", "license": "MIT" }, "node_modules/@vue/test-utils": { @@ -16270,16 +16270,16 @@ "license": "MIT" }, "node_modules/vue": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.8.tgz", - "integrity": "sha512-hvuvuCy51nP/1fSRvrrIqTLSvrSyz2Pq+KQ8S8SXCxTWVE0nMaOnSDnSOxV1eYmGfvK7mqiwvd1C59CEEz7dAQ==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.10.tgz", + "integrity": "sha512-Vy2kmJwHPlouC/tSnIgXVg03SG+9wSqT1xu1Vehc+ChsXsRd7jLkKgMltVEFOzUdBr3uFwBCG+41LJtfAcBRng==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.8", - "@vue/compiler-sfc": "3.5.8", - "@vue/runtime-dom": "3.5.8", - "@vue/server-renderer": "3.5.8", - "@vue/shared": "3.5.8" + "@vue/compiler-dom": "3.5.10", + "@vue/compiler-sfc": "3.5.10", + "@vue/runtime-dom": "3.5.10", + "@vue/server-renderer": "3.5.10", + "@vue/shared": "3.5.10" }, "peerDependencies": { "typescript": "*" diff --git a/package.json b/package.json index 24e3bd3eb9..d3d88bfd3f 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", "vanilla-colorful": "0.7.2", - "vue": "3.5.8", + "vue": "3.5.10", "vue-chartjs": "5.3.1", "vue-loader": "17.4.2", "vue3-calendar-heatmap": "2.0.5", From ff65d34f03f8596d3981461b0c95dbb684fb51b6 Mon Sep 17 00:00:00 2001 From: cloudchamb3r Date: Tue, 24 Sep 2024 02:09:57 +0900 Subject: [PATCH 056/443] Fix Bug in Issue/pulls list (#32081) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix #32080 ## After ### for opened issues Screenshot 2024-09-19 at 6 29 31 PM ### for closed issues Screenshot 2024-09-19 at 6 29 37 PM ### for all issues Screenshot 2024-09-20 at 12 07 12 PM (cherry picked from commit e1f0598c8f5af5ac95f5e13b74fbab99506762db) --- routers/web/repo/issue.go | 1 + templates/repo/issue/filter_actions.tmpl | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 01fd1e2725..5d13ccc97c 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -476,6 +476,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt ctx.Data["PosterID"] = posterID ctx.Data["IsFuzzy"] = isFuzzy ctx.Data["Keyword"] = keyword + ctx.Data["IsShowClosed"] = isShowClosed switch { case isShowClosed.Value(): ctx.Data["State"] = "closed" diff --git a/templates/repo/issue/filter_actions.tmpl b/templates/repo/issue/filter_actions.tmpl index a341448bcc..58b1ef8ecd 100644 --- a/templates/repo/issue/filter_actions.tmpl +++ b/templates/repo/issue/filter_actions.tmpl @@ -1,9 +1,9 @@