Compare commits

...

13 Commits

Author SHA1 Message Date
silverwind
040970c320
Enable two vue eslint rules (#24780)
These two rules are no longer violated, so we can enable them again.
2023-05-17 22:00:34 -04:00
silverwind
4aacc3ac78
Add two eslint plugins (#24776)
Add these two plugins and autofix issues:

-
[eslint-plugin-no-use-extend-native](https://github.com/dustinspecker/eslint-plugin-no-use-extend-native)
-
[eslint-plugin-array-func](https://github.com/freaktechnik/eslint-plugin-array-func)
2023-05-18 09:14:31 +08:00
silverwind
71451ab844
Mark models/fixtures as generated (#24775)
Makes diffs like https://github.com/go-gitea/gitea/pull/24676/files more
readable. I'm not sure if those are actually generated, but they are
good to collapse in diffs anyways.
2023-05-17 22:59:12 +02:00
silverwind
655c890cbd
Fix TestMinioStorageIterator skip message (#24765)
Followup to https://github.com/go-gitea/gitea/pull/24762, fix this
message.
2023-05-17 16:22:17 +00:00
Lunny Xiao
9dd13e84ca
Fix missed table name on iterate lfs meta objects (#24768) 2023-05-17 23:51:22 +08:00
Yarden Shoham
c839d6f92a
Revert "Fix missed table name on iterate lfs meta objects" (#24764)
This reverts commit 3364092013aa4d5d27ad02806b0f47967c04de18.

It was accidentally pushed to `main` without a review.
2023-05-17 21:20:11 +08:00
Evur
29096d8ef5
Make the color of zero-contribution-squares in the activity heatmap more subtle (#24758)
The previous color had a too high contrast with the background.

---------

Co-authored-by: silverwind <me@silverwind.io>
2023-05-17 10:55:34 +00:00
Lunny Xiao
3364092013
Fix missed table name on iterate lfs meta objects 2023-05-17 18:26:43 +08:00
Lunny Xiao
6c8235dc98
Skip TestMinioStorageIterator on CI (#24762)
Fix https://github.com/go-gitea/gitea/pull/24691#issuecomment-1550987681

---------

Co-authored-by: silverwind <me@silverwind.io>
2023-05-17 10:00:58 +00:00
Lunny Xiao
b807d2f620
Support no label/assignee filter and batch clearing labels/assignees (#24707)
Since milestones has been implemented, this PR will fix #3407

---------

Co-authored-by: Jason Song <i@wolfogre.com>
2023-05-17 17:21:35 +08:00
Zettat123
e7c2231dee
Support for status check pattern (#24633)
This PR is to allow users to specify status checks by patterns. Users
can enter patterns in the "Status Check Pattern" `textarea` to match
status checks and each line specifies a pattern. If "Status Check" is
enabled, patterns cannot be empty and user must enter at least one
pattern.
Users will no longer be able to choose status checks from the table. But
a __*`Matched`*__ mark will be added to the matched checks to help users
enter patterns.

Benefits:
- Even if no status checks have been completed, users can specify
necessary status checks in advance.
- More flexible. Users can specify a series of status checks by one
pattern.

Before:

![image](https://github.com/go-gitea/gitea/assets/15528715/635738ad-580c-49cd-941d-c721e5b99be4)

After:

![image](https://github.com/go-gitea/gitea/assets/15528715/16aa7b1b-abf1-4170-9bfa-ae6fc9803a82)

---------

Co-authored-by: silverwind <me@silverwind.io>
2023-05-17 16:11:13 +08:00
Alejandro Leal
9fb0945a09
Updates to doc (#24757)
## Misspelling fixes to:
- docs/content/doc/administration/config-cheat-sheet.en-us.md
- docs/content/doc/installation/from-source.en-us.md
- docs/content/doc/usage/packages/cargo.en-us.md
- docs/content/doc/usage/packages/storage.en-us.md

---------

Co-authored-by: delvh <dev.lh@web.de>
2023-05-17 05:45:26 +00:00
Lunny Xiao
473dee7c7a
Ignore build for docs only (#24761)
Fix https://github.com/go-gitea/gitea/pull/24530#issuecomment-1550227919
2023-05-17 13:42:08 +08:00
27 changed files with 479 additions and 107 deletions

View File

@ -10,10 +10,12 @@ parserOptions:
plugins: plugins:
- "@eslint-community/eslint-plugin-eslint-comments" - "@eslint-community/eslint-plugin-eslint-comments"
- eslint-plugin-array-func
- eslint-plugin-custom-elements - eslint-plugin-custom-elements
- eslint-plugin-import - eslint-plugin-import
- eslint-plugin-jquery - eslint-plugin-jquery
- eslint-plugin-no-jquery - eslint-plugin-no-jquery
- eslint-plugin-no-use-extend-native
- eslint-plugin-regexp - eslint-plugin-regexp
- eslint-plugin-sonarjs - eslint-plugin-sonarjs
- eslint-plugin-unicorn - eslint-plugin-unicorn
@ -59,6 +61,12 @@ rules:
array-bracket-spacing: [2, never] array-bracket-spacing: [2, never]
array-callback-return: [2, {checkForEach: true}] array-callback-return: [2, {checkForEach: true}]
array-element-newline: [0] array-element-newline: [0]
array-func/avoid-reverse: [2]
array-func/from-map: [2]
array-func/no-unnecessary-this-arg: [2]
array-func/prefer-array-from: [2]
array-func/prefer-flat-map: [0] # handled by unicorn/prefer-array-flat-map
array-func/prefer-flat: [0] # handled by unicorn/prefer-array-flat
arrow-body-style: [0] arrow-body-style: [0]
arrow-parens: [2, always] arrow-parens: [2, always]
arrow-spacing: [2, {before: true, after: true}] arrow-spacing: [2, {before: true, after: true}]
@ -444,6 +452,7 @@ rules:
no-unused-private-class-members: [2] no-unused-private-class-members: [2]
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}] no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}] no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}]
no-use-extend-native/no-use-extend-native: [2]
no-useless-backreference: [2] no-useless-backreference: [2]
no-useless-call: [2] no-useless-call: [2]
no-useless-catch: [2] no-useless-catch: [2]

1
.gitattributes vendored
View File

@ -1,6 +1,7 @@
* text=auto eol=lf * text=auto eol=lf
*.tmpl linguist-language=Handlebars *.tmpl linguist-language=Handlebars
/assets/*.json linguist-generated /assets/*.json linguist-generated
/models/fixtures/** linguist-generated
/public/img/svg/*.svg linguist-generated /public/img/svg/*.svg linguist-generated
/public/vendor/** -text -eol linguist-vendored /public/vendor/** -text -eol linguist-vendored
/templates/swagger/v1_json.tmpl linguist-generated /templates/swagger/v1_json.tmpl linguist-generated

View File

@ -11,3 +11,33 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- run: echo "No build required" - run: echo "No build required"
lint-backend:
runs-on: ubuntu-latest
steps:
- run: echo "No build required"
lint-go-windows:
runs-on: ubuntu-latest
steps:
- run: echo "No build required"
lint-go-gogit:
runs-on: ubuntu-latest
steps:
- run: echo "No build required"
checks-backend:
runs-on: ubuntu-latest
steps:
- run: echo "No build required"
frontend:
runs-on: ubuntu-latest
steps:
- run: echo "No build required"
backend:
runs-on: ubuntu-latest
steps:
- run: echo "No build required"

View File

@ -220,7 +220,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `SHOW_USER_EMAIL`: **true**: Whether the email of the user should be shown in the Explore Users page. - `SHOW_USER_EMAIL`: **true**: Whether the email of the user should be shown in the Explore Users page.
- `THEMES`: **auto,gitea,arc-green**: All available themes. Allow users select personalized themes. - `THEMES`: **auto,gitea,arc-green**: All available themes. Allow users select personalized themes.
regardless of the value of `DEFAULT_THEME`. regardless of the value of `DEFAULT_THEME`.
- `THEME_COLOR_META_TAG`: **\<empty\>**: Value of `theme-color` meta tag, used by some mobile browers for chrome and out-of-viewport areas. Default is unset which uses body color. - `THEME_COLOR_META_TAG`: **\<empty\>**: Value of `theme-color` meta tag, used by some mobile browsers for chrome and out-of-viewport areas. Default is unset which uses body color.
- `MAX_DISPLAY_FILE_SIZE`: **8388608**: Max size of files to be displayed (default is 8MiB) - `MAX_DISPLAY_FILE_SIZE`: **8388608**: Max size of files to be displayed (default is 8MiB)
- `REACTIONS`: All available reactions users can choose on issues/prs and comments - `REACTIONS`: All available reactions users can choose on issues/prs and comments
Values can be emoji alias (:smile:) or a unicode emoji. Values can be emoji alias (:smile:) or a unicode emoji.

View File

@ -201,7 +201,7 @@ This can be combined with `CC`, `GOOS`, and `GOARCH` as above.
A script to enable bash-completion can be found at [`contrib/autocompletion/bash_autocomplete`](https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/autocompletion/bash_autocomplete). This should be altered as appropriate and can be `source` in your `.bashrc` A script to enable bash-completion can be found at [`contrib/autocompletion/bash_autocomplete`](https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/autocompletion/bash_autocomplete). This should be altered as appropriate and can be `source` in your `.bashrc`
or copied as `/usr/share/bash-completion/completions/gitea`. or copied as `/usr/share/bash-completion/completions/gitea`.
Similary a script for zsh-completion can be found at [`contrib/autocompletion/zsh_autocomplete`](https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/autocompletion/zsh_autocomplete). This can be copied to `/usr/share/zsh/_gitea` or sourced within your Similarly, a script for zsh-completion can be found at [`contrib/autocompletion/zsh_autocomplete`](https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/autocompletion/zsh_autocomplete). This can be copied to `/usr/share/zsh/_gitea` or sourced within your
`.zshrc`. `.zshrc`.
YMMV and these scripts may need further improvement. YMMV and these scripts may need further improvement.

View File

@ -25,13 +25,13 @@ Publish [Cargo](https://doc.rust-lang.org/stable/cargo/) packages for your user
To work with the Cargo package registry, you need [Rust and Cargo](https://www.rust-lang.org/tools/install). To work with the Cargo package registry, you need [Rust and Cargo](https://www.rust-lang.org/tools/install).
Cargo stores informations about the available packages in a package index stored in a git repository. Cargo stores information about the available packages in a package index stored in a git repository.
This repository is needed to work with the registry. This repository is needed to work with the registry.
The following section describes how to create it. The following section describes how to create it.
## Index Repository ## Index Repository
Cargo stores informations about the available packages in a package index stored in a git repository. Cargo stores information about the available packages in a package index stored in a git repository.
In Gitea this repository has the special name `_cargo-index`. In Gitea this repository has the special name `_cargo-index`.
After a package was uploaded, its metadata is automatically written to the index. After a package was uploaded, its metadata is automatically written to the index.
The content of this repository should not be manually modified. The content of this repository should not be manually modified.

View File

@ -28,7 +28,7 @@ If two identical files are uploaded only one blob is saved on the filesystem.
This ensures no space is wasted for duplicated files. This ensures no space is wasted for duplicated files.
If two packages are uploaded with identical files, both packages will display the same size but on the filesystem they require only half of the size. If two packages are uploaded with identical files, both packages will display the same size but on the filesystem they require only half of the size.
Whenever a package gets deleted only the references to the underlaying blobs are removed. Whenever a package gets deleted, only the references to the underlying blobs are removed.
The blobs get not removed at this moment, so they still require space on the filesystem. The blobs get not removed at this moment, so they still require space on the filesystem.
When a new package gets uploaded the existing blobs may get referenced again. When a new package gets uploaded the existing blobs may get referenced again.

View File

@ -390,7 +390,7 @@ func IterateLFSMetaObjectsForRepo(ctx context.Context, repoID int64, f func(cont
for { for {
beans := make([]*CountLFSMetaObject, 0, batchSize) beans := make([]*CountLFSMetaObject, 0, batchSize)
sess := engine.Select("`lfs_meta_object`.*, COUNT(`l1`.oid) AS `count`"). sess := engine.Table("lfs_meta_object").Select("`lfs_meta_object`.*, COUNT(`l1`.oid) AS `count`").
Join("INNER", "`lfs_meta_object` AS l1", "`lfs_meta_object`.oid = `l1`.oid"). Join("INNER", "`lfs_meta_object` AS l1", "`lfs_meta_object`.oid = `l1`.oid").
Where("`lfs_meta_object`.repository_id = ?", repoID) Where("`lfs_meta_object`.repository_id = ?", repoID)
if !opts.OlderThan.IsZero() { if !opts.OlderThan.IsZero() {

View File

@ -1251,6 +1251,8 @@ func (opts *IssuesOptions) setupSessionNoLimit(sess *xorm.Session) {
if opts.AssigneeID > 0 { if opts.AssigneeID > 0 {
applyAssigneeCondition(sess, opts.AssigneeID) applyAssigneeCondition(sess, opts.AssigneeID)
} else if opts.AssigneeID == db.NoConditionID {
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_assignees)")
} }
if opts.PosterID > 0 { if opts.PosterID > 0 {
@ -1312,13 +1314,17 @@ func (opts *IssuesOptions) setupSessionNoLimit(sess *xorm.Session) {
sess.And(builder.Eq{"repository.is_archived": opts.IsArchived.IsTrue()}) sess.And(builder.Eq{"repository.is_archived": opts.IsArchived.IsTrue()})
} }
if opts.LabelIDs != nil { if len(opts.LabelIDs) > 0 {
for i, labelID := range opts.LabelIDs { if opts.LabelIDs[0] == 0 {
if labelID > 0 { sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_label)")
sess.Join("INNER", fmt.Sprintf("issue_label il%d", i), } else {
fmt.Sprintf("issue.id = il%[1]d.issue_id AND il%[1]d.label_id = %[2]d", i, labelID)) for i, labelID := range opts.LabelIDs {
} else { if labelID > 0 {
sess.Where("issue.id not in (select issue_id from issue_label where label_id = ?)", -labelID) sess.Join("INNER", fmt.Sprintf("issue_label il%d", i),
fmt.Sprintf("issue.id = il%[1]d.issue_id AND il%[1]d.label_id = %[2]d", i, labelID))
} else if labelID < 0 { // 0 is not supported here, so just ignore it
sess.Where("issue.id not in (select issue_id from issue_label where label_id = ?)", -labelID)
}
} }
} }
} }
@ -1705,17 +1711,21 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
sess.In("issue.id", issueIDs) sess.In("issue.id", issueIDs)
} }
if len(opts.Labels) > 0 && opts.Labels != "0" { if len(opts.Labels) > 0 {
labelIDs, err := base.StringsToInt64s(strings.Split(opts.Labels, ",")) labelIDs, err := base.StringsToInt64s(strings.Split(opts.Labels, ","))
if err != nil { if err != nil {
log.Warn("Malformed Labels argument: %s", opts.Labels) log.Warn("Malformed Labels argument: %s", opts.Labels)
} else { } else {
for i, labelID := range labelIDs { if labelIDs[0] == 0 {
if labelID > 0 { sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_label)")
sess.Join("INNER", fmt.Sprintf("issue_label il%d", i), } else {
fmt.Sprintf("issue.id = il%[1]d.issue_id AND il%[1]d.label_id = %[2]d", i, labelID)) for i, labelID := range labelIDs {
} else { if labelID > 0 {
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_label WHERE label_id = ?)", -labelID) sess.Join("INNER", fmt.Sprintf("issue_label il%d", i),
fmt.Sprintf("issue.id = il%[1]d.issue_id AND il%[1]d.label_id = %[2]d", i, labelID))
} else if labelID < 0 { // 0 is not supported here, so just ignore it
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_label WHERE label_id = ?)", -labelID)
}
} }
} }
} }
@ -1734,6 +1744,8 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
if opts.AssigneeID > 0 { if opts.AssigneeID > 0 {
applyAssigneeCondition(sess, opts.AssigneeID) applyAssigneeCondition(sess, opts.AssigneeID)
} else if opts.AssigneeID == db.NoConditionID {
sess.Where("id NOT IN (SELECT issue_id FROM issue_assignees)")
} }
if opts.PosterID > 0 { if opts.PosterID > 0 {

View File

@ -4,10 +4,15 @@
package storage package storage
import ( import (
"os"
"testing" "testing"
) )
func TestMinioStorageIterator(t *testing.T) { func TestMinioStorageIterator(t *testing.T) {
if os.Getenv("CI") == "" {
t.Skip("minioStorage not present outside of CI")
return
}
testStorageIterator(t, string(MinioStorageType), MinioStorageConfig{ testStorageIterator(t, string(MinioStorageType), MinioStorageConfig{
Endpoint: "127.0.0.1:9000", Endpoint: "127.0.0.1:9000",
AccessKeyID: "123456", AccessKeyID: "123456",

View File

@ -1361,6 +1361,7 @@ issues.delete_branch_at = `deleted branch <b>%s</b> %s`
issues.filter_label = Label issues.filter_label = Label
issues.filter_label_exclude = `Use <code>alt</code> + <code>click/enter</code> to exclude labels` issues.filter_label_exclude = `Use <code>alt</code> + <code>click/enter</code> to exclude labels`
issues.filter_label_no_select = All labels issues.filter_label_no_select = All labels
issues.filter_label_select_no_label = No Label
issues.filter_milestone = Milestone issues.filter_milestone = Milestone
issues.filter_milestone_all = All milestones issues.filter_milestone_all = All milestones
issues.filter_milestone_none = No milestones issues.filter_milestone_none = No milestones
@ -1371,6 +1372,7 @@ issues.filter_project_all = All projects
issues.filter_project_none = No project issues.filter_project_none = No project
issues.filter_assignee = Assignee issues.filter_assignee = Assignee
issues.filter_assginee_no_select = All assignees issues.filter_assginee_no_select = All assignees
issues.filter_assginee_no_assignee = No assignee
issues.filter_poster = Author issues.filter_poster = Author
issues.filter_poster_no_select = All authors issues.filter_poster_no_select = All authors
issues.filter_type = Type issues.filter_type = Type
@ -2190,8 +2192,13 @@ settings.protect_merge_whitelist_committers_desc = Allow only whitelisted users
settings.protect_merge_whitelist_users = Whitelisted users for merging: settings.protect_merge_whitelist_users = Whitelisted users for merging:
settings.protect_merge_whitelist_teams = Whitelisted teams for merging: settings.protect_merge_whitelist_teams = Whitelisted teams for merging:
settings.protect_check_status_contexts = Enable Status Check settings.protect_check_status_contexts = Enable Status Check
settings.protect_check_status_contexts_desc = Require status checks to pass before merging. Choose which status checks must pass before branches can be merged into a branch that matches this rule. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. If no contexts are selected, the last commit must be successful regardless of context. settings.protect_status_check_patterns = Status check patterns:
settings.protect_status_check_patterns_desc = Enter patterns to specify which status checks must pass before branches can be merged into a branch that matches this rule. Each line specifies a pattern. Patterns cannot be empty.
settings.protect_check_status_contexts_desc = Require status checks to pass before merging. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. If no contexts are matched, the last commit must be successful regardless of context.
settings.protect_check_status_contexts_list = Status checks found in the last week for this repository settings.protect_check_status_contexts_list = Status checks found in the last week for this repository
settings.protect_status_check_matched = Matched
settings.protect_invalid_status_check_pattern = Invalid status check pattern: "%s".
settings.protect_no_valid_status_check_patterns = No valid status check patterns.
settings.protect_required_approvals = Required approvals: settings.protect_required_approvals = Required approvals:
settings.protect_required_approvals_desc = Allow only to merge pull request with enough positive reviews. settings.protect_required_approvals_desc = Allow only to merge pull request with enough positive reviews.
settings.protect_approvals_whitelist_enabled = Restrict approvals to whitelisted users or teams settings.protect_approvals_whitelist_enabled = Restrict approvals to whitelisted users or teams

310
package-lock.json generated
View File

@ -35,6 +35,7 @@
"license-checker-webpack-plugin": "0.2.1", "license-checker-webpack-plugin": "0.2.1",
"mermaid": "10.1.0", "mermaid": "10.1.0",
"mini-css-extract-plugin": "2.7.5", "mini-css-extract-plugin": "2.7.5",
"minimatch": "9.0.0",
"monaco-editor": "0.38.0", "monaco-editor": "0.38.0",
"monaco-editor-webpack-plugin": "7.0.1", "monaco-editor-webpack-plugin": "7.0.1",
"pretty-ms": "8.0.0", "pretty-ms": "8.0.0",
@ -61,10 +62,12 @@
"@stoplight/spectral-cli": "6.6.0", "@stoplight/spectral-cli": "6.6.0",
"@vitejs/plugin-vue": "4.2.3", "@vitejs/plugin-vue": "4.2.3",
"eslint": "8.40.0", "eslint": "8.40.0",
"eslint-plugin-array-func": "3.1.8",
"eslint-plugin-custom-elements": "0.0.8", "eslint-plugin-custom-elements": "0.0.8",
"eslint-plugin-import": "2.27.5", "eslint-plugin-import": "2.27.5",
"eslint-plugin-jquery": "1.5.1", "eslint-plugin-jquery": "1.5.1",
"eslint-plugin-no-jquery": "2.7.0", "eslint-plugin-no-jquery": "2.7.0",
"eslint-plugin-no-use-extend-native": "0.5.0",
"eslint-plugin-regexp": "1.15.0", "eslint-plugin-regexp": "1.15.0",
"eslint-plugin-sonarjs": "0.19.0", "eslint-plugin-sonarjs": "0.19.0",
"eslint-plugin-unicorn": "47.0.0", "eslint-plugin-unicorn": "47.0.0",
@ -855,12 +858,34 @@
"url": "https://github.com/sponsors/epoberezkin" "url": "https://github.com/sponsors/epoberezkin"
} }
}, },
"node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true "dev": true
}, },
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/@eslint/js": { "node_modules/@eslint/js": {
"version": "8.40.0", "version": "8.40.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
@ -907,6 +932,28 @@
"node": ">=10.10.0" "node": ">=10.10.0"
} }
}, },
"node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/@humanwhocodes/module-importer": { "node_modules/@humanwhocodes/module-importer": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
@ -1480,6 +1527,28 @@
"node": "^12.20 || >=14.13" "node": "^12.20 || >=14.13"
} }
}, },
"node_modules/@stoplight/spectral-core/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/@stoplight/spectral-core/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/@stoplight/spectral-formats": { "node_modules/@stoplight/spectral-formats": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.5.0.tgz", "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.5.0.tgz",
@ -2668,12 +2737,11 @@
"dev": true "dev": true
}, },
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "1.1.11", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0"
"concat-map": "0.0.1"
} }
}, },
"node_modules/braces": { "node_modules/braces": {
@ -4536,6 +4604,18 @@
"ms": "^2.1.1" "ms": "^2.1.1"
} }
}, },
"node_modules/eslint-plugin-array-func": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/eslint-plugin-array-func/-/eslint-plugin-array-func-3.1.8.tgz",
"integrity": "sha512-BjnbJvw+knaHgVddIL3q5xYcoqAZoK8wOdT7QF+mkvSAjXdZCdhL0z71Y7oRtgXA8BpN9QLJ2uHgD3I6ymlbOw==",
"dev": true,
"engines": {
"node": ">= 6.8.0"
},
"peerDependencies": {
"eslint": ">=3.0.0"
}
},
"node_modules/eslint-plugin-custom-elements": { "node_modules/eslint-plugin-custom-elements": {
"version": "0.0.8", "version": "0.0.8",
"resolved": "https://registry.npmjs.org/eslint-plugin-custom-elements/-/eslint-plugin-custom-elements-0.0.8.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-custom-elements/-/eslint-plugin-custom-elements-0.0.8.tgz",
@ -4574,6 +4654,16 @@
"eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
} }
}, },
"node_modules/eslint-plugin-import/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/eslint-plugin-import/node_modules/debug": { "node_modules/eslint-plugin-import/node_modules/debug": {
"version": "3.2.7", "version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
@ -4595,6 +4685,18 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/eslint-plugin-import/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/eslint-plugin-import/node_modules/semver": { "node_modules/eslint-plugin-import/node_modules/semver": {
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@ -4622,6 +4724,21 @@
"eslint": ">=2.3.0" "eslint": ">=2.3.0"
} }
}, },
"node_modules/eslint-plugin-no-use-extend-native": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.5.0.tgz",
"integrity": "sha512-dBNjs8hor8rJgeXLH4HTut5eD3RGWf9JUsadIfuL7UosVQ/dnvOKwxEcRrXrFxrMZ8llUVWT+hOimxJABsAUzQ==",
"dev": true,
"dependencies": {
"is-get-set-prop": "^1.0.0",
"is-js-type": "^2.0.0",
"is-obj-prop": "^1.0.0",
"is-proto-prop": "^2.0.0"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/eslint-plugin-regexp": { "node_modules/eslint-plugin-regexp": {
"version": "1.15.0", "version": "1.15.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-1.15.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-1.15.0.tgz",
@ -4767,12 +4884,34 @@
"url": "https://github.com/sponsors/epoberezkin" "url": "https://github.com/sponsors/epoberezkin"
} }
}, },
"node_modules/eslint/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/eslint/node_modules/json-schema-traverse": { "node_modules/eslint/node_modules/json-schema-traverse": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true "dev": true
}, },
"node_modules/eslint/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/espree": { "node_modules/espree": {
"version": "9.5.2", "version": "9.5.2",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
@ -5159,6 +5298,15 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/get-set-props": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz",
"integrity": "sha512-7oKuKzAGKj0ag+eWZwcGw2fjiZ78tXnXQoBgY0aU7ZOxTu4bB7hSuQSDgtKy978EDH062P5FmD2EWiDpQS9K9Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/get-source": { "node_modules/get-source": {
"version": "2.0.12", "version": "2.0.12",
"resolved": "https://registry.npmjs.org/get-source/-/get-source-2.0.12.tgz", "resolved": "https://registry.npmjs.org/get-source/-/get-source-2.0.12.tgz",
@ -5273,6 +5421,26 @@
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
}, },
"node_modules/glob/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/glob/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/global-modules": { "node_modules/global-modules": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
@ -5869,6 +6037,16 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/is-get-set-prop": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz",
"integrity": "sha512-DvAYZ1ZgGUz4lzxKMPYlt08qAUqyG9ckSg2pIjfvcQ7+pkVNUHk8yVLXOnCLe5WKXhLop8oorWFBJHpwWQpszQ==",
"dev": true,
"dependencies": {
"get-set-props": "^0.1.0",
"lowercase-keys": "^1.0.0"
}
},
"node_modules/is-glob": { "node_modules/is-glob": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@ -5880,6 +6058,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/is-js-type": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz",
"integrity": "sha512-Aj13l47+uyTjlQNHtXBV8Cji3jb037vxwMWCgopRR8h6xocgBGW3qG8qGlIOEmbXQtkKShKuBM9e8AA1OeQ+xw==",
"dev": true,
"dependencies": {
"js-types": "^1.0.0"
}
},
"node_modules/is-negative-zero": { "node_modules/is-negative-zero": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
@ -5915,6 +6102,16 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/is-obj-prop": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz",
"integrity": "sha512-5Idb61slRlJlsAzi0Wsfwbp+zZY+9LXKUAZpvT/1ySw+NxKLRWfa0Bzj+wXI3fX5O9hiddm5c3DAaRSNP/yl2w==",
"dev": true,
"dependencies": {
"lowercase-keys": "^1.0.0",
"obj-props": "^1.0.0"
}
},
"node_modules/is-path-inside": { "node_modules/is-path-inside": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
@ -5948,6 +6145,16 @@
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
"dev": true "dev": true
}, },
"node_modules/is-proto-prop": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz",
"integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==",
"dev": true,
"dependencies": {
"lowercase-keys": "^1.0.0",
"proto-props": "^2.0.0"
}
},
"node_modules/is-reference": { "node_modules/is-reference": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
@ -6165,6 +6372,15 @@
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
}, },
"node_modules/js-types": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz",
"integrity": "sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/js-yaml": { "node_modules/js-yaml": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@ -6396,6 +6612,26 @@
"webpack": "^4.4.0 || ^5.4.0" "webpack": "^4.4.0 || ^5.4.0"
} }
}, },
"node_modules/license-checker-webpack-plugin/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/license-checker-webpack-plugin/node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/license-checker-webpack-plugin/node_modules/semver": { "node_modules/license-checker-webpack-plugin/node_modules/semver": {
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@ -6551,6 +6787,15 @@
"get-func-name": "^2.0.0" "get-func-name": "^2.0.0"
} }
}, },
"node_modules/lowercase-keys": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/lru-cache": { "node_modules/lru-cache": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@ -6645,15 +6890,6 @@
"node": ">=14" "node": ">=14"
} }
}, },
"node_modules/markdownlint-cli/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/markdownlint-cli/node_modules/commander": { "node_modules/markdownlint-cli/node_modules/commander": {
"version": "10.0.1", "version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
@ -6691,21 +6927,6 @@
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
"dev": true "dev": true
}, },
"node_modules/markdownlint-cli/node_modules/minimatch": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
"integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/markdownlint-micromark": { "node_modules/markdownlint-micromark": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.2.tgz", "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.2.tgz",
@ -6939,14 +7160,17 @@
} }
}, },
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "3.1.2", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
"dependencies": { "dependencies": {
"brace-expansion": "^1.1.7" "brace-expansion": "^2.0.1"
}, },
"engines": { "engines": {
"node": "*" "node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/minimist": { "node_modules/minimist": {
@ -7183,6 +7407,15 @@
"integrity": "sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g==", "integrity": "sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g==",
"dev": true "dev": true
}, },
"node_modules/obj-props": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz",
"integrity": "sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-assign": { "node_modules/object-assign": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@ -7828,6 +8061,15 @@
"react-is": "^16.13.1" "react-is": "^16.13.1"
} }
}, },
"node_modules/proto-props": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz",
"integrity": "sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/proxy-agent": { "node_modules/proxy-agent": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz",

View File

@ -35,6 +35,7 @@
"license-checker-webpack-plugin": "0.2.1", "license-checker-webpack-plugin": "0.2.1",
"mermaid": "10.1.0", "mermaid": "10.1.0",
"mini-css-extract-plugin": "2.7.5", "mini-css-extract-plugin": "2.7.5",
"minimatch": "9.0.0",
"monaco-editor": "0.38.0", "monaco-editor": "0.38.0",
"monaco-editor-webpack-plugin": "7.0.1", "monaco-editor-webpack-plugin": "7.0.1",
"pretty-ms": "8.0.0", "pretty-ms": "8.0.0",
@ -61,10 +62,12 @@
"@stoplight/spectral-cli": "6.6.0", "@stoplight/spectral-cli": "6.6.0",
"@vitejs/plugin-vue": "4.2.3", "@vitejs/plugin-vue": "4.2.3",
"eslint": "8.40.0", "eslint": "8.40.0",
"eslint-plugin-array-func": "3.1.8",
"eslint-plugin-custom-elements": "0.0.8", "eslint-plugin-custom-elements": "0.0.8",
"eslint-plugin-import": "2.27.5", "eslint-plugin-import": "2.27.5",
"eslint-plugin-jquery": "1.5.1", "eslint-plugin-jquery": "1.5.1",
"eslint-plugin-no-jquery": "2.7.0", "eslint-plugin-no-jquery": "2.7.0",
"eslint-plugin-no-use-extend-native": "0.5.0",
"eslint-plugin-regexp": "1.15.0", "eslint-plugin-regexp": "1.15.0",
"eslint-plugin-sonarjs": "0.19.0", "eslint-plugin-sonarjs": "0.19.0",
"eslint-plugin-unicorn": "47.0.0", "eslint-plugin-unicorn": "47.0.0",

View File

@ -170,8 +170,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
var labelIDs []int64 var labelIDs []int64
// 1,-2 means including label 1 and excluding label 2
// 0 means issues with no label
// blank means labels will not be filtered for issues
selectLabels := ctx.FormString("labels") selectLabels := ctx.FormString("labels")
if len(selectLabels) > 0 && selectLabels != "0" { if len(selectLabels) > 0 {
labelIDs, err = base.StringsToInt64s(strings.Split(selectLabels, ",")) labelIDs, err = base.StringsToInt64s(strings.Split(selectLabels, ","))
if err != nil { if err != nil {
ctx.ServerError("StringsToInt64s", err) ctx.ServerError("StringsToInt64s", err)

View File

@ -45,6 +45,8 @@ import (
"code.gitea.io/gitea/services/gitdiff" "code.gitea.io/gitea/services/gitdiff"
pull_service "code.gitea.io/gitea/services/pull" pull_service "code.gitea.io/gitea/services/pull"
repo_service "code.gitea.io/gitea/services/repository" repo_service "code.gitea.io/gitea/services/repository"
"github.com/gobwas/glob"
) )
const ( const (
@ -575,7 +577,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
if pb != nil && pb.EnableStatusCheck { if pb != nil && pb.EnableStatusCheck {
ctx.Data["is_context_required"] = func(context string) bool { ctx.Data["is_context_required"] = func(context string) bool {
for _, c := range pb.StatusCheckContexts { for _, c := range pb.StatusCheckContexts {
if c == context { if gp, err := glob.Compile(c); err == nil && gp.Match(context) {
return true return true
} }
} }

View File

@ -6,6 +6,7 @@ package repo
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"strings" "strings"
"time" "time"
@ -23,6 +24,8 @@ import (
"code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/forms"
pull_service "code.gitea.io/gitea/services/pull" pull_service "code.gitea.io/gitea/services/pull"
"code.gitea.io/gitea/services/repository" "code.gitea.io/gitea/services/repository"
"github.com/gobwas/glob"
) )
const ( const (
@ -115,21 +118,10 @@ func SettingsProtectedBranch(c *context.Context) {
c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(rule.WhitelistUserIDs), ",") c.Data["whitelist_users"] = strings.Join(base.Int64sToStrings(rule.WhitelistUserIDs), ",")
c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.MergeWhitelistUserIDs), ",") c.Data["merge_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.MergeWhitelistUserIDs), ",")
c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.ApprovalsWhitelistUserIDs), ",") c.Data["approvals_whitelist_users"] = strings.Join(base.Int64sToStrings(rule.ApprovalsWhitelistUserIDs), ",")
c.Data["status_check_contexts"] = strings.Join(rule.StatusCheckContexts, "\n")
contexts, _ := git_model.FindRepoRecentCommitStatusContexts(c, c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts contexts, _ := git_model.FindRepoRecentCommitStatusContexts(c, c.Repo.Repository.ID, 7*24*time.Hour) // Find last week status check contexts
for _, ctx := range rule.StatusCheckContexts { c.Data["recent_status_checks"] = contexts
var found bool
for i := range contexts {
if contexts[i] == ctx {
found = true
break
}
}
if !found {
contexts = append(contexts, ctx)
}
}
c.Data["branch_status_check_contexts"] = contexts
if c.Repo.Owner.IsOrganization() { if c.Repo.Owner.IsOrganization() {
teams, err := organization.OrgFromUser(c.Repo.Owner).TeamsWithAccessToRepo(c.Repo.Repository.ID, perm.AccessModeRead) teams, err := organization.OrgFromUser(c.Repo.Owner).TeamsWithAccessToRepo(c.Repo.Repository.ID, perm.AccessModeRead)
if err != nil { if err != nil {
@ -237,7 +229,27 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
protectBranch.EnableStatusCheck = f.EnableStatusCheck protectBranch.EnableStatusCheck = f.EnableStatusCheck
if f.EnableStatusCheck { if f.EnableStatusCheck {
protectBranch.StatusCheckContexts = f.StatusCheckContexts patterns := strings.Split(strings.ReplaceAll(f.StatusCheckContexts, "\r", "\n"), "\n")
validPatterns := make([]string, 0, len(patterns))
for _, pattern := range patterns {
trimmed := strings.TrimSpace(pattern)
if trimmed == "" {
continue
}
if _, err := glob.Compile(trimmed); err != nil {
ctx.Flash.Error(ctx.Tr("repo.settings.protect_invalid_status_check_pattern", pattern))
ctx.Redirect(fmt.Sprintf("%s/settings/branches/edit?rule_name=%s", ctx.Repo.RepoLink, url.QueryEscape(protectBranch.RuleName)))
return
}
validPatterns = append(validPatterns, trimmed)
}
if len(validPatterns) == 0 {
// if status check is enabled, patterns slice is not allowed to be empty
ctx.Flash.Error(ctx.Tr("repo.settings.protect_no_valid_status_check_patterns"))
ctx.Redirect(fmt.Sprintf("%s/settings/branches/edit?rule_name=%s", ctx.Repo.RepoLink, url.QueryEscape(protectBranch.RuleName)))
return
}
protectBranch.StatusCheckContexts = validPatterns
} else { } else {
protectBranch.StatusCheckContexts = nil protectBranch.StatusCheckContexts = nil
} }

View File

@ -199,7 +199,7 @@ type ProtectBranchForm struct {
MergeWhitelistUsers string MergeWhitelistUsers string
MergeWhitelistTeams string MergeWhitelistTeams string
EnableStatusCheck bool EnableStatusCheck bool
StatusCheckContexts []string StatusCheckContexts string
RequiredApprovals int64 RequiredApprovals int64
EnableApprovalsWhitelist bool EnableApprovalsWhitelist bool
ApprovalsWhitelistUsers string ApprovalsWhitelistUsers string

View File

@ -11,14 +11,46 @@ import (
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"github.com/gobwas/glob"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// MergeRequiredContextsCommitStatus returns a commit status state for given required contexts // MergeRequiredContextsCommitStatus returns a commit status state for given required contexts
func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus, requiredContexts []string) structs.CommitStatusState { func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus, requiredContexts []string) structs.CommitStatusState {
if len(requiredContexts) == 0 { // matchedCount is the number of `CommitStatus.Context` that match any context of `requiredContexts`
matchedCount := 0
returnedStatus := structs.CommitStatusSuccess
if len(requiredContexts) > 0 {
requiredContextsGlob := make(map[string]glob.Glob, len(requiredContexts))
for _, ctx := range requiredContexts {
if gp, err := glob.Compile(ctx); err != nil {
log.Error("glob.Compile %s failed. Error: %v", ctx, err)
} else {
requiredContextsGlob[ctx] = gp
}
}
for _, commitStatus := range commitStatuses {
var targetStatus structs.CommitStatusState
for _, gp := range requiredContextsGlob {
if gp.Match(commitStatus.Context) {
targetStatus = commitStatus.State
matchedCount++
break
}
}
if targetStatus != "" && targetStatus.NoBetterThan(returnedStatus) {
returnedStatus = targetStatus
}
}
}
if matchedCount == 0 {
status := git_model.CalcCommitStatus(commitStatuses) status := git_model.CalcCommitStatus(commitStatuses)
if status != nil { if status != nil {
return status.State return status.State
@ -26,28 +58,6 @@ func MergeRequiredContextsCommitStatus(commitStatuses []*git_model.CommitStatus,
return structs.CommitStatusSuccess return structs.CommitStatusSuccess
} }
returnedStatus := structs.CommitStatusSuccess
for _, ctx := range requiredContexts {
var targetStatus structs.CommitStatusState
for _, commitStatus := range commitStatuses {
if commitStatus.Context == ctx {
targetStatus = commitStatus.State
break
}
}
if targetStatus == "" {
targetStatus = structs.CommitStatusPending
commitStatuses = append(commitStatuses, &git_model.CommitStatus{
State: targetStatus,
Context: ctx,
Description: "Pending",
})
}
if targetStatus.NoBetterThan(returnedStatus) {
returnedStatus = targetStatus
}
}
return returnedStatus return returnedStatus
} }

View File

@ -38,6 +38,7 @@
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_label"}}"> <input type="text" placeholder="{{.locale.Tr "repo.issues.filter_label"}}">
</div> </div>
<span class="info">{{.locale.Tr "repo.issues.filter_label_exclude" | Safe}}</span> <span class="info">{{.locale.Tr "repo.issues.filter_label_exclude" | Safe}}</span>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels=0&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_label_select_no_label"}}</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_label_no_select"}}</a> <a class="item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_label_no_select"}}</a>
{{$previousExclusiveScope := "_no_scope"}} {{$previousExclusiveScope := "_no_scope"}}
{{range .Labels}} {{range .Labels}}
@ -156,6 +157,7 @@
<i class="icon gt-df gt-ac gt-jc">{{svg "octicon-search" 16}}</i> <i class="icon gt-df gt-ac gt-jc">{{svg "octicon-search" 16}}</i>
<input type="text" placeholder="{{.locale.Tr "repo.issues.filter_assignee"}}"> <input type="text" placeholder="{{.locale.Tr "repo.issues.filter_assignee"}}">
</div> </div>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee=-1&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_assginee_no_assignee"}}</a>
<a class="item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_assginee_no_select"}}</a> <a class="item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_assginee_no_select"}}</a>
{{range .Assignees}} {{range .Assignees}}
<a class="{{if eq $.AssigneeID .ID}}active selected{{end}} item gt-df" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{.ID}}&poster={{$.PosterID}}"> <a class="{{if eq $.AssigneeID .ID}}active selected{{end}} item gt-df" href="{{$.Link}}?type={{$.ViewType}}&sort={{$.SortType}}&state={{$.State}}&labels={{$.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{.ID}}&poster={{$.PosterID}}">
@ -226,6 +228,9 @@
{{svg "octicon-triangle-down" 14 "dropdown icon"}} {{svg "octicon-triangle-down" 14 "dropdown icon"}}
</span> </span>
<div class="menu"> <div class="menu">
<div class="item issue-action" data-action="clear" data-url="{{$.RepoLink}}/issues/labels">
{{.locale.Tr "repo.issues.new.clear_labels"}}
</div>
{{$previousExclusiveScope := "_no_scope"}} {{$previousExclusiveScope := "_no_scope"}}
{{range .Labels}} {{range .Labels}}
{{$exclusiveScope := .ExclusiveScope}} {{$exclusiveScope := .ExclusiveScope}}
@ -313,6 +318,9 @@
{{svg "octicon-triangle-down" 14 "dropdown icon"}} {{svg "octicon-triangle-down" 14 "dropdown icon"}}
</span> </span>
<div class="menu"> <div class="menu">
<div class="item issue-action" data-action="clear" data-url="{{$.Link}}/assignee">
{{.locale.Tr "repo.issues.new.clear_assignees"}}
</div>
<div class="item issue-action" data-element-id="0" data-url="{{$.Link}}/assignee"> <div class="item issue-action" data-element-id="0" data-url="{{$.Link}}/assignee">
{{.locale.Tr "repo.issues.action_assignee_no_select"}} {{.locale.Tr "repo.issues.action_assignee_no_select"}}
</div> </div>

View File

@ -157,6 +157,9 @@
</div> </div>
</div> </div>
<div id="statuscheck_contexts_box" class="checkbox-sub-item field {{if not .Rule.EnableStatusCheck}}disabled{{end}}"> <div id="statuscheck_contexts_box" class="checkbox-sub-item field {{if not .Rule.EnableStatusCheck}}disabled{{end}}">
<label>{{.locale.Tr "repo.settings.protect_status_check_patterns"}}</label>
<textarea id="status_check_contexts" name="status_check_contexts" rows="3">{{.status_check_contexts}}</textarea>
<p class="help">{{.locale.Tr "repo.settings.protect_status_check_patterns_desc"}}</p>
<table class="ui celled table"> <table class="ui celled table">
<thead> <thead>
<tr> <tr>
@ -164,13 +167,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{{range $.branch_status_check_contexts}} {{range $.recent_status_checks}}
<tr> <tr>
<td> <td>
<span class="ui checkbox"> <span>{{.}}</span>
<label>{{.}}</label> <span class="status-check-matched-mark gt-hidden" data-status-check="{{.}}">{{$.locale.Tr "repo.settings.protect_status_check_matched"}}</span>
<input name="status_check_contexts" value="{{.}}" type="checkbox" {{if SliceUtils.Contains $.Rule.StatusCheckContexts .}}checked{{end}}>
</span>
</td> </td>
</tr> </tr>
{{else}} {{else}}

View File

@ -1990,6 +1990,11 @@
padding-left: 26px; padding-left: 26px;
} }
.repository.settings.branches .branch-protection .status-check-matched-mark {
font-weight: var(--font-weight-bold);
font-style: italic;
}
.repository.settings.webhook .events .column { .repository.settings.webhook .events .column {
padding-bottom: 0; padding-bottom: 0;
} }

View File

@ -10,7 +10,5 @@ env:
rules: rules:
vue/attributes-order: [0] vue/attributes-order: [0]
vue/component-definition-name-casing: [0]
vue/html-closing-bracket-spacing: [0] vue/html-closing-bracket-spacing: [0]
vue/max-attributes-per-line: [0] vue/max-attributes-per-line: [0]
vue/one-component-per-file: [0]

View File

@ -31,8 +31,8 @@ export default {
}, },
data: () => ({ data: () => ({
colorRange: [ colorRange: [
'var(--color-secondary-alpha-70)', 'var(--color-secondary-alpha-60)',
'var(--color-secondary-alpha-70)', 'var(--color-secondary-alpha-60)',
'var(--color-primary-light-4)', 'var(--color-primary-light-4)',
'var(--color-primary-light-2)', 'var(--color-primary-light-2)',
'var(--color-primary)', 'var(--color-primary)',

View File

@ -36,7 +36,7 @@ export function initCopyContent() {
} }
} else { // text, read from DOM } else { // text, read from DOM
const lineEls = document.querySelectorAll('.file-view .lines-code'); const lineEls = document.querySelectorAll('.file-view .lines-code');
content = Array.from(lineEls).map((el) => el.textContent).join(''); content = Array.from(lineEls, (el) => el.textContent).join('');
} }
// try copy original first, if that fails and it's an image, convert it to png // try copy original first, if that fails and it's an image, convert it to png

View File

@ -15,7 +15,7 @@ function moveIssue({item, from, to, oldIndex}) {
updateIssueCount(to); updateIssueCount(to);
const columnSorting = { const columnSorting = {
issues: [...columnCards].map((card, i) => ({ issues: Array.from(columnCards, (card, i) => ({
issueID: parseInt($(card).attr('data-issue')), issueID: parseInt($(card).attr('data-issue')),
sorting: i sorting: i
})) }))

View File

@ -1,5 +1,7 @@
import $ from 'jquery'; import $ from 'jquery';
import {minimatch} from 'minimatch';
import {createMonaco} from './codeeditor.js'; import {createMonaco} from './codeeditor.js';
import {onInputDebounce, toggleElem} from '../utils/dom.js';
const {appSubUrl, csrfToken} = window.config; const {appSubUrl, csrfToken} = window.config;
@ -81,4 +83,26 @@ export function initRepoSettingBranches() {
const $target = $($(this).attr('data-target')); const $target = $($(this).attr('data-target'));
if (this.checked) $target.addClass('disabled'); // only disable, do not auto enable if (this.checked) $target.addClass('disabled'); // only disable, do not auto enable
}); });
// show the `Matched` mark for the status checks that match the pattern
const markMatchedStatusChecks = () => {
const patterns = (document.getElementById('status_check_contexts').value || '').split(/[\r\n]+/);
const validPatterns = patterns.map((item) => item.trim()).filter(Boolean);
const marks = document.getElementsByClassName('status-check-matched-mark');
for (const el of marks) {
let matched = false;
const statusCheck = el.getAttribute('data-status-check');
for (const pattern of validPatterns) {
if (minimatch(statusCheck, pattern)) {
matched = true;
break;
}
}
toggleElem(el, matched);
}
};
markMatchedStatusChecks();
document.getElementById('status_check_contexts').addEventListener('input', onInputDebounce(markMatchedStatusChecks));
} }

View File

@ -3,7 +3,7 @@ import emojis from '../../../assets/emoji.json';
const maxMatches = 6; const maxMatches = 6;
function sortAndReduce(map) { function sortAndReduce(map) {
const sortedMap = new Map([...map.entries()].sort((a, b) => a[1] - b[1])); const sortedMap = new Map(Array.from(map.entries()).sort((a, b) => a[1] - b[1]));
return Array.from(sortedMap.keys()).slice(0, maxMatches); return Array.from(sortedMap.keys()).slice(0, maxMatches);
} }