diff --git a/.air.toml b/.air.toml index d13f8c4f99..de97bd8b29 100644 --- a/.air.toml +++ b/.air.toml @@ -8,6 +8,15 @@ delay = 1000 include_ext = ["go", "tmpl"] include_file = ["main.go"] include_dir = ["cmd", "models", "modules", "options", "routers", "services"] -exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata", "models/fixtures", "models/migrations/fixtures", "modules/migration/file_format_testdata", "modules/avatar/identicon/testdata"] +exclude_dir = [ + "models/fixtures", + "models/migrations/fixtures", + "modules/avatar/identicon/testdata", + "modules/avatar/testdata", + "modules/git/tests", + "modules/migration/file_format_testdata", + "routers/private/tests", + "services/gitdiff/testdata", +] exclude_regex = ["_test.go$", "_gen.go$"] stop_on_error = true diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 8563aafd04..1b1b66c7dd 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -4,7 +4,7 @@ "features": { // installs nodejs into container "ghcr.io/devcontainers/features/node:1": { - "version":"20" + "version": "20" }, "ghcr.io/devcontainers/features/git-lfs:1.1.0": {}, "ghcr.io/devcontainers-contrib/features/poetry:2": {}, @@ -24,7 +24,7 @@ "DavidAnson.vscode-markdownlint", "Vue.volar", "ms-azuretools.vscode-docker", - "zixuanchen.vitest-explorer", + "vitest.explorer", "qwtel.sqlite-viewer", "GitHub.vscode-pull-request-github" ] diff --git a/.dockerignore b/.dockerignore index d1a08977a5..98ef522331 100644 --- a/.dockerignore +++ b/.dockerignore @@ -62,7 +62,6 @@ cpu.out /data /indexers /log -/public/img/avatar /tests/integration/gitea-integration-* /tests/integration/indexers-* /tests/e2e/gitea-e2e-* @@ -77,6 +76,7 @@ cpu.out /public/assets/js /public/assets/css /public/assets/fonts +/public/assets/img/avatar /public/assets/img/webpack /vendor /web_src/fomantic/node_modules diff --git a/.eslintrc.yaml b/.eslintrc.yaml index b62b13cefe..eeb3e20cb8 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -42,10 +42,6 @@ overrides: worker: true rules: no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, status, statusbar, stop, toolbar, top] - - files: ["build/generate-images.js"] - rules: - i/no-unresolved: [0] - i/no-extraneous-dependencies: [0] - files: ["*.config.*"] rules: i/no-unused-modules: [0] @@ -123,7 +119,7 @@ rules: "@stylistic/js/arrow-spacing": [2, {before: true, after: true}] "@stylistic/js/block-spacing": [0] "@stylistic/js/brace-style": [2, 1tbs, {allowSingleLine: true}] - "@stylistic/js/comma-dangle": [2, only-multiline] + "@stylistic/js/comma-dangle": [2, always-multiline] "@stylistic/js/comma-spacing": [2, {before: false, after: true}] "@stylistic/js/comma-style": [2, last] "@stylistic/js/computed-property-spacing": [2, never] @@ -290,7 +286,7 @@ rules: jquery/no-class: [0] jquery/no-clone: [2] jquery/no-closest: [0] - jquery/no-css: [0] + jquery/no-css: [2] jquery/no-data: [0] jquery/no-deferred: [2] jquery/no-delegate: [2] @@ -413,7 +409,7 @@ rules: no-jquery/no-constructor-attributes: [2] no-jquery/no-contains: [2] no-jquery/no-context-prop: [2] - no-jquery/no-css: [0] + no-jquery/no-css: [2] no-jquery/no-data: [0] no-jquery/no-deferred: [2] no-jquery/no-delegate: [2] diff --git a/.gitignore b/.gitignore index 34c71b6973..b883e079d1 100644 --- a/.gitignore +++ b/.gitignore @@ -64,7 +64,7 @@ cpu.out /data /indexers /log -/public/img/avatar +/public/assets/img/avatar /tests/integration/gitea-integration-* /tests/integration/indexers-* /tests/e2e/gitea-e2e-* diff --git a/.gitpod.yml b/.gitpod.yml index ed2f57f4bf..f573d55a76 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -42,7 +42,7 @@ vscode: - DavidAnson.vscode-markdownlint - Vue.volar - ms-azuretools.vscode-docker - - zixuanchen.vitest-explorer + - vitest.explorer - qwtel.sqlite-viewer - GitHub.vscode-pull-request-github diff --git a/.stylelintrc.yaml b/.stylelintrc.yaml index c7725159f1..60cce7dbf7 100644 --- a/.stylelintrc.yaml +++ b/.stylelintrc.yaml @@ -30,7 +30,7 @@ rules: "@stylistic/block-opening-brace-newline-after": null "@stylistic/block-opening-brace-newline-before": null "@stylistic/block-opening-brace-space-after": null - "@stylistic/block-opening-brace-space-before": null + "@stylistic/block-opening-brace-space-before": always "@stylistic/color-hex-case": lower "@stylistic/declaration-bang-space-after": never "@stylistic/declaration-bang-space-before": null @@ -140,7 +140,7 @@ rules: function-disallowed-list: null function-linear-gradient-no-nonstandard-direction: true function-name-case: lower - function-no-unknown: null + function-no-unknown: true function-url-no-scheme-relative: null function-url-quotes: always function-url-scheme-allowed-list: null @@ -168,7 +168,7 @@ rules: no-duplicate-selectors: true no-empty-source: true no-invalid-double-slash-comments: true - no-invalid-position-at-import-rule: null + no-invalid-position-at-import-rule: [true, ignoreAtRules: [tailwind]] no-irregular-whitespace: true no-unknown-animations: null no-unknown-custom-properties: null @@ -181,6 +181,7 @@ rules: rule-empty-line-before: null rule-selector-property-disallowed-list: null scale-unlimited/declaration-strict-value: [[/color$/, font-weight], {ignoreValues: /^(inherit|transparent|unset|initial|currentcolor|none)$/, ignoreFunctions: false, disableFix: true, expandShorthand: true}] + selector-anb-no-unmatchable: true selector-attribute-name-disallowed-list: null selector-attribute-operator-allowed-list: null selector-attribute-operator-disallowed-list: null diff --git a/Makefile b/Makefile index 6735ffd1a5..b1c4864c7a 100644 --- a/Makefile +++ b/Makefile @@ -44,9 +44,6 @@ DOCKER_TAG ?= latest DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG) ifeq ($(HAS_GO), yes) - GOPATH ?= $(shell $(GO) env GOPATH) - export PATH := $(GOPATH)/bin:$(PATH) - CGO_EXTRA_CFLAGS := -DSQLITE_MAX_VARIABLE_NUMBER=32766 CGO_CFLAGS ?= $(shell $(GO) env CGO_CFLAGS) $(CGO_EXTRA_CFLAGS) endif @@ -148,6 +145,8 @@ TAR_EXCLUDES := .git data indexers queues log node_modules $(EXECUTABLE) $(FOMAN GO_DIRS := build cmd models modules routers services tests WEB_DIRS := web_src/js web_src/css +ESLINT_FILES := web_src/js tools *.config.js tests/e2e +STYLELINT_FILES := web_src/css web_src/js/components/*.vue SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github GO_SOURCES := $(wildcard *.go) @@ -396,19 +395,19 @@ lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig .PHONY: lint-js lint-js: node_modules - npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js tests/e2e + npx eslint --color --max-warnings=0 --ext js,vue $(ESLINT_FILES) .PHONY: lint-js-fix lint-js-fix: node_modules - npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js tests/e2e --fix + npx eslint --color --max-warnings=0 --ext js,vue $(ESLINT_FILES) --fix .PHONY: lint-css lint-css: node_modules - npx stylelint --color --max-warnings=0 web_src/css web_src/js/components/*.vue + npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) .PHONY: lint-css-fix lint-css-fix: node_modules - npx stylelint --color --max-warnings=0 web_src/css web_src/js/components/*.vue --fix + npx stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix .PHONY: lint-swagger lint-swagger: node_modules @@ -468,7 +467,7 @@ lint-yaml: .venv .PHONY: watch watch: - @bash build/watch.sh + @bash tools/watch.sh .PHONY: watch-frontend watch-frontend: node-check node_modules @@ -962,7 +961,7 @@ $(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json .PHONY: svg svg: node-check | node_modules rm -rf $(SVG_DEST_DIR) - node build/generate-svg.js + node tools/generate-svg.js .PHONY: svg-check svg-check: svg @@ -997,7 +996,7 @@ generate-gitignore: .PHONY: generate-images generate-images: | node_modules npm install --no-save fabric@6.0.0-beta19 imagemin-zopfli@7 - node build/generate-images.js $(TAGS) + node tools/generate-images.js $(TAGS) .PHONY: generate-manpage generate-manpage: diff --git a/docs/content/administration/cmd-embedded.zh-cn.md b/docs/content/administration/cmd-embedded.zh-cn.md index 4570bb58a3..a2df1aa2f5 100644 --- a/docs/content/administration/cmd-embedded.zh-cn.md +++ b/docs/content/administration/cmd-embedded.zh-cn.md @@ -37,7 +37,7 @@ gitea embedded list [--include-vendored] [patterns...] - 列出所有模板文件,无论在哪个虚拟目录下:`**.tmpl` - 列出所有邮件模板文件:`templates/mail/**.tmpl` -- 列出 `public/img` 目录下的所有文件:`public/img/**` +列出 `public/assets/img` 目录下的所有文件:`public/assets/img/**` 不要忘记为模式使用引号,因为空格、`*` 和其他字符可能对命令行解释器有特殊含义。 @@ -49,8 +49,8 @@ gitea embedded list [--include-vendored] [patterns...] ```sh $ gitea embedded list '**openid**' -public/img/auth/openid_connect.svg -public/img/openid-16x16.png +public/assets/img/auth/openid_connect.svg +public/assets/img/openid-16x16.png templates/user/auth/finalize_openid.tmpl templates/user/auth/signin_openid.tmpl templates/user/auth/signup_openid_connect.tmpl diff --git a/docs/content/contributing/guidelines-frontend.en-us.md b/docs/content/contributing/guidelines-frontend.en-us.md index 2637780718..b19101dd47 100644 --- a/docs/content/contributing/guidelines-frontend.en-us.md +++ b/docs/content/contributing/guidelines-frontend.en-us.md @@ -47,7 +47,7 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h 9. Avoid unnecessary `!important` in CSS, add comments to explain why it's necessary if it can't be avoided. 10. Avoid mixing different events in one event listener, prefer to use individual event listeners for every event. 11. Custom event names are recommended to use `ce-` prefix. -12. Prefer using Tailwind CSS which is available via `tw-` prefix, e.g. `tw-relative`. Gitea's helper CSS classes use `gt-` prefix (`gt-df`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`). +12. Prefer using Tailwind CSS which is available via `tw-` prefix, e.g. `tw-relative`. Gitea's helper CSS classes use `gt-` prefix (`gt-mono`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`). 13. Avoid inline scripts & styles as much as possible, it's recommended to put JS code into JS files and use CSS classes. If inline scripts & styles are unavoidable, explain the reason why it can't be avoided. ### Accessibility / ARIA diff --git a/docs/content/contributing/guidelines-frontend.zh-cn.md b/docs/content/contributing/guidelines-frontend.zh-cn.md index ace0d97f49..961a331ac2 100644 --- a/docs/content/contributing/guidelines-frontend.zh-cn.md +++ b/docs/content/contributing/guidelines-frontend.zh-cn.md @@ -47,7 +47,7 @@ HTML 页面由[Go HTML Template](https://pkg.go.dev/html/template)渲染。 9. 避免在 CSS 中使用不必要的`!important`,如果无法避免,添加注释解释为什么需要它。 10. 避免在一个事件监听器中混合不同的事件,优先为每个事件使用独立的事件监听器。 11. 推荐使用自定义事件名称前缀`ce-`。 -12. 建议使用 Tailwind CSS,它可以通过 `tw-` 前缀获得,例如 `tw-relative`. Gitea 自身的助手类 CSS 使用 `gt-` 前缀(`gt-df`),Gitea 自身的私有框架级 CSS 类使用 `g-` 前缀(`g-modal-confirm`)。 +12. 建议使用 Tailwind CSS,它可以通过 `tw-` 前缀获得,例如 `tw-relative`. Gitea 自身的助手类 CSS 使用 `gt-` 前缀(`gt-mono`),Gitea 自身的私有框架级 CSS 类使用 `g-` 前缀(`g-modal-confirm`)。 13. 尽量避免内联脚本和样式,建议将JS代码放入JS文件中并使用CSS类。如果内联脚本和样式不可避免,请解释无法避免的原因。 ### 可访问性 / ARIA diff --git a/docs/content/development/hacking-on-gitea.en-us.md b/docs/content/development/hacking-on-gitea.en-us.md index 982dbcf6ea..004e803827 100644 --- a/docs/content/development/hacking-on-gitea.en-us.md +++ b/docs/content/development/hacking-on-gitea.en-us.md @@ -214,7 +214,7 @@ REPO_INDEXER_CONN_STR = http://elastic:changeme@localhost:9200 ### Building and adding SVGs -SVG icons are built using the `make svg` target which compiles the icon sources defined in `build/generate-svg.js` into the output directory `public/assets/img/svg`. Custom icons can be added in the `web_src/svg` directory. +SVG icons are built using the `make svg` target which compiles the icon sources into the output directory `public/assets/img/svg`. Custom icons can be added in the `web_src/svg` directory. ### Building the Logo diff --git a/docs/content/development/hacking-on-gitea.zh-cn.md b/docs/content/development/hacking-on-gitea.zh-cn.md index a31e1dc511..7dfea30538 100644 --- a/docs/content/development/hacking-on-gitea.zh-cn.md +++ b/docs/content/development/hacking-on-gitea.zh-cn.md @@ -201,7 +201,7 @@ REPO_INDEXER_CONN_STR = http://elastic:changeme@localhost:9200 ### 构建和添加 SVGs -SVG 图标是使用 `make svg` 目标构建的,该目标将 `build/generate-svg.js` 中定义的图标源编译到输出目录 `public/img/svg` 中。可以在 `web_src/svg` 目录中添加自定义图标。 +SVG 图标是使用 `make svg` 命令构建的,该命令将图标资源编译到输出目录 `public/assets/img/svg` 中。可以在 `web_src/svg` 目录中添加自定义图标。 ### 构建 Logo diff --git a/models/activities/notification.go b/models/activities/notification.go index 4ca9f80270..211e84f418 100644 --- a/models/activities/notification.go +++ b/models/activities/notification.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) @@ -841,3 +842,31 @@ func UpdateNotificationStatuses(ctx context.Context, user *user_model.User, curr Update(n) return err } + +// LoadIssuePullRequests loads all issues' pull requests if possible +func (nl NotificationList) LoadIssuePullRequests(ctx context.Context) error { + issues := make(map[int64]*issues_model.Issue, len(nl)) + for _, notification := range nl { + if notification.Issue != nil && notification.Issue.IsPull && notification.Issue.PullRequest == nil { + issues[notification.Issue.ID] = notification.Issue + } + } + + if len(issues) == 0 { + return nil + } + + pulls, err := issues_model.GetPullRequestByIssueIDs(ctx, util.KeysOfMap(issues)) + if err != nil { + return err + } + + for _, pull := range pulls { + if issue := issues[pull.IssueID]; issue != nil { + issue.PullRequest = pull + issue.PullRequest.Issue = issue + } + } + + return nil +} diff --git a/models/asymkey/ssh_key_authorized_keys.go b/models/asymkey/ssh_key_authorized_keys.go index 2b15450c98..d3f9f3f3be 100644 --- a/models/asymkey/ssh_key_authorized_keys.go +++ b/models/asymkey/ssh_key_authorized_keys.go @@ -198,6 +198,8 @@ func RegeneratePublicKeys(ctx context.Context, t io.StringWriter) error { if err != nil { return err } + defer f.Close() + scanner := bufio.NewScanner(f) for scanner.Scan() { line := scanner.Text() @@ -207,11 +209,12 @@ func RegeneratePublicKeys(ctx context.Context, t io.StringWriter) error { } _, err = t.WriteString(line + "\n") if err != nil { - f.Close() return err } } - f.Close() + if err = scanner.Err(); err != nil { + return fmt.Errorf("RegeneratePublicKeys scan: %w", err) + } } return nil } diff --git a/models/asymkey/ssh_key_authorized_principals.go b/models/asymkey/ssh_key_authorized_principals.go index f3017c3089..f85de12aae 100644 --- a/models/asymkey/ssh_key_authorized_principals.go +++ b/models/asymkey/ssh_key_authorized_principals.go @@ -120,6 +120,8 @@ func regeneratePrincipalKeys(ctx context.Context, t io.StringWriter) error { if err != nil { return err } + defer f.Close() + scanner := bufio.NewScanner(f) for scanner.Scan() { line := scanner.Text() @@ -129,11 +131,12 @@ func regeneratePrincipalKeys(ctx context.Context, t io.StringWriter) error { } _, err = t.WriteString(line + "\n") if err != nil { - f.Close() return err } } - f.Close() + if err = scanner.Err(); err != nil { + return fmt.Errorf("regeneratePrincipalKeys scan: %w", err) + } } return nil } diff --git a/models/avatars/avatar.go b/models/avatars/avatar.go index bbe16483bf..9c56e0f9a0 100644 --- a/models/avatars/avatar.go +++ b/models/avatars/avatar.go @@ -24,7 +24,7 @@ import ( const ( // DefaultAvatarClass is the default class of a rendered avatar - DefaultAvatarClass = "ui avatar gt-vm" + DefaultAvatarClass = "ui avatar tw-align-middle" // DefaultAvatarPixelSize is the default size in pixels of a rendered avatar DefaultAvatarPixelSize = 28 ) diff --git a/models/issues/issue.go b/models/issues/issue.go index 54ef5cec7a..11256f788a 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -194,20 +194,6 @@ func (issue *Issue) IsTimetrackerEnabled(ctx context.Context) bool { return issue.Repo.IsTimetrackerEnabled(ctx) } -// GetPullRequest returns the issue pull request -func (issue *Issue) GetPullRequest(ctx context.Context) (pr *PullRequest, err error) { - if !issue.IsPull { - return nil, fmt.Errorf("Issue is not a pull request") - } - - pr, err = GetPullRequestByIssueID(ctx, issue.ID) - if err != nil { - return nil, err - } - pr.Issue = issue - return pr, err -} - // LoadPoster loads poster func (issue *Issue) LoadPoster(ctx context.Context) (err error) { if issue.Poster == nil && issue.PosterID != 0 { diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go index 0fb8447ff7..9ccb93bf42 100644 --- a/models/issues/issue_list.go +++ b/models/issues/issue_list.go @@ -370,6 +370,9 @@ func (issues IssueList) LoadPullRequests(ctx context.Context) error { for _, issue := range issues { issue.PullRequest = pullRequestMaps[issue.ID] + if issue.PullRequest != nil { + issue.PullRequest.Issue = issue + } } return nil } diff --git a/models/issues/pull_list.go b/models/issues/pull_list.go index d539ed5403..084f7d6242 100644 --- a/models/issues/pull_list.go +++ b/models/issues/pull_list.go @@ -11,7 +11,6 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" @@ -23,7 +22,7 @@ type PullRequestsOptions struct { db.ListOptions State string SortType string - Labels []string + Labels []int64 MilestoneID int64 } @@ -36,11 +35,9 @@ func listPullRequestStatement(ctx context.Context, baseRepoID int64, opts *PullR sess.And("issue.is_closed=?", opts.State == "closed") } - if labelIDs, err := base.StringsToInt64s(opts.Labels); err != nil { - return nil, err - } else if len(labelIDs) > 0 { + if len(opts.Labels) > 0 { sess.Join("INNER", "issue_label", "issue.id = issue_label.issue_id"). - In("issue_label.label_id", labelIDs) + In("issue_label.label_id", opts.Labels) } if opts.MilestoneID > 0 { @@ -220,3 +217,12 @@ func HasMergedPullRequestInRepo(ctx context.Context, repoID, posterID int64) (bo Limit(1). Get(new(Issue)) } + +// GetPullRequestByIssueIDs returns all pull requests by issue ids +func GetPullRequestByIssueIDs(ctx context.Context, issueIDs []int64) (PullRequestList, error) { + prs := make([]*PullRequest, 0, len(issueIDs)) + return prs, db.GetEngine(ctx). + Where("issue_id > 0"). + In("issue_id", issueIDs). + Find(&prs) +} diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index 213838abec..1a43d8994e 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -67,7 +67,6 @@ func TestPullRequestsNewest(t *testing.T) { }, State: "open", SortType: "newest", - Labels: []string{}, }) assert.NoError(t, err) assert.EqualValues(t, 3, count) @@ -114,7 +113,6 @@ func TestPullRequestsOldest(t *testing.T) { }, State: "open", SortType: "oldest", - Labels: []string{}, }) assert.NoError(t, err) assert.EqualValues(t, 3, count) diff --git a/models/issues/review.go b/models/issues/review.go index fc110630e0..70aba0f94d 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -239,11 +239,11 @@ type CreateReviewOptions struct { // IsOfficialReviewer check if at least one of the provided reviewers can make official reviews in issue (counts towards required approvals) func IsOfficialReviewer(ctx context.Context, issue *Issue, reviewer *user_model.User) (bool, error) { - pr, err := GetPullRequestByIssueID(ctx, issue.ID) - if err != nil { + if err := issue.LoadPullRequest(ctx); err != nil { return false, err } + pr := issue.PullRequest rule, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch) if err != nil { return false, err @@ -271,11 +271,10 @@ func IsOfficialReviewer(ctx context.Context, issue *Issue, reviewer *user_model. // IsOfficialReviewerTeam check if reviewer in this team can make official reviews in issue (counts towards required approvals) func IsOfficialReviewerTeam(ctx context.Context, issue *Issue, team *organization.Team) (bool, error) { - pr, err := GetPullRequestByIssueID(ctx, issue.ID) - if err != nil { + if err := issue.LoadPullRequest(ctx); err != nil { return false, err } - pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch) + pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, issue.PullRequest.BaseRepoID, issue.PullRequest.BaseBranch) if err != nil { return false, err } diff --git a/models/organization/org.go b/models/organization/org.go index b4919defb4..47230bdc36 100644 --- a/models/organization/org.go +++ b/models/organization/org.go @@ -319,8 +319,9 @@ func CreateOrganization(ctx context.Context, org *Organization, owner *user_mode // Add initial creator to organization and owner team. if err = db.Insert(ctx, &OrgUser{ - UID: owner.ID, - OrgID: org.ID, + UID: owner.ID, + OrgID: org.ID, + IsPublic: setting.Service.DefaultOrgMemberVisible, }); err != nil { return fmt.Errorf("insert org-user relation: %w", err) } diff --git a/models/user/email_address.go b/models/user/email_address.go index f2ee5e61b2..45bcc54aa3 100644 --- a/models/user/email_address.go +++ b/models/user/email_address.go @@ -443,7 +443,7 @@ func SearchEmails(ctx context.Context, opts *SearchEmailOptions) ([]*SearchEmail cond = cond.And(builder.Eq{"email_address.is_activated": opts.IsActivated.Value()}) } - count, err := db.GetEngine(ctx).Join("INNER", "`user`", "`user`.ID = email_address.uid"). + count, err := db.GetEngine(ctx).Join("INNER", "`user`", "`user`.id = email_address.uid"). Where(cond).Count(new(EmailAddress)) if err != nil { return nil, 0, fmt.Errorf("Count: %w", err) @@ -459,7 +459,7 @@ func SearchEmails(ctx context.Context, opts *SearchEmailOptions) ([]*SearchEmail emails := make([]*SearchEmailResult, 0, opts.PageSize) err = db.GetEngine(ctx).Table("email_address"). Select("email_address.*, `user`.name, `user`.full_name"). - Join("INNER", "`user`", "`user`.ID = email_address.uid"). + Join("INNER", "`user`", "`user`.id = email_address.uid"). Where(cond). OrderBy(orderby). Limit(opts.PageSize, (opts.Page-1)*opts.PageSize). diff --git a/modules/actions/log.go b/modules/actions/log.go index cdf18646aa..c38082b5dc 100644 --- a/modules/actions/log.go +++ b/modules/actions/log.go @@ -100,7 +100,7 @@ func ReadLogs(ctx context.Context, inStorage bool, filename string, offset, limi } if err := scanner.Err(); err != nil { - return nil, fmt.Errorf("scan: %w", err) + return nil, fmt.Errorf("ReadLogs scan: %w", err) } return rows, nil diff --git a/modules/actions/task_state.go b/modules/actions/task_state.go index fe925bbb5d..31a74be3fd 100644 --- a/modules/actions/task_state.go +++ b/modules/actions/task_state.go @@ -41,6 +41,12 @@ func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep { } logIndex += preStep.LogLength + // lastHasRunStep is the last step that has run. + // For example, + // 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): lastHasRunStep is step1. + // 2. preStep(Success) -> step1(Success) -> step2(Success) -> step3(Success) -> postStep(Success): lastHasRunStep is step3. + // 3. preStep(Success) -> step1(Success) -> step2(Failure) -> step3 -> postStep(Waiting): lastHasRunStep is step2. + // So its Stopped is the Started of postStep when there are no more steps to run. var lastHasRunStep *actions_model.ActionTaskStep for _, step := range task.Steps { if step.Status.HasRun() { @@ -56,11 +62,15 @@ func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep { Name: postStepName, Status: actions_model.StatusWaiting, } - if task.Status.IsDone() { + // If the lastHasRunStep is the last step, or it has failed, postStep has started. + if lastHasRunStep.Status.IsFailure() || lastHasRunStep == task.Steps[len(task.Steps)-1] { postStep.LogIndex = logIndex postStep.LogLength = task.LogLength - postStep.LogIndex - postStep.Status = task.Status postStep.Started = lastHasRunStep.Stopped + postStep.Status = actions_model.StatusRunning + } + if task.Status.IsDone() { + postStep.Status = task.Status postStep.Stopped = task.Stopped } ret := make([]*actions_model.ActionTaskStep, 0, len(task.Steps)+2) diff --git a/modules/actions/task_state_test.go b/modules/actions/task_state_test.go index 3a599fbcbd..28213d781b 100644 --- a/modules/actions/task_state_test.go +++ b/modules/actions/task_state_test.go @@ -103,6 +103,40 @@ func TestFullSteps(t *testing.T) { {Name: postStepName, Status: actions_model.StatusSuccess, LogIndex: 100, LogLength: 0, Started: 10100, Stopped: 10100}, }, }, + { + name: "all steps finished but task is running", + task: &actions_model.ActionTask{ + Steps: []*actions_model.ActionTaskStep{ + {Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090}, + }, + Status: actions_model.StatusRunning, + Started: 10000, + Stopped: 0, + LogLength: 100, + }, + want: []*actions_model.ActionTaskStep{ + {Name: preStepName, Status: actions_model.StatusSuccess, LogIndex: 0, LogLength: 10, Started: 10000, Stopped: 10010}, + {Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090}, + {Name: postStepName, Status: actions_model.StatusRunning, LogIndex: 90, LogLength: 10, Started: 10090, Stopped: 0}, + }, + }, + { + name: "skipped task", + task: &actions_model.ActionTask{ + Steps: []*actions_model.ActionTaskStep{ + {Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0}, + }, + Status: actions_model.StatusSkipped, + Started: 0, + Stopped: 0, + LogLength: 0, + }, + want: []*actions_model.ActionTaskStep{ + {Name: preStepName, Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0}, + {Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0}, + {Name: postStepName, Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0}, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/modules/base/tool.go b/modules/base/tool.go index 231507546d..e4c3fb1818 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -150,13 +150,16 @@ func TruncateString(str string, limit int) string { // StringsToInt64s converts a slice of string to a slice of int64. func StringsToInt64s(strs []string) ([]int64, error) { - ints := make([]int64, len(strs)) - for i := range strs { - n, err := strconv.ParseInt(strs[i], 10, 64) + if strs == nil { + return nil, nil + } + ints := make([]int64, 0, len(strs)) + for _, s := range strs { + n, err := strconv.ParseInt(s, 10, 64) if err != nil { - return ints, err + return nil, err } - ints[i] = n + ints = append(ints, n) } return ints, nil } diff --git a/modules/base/tool_test.go b/modules/base/tool_test.go index d28deb593d..f21b89c74c 100644 --- a/modules/base/tool_test.go +++ b/modules/base/tool_test.go @@ -138,12 +138,13 @@ func TestStringsToInt64s(t *testing.T) { assert.NoError(t, err) assert.Equal(t, expected, result) } + testSuccess(nil, nil) testSuccess([]string{}, []int64{}) testSuccess([]string{"-1234"}, []int64{-1234}) - testSuccess([]string{"1", "4", "16", "64", "256"}, - []int64{1, 4, 16, 64, 256}) + testSuccess([]string{"1", "4", "16", "64", "256"}, []int64{1, 4, 16, 64, 256}) - _, err := StringsToInt64s([]string{"-1", "a", "$"}) + ints, err := StringsToInt64s([]string{"-1", "a"}) + assert.Len(t, ints, 0) assert.Error(t, err) } diff --git a/modules/git/commit.go b/modules/git/commit.go index c30f1e35e5..00681e3b2f 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -9,6 +9,7 @@ import ( "bytes" "context" "errors" + "fmt" "io" "os/exec" "strconv" @@ -390,6 +391,9 @@ func (c *Commit) GetSubModules() (*ObjectCache, error) { } } } + if err = scanner.Err(); err != nil { + return nil, fmt.Errorf("GetSubModules scan: %w", err) + } return c.submoduleCache, nil } diff --git a/modules/git/repo.go b/modules/git/repo.go index 60078f3273..e8a7016d99 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -283,7 +283,7 @@ type DivergeObject struct { // GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch func GetDivergingCommits(ctx context.Context, repoPath, baseBranch, targetBranch string) (do DivergeObject, err error) { cmd := NewCommand(ctx, "rev-list", "--count", "--left-right"). - AddDynamicArguments(baseBranch + "..." + targetBranch) + AddDynamicArguments(baseBranch + "..." + targetBranch).AddArguments("--") stdout, _, err := cmd.RunStdString(&RunOpts{Dir: repoPath}) if err != nil { return do, err diff --git a/modules/git/repo_stats.go b/modules/git/repo_stats.go index 41f94e24f9..83220104bd 100644 --- a/modules/git/repo_stats.go +++ b/modules/git/repo_stats.go @@ -124,6 +124,10 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string) } } } + if err = scanner.Err(); err != nil { + _ = stdoutReader.Close() + return fmt.Errorf("GetCodeActivityStats scan: %w", err) + } a := make([]*CodeActivityAuthor, 0, len(authors)) for _, v := range authors { a = append(a, v) diff --git a/modules/graceful/manager_unix.go b/modules/graceful/manager_unix.go index f49c42650c..d03fff9b5b 100644 --- a/modules/graceful/manager_unix.go +++ b/modules/graceful/manager_unix.go @@ -59,8 +59,8 @@ func (g *Manager) start() { go func() { defer func() { close(startupDone) - // Close the unused listeners and ignore the error here there's not much we can do with it, they're logged in the CloseProvidedListeners function - _ = CloseProvidedListeners() + // Close the unused listeners + closeProvidedListeners() }() // Wait for all servers to be created g.createServerCond.L.Lock() diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go index 4f8c036a69..796e00507c 100644 --- a/modules/graceful/net_unix.go +++ b/modules/graceful/net_unix.go @@ -129,25 +129,17 @@ func getProvidedFDs() (savedErr error) { return savedErr } -// CloseProvidedListeners closes all unused provided listeners. -func CloseProvidedListeners() error { +// closeProvidedListeners closes all unused provided listeners. +func closeProvidedListeners() { mutex.Lock() defer mutex.Unlock() - var returnableError error for _, l := range providedListeners { err := l.Close() if err != nil { log.Error("Error in closing unused provided listener: %v", err) - if returnableError != nil { - returnableError = fmt.Errorf("%v & %w", returnableError, err) - } else { - returnableError = err - } } } providedListeners = []net.Listener{} - - return returnableError } // DefaultGetListener obtains a listener for the stream-oriented local network address: diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go index d7f735e957..c607d780ef 100644 --- a/modules/indexer/code/bleve/bleve.go +++ b/modules/indexer/code/bleve/bleve.go @@ -39,6 +39,8 @@ import ( const ( unicodeNormalizeName = "unicodeNormalize" maxBatchSize = 16 + // fuzzyDenominator determines the levenshtein distance per each character of a keyword + fuzzyDenominator = 4 ) func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error { @@ -239,15 +241,12 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int keywordQuery query.Query ) + phraseQuery := bleve.NewMatchPhraseQuery(opts.Keyword) + phraseQuery.FieldVal = "Content" + phraseQuery.Analyzer = repoIndexerAnalyzer + keywordQuery = phraseQuery if opts.IsKeywordFuzzy { - phraseQuery := bleve.NewMatchPhraseQuery(opts.Keyword) - phraseQuery.FieldVal = "Content" - phraseQuery.Analyzer = repoIndexerAnalyzer - keywordQuery = phraseQuery - } else { - prefixQuery := bleve.NewPrefixQuery(opts.Keyword) - prefixQuery.FieldVal = "Content" - keywordQuery = prefixQuery + phraseQuery.Fuzziness = len(opts.Keyword) / fuzzyDenominator } if len(opts.RepoIDs) > 0 { diff --git a/modules/indexer/internal/bleve/query.go b/modules/indexer/internal/bleve/query.go index b96875343e..21422b281c 100644 --- a/modules/indexer/internal/bleve/query.go +++ b/modules/indexer/internal/bleve/query.go @@ -20,17 +20,11 @@ func NumericEqualityQuery(value int64, field string) *query.NumericRangeQuery { } // MatchPhraseQuery generates a match phrase query for the given phrase, field and analyzer -func MatchPhraseQuery(matchPhrase, field, analyzer string) *query.MatchPhraseQuery { +func MatchPhraseQuery(matchPhrase, field, analyzer string, fuzziness int) *query.MatchPhraseQuery { q := bleve.NewMatchPhraseQuery(matchPhrase) q.FieldVal = field q.Analyzer = analyzer - return q -} - -// PrefixQuery generates a match prefix query for the given prefix and field -func PrefixQuery(matchPrefix, field string) *query.PrefixQuery { - q := bleve.NewPrefixQuery(matchPrefix) - q.FieldVal = field + q.Fuzziness = fuzziness return q } diff --git a/modules/indexer/issues/bleve/bleve.go b/modules/indexer/issues/bleve/bleve.go index 927ad58cd4..1f54be721b 100644 --- a/modules/indexer/issues/bleve/bleve.go +++ b/modules/indexer/issues/bleve/bleve.go @@ -35,7 +35,11 @@ func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error { }) } -const maxBatchSize = 16 +const ( + maxBatchSize = 16 + // fuzzyDenominator determines the levenshtein distance per each character of a keyword + fuzzyDenominator = 4 +) // IndexerData an update to the issue indexer type IndexerData internal.IndexerData @@ -156,19 +160,16 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) ( var queries []query.Query if options.Keyword != "" { + fuzziness := 0 if options.IsFuzzyKeyword { - queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{ - inner_bleve.MatchPhraseQuery(options.Keyword, "title", issueIndexerAnalyzer), - inner_bleve.MatchPhraseQuery(options.Keyword, "content", issueIndexerAnalyzer), - inner_bleve.MatchPhraseQuery(options.Keyword, "comments", issueIndexerAnalyzer), - }...)) - } else { - queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{ - inner_bleve.PrefixQuery(options.Keyword, "title"), - inner_bleve.PrefixQuery(options.Keyword, "content"), - inner_bleve.PrefixQuery(options.Keyword, "comments"), - }...)) + fuzziness = len(options.Keyword) / fuzzyDenominator } + + queries = append(queries, bleve.NewDisjunctionQuery([]query.Query{ + inner_bleve.MatchPhraseQuery(options.Keyword, "title", issueIndexerAnalyzer, fuzziness), + inner_bleve.MatchPhraseQuery(options.Keyword, "content", issueIndexerAnalyzer, fuzziness), + inner_bleve.MatchPhraseQuery(options.Keyword, "comments", issueIndexerAnalyzer, fuzziness), + }...)) } if len(options.RepoIDs) > 0 || options.AllPublic { diff --git a/modules/indexer/issues/internal/tests/tests.go b/modules/indexer/issues/internal/tests/tests.go index 91aafd589c..2209377c2f 100644 --- a/modules/indexer/issues/internal/tests/tests.go +++ b/modules/indexer/issues/internal/tests/tests.go @@ -515,10 +515,8 @@ var cases = []*testIndexerCase{ { Name: "SortByCreatedDesc", SearchOptions: &internal.SearchOptions{ - Paginator: &db.ListOptions{ - ListAll: true, - }, - SortBy: internal.SortByCreatedDesc, + Paginator: &db.ListOptionsAll, + SortBy: internal.SortByCreatedDesc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Equal(t, len(data), len(result.Hits)) @@ -533,10 +531,8 @@ var cases = []*testIndexerCase{ { Name: "SortByUpdatedDesc", SearchOptions: &internal.SearchOptions{ - Paginator: &db.ListOptions{ - ListAll: true, - }, - SortBy: internal.SortByUpdatedDesc, + Paginator: &db.ListOptionsAll, + SortBy: internal.SortByUpdatedDesc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Equal(t, len(data), len(result.Hits)) @@ -551,10 +547,8 @@ var cases = []*testIndexerCase{ { Name: "SortByCommentsDesc", SearchOptions: &internal.SearchOptions{ - Paginator: &db.ListOptions{ - ListAll: true, - }, - SortBy: internal.SortByCommentsDesc, + Paginator: &db.ListOptionsAll, + SortBy: internal.SortByCommentsDesc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Equal(t, len(data), len(result.Hits)) @@ -569,10 +563,8 @@ var cases = []*testIndexerCase{ { Name: "SortByDeadlineDesc", SearchOptions: &internal.SearchOptions{ - Paginator: &db.ListOptions{ - ListAll: true, - }, - SortBy: internal.SortByDeadlineDesc, + Paginator: &db.ListOptionsAll, + SortBy: internal.SortByDeadlineDesc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Equal(t, len(data), len(result.Hits)) @@ -587,10 +579,8 @@ var cases = []*testIndexerCase{ { Name: "SortByCreatedAsc", SearchOptions: &internal.SearchOptions{ - Paginator: &db.ListOptions{ - ListAll: true, - }, - SortBy: internal.SortByCreatedAsc, + Paginator: &db.ListOptionsAll, + SortBy: internal.SortByCreatedAsc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Equal(t, len(data), len(result.Hits)) @@ -605,10 +595,8 @@ var cases = []*testIndexerCase{ { Name: "SortByUpdatedAsc", SearchOptions: &internal.SearchOptions{ - Paginator: &db.ListOptions{ - ListAll: true, - }, - SortBy: internal.SortByUpdatedAsc, + Paginator: &db.ListOptionsAll, + SortBy: internal.SortByUpdatedAsc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Equal(t, len(data), len(result.Hits)) @@ -623,10 +611,8 @@ var cases = []*testIndexerCase{ { Name: "SortByCommentsAsc", SearchOptions: &internal.SearchOptions{ - Paginator: &db.ListOptions{ - ListAll: true, - }, - SortBy: internal.SortByCommentsAsc, + Paginator: &db.ListOptionsAll, + SortBy: internal.SortByCommentsAsc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Equal(t, len(data), len(result.Hits)) @@ -641,10 +627,8 @@ var cases = []*testIndexerCase{ { Name: "SortByDeadlineAsc", SearchOptions: &internal.SearchOptions{ - Paginator: &db.ListOptions{ - ListAll: true, - }, - SortBy: internal.SortByDeadlineAsc, + Paginator: &db.ListOptionsAll, + SortBy: internal.SortByDeadlineAsc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { assert.Equal(t, len(data), len(result.Hits)) diff --git a/modules/indexer/issues/util.go b/modules/indexer/issues/util.go index 510b4060b2..9861c808dc 100644 --- a/modules/indexer/issues/util.go +++ b/modules/indexer/issues/util.go @@ -61,9 +61,7 @@ func getIssueIndexerData(ctx context.Context, issueID int64) (*internal.IndexerD ) { reviews, err := issue_model.FindReviews(ctx, issue_model.FindReviewOptions{ - ListOptions: db.ListOptions{ - ListAll: true, - }, + ListOptions: db.ListOptionsAll, IssueID: issueID, OfficialOnly: false, }) diff --git a/modules/markup/csv/csv.go b/modules/markup/csv/csv.go index 570c4f4704..1dd26eb8ac 100644 --- a/modules/markup/csv/csv.go +++ b/modules/markup/csv/csv.go @@ -6,6 +6,7 @@ package markup import ( "bufio" "bytes" + "fmt" "html" "io" "regexp" @@ -123,6 +124,9 @@ func (Renderer) fallbackRender(input io.Reader, tmpBlock *bufio.Writer) error { return err } } + if err = scan.Err(); err != nil { + return fmt.Errorf("fallbackRender scan: %w", err) + } _, err = tmpBlock.WriteString("") if err != nil { diff --git a/modules/util/slice.go b/modules/util/slice.go index f00e84bf06..9c878c24be 100644 --- a/modules/util/slice.go +++ b/modules/util/slice.go @@ -54,7 +54,7 @@ func Sorted[S ~[]E, E cmp.Ordered](values S) S { return values } -// TODO: Replace with "maps.Values" once available +// TODO: Replace with "maps.Values" once available, current it only in golang.org/x/exp/maps but not in standard library func ValuesOfMap[K comparable, V any](m map[K]V) []V { values := make([]V, 0, len(m)) for _, v := range m { @@ -62,3 +62,12 @@ func ValuesOfMap[K comparable, V any](m map[K]V) []V { } return values } + +// TODO: Replace with "maps.Keys" once available, current it only in golang.org/x/exp/maps but not in standard library +func KeysOfMap[K comparable, V any](m map[K]V) []K { + keys := make([]K, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + return keys +} diff --git a/options/license/threeparttable b/options/license/threeparttable new file mode 100644 index 0000000000..498b728226 --- /dev/null +++ b/options/license/threeparttable @@ -0,0 +1,3 @@ +This file may be distributed, modified, and used in other works with just +one restriction: modified versions must clearly indicate the modification +(a name change, or a displayed message, or ?). diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 620c469bdd..e93be52214 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -115,6 +115,7 @@ loading = Loading… error = Error error404 = The page you are trying to reach either does not exist or you are not authorized to view it. go_back = Go Back +invalid_data = Invalid data: %v never = Never unknown = Unknown @@ -1333,6 +1334,8 @@ editor.file_editing_no_longer_exists = The file being edited, "%s", no longer ex editor.file_deleting_no_longer_exists = The file being deleted, "%s", no longer exists in this repository. editor.file_changed_while_editing = The file contents have changed since you started editing. Click here to see them or Commit Changes again to overwrite them. editor.file_already_exists = A file named "%s" already exists in this repository. +editor.commit_id_not_matching = The Commit ID does not match the ID when you began editing. Commit into a patch branch and then merge. +editor.push_out_of_date = The push appears to be out of date. editor.commit_empty_file_header = Commit an empty file editor.commit_empty_file_text = The file you're about to commit is empty. Proceed? editor.no_changes_to_show = There are no changes to show. @@ -3133,7 +3136,7 @@ auths.tip.nextcloud = Register a new OAuth consumer on your instance using the f auths.tip.dropbox = Create a new application at https://www.dropbox.com/developers/apps auths.tip.facebook = Register a new application at https://developers.facebook.com/apps and add the product "Facebook Login" auths.tip.github = Register a new OAuth application on https://github.com/settings/applications/new -auths.tip.gitlab = Register a new application on https://gitlab.com/profile/applications +auths.tip.gitlab_new = Register a new application on https://gitlab.com/-/profile/applications auths.tip.google_plus = Obtain OAuth2 client credentials from the Google API console at https://console.developers.google.com/ auths.tip.openid_connect = Use the OpenID Connect Discovery URL (/.well-known/openid-configuration) to specify the endpoints auths.tip.twitter = Go to https://dev.twitter.com/apps, create an application and ensure that the “Allow this application to be used to Sign in with Twitter” option is enabled @@ -3671,6 +3674,7 @@ runs.pushed_by = pushed by runs.workflow = Workflow runs.invalid_workflow_helper = Workflow config file is invalid. Please check your config file: %s runs.no_matching_online_runner_helper = No matching online runner with label: %s +runs.no_job_without_needs = The workflow must contain at least one job without dependencies. runs.actor = Actor runs.status = Status runs.actors_no_select = All actors diff --git a/package-lock.json b/package-lock.json index b87b1d5920..f6df16f2a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -85,7 +85,7 @@ "eslint-plugin-vue": "9.23.0", "eslint-plugin-vue-scoped-css": "2.7.2", "eslint-plugin-wc": "2.0.4", - "jsdom": "24.0.0", + "happy-dom": "14.2.0", "markdownlint-cli": "0.39.0", "postcss-html": "1.6.0", "stylelint": "16.2.1", @@ -130,81 +130,17 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", @@ -214,13 +150,14 @@ } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -296,9 +233,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", - "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", + "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -307,9 +244,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", - "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz", + "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2204,9 +2141,9 @@ } }, "node_modules/@types/eslint": { - "version": "8.56.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz", - "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==", + "version": "8.56.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.6.tgz", + "integrity": "sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -2256,9 +2193,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.11.27", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.27.tgz", - "integrity": "sha512-qyUZfMnCg1KEz57r7pzFtSGt49f6RPkPBis3Vo4PbS7roQEDn22hiHzl/Lo1q4i4hDEgBJmBF/NTNg2XR0HbFg==", + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", "dependencies": { "undici-types": "~5.26.4" } @@ -2301,16 +2238,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.2.0.tgz", - "integrity": "sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.3.1.tgz", + "integrity": "sha512-STEDMVQGww5lhCuNXVSQfbfuNII5E08QWkvAw5Qwf+bj2WT+JkG1uc+5/vXA3AOYMDHVOSpL+9rcbEUiHIm2dw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/type-utils": "7.2.0", - "@typescript-eslint/utils": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/scope-manager": "7.3.1", + "@typescript-eslint/type-utils": "7.3.1", + "@typescript-eslint/utils": "7.3.1", + "@typescript-eslint/visitor-keys": "7.3.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2319,7 +2256,7 @@ "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2336,19 +2273,19 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", - "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.3.1.tgz", + "integrity": "sha512-Rq49+pq7viTRCH48XAbTA+wdLRrB/3sRq4Lpk0oGDm0VmnjBrAOVXH/Laalmwsv2VpekiEfVFwJYVk6/e8uvQw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/scope-manager": "7.3.1", + "@typescript-eslint/types": "7.3.1", + "@typescript-eslint/typescript-estree": "7.3.1", + "@typescript-eslint/visitor-keys": "7.3.1", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2364,16 +2301,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.3.1.tgz", + "integrity": "sha512-fVS6fPxldsKY2nFvyT7IP78UO1/I2huG+AYu5AMjCT9wtl6JFiDnsv4uad4jQ0GTFzcUV5HShVeN96/17bTBag==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0" + "@typescript-eslint/types": "7.3.1", + "@typescript-eslint/visitor-keys": "7.3.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2381,18 +2318,18 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz", - "integrity": "sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.3.1.tgz", + "integrity": "sha512-iFhaysxFsMDQlzJn+vr3OrxN8NmdQkHks4WaqD4QBnt5hsq234wcYdyQ9uquzJJIDAj5W4wQne3yEsYA6OmXGw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.2.0", - "@typescript-eslint/utils": "7.2.0", + "@typescript-eslint/typescript-estree": "7.3.1", + "@typescript-eslint/utils": "7.3.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2408,12 +2345,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.3.1.tgz", + "integrity": "sha512-2tUf3uWggBDl4S4183nivWQ2HqceOZh1U4hhu4p1tPiIJoRRXrab7Y+Y0p+dozYwZVvLPRI6r5wKe9kToF9FIw==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2421,13 +2358,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.3.1.tgz", + "integrity": "sha512-tLpuqM46LVkduWP7JO7yVoWshpJuJzxDOPYIVWUUZbW+4dBpgGeUdl/fQkhuV0A8eGnphYw3pp8d2EnvPOfxmQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/types": "7.3.1", + "@typescript-eslint/visitor-keys": "7.3.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2436,7 +2373,7 @@ "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2449,21 +2386,21 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.2.0.tgz", - "integrity": "sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.3.1.tgz", + "integrity": "sha512-jIERm/6bYQ9HkynYlNZvXpzmXWZGhMbrOvq3jJzOSOlKXsVjrrolzWBjDW6/TvT5Q3WqaN4EkmcfdQwi9tDjBQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", + "@typescript-eslint/scope-manager": "7.3.1", + "@typescript-eslint/types": "7.3.1", + "@typescript-eslint/typescript-estree": "7.3.1", "semver": "^7.5.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2474,16 +2411,16 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.3.1.tgz", + "integrity": "sha512-9RMXwQF8knsZvfv9tdi+4D/j7dMG28X/wMJ8Jj6eOHyHWwDW4ngQJcqEczSsqIKKjFiLFr40Mnr7a5ulDD3vmw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/types": "7.3.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2978,18 +2915,6 @@ "webpack": ">=5" } }, - "node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", @@ -3146,15 +3071,16 @@ } }, "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -3173,35 +3099,17 @@ "node": ">=8" } }, - "node_modules/array.prototype.filter": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", - "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array.prototype.findlastindex": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", - "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", + "es-abstract": "^1.23.2", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "es-shim-unscopables": "^1.0.2" }, "engines": { @@ -3332,21 +3240,6 @@ "astring": "bin/astring" } }, - "node_modules/asynciterator.prototype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", - "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, "node_modules/atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -3582,9 +3475,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001597", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz", - "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==", + "version": "1.0.30001599", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz", + "integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==", "funding": [ { "type": "opencollective", @@ -3868,18 +3761,6 @@ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", @@ -3909,12 +3790,12 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/core-js-compat": { - "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", - "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "version": "3.36.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", + "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", "dev": true, "dependencies": { - "browserslist": "^4.22.3" + "browserslist": "^4.23.0" }, "funding": { "type": "opencollective", @@ -4106,18 +3987,6 @@ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", "dev": true }, - "node_modules/cssstyle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", - "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", - "dev": true, - "dependencies": { - "rrweb-cssom": "^0.6.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -4580,17 +4449,55 @@ "integrity": "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==", "dev": true }, - "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", "dev": true, "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=18" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/dayjs": { @@ -4614,12 +4521,6 @@ } } }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true - }, "node_modules/decode-named-character-reference": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", @@ -4710,15 +4611,6 @@ "robust-predicates": "^3.0.2" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/dependency-graph": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", @@ -4829,9 +4721,9 @@ } }, "node_modules/dompurify": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.9.tgz", - "integrity": "sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ==" + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.10.tgz", + "integrity": "sha512-WZDL8ZHTliEVP3Lk4phtvjg8SNQ3YMc5WVstxE8cszKZrFjzI4PF4ZTIk9VGAc9vZADO7uGO2V/ZiStcRSAT4Q==" }, "node_modules/domutils": { "version": "3.1.0", @@ -4874,9 +4766,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.706", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.706.tgz", - "integrity": "sha512-fO01fufoGd6jKK3HR8ofBapF3ZPfgxNJ/ua9xQAhFu93TwWIs4d+weDn3kje3GB4S7aGUTfk5nvdU5F7z5mF9Q==" + "version": "1.4.713", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.713.tgz", + "integrity": "sha512-vDarADhwntXiULEdmWd77g2dV6FrNGa8ecAC29MZ4TwPut2fvosD0/5sJd1qWNNe8HcJFAC+F5Lf9jW1NPtWmw==" }, "node_modules/elkjs": { "version": "0.9.2", @@ -4947,17 +4839,21 @@ } }, "node_modules/es-abstract": { - "version": "1.22.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", - "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.2.tgz", + "integrity": "sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", "es-define-property": "^1.0.0", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", @@ -4968,10 +4864,11 @@ "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "hasown": "^2.0.1", + "hasown": "^2.0.2", "internal-slot": "^1.0.7", "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.3", @@ -4982,17 +4879,17 @@ "object-keys": "^1.1.1", "object.assign": "^4.1.5", "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.0", + "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", "string.prototype.trimstart": "^1.0.7", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", "typed-array-byte-offset": "^1.0.2", "typed-array-length": "^1.0.5", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -5023,12 +4920,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -5051,35 +4942,46 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", - "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", + "version": "1.0.18", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.18.tgz", + "integrity": "sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==", "dev": true, "dependencies": { - "asynciterator.prototype": "^1.0.0", "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.4", + "es-abstract": "^1.23.0", "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.0.2", + "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.1", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.7", "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.1.0" + "safe-array-concat": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.2.tgz", + "integrity": "sha512-7nOqkomXZEaxUDJw21XZNtRk739QvrPSoZoRtbsEfcii00vdzZUh6zh1CQwHhrib8MdEtJfv5rJiGeb4KuV/vw==" + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/es-set-tostringtag": { "version": "2.0.3", @@ -6131,25 +6033,6 @@ } } }, - "node_modules/fetch-ponyfill/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/fetch-ponyfill/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/fetch-ponyfill/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -6241,20 +6124,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -6632,6 +6501,20 @@ "node": ">=0.8.0" } }, + "node_modules/happy-dom": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.2.0.tgz", + "integrity": "sha512-vTqF/9MEkRKgYy5eKq9W0uiNmkgnVAmJhRwn8x8fQBR7lc4C84859jLhgZ1lR4Gi/t70oSdgvtLpxlHjgdJrAw==", + "dev": true, + "dependencies": { + "entities": "^4.5.0", + "webidl-conversions": "^7.0.0", + "whatwg-mimetype": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -6736,18 +6619,6 @@ "node": ">=14" } }, - "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^3.1.1" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/html-tags": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", @@ -6784,32 +6655,6 @@ "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-1.9.11.tgz", "integrity": "sha512-WlVuICn8dfNOOgYmdYzYG8zSnP3++AdHkMHooQAzGZObWpVXYathpz/I37ycF4zikR6YduzfCvEcxk20JkIUsw==" }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/human-signals": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", @@ -7101,6 +6946,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -7568,55 +7428,6 @@ "node": ">=12.0.0" } }, - "node_modules/jsdom": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.0.0.tgz", - "integrity": "sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==", - "dev": true, - "dependencies": { - "cssstyle": "^4.0.1", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.2", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.7", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.3", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.16.0", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^2.11.2" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "dev": true, - "engines": { - "node": ">=18" - } - }, "node_modules/jsep": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz", @@ -8956,25 +8767,6 @@ } } }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", @@ -9066,12 +8858,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", - "dev": true - }, "node_modules/obj-props": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz", @@ -9134,28 +8920,29 @@ } }, "node_modules/object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -9165,27 +8952,28 @@ } }, "node_modules/object.groupby": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", - "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, "dependencies": { - "array.prototype.filter": "^1.0.3", - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.0.0" + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -9311,18 +9099,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dev": true, - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -9949,12 +9725,6 @@ "node": ">=4" } }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -9972,12 +9742,6 @@ "node": ">=6" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -10156,16 +9920,16 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", - "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.0.0", - "get-intrinsic": "^1.2.3", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", "globalthis": "^1.0.3", "which-builtin-type": "^1.1.3" }, @@ -10259,12 +10023,6 @@ "node": ">=0.10.0" } }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, "node_modules/reserved": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/reserved/-/reserved-0.1.2.tgz", @@ -10369,12 +10127,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "dev": true - }, "node_modules/run-con": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", @@ -10499,18 +10251,6 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=v12.22.7" - } - }, "node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", @@ -10720,12 +10460,12 @@ } }, "node_modules/solid-js": { - "version": "1.8.15", - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.15.tgz", - "integrity": "sha512-d0QP/efr3UVcwGgWVPveQQ0IHOH6iU7yUhc2piy8arNG8wxKmvUy1kFxyF8owpmfCWGB87usDKMaVnsNYZm+Vw==", + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.16.tgz", + "integrity": "sha512-rja94MNU9flF3qQRLNsu60QHKBDKBkVE1DldJZPIfn2ypIn3NV2WpSbGTQIvsyGPBo+9E2IMjwqnqpbgfWuzeg==", "dependencies": { "csstype": "^3.1.0", - "seroval": "^1.0.3", + "seroval": "^1.0.4", "seroval-plugins": "^1.0.3" } }, @@ -10748,9 +10488,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "engines": { "node": ">=0.10.0" } @@ -10904,14 +10644,15 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -10921,14 +10662,14 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11386,12 +11127,6 @@ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.12.0.tgz", "integrity": "sha512-Rt1xUpbHulJVGbiQjq9yy9/r/0Pg6TmpcG+fXTaMePDc8z5WUw4LfaWts5qcNv/8ewPvBIbY7DKq7qReIKNCCQ==" }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, "node_modules/sync-fetch": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/sync-fetch/-/sync-fetch-0.4.5.tgz", @@ -11724,41 +11459,10 @@ "resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.12.0.tgz", "integrity": "sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ==" }, - "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", - "dev": true, - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/tributejs": { "version": "5.1.3", @@ -11927,9 +11631,9 @@ } }, "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", "devOptional": true, "peer": true, "bin": { @@ -11952,9 +11656,9 @@ "dev": true }, "node_modules/ufo": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz", - "integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", "dev": true }, "node_modules/uint8-to-base64": { @@ -12058,16 +11762,6 @@ "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", "dev": true }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -12131,14 +11825,14 @@ } }, "node_modules/vite": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz", - "integrity": "sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.2.tgz", + "integrity": "sha512-FWZbz0oSdLq5snUI0b6sULbz58iXFXdvkZfZWR/F0ZJuKTSPO7v72QPXt6KqYeMFb0yytNp6kZosxJ96Nr/wDQ==", "dev": true, "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.35", - "rollup": "^4.2.0" + "esbuild": "^0.20.1", + "postcss": "^8.4.36", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" @@ -12213,418 +11907,12 @@ "integrity": "sha512-KRCIFX3PWVUuEjpi9O7EKLT9E27OqOA3RimIvVx6cziLAUxvnk2VvHQfMrP+mKkqyqqSmnnYyTig3OyDnK/zlA==", "dev": true }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/vite/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==", "dev": true }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" - } - }, "node_modules/vite/node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -12639,6 +11927,34 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/vite/node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/vite/node_modules/rollup": { "version": "4.13.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", @@ -12843,27 +12159,6 @@ "vue": "^3.2.29" } }, - "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/w3c-xmlserializer/node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "dev": true, - "engines": { - "node": ">=18" - } - }, "node_modules/watchpack": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", @@ -13088,40 +12383,29 @@ "node": ">=10.13.0" } }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "dev": true, - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", "dev": true, "engines": { - "node": ">=18" + "node": ">=12" } }, "node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", - "dev": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { - "tr46": "^5.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, + "node_modules/whatwg-url/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -13344,27 +12628,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/xml-name-validator": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", @@ -13374,12 +12637,6 @@ "node": ">=12" } }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index b8594e8b3e..77a58dacf5 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "eslint-plugin-vue": "9.23.0", "eslint-plugin-vue-scoped-css": "2.7.2", "eslint-plugin-wc": "2.0.4", - "jsdom": "24.0.0", + "happy-dom": "14.2.0", "markdownlint-cli": "0.39.0", "postcss-html": "1.6.0", "stylelint": "16.2.1", diff --git a/playwright.config.js b/playwright.config.js index 6595bc4312..fdf6514f26 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -27,7 +27,7 @@ export default { * Maximum time expect() should wait for the condition to be met. * For example in `await expect(locator).toHaveText();` */ - timeout: 2000 + timeout: 2000, }, /* Fail the build on CI if you accidentally left test.only in the source code. */ diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 843da55139..2640819a54 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -874,10 +874,11 @@ func EditIssue(ctx *context.APIContext) { } if form.State != nil { if issue.IsPull { - if pr, err := issue.GetPullRequest(ctx); err != nil { + if err := issue.LoadPullRequest(ctx); err != nil { ctx.Error(http.StatusInternalServerError, "GetPullRequest", err) return - } else if pr.HasMerged { + } + if issue.PullRequest.HasMerged { ctx.Error(http.StatusPreconditionFailed, "MergedPRState", "cannot change state of this pull request, it was already merged") return } diff --git a/routers/api/v1/repo/issue_pin.go b/routers/api/v1/repo/issue_pin.go index ff1135862b..8fcf670fd0 100644 --- a/routers/api/v1/repo/issue_pin.go +++ b/routers/api/v1/repo/issue_pin.go @@ -240,18 +240,12 @@ func ListPinnedPullRequests(ctx *context.APIContext) { } apiPrs := make([]*api.PullRequest, len(issues)) + if err := issues.LoadPullRequests(ctx); err != nil { + ctx.Error(http.StatusInternalServerError, "LoadPullRequests", err) + return + } for i, currentIssue := range issues { - pr, err := currentIssue.GetPullRequest(ctx) - if err != nil { - ctx.Error(http.StatusInternalServerError, "GetPullRequest", err) - return - } - - if err = pr.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadIssue", err) - return - } - + pr := currentIssue.PullRequest if err = pr.LoadAttributes(ctx); err != nil { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index c2d86541b6..eec3c49bc4 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -21,6 +21,7 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" @@ -96,13 +97,17 @@ func ListPullRequests(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" + labelIDs, err := base.StringsToInt64s(ctx.FormStrings("labels")) + if err != nil { + ctx.Error(http.StatusInternalServerError, "PullRequests", err) + return + } listOptions := utils.GetListOptions(ctx) - prs, maxResults, err := issues_model.PullRequests(ctx, ctx.Repo.Repository.ID, &issues_model.PullRequestsOptions{ ListOptions: listOptions, State: ctx.FormTrim("state"), SortType: ctx.FormTrim("sort"), - Labels: ctx.FormStrings("labels"), + Labels: labelIDs, MilestoneID: ctx.FormInt64("milestone"), }) if err != nil { diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index f5527cb15b..fff47caa88 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -75,6 +75,10 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { updates = append(updates, option) if repo.IsEmpty && (refFullName.BranchName() == "master" || refFullName.BranchName() == "main") { // put the master/main branch first + // FIXME: It doesn't always work, since the master/main branch may not be the first batch of updates. + // If the user pushes many branches at once, the Git hook will call the internal API in batches, rather than all at once. + // See https://github.com/go-gitea/gitea/blob/cb52b17f92e2d2293f7c003649743464492bca48/cmd/hook.go#L27 + // If the user executes `git push origin --all` and pushes more than 30 branches, the master/main may not be the default branch. copy(updates[1:], updates) updates[0] = option } diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index 6dfcfc3d9a..b93668c5a2 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -275,9 +275,7 @@ func ViewUser(ctx *context.Context) { } repos, count, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{ - ListOptions: db.ListOptions{ - ListAll: true, - }, + ListOptions: db.ListOptionsAll, OwnerID: u.ID, OrderBy: db.SearchOrderByAlphabetically, Private: true, @@ -300,9 +298,7 @@ func ViewUser(ctx *context.Context) { ctx.Data["EmailsTotal"] = len(emails) orgs, err := db.Find[org_model.Organization](ctx, org_model.FindOrgOptions{ - ListOptions: db.ListOptions{ - ListAll: true, - }, + ListOptions: db.ListOptionsAll, UserID: u.ID, IncludePrivate: true, }) diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index f27329aa0f..6059ad1414 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -104,8 +104,13 @@ func List(ctx *context.Context) { workflows = append(workflows, workflow) continue } - // Check whether have matching runner + // The workflow must contain at least one job without "needs". Otherwise, a deadlock will occur and no jobs will be able to run. + hasJobWithoutNeeds := false + // Check whether have matching runner and a job without "needs" for _, j := range wf.Jobs { + if !hasJobWithoutNeeds && len(j.Needs()) == 0 { + hasJobWithoutNeeds = true + } runsOnList := j.RunsOn() for _, ro := range runsOnList { if strings.Contains(ro, "${{") { @@ -123,6 +128,9 @@ func List(ctx *context.Context) { break } } + if !hasJobWithoutNeeds { + workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_job_without_needs") + } workflows = append(workflows, workflow) } } diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 23ce70a153..fa687bbb93 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -353,12 +353,25 @@ func Rerun(ctx *context_module.Context) { return } - if jobIndexStr != "" { - jobs = []*actions_model.ActionRunJob{job} + if jobIndexStr == "" { // rerun all jobs + for _, j := range jobs { + // if the job has needs, it should be set to "blocked" status to wait for other jobs + shouldBlock := len(j.Needs) > 0 + if err := rerunJob(ctx, j, shouldBlock); err != nil { + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + } + ctx.JSON(http.StatusOK, struct{}{}) + return } - for _, j := range jobs { - if err := rerunJob(ctx, j); err != nil { + rerunJobs := actions_service.GetAllRerunJobs(job, jobs) + + for _, j := range rerunJobs { + // jobs other than the specified one should be set to "blocked" status + shouldBlock := j.JobID != job.JobID + if err := rerunJob(ctx, j, shouldBlock); err != nil { ctx.Error(http.StatusInternalServerError, err.Error()) return } @@ -367,7 +380,7 @@ func Rerun(ctx *context_module.Context) { ctx.JSON(http.StatusOK, struct{}{}) } -func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob) error { +func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob, shouldBlock bool) error { status := job.Status if !status.IsDone() { return nil @@ -375,6 +388,9 @@ func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob) erro job.TaskID = 0 job.Status = actions_model.StatusWaiting + if shouldBlock { + job.Status = actions_model.StatusBlocked + } job.Started = 0 job.Stopped = 0 diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 0c585a93b8..718454e063 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -367,7 +367,7 @@ func Diff(ctx *context.Context) { ctx.Data["Commit"] = commit ctx.Data["Diff"] = diff - statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, commitID, db.ListOptions{ListAll: true}) + statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, commitID, db.ListOptionsAll) if err != nil { log.Error("GetLatestCommitStatus: %v", err) } diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index b0570f97c3..cfb0e859bd 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -697,10 +697,8 @@ func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repositor defer gitRepo.Close() branches, err = git_model.FindBranchNames(ctx, git_model.FindBranchOptions{ - RepoID: repo.ID, - ListOptions: db.ListOptions{ - ListAll: true, - }, + RepoID: repo.ID, + ListOptions: db.ListOptionsAll, IsDeletedBranch: optional.Some(false), }) if err != nil { @@ -754,10 +752,8 @@ func CompareDiff(ctx *context.Context) { } headBranches, err := git_model.FindBranchNames(ctx, git_model.FindBranchOptions{ - RepoID: ci.HeadRepo.ID, - ListOptions: db.ListOptions{ - ListAll: true, - }, + RepoID: ci.HeadRepo.ID, + ListOptions: db.ListOptionsAll, IsDeletedBranch: optional.Some(false), }) if err != nil { @@ -980,5 +976,8 @@ func getExcerptLines(commit *git.Commit, filePath string, idxLeft, idxRight, chu } diffLines = append(diffLines, diffLine) } + if err = scanner.Err(); err != nil { + return nil, fmt.Errorf("getExcerptLines scan: %w", err) + } return diffLines, nil } diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index 4f26c0c521..ea0c8ddb7e 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -374,9 +374,9 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b ctx.Error(http.StatusInternalServerError, err.Error()) } } else if models.IsErrCommitIDDoesNotMatch(err) { - ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(ctx.Repo.CommitID)), tplEditFile, &form) + ctx.RenderWithErr(ctx.Tr("repo.editor.commit_id_not_matching"), tplEditFile, &form) } else if git.IsErrPushOutOfDate(err) { - ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(form.NewBranchName)), tplEditFile, &form) + ctx.RenderWithErr(ctx.Tr("repo.editor.push_out_of_date"), tplEditFile, &form) } else if git.IsErrPushRejected(err) { errPushRej := err.(*git.ErrPushRejected) if len(errPushRej.Message) == 0 { diff --git a/routers/web/repo/find.go b/routers/web/repo/find.go index 07b3722798..9da4237c1e 100644 --- a/routers/web/repo/find.go +++ b/routers/web/repo/find.go @@ -7,6 +7,7 @@ import ( "net/http" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/context" ) @@ -17,7 +18,7 @@ const ( // FindFiles render the page to find repository files func FindFiles(ctx *context.Context) { path := ctx.Params("*") - ctx.Data["TreeLink"] = ctx.Repo.RepoLink + "/src/" + path - ctx.Data["DataLink"] = ctx.Repo.RepoLink + "/tree-list/" + path + ctx.Data["TreeLink"] = ctx.Repo.RepoLink + "/src/" + util.PathEscapeSegments(path) + ctx.Data["DataLink"] = ctx.Repo.RepoLink + "/tree-list/" + util.PathEscapeSegments(path) ctx.HTML(http.StatusOK, tplFindFiles) } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index e4193e9b79..c0ec121336 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -192,8 +192,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt if len(selectLabels) > 0 { labelIDs, err = base.StringsToInt64s(strings.Split(selectLabels, ",")) if err != nil { - ctx.ServerError("StringsToInt64s", err) - return + ctx.Flash.Error(ctx.Tr("invalid_data", selectLabels), true) } } @@ -451,13 +450,13 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt linkStr := "%s?q=%s&type=%s&sort=%s&state=%s&labels=%s&milestone=%d&project=%d&assignee=%d&poster=%d&archived=%t" ctx.Data["AllStatesLink"] = fmt.Sprintf(linkStr, ctx.Link, url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "all", url.QueryEscape(selectLabels), - mentionedID, projectID, assigneeID, posterID, archived) + milestoneID, projectID, assigneeID, posterID, archived) ctx.Data["OpenLink"] = fmt.Sprintf(linkStr, ctx.Link, url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "open", url.QueryEscape(selectLabels), - mentionedID, projectID, assigneeID, posterID, archived) + milestoneID, projectID, assigneeID, posterID, archived) ctx.Data["ClosedLink"] = fmt.Sprintf(linkStr, ctx.Link, url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "closed", url.QueryEscape(selectLabels), - mentionedID, projectID, assigneeID, posterID, archived) + milestoneID, projectID, assigneeID, posterID, archived) ctx.Data["SelLabelIDs"] = labelIDs ctx.Data["SelectLabels"] = selectLabels ctx.Data["ViewType"] = viewType diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 8727f3d1e3..c6c6142534 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -505,7 +505,7 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) if len(compareInfo.Commits) != 0 { sha := compareInfo.Commits[0].ID.String() - commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, sha, db.ListOptions{ListAll: true}) + commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, sha, db.ListOptionsAll) if err != nil { ctx.ServerError("GetLatestCommitStatus", err) return nil @@ -567,7 +567,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C ctx.ServerError(fmt.Sprintf("GetRefCommitID(%s)", pull.GetGitRefName()), err) return nil } - commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptions{ListAll: true}) + commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptionsAll) if err != nil { ctx.ServerError("GetLatestCommitStatus", err) return nil @@ -659,7 +659,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C return nil } - commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptions{ListAll: true}) + commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptionsAll) if err != nil { ctx.ServerError("GetLatestCommitStatus", err) return nil diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index 95447a8f54..38bb1305fb 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -136,7 +136,7 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions) } if canReadActions { - statuses, _, err := git_model.GetLatestCommitStatus(ctx, r.Repo.ID, r.Sha1, db.ListOptions{ListAll: true}) + statuses, _, err := git_model.GetLatestCommitStatus(ctx, r.Repo.ID, r.Sha1, db.ListOptionsAll) if err != nil { return nil, err } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 07e6c937b0..b2458a561a 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -618,26 +618,31 @@ func SearchRepo(ctx *context.Context) { } } - var err error + // To improve performance when only the count is requested + if ctx.FormBool("count_only") { + if count, err := repo_model.CountRepository(ctx, opts); err != nil { + log.Error("CountRepository: %v", err) + ctx.JSON(http.StatusInternalServerError, nil) // frontend JS doesn't handle error response (same as below) + } else { + ctx.SetTotalCountHeader(count) + ctx.JSONOK() + } + return + } + repos, count, err := repo_model.SearchRepository(ctx, opts) if err != nil { - ctx.JSON(http.StatusInternalServerError, api.SearchError{ - OK: false, - Error: err.Error(), - }) + log.Error("SearchRepository: %v", err) + ctx.JSON(http.StatusInternalServerError, nil) return } ctx.SetTotalCountHeader(count) - // To improve performance when only the count is requested - if ctx.FormBool("count_only") { - return - } - latestCommitStatuses, err := commitstatus_service.FindReposLastestCommitStatuses(ctx, repos) if err != nil { log.Error("FindReposLastestCommitStatuses: %v", err) + ctx.JSON(http.StatusInternalServerError, nil) return } @@ -679,9 +684,7 @@ func GetBranchesList(ctx *context.Context) { branchOpts := git_model.FindBranchOptions{ RepoID: ctx.Repo.Repository.ID, IsDeletedBranch: optional.Some(false), - ListOptions: db.ListOptions{ - ListAll: true, - }, + ListOptions: db.ListOptionsAll, } branches, err := git_model.FindBranchNames(ctx, branchOpts) if err != nil { @@ -714,9 +717,7 @@ func PrepareBranchList(ctx *context.Context) { branchOpts := git_model.FindBranchOptions{ RepoID: ctx.Repo.Repository.ID, IsDeletedBranch: optional.Some(false), - ListOptions: db.ListOptions{ - ListAll: true, - }, + ListOptions: db.ListOptionsAll, } brs, err := git_model.FindBranchNames(ctx, branchOpts) if err != nil { diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 8ddfd92aa1..e4d7179f63 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -364,7 +364,7 @@ func loadLatestCommitData(ctx *context.Context, latestCommit *git.Commit) bool { ctx.Data["LatestCommitVerification"] = verification ctx.Data["LatestCommitUser"] = user_model.ValidateCommitWithEmail(ctx, latestCommit) - statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, latestCommit.ID.String(), db.ListOptions{ListAll: true}) + statuses, _, err := git_model.GetLatestCommitStatus(ctx, ctx.Repo.Repository.ID, latestCommit.ID.String(), db.ListOptionsAll) if err != nil { log.Error("GetLatestCommitStatus: %v", err) } diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go index f007772d6c..7d0b34cb7d 100644 --- a/routers/web/shared/user/header.go +++ b/routers/web/shared/user/header.go @@ -16,6 +16,8 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/services/context" @@ -35,6 +37,7 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) { prepareContextForCommonProfile(ctx) ctx.Data["IsBlocked"] = ctx.Doer != nil && user_model.IsBlocked(ctx, ctx.Doer.ID, ctx.ContextUser.ID) + ctx.Data["IsFollowing"] = ctx.Doer != nil && user_model.IsFollowing(ctx, ctx.Doer.ID, ctx.ContextUser.ID) ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail && ctx.ContextUser.Email != "" && ctx.IsSigned && !ctx.ContextUser.KeepEmailPrivate if setting.Service.UserLocationMapURL != "" { ctx.Data["ContextUserLocationMapURL"] = setting.Service.UserLocationMapURL + url.QueryEscape(ctx.ContextUser.Location) @@ -46,6 +49,17 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) { return } ctx.Data["OpenIDs"] = openIDs + if len(ctx.ContextUser.Description) != 0 { + content, err := markdown.RenderString(&markup.RenderContext{ + Metas: map[string]string{"mode": "document"}, + Ctx: ctx, + }, ctx.ContextUser.Description) + if err != nil { + ctx.ServerError("RenderString", err) + return + } + ctx.Data["RenderedDescription"] = content + } showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID) orgs, err := db.Find[organization.Organization](ctx, organization.FindOrgOptions{ diff --git a/routers/web/user/home.go b/routers/web/user/home.go index e58fb95131..f122dc5d9c 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -529,17 +529,14 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // Get IDs for labels (a filter option for issues/pulls). // Required for IssuesOptions. - var labelIDs []int64 selectedLabels := ctx.FormString("labels") if len(selectedLabels) > 0 && selectedLabels != "0" { var err error - labelIDs, err = base.StringsToInt64s(strings.Split(selectedLabels, ",")) + opts.LabelIDs, err = base.StringsToInt64s(strings.Split(selectedLabels, ",")) if err != nil { - ctx.ServerError("StringsToInt64s", err) - return + ctx.Flash.Error(ctx.Tr("invalid_data", selectedLabels), true) } } - opts.LabelIDs = labelIDs // ------------------------------ // Get issues as defined by opts. diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index 324205ed91..2105cfe5c5 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -144,6 +144,12 @@ func getNotifications(ctx *context.Context) { ctx.ServerError("LoadIssues", err) return } + + if err = notifications.LoadIssuePullRequests(ctx); err != nil { + ctx.ServerError("LoadIssuePullRequests", err) + return + } + notifications = notifications.Without(failures) failCount += len(failures) @@ -262,8 +268,7 @@ func NotificationSubscriptions(ctx *context.Context) { var err error labelIDs, err = base.StringsToInt64s(strings.Split(selectedLabels, ",")) if err != nil { - ctx.ServerError("StringsToInt64s", err) - return + ctx.Flash.Error(ctx.Tr("invalid_data", selectedLabels), true) } } diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go index edd1fd1568..4236553927 100644 --- a/services/actions/commit_status.go +++ b/services/actions/commit_status.go @@ -79,7 +79,7 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er } ctxname := fmt.Sprintf("%s / %s (%s)", runName, job.Name, event) state := toCommitStatus(job.Status) - if statuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptions{ListAll: true}); err == nil { + if statuses, _, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, db.ListOptionsAll); err == nil { for _, v := range statuses { if v.Context == ctxname { if v.State == state { diff --git a/services/actions/notifier.go b/services/actions/notifier.go index aa88d4e0d8..eec5f814da 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -515,6 +515,12 @@ func (*actionsNotifier) MergePullRequest(ctx context.Context, doer *user_model.U } func (n *actionsNotifier) PushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { + commitID, _ := git.NewIDFromString(opts.NewCommitID) + if commitID.IsZero() { + log.Trace("new commitID is empty") + return + } + ctx = withMethod(ctx, "PushCommits") apiPusher := convert.ToUser(ctx, pusher, nil) @@ -547,9 +553,9 @@ func (n *actionsNotifier) CreateRef(ctx context.Context, pusher *user_model.User apiRepo := convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}) newNotifyInput(repo, pusher, webhook_module.HookEventCreate). - WithRef(refFullName.ShortName()). // FIXME: should we use a full ref name + WithRef(refFullName.String()). WithPayload(&api.CreatePayload{ - Ref: refFullName.ShortName(), + Ref: refFullName.String(), Sha: refID, RefType: refFullName.RefType(), Repo: apiRepo, @@ -566,7 +572,7 @@ func (n *actionsNotifier) DeleteRef(ctx context.Context, pusher *user_model.User newNotifyInput(repo, pusher, webhook_module.HookEventDelete). WithPayload(&api.DeletePayload{ - Ref: refFullName.ShortName(), + Ref: refFullName.String(), RefType: refFullName.RefType(), PusherType: api.PusherTypeUser, Repo: apiRepo, @@ -623,6 +629,10 @@ func (n *actionsNotifier) UpdateRelease(ctx context.Context, doer *user_model.Us } func (n *actionsNotifier) DeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) { + if rel.IsTag { + // has sent same action in `PushCommits`, so skip it. + return + } ctx = withMethod(ctx, "DeleteRelease") notifyRelease(ctx, doer, rel, api.HookReleaseDeleted) } diff --git a/services/actions/rerun.go b/services/actions/rerun.go new file mode 100644 index 0000000000..60f6650905 --- /dev/null +++ b/services/actions/rerun.go @@ -0,0 +1,38 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + actions_model "code.gitea.io/gitea/models/actions" + "code.gitea.io/gitea/modules/container" +) + +// GetAllRerunJobs get all jobs that need to be rerun when job should be rerun +func GetAllRerunJobs(job *actions_model.ActionRunJob, allJobs []*actions_model.ActionRunJob) []*actions_model.ActionRunJob { + rerunJobs := []*actions_model.ActionRunJob{job} + rerunJobsIDSet := make(container.Set[string]) + rerunJobsIDSet.Add(job.JobID) + + for { + found := false + for _, j := range allJobs { + if rerunJobsIDSet.Contains(j.JobID) { + continue + } + for _, need := range j.Needs { + if rerunJobsIDSet.Contains(need) { + found = true + rerunJobs = append(rerunJobs, j) + rerunJobsIDSet.Add(j.JobID) + break + } + } + } + if !found { + break + } + } + + return rerunJobs +} diff --git a/services/actions/rerun_test.go b/services/actions/rerun_test.go new file mode 100644 index 0000000000..a98de7b788 --- /dev/null +++ b/services/actions/rerun_test.go @@ -0,0 +1,48 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + "testing" + + actions_model "code.gitea.io/gitea/models/actions" + + "github.com/stretchr/testify/assert" +) + +func TestGetAllRerunJobs(t *testing.T) { + job1 := &actions_model.ActionRunJob{JobID: "job1"} + job2 := &actions_model.ActionRunJob{JobID: "job2", Needs: []string{"job1"}} + job3 := &actions_model.ActionRunJob{JobID: "job3", Needs: []string{"job2"}} + job4 := &actions_model.ActionRunJob{JobID: "job4", Needs: []string{"job2", "job3"}} + + jobs := []*actions_model.ActionRunJob{job1, job2, job3, job4} + + testCases := []struct { + job *actions_model.ActionRunJob + rerunJobs []*actions_model.ActionRunJob + }{ + { + job1, + []*actions_model.ActionRunJob{job1, job2, job3, job4}, + }, + { + job2, + []*actions_model.ActionRunJob{job2, job3, job4}, + }, + { + job3, + []*actions_model.ActionRunJob{job3, job4}, + }, + { + job4, + []*actions_model.ActionRunJob{job4}, + }, + } + + for _, tc := range testCases { + rerunJobs := GetAllRerunJobs(tc.job, jobs) + assert.ElementsMatch(t, tc.rerunJobs, rerunJobs) + } +} diff --git a/services/auth/session.go b/services/auth/session.go index d13813dcbe..35d97e42da 100644 --- a/services/auth/session.go +++ b/services/auth/session.go @@ -4,7 +4,6 @@ package auth import ( - "context" "net/http" user_model "code.gitea.io/gitea/models/user" @@ -29,40 +28,33 @@ func (s *Session) Name() string { // object for that uid. // Returns nil if there is no user uid stored in the session. func (s *Session) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { - user := SessionUser(req.Context(), sess) - if user != nil { - return user, nil - } - return nil, nil -} - -// SessionUser returns the user object corresponding to the "uid" session variable. -func SessionUser(ctx context.Context, sess SessionStore) *user_model.User { if sess == nil { - return nil + return nil, nil } // Get user ID uid := sess.Get("uid") if uid == nil { - return nil + return nil, nil } log.Trace("Session Authorization: Found user[%d]", uid) id, ok := uid.(int64) if !ok { - return nil + return nil, nil } // Get user object - user, err := user_model.GetUserByID(ctx, id) + user, err := user_model.GetUserByID(req.Context(), id) if err != nil { if !user_model.IsErrUserNotExist(err) { - log.Error("GetUserById: %v", err) + log.Error("GetUserByID: %v", err) + // Return the err as-is to keep current signed-in session, in case the err is something like context.Canceled. Otherwise non-existing user (nil, nil) will make the caller clear the signed-in session. + return nil, err } - return nil + return nil, nil } log.Trace("Session Authorization: Logged in user %-v", user) - return user + return user, nil } diff --git a/services/convert/notification.go b/services/convert/notification.go index 0b97530d8b..41063cf399 100644 --- a/services/convert/notification.go +++ b/services/convert/notification.go @@ -61,8 +61,9 @@ func ToNotificationThread(ctx context.Context, n *activities_model.Notification) result.Subject.LatestCommentHTMLURL = comment.HTMLURL(ctx) } - pr, _ := n.Issue.GetPullRequest(ctx) - if pr != nil && pr.HasMerged { + if err := n.Issue.LoadPullRequest(ctx); err == nil && + n.Issue.PullRequest != nil && + n.Issue.PullRequest.HasMerged { result.Subject.State = "merged" } } diff --git a/services/doctor/authorizedkeys.go b/services/doctor/authorizedkeys.go index 050a4e7974..eb6dec613f 100644 --- a/services/doctor/authorizedkeys.go +++ b/services/doctor/authorizedkeys.go @@ -50,7 +50,11 @@ func checkAuthorizedKeys(ctx context.Context, logger log.Logger, autofix bool) e } linesInAuthorizedKeys.Add(line) } - f.Close() + if err = scanner.Err(); err != nil { + return fmt.Errorf("scan: %w", err) + } + // although there is a "defer close" above, here close explicitly before the generating, because it needs to open the file for writing again + _ = f.Close() // now we regenerate and check if there are any lines missing regenerated := &bytes.Buffer{} diff --git a/services/pull/commit_status.go b/services/pull/commit_status.go index cb63123463..0d4763a838 100644 --- a/services/pull/commit_status.go +++ b/services/pull/commit_status.go @@ -153,7 +153,7 @@ func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullR return "", fmt.Errorf("LoadBaseRepo: %w", err) } - commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, pr.BaseRepo.ID, sha, db.ListOptions{ListAll: true}) + commitStatuses, _, err := git_model.GetLatestCommitStatus(ctx, pr.BaseRepo.ID, sha, db.ListOptionsAll) if err != nil { return "", fmt.Errorf("GetLatestCommitStatus: %w", err) } diff --git a/services/pull/pull.go b/services/pull/pull.go index 29a49fb4dc..23a75e2924 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -893,7 +893,7 @@ func getAllCommitStatus(ctx context.Context, gitRepo *git.Repository, pr *issues return nil, nil, shaErr } - statuses, _, err = git_model.GetLatestCommitStatus(ctx, pr.BaseRepo.ID, sha, db.ListOptions{ListAll: true}) + statuses, _, err = git_model.GetLatestCommitStatus(ctx, pr.BaseRepo.ID, sha, db.ListOptionsAll) lastStatus = git_model.CalcCommitStatus(statuses) return statuses, lastStatus, err } diff --git a/services/pull/review.go b/services/pull/review.go index 1220d54728..7d698a14f6 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -52,9 +52,7 @@ func InvalidateCodeComments(ctx context.Context, prs issues_model.PullRequestLis issueIDs := prs.GetIssueIDs() codeComments, err := db.Find[issues_model.Comment](ctx, issues_model.FindCommentsOptions{ - ListOptions: db.ListOptions{ - ListAll: true, - }, + ListOptions: db.ListOptionsAll, Type: issues_model.CommentTypeCode, Invalidated: optional.Some(false), IssueIDs: issueIDs, @@ -268,11 +266,11 @@ func CreateCodeCommentKnownReviewID(ctx context.Context, doer *user_model.User, // SubmitReview creates a review out of the existing pending review or creates a new one if no pending review exist func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repository, issue *issues_model.Issue, reviewType issues_model.ReviewType, content, commitID string, attachmentUUIDs []string) (*issues_model.Review, *issues_model.Comment, error) { - pr, err := issue.GetPullRequest(ctx) - if err != nil { + if err := issue.LoadPullRequest(ctx); err != nil { return nil, nil, err } + pr := issue.PullRequest var stale bool if reviewType != issues_model.ReviewTypeApprove && reviewType != issues_model.ReviewTypeReject { stale = false @@ -322,12 +320,10 @@ func SubmitReview(ctx context.Context, doer *user_model.User, gitRepo *git.Repos // DismissApprovalReviews dismiss all approval reviews because of new commits func DismissApprovalReviews(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest) error { reviews, err := issues_model.FindReviews(ctx, issues_model.FindReviewOptions{ - ListOptions: db.ListOptions{ - ListAll: true, - }, - IssueID: pull.IssueID, - Type: issues_model.ReviewTypeApprove, - Dismissed: optional.Some(false), + ListOptions: db.ListOptionsAll, + IssueID: pull.IssueID, + Type: issues_model.ReviewTypeApprove, + Dismissed: optional.Some(false), }) if err != nil { return err diff --git a/services/repository/adopt.go b/services/repository/adopt.go index 0ac3c774b7..b337eac38a 100644 --- a/services/repository/adopt.go +++ b/services/repository/adopt.go @@ -144,10 +144,8 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r } branches, _ := git_model.FindBranchNames(ctx, git_model.FindBranchOptions{ - RepoID: repo.ID, - ListOptions: db.ListOptions{ - ListAll: true, - }, + RepoID: repo.ID, + ListOptions: db.ListOptionsAll, IsDeletedBranch: optional.Some(false), }) diff --git a/services/repository/branch.go b/services/repository/branch.go index b683553245..64d8eda4e9 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -127,10 +127,7 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g p := protectedBranches.GetFirstMatched(branchName) isProtected := p != nil - divergence := &git.DivergeObject{ - Ahead: -1, - Behind: -1, - } + var divergence *git.DivergeObject // it's not default branch if repo.DefaultBranch != dbBranch.Name && !dbBranch.IsDeleted { @@ -141,6 +138,11 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g } } + if divergence == nil { + // tolerate the error that we cannot get divergence + divergence = &git.DivergeObject{Ahead: -1, Behind: -1} + } + pr, err := issues_model.GetLatestPullRequestByHeadInfo(ctx, repo.ID, branchName) if err != nil { return nil, fmt.Errorf("GetLatestPullRequestByHeadInfo: %v", err) diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go index e4a5b5a424..c2b4820032 100644 --- a/services/webhook/telegram.go +++ b/services/webhook/telegram.go @@ -181,7 +181,9 @@ func (t telegramConvertor) Package(p *api.PackagePayload) (TelegramPayload, erro func createTelegramPayload(message string) TelegramPayload { return TelegramPayload{ - Message: strings.TrimSpace(message), + Message: strings.TrimSpace(message), + ParseMode: "HTML", + DisableWebPreview: true, } } diff --git a/services/webhook/telegram_test.go b/services/webhook/telegram_test.go index 27ab96cd09..2fe5161b22 100644 --- a/services/webhook/telegram_test.go +++ b/services/webhook/telegram_test.go @@ -18,6 +18,15 @@ import ( func TestTelegramPayload(t *testing.T) { tc := telegramConvertor{} + + t.Run("Correct webhook params", func(t *testing.T) { + p := createTelegramPayload("testMsg ") + + assert.Equal(t, "HTML", p.ParseMode) + assert.Equal(t, true, p.DisableWebPreview) + assert.Equal(t, "testMsg", p.Message) + }) + t.Run("Create", func(t *testing.T) { p := createTestPayload() diff --git a/tailwind.config.js b/tailwind.config.js index d783268bd7..0754ab3631 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -55,5 +55,41 @@ export default { current: 'currentcolor', transparent: 'transparent', }, + borderRadius: { + 'none': '0', + 'sm': '2px', + 'DEFAULT': 'var(--border-radius)', // 4px + 'md': 'var(--border-radius-medium)', // 6px + 'lg': '8px', + 'xl': '12px', + '2xl': '16px', + '3xl': '24px', + 'full': 'var(--border-radius-circle)', // 50% + }, + fontWeight: { + light: 'var(--font-weight-light)', + normal: 'var(--font-weight-normal)', + medium: 'var(--font-weight-medium)', + semibold: 'var(--font-weight-semibold)', + bold: 'var(--font-weight-bold)', + }, + fontSize: { // not using `rem` units because our root is currently 14px + 'xs': '12px', + 'sm': '14px', + 'base': '16px', + 'lg': '18px', + 'xl': '20px', + '2xl': '24px', + '3xl': '30px', + '4xl': '36px', + '5xl': '48px', + '6xl': '60px', + '7xl': '72px', + '8xl': '96px', + '9xl': '128px', + ...Object.fromEntries(Array.from({length: 100}, (_, i) => { + return [`${i}`, `${i === 0 ? '0' : `${i}px`}`]; + })), + }, }, }; diff --git a/templates/admin/auth/new.tmpl b/templates/admin/auth/new.tmpl index d8935341f4..255eac202c 100644 --- a/templates/admin/auth/new.tmpl +++ b/templates/admin/auth/new.tmpl @@ -99,7 +99,7 @@
  • GitHub
  • {{ctx.Locale.Tr "admin.auths.tip.github"}}
  • GitLab
  • - {{ctx.Locale.Tr "admin.auths.tip.gitlab"}} + {{ctx.Locale.Tr "admin.auths.tip.gitlab_new"}}
  • Google
  • {{ctx.Locale.Tr "admin.auths.tip.google_plus"}}
  • OpenID Connect
  • diff --git a/templates/admin/emails/list.tmpl b/templates/admin/emails/list.tmpl index 1e552fba88..b72aef8f35 100644 --- a/templates/admin/emails/list.tmpl +++ b/templates/admin/emails/list.tmpl @@ -4,8 +4,8 @@ {{ctx.Locale.Tr "admin.emails.email_manage_panel"}} ({{ctx.Locale.Tr "admin.total" .Total}})
    - diff --git a/templates/admin/notice.tmpl b/templates/admin/notice.tmpl index e0abe4f8c0..5ea003e5ec 100644 --- a/templates/admin/notice.tmpl +++ b/templates/admin/notice.tmpl @@ -17,10 +17,10 @@ {{range .Notices}} -
    +
    {{.ID}} {{ctx.Locale.Tr .TrStr}} - {{.Description}} + {{.Description}} {{DateTime "short" .CreatedUnix}} {{svg "octicon-note" 16}} @@ -49,8 +49,8 @@
    - diff --git a/templates/admin/org/list.tmpl b/templates/admin/org/list.tmpl index efb0a8847e..ca0ee30092 100644 --- a/templates/admin/org/list.tmpl +++ b/templates/admin/org/list.tmpl @@ -7,8 +7,8 @@
    - diff --git a/templates/admin/queue_manage.tmpl b/templates/admin/queue_manage.tmpl index 80214d1021..dd1682a000 100644 --- a/templates/admin/queue_manage.tmpl +++ b/templates/admin/queue_manage.tmpl @@ -30,7 +30,7 @@ - {{else}} {{$sum}} -
    + {{$.CsrfTokenHtml}}
    diff --git a/templates/admin/repo/unadopted.tmpl b/templates/admin/repo/unadopted.tmpl index c65cfd9db4..9166a844a7 100644 --- a/templates/admin/repo/unadopted.tmpl +++ b/templates/admin/repo/unadopted.tmpl @@ -20,8 +20,8 @@ {{if .Dirs}}
    {{range $dirI, $dir := .Dirs}} -
    - {{svg "octicon-file-directory-fill"}} {{$dir}} +
    + {{svg "octicon-file-directory-fill"}} {{$dir}}