diff --git a/.air.toml b/.air.toml
index 3740c4d4aa..8854041a25 100644
--- a/.air.toml
+++ b/.air.toml
@@ -21,3 +21,6 @@ exclude_dir = [
]
exclude_regex = ["_test.go$", "_gen.go$"]
stop_on_error = true
+
+[log]
+main_only = true
diff --git a/.eslintrc.yaml b/.eslintrc.yaml
index 3b25995c09..293d435b11 100644
--- a/.eslintrc.yaml
+++ b/.eslintrc.yaml
@@ -6,17 +6,30 @@ ignorePatterns:
- /web_src/fomantic
- /public/assets/js
+parser: "@typescript-eslint/parser"
+
parserOptions:
sourceType: module
ecmaVersion: latest
+ project: true
+ extraFileExtensions: [".vue"]
+ parser: "@typescript-eslint/parser" # for vue plugin - https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser
+
+settings:
+ import/extensions: [".js", ".ts"]
+ import/parsers:
+ "@typescript-eslint/parser": [".js", ".ts"]
+ import/resolver:
+ typescript: true
plugins:
- "@eslint-community/eslint-plugin-eslint-comments"
- "@stylistic/eslint-plugin-js"
+ - "@typescript-eslint/eslint-plugin"
- eslint-plugin-array-func
+ - eslint-plugin-deprecation
- eslint-plugin-github
- eslint-plugin-i
- - eslint-plugin-jquery
- eslint-plugin-no-jquery
- eslint-plugin-no-use-extend-native
- eslint-plugin-regexp
@@ -34,6 +47,7 @@ overrides:
- files: ["web_src/**/*"]
globals:
__webpack_public_path__: true
+ htmx: true
process: false # https://github.com/webpack/webpack/issues/15833
- files: ["web_src/**/*", "docs/**/*"]
env:
@@ -103,6 +117,22 @@ overrides:
- files: ["web_src/js/modules/fetch.js", "web_src/js/standalone/**/*"]
rules:
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression]
+ - files: ["**/*.vue"]
+ plugins:
+ - eslint-plugin-vue
+ - eslint-plugin-vue-scoped-css
+ extends:
+ - plugin:vue/vue3-recommended
+ - plugin:vue-scoped-css/vue3-recommended
+ rules:
+ vue/attributes-order: [0]
+ vue/html-closing-bracket-spacing: [2, {startTag: never, endTag: never, selfClosingTag: never}]
+ vue/max-attributes-per-line: [0]
+ vue/singleline-html-element-content-newline: [0]
+ - files: ["tests/e2e/**"]
+ plugins:
+ - eslint-plugin-playwright
+ extends: plugin:playwright/recommended
rules:
"@eslint-community/eslint-comments/disable-enable-pair": [2]
@@ -182,6 +212,123 @@ rules:
"@stylistic/js/wrap-iife": [2, inside]
"@stylistic/js/wrap-regex": [0]
"@stylistic/js/yield-star-spacing": [2, after]
+ "@typescript-eslint/adjacent-overload-signatures": [0]
+ "@typescript-eslint/array-type": [0]
+ "@typescript-eslint/await-thenable": [2]
+ "@typescript-eslint/ban-ts-comment": [2, {'ts-expect-error': false, 'ts-ignore': true, 'ts-nocheck': false, 'ts-check': false}]
+ "@typescript-eslint/ban-tslint-comment": [0]
+ "@typescript-eslint/ban-types": [2, {extendDefaults: true, types: {Function: false}}]
+ "@typescript-eslint/class-literal-property-style": [0]
+ "@typescript-eslint/class-methods-use-this": [0]
+ "@typescript-eslint/consistent-generic-constructors": [0]
+ "@typescript-eslint/consistent-indexed-object-style": [0]
+ "@typescript-eslint/consistent-return": [0]
+ "@typescript-eslint/consistent-type-assertions": [2, {assertionStyle: as, objectLiteralTypeAssertions: allow}]
+ "@typescript-eslint/consistent-type-definitions": [2, type]
+ "@typescript-eslint/consistent-type-exports": [2, {fixMixedExportsWithInlineTypeSpecifier: false}]
+ "@typescript-eslint/consistent-type-imports": [2, {prefer: type-imports, fixStyle: separate-type-imports, disallowTypeAnnotations: true}]
+ "@typescript-eslint/default-param-last": [0]
+ "@typescript-eslint/dot-notation": [0]
+ "@typescript-eslint/explicit-function-return-type": [0]
+ "@typescript-eslint/explicit-member-accessibility": [0]
+ "@typescript-eslint/explicit-module-boundary-types": [0]
+ "@typescript-eslint/init-declarations": [0]
+ "@typescript-eslint/max-params": [0]
+ "@typescript-eslint/member-ordering": [0]
+ "@typescript-eslint/method-signature-style": [0]
+ "@typescript-eslint/naming-convention": [0]
+ "@typescript-eslint/no-array-constructor": [2]
+ "@typescript-eslint/no-array-delete": [2]
+ "@typescript-eslint/no-base-to-string": [0]
+ "@typescript-eslint/no-confusing-non-null-assertion": [2]
+ "@typescript-eslint/no-confusing-void-expression": [0]
+ "@typescript-eslint/no-dupe-class-members": [0]
+ "@typescript-eslint/no-duplicate-enum-values": [2]
+ "@typescript-eslint/no-duplicate-type-constituents": [2, {ignoreUnions: true}]
+ "@typescript-eslint/no-dynamic-delete": [0]
+ "@typescript-eslint/no-empty-function": [0]
+ "@typescript-eslint/no-empty-interface": [0]
+ "@typescript-eslint/no-explicit-any": [0]
+ "@typescript-eslint/no-extra-non-null-assertion": [2]
+ "@typescript-eslint/no-extraneous-class": [0]
+ "@typescript-eslint/no-floating-promises": [0]
+ "@typescript-eslint/no-for-in-array": [2]
+ "@typescript-eslint/no-implied-eval": [2]
+ "@typescript-eslint/no-import-type-side-effects": [0] # dupe with consistent-type-imports
+ "@typescript-eslint/no-inferrable-types": [0]
+ "@typescript-eslint/no-invalid-this": [0]
+ "@typescript-eslint/no-invalid-void-type": [0]
+ "@typescript-eslint/no-loop-func": [0]
+ "@typescript-eslint/no-loss-of-precision": [2]
+ "@typescript-eslint/no-magic-numbers": [0]
+ "@typescript-eslint/no-meaningless-void-operator": [0]
+ "@typescript-eslint/no-misused-new": [2]
+ "@typescript-eslint/no-misused-promises": [2, {checksVoidReturn: {attributes: false, arguments: false}}]
+ "@typescript-eslint/no-mixed-enums": [0]
+ "@typescript-eslint/no-namespace": [2]
+ "@typescript-eslint/no-non-null-asserted-nullish-coalescing": [0]
+ "@typescript-eslint/no-non-null-asserted-optional-chain": [2]
+ "@typescript-eslint/no-non-null-assertion": [0]
+ "@typescript-eslint/no-redeclare": [0]
+ "@typescript-eslint/no-redundant-type-constituents": [2]
+ "@typescript-eslint/no-require-imports": [0]
+ "@typescript-eslint/no-restricted-imports": [0]
+ "@typescript-eslint/no-shadow": [0]
+ "@typescript-eslint/no-this-alias": [0] # handled by unicorn/no-this-assignment
+ "@typescript-eslint/no-unnecessary-boolean-literal-compare": [0]
+ "@typescript-eslint/no-unnecessary-condition": [0]
+ "@typescript-eslint/no-unnecessary-qualifier": [0]
+ "@typescript-eslint/no-unnecessary-template-expression": [0]
+ "@typescript-eslint/no-unnecessary-type-arguments": [0]
+ "@typescript-eslint/no-unnecessary-type-assertion": [2]
+ "@typescript-eslint/no-unnecessary-type-constraint": [2]
+ "@typescript-eslint/no-unsafe-argument": [0]
+ "@typescript-eslint/no-unsafe-assignment": [0]
+ "@typescript-eslint/no-unsafe-call": [0]
+ "@typescript-eslint/no-unsafe-declaration-merging": [2]
+ "@typescript-eslint/no-unsafe-enum-comparison": [2]
+ "@typescript-eslint/no-unsafe-member-access": [0]
+ "@typescript-eslint/no-unsafe-return": [0]
+ "@typescript-eslint/no-unsafe-unary-minus": [2]
+ "@typescript-eslint/no-unused-expressions": [0]
+ "@typescript-eslint/no-unused-vars": [2, {vars: all, args: all, caughtErrors: all, ignoreRestSiblings: false, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_}]
+ "@typescript-eslint/no-use-before-define": [0]
+ "@typescript-eslint/no-useless-constructor": [0]
+ "@typescript-eslint/no-useless-empty-export": [0]
+ "@typescript-eslint/no-var-requires": [2]
+ "@typescript-eslint/non-nullable-type-assertion-style": [0]
+ "@typescript-eslint/only-throw-error": [2]
+ "@typescript-eslint/parameter-properties": [0]
+ "@typescript-eslint/prefer-as-const": [2]
+ "@typescript-eslint/prefer-destructuring": [0]
+ "@typescript-eslint/prefer-enum-initializers": [0]
+ "@typescript-eslint/prefer-find": [2]
+ "@typescript-eslint/prefer-for-of": [2]
+ "@typescript-eslint/prefer-function-type": [2]
+ "@typescript-eslint/prefer-includes": [2]
+ "@typescript-eslint/prefer-literal-enum-member": [0]
+ "@typescript-eslint/prefer-namespace-keyword": [0]
+ "@typescript-eslint/prefer-nullish-coalescing": [0]
+ "@typescript-eslint/prefer-optional-chain": [2, {requireNullish: true}]
+ "@typescript-eslint/prefer-promise-reject-errors": [0]
+ "@typescript-eslint/prefer-readonly": [0]
+ "@typescript-eslint/prefer-readonly-parameter-types": [0]
+ "@typescript-eslint/prefer-reduce-type-parameter": [0]
+ "@typescript-eslint/prefer-regexp-exec": [0]
+ "@typescript-eslint/prefer-return-this-type": [0]
+ "@typescript-eslint/prefer-string-starts-ends-with": [2, {allowSingleElementEquality: always}]
+ "@typescript-eslint/promise-function-async": [0]
+ "@typescript-eslint/require-array-sort-compare": [0]
+ "@typescript-eslint/require-await": [0]
+ "@typescript-eslint/restrict-plus-operands": [2]
+ "@typescript-eslint/restrict-template-expressions": [0]
+ "@typescript-eslint/return-await": [0]
+ "@typescript-eslint/strict-boolean-expressions": [0]
+ "@typescript-eslint/switch-exhaustiveness-check": [0]
+ "@typescript-eslint/triple-slash-reference": [2]
+ "@typescript-eslint/typedef": [0]
+ "@typescript-eslint/unbound-method": [2]
+ "@typescript-eslint/unified-signatures": [2]
accessor-pairs: [2]
array-callback-return: [2, {checkForEach: true}]
array-func/avoid-reverse: [2]
@@ -203,6 +350,7 @@ rules:
default-case-last: [2]
default-case: [0]
default-param-last: [0]
+ deprecation/deprecation: [2]
dot-notation: [0]
eqeqeq: [2]
for-direction: [2]
@@ -264,7 +412,7 @@ rules:
i/no-internal-modules: [0]
i/no-mutable-exports: [0]
i/no-named-as-default-member: [0]
- i/no-named-as-default: [2]
+ i/no-named-as-default: [0]
i/no-named-default: [0]
i/no-named-export: [0]
i/no-namespace: [0]
@@ -274,7 +422,7 @@ rules:
i/no-restricted-paths: [0]
i/no-self-import: [2]
i/no-unassigned-import: [0]
- i/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$", ^vitest/]}]
+ i/no-unresolved: [2, {commonjs: true, ignore: ["\\?.+$"]}]
i/no-unused-modules: [2, {unusedExports: true}]
i/no-useless-path-segments: [2, {commonjs: true}]
i/no-webpack-loader-syntax: [2]
@@ -282,55 +430,6 @@ rules:
i/prefer-default-export: [0]
i/unambiguous: [0]
init-declarations: [0]
- jquery/no-ajax-events: [2]
- jquery/no-ajax: [2]
- jquery/no-animate: [2]
- jquery/no-attr: [2]
- jquery/no-bind: [2]
- jquery/no-class: [0]
- jquery/no-clone: [2]
- jquery/no-closest: [0]
- jquery/no-css: [2]
- jquery/no-data: [0]
- jquery/no-deferred: [2]
- jquery/no-delegate: [2]
- jquery/no-each: [0]
- jquery/no-extend: [2]
- jquery/no-fade: [2]
- jquery/no-filter: [0]
- jquery/no-find: [0]
- jquery/no-global-eval: [2]
- jquery/no-grep: [2]
- jquery/no-has: [2]
- jquery/no-hide: [2]
- jquery/no-html: [0]
- jquery/no-in-array: [2]
- jquery/no-is-array: [2]
- jquery/no-is-function: [2]
- jquery/no-is: [2]
- jquery/no-load: [2]
- jquery/no-map: [2]
- jquery/no-merge: [2]
- jquery/no-param: [2]
- jquery/no-parent: [0]
- jquery/no-parents: [2]
- jquery/no-parse-html: [2]
- jquery/no-prop: [2]
- jquery/no-proxy: [2]
- jquery/no-ready: [2]
- jquery/no-serialize: [2]
- jquery/no-show: [2]
- jquery/no-size: [2]
- jquery/no-sizzle: [2]
- jquery/no-slide: [2]
- jquery/no-submit: [2]
- jquery/no-text: [2]
- jquery/no-toggle: [2]
- jquery/no-trigger: [0]
- jquery/no-trim: [2]
- jquery/no-val: [0]
- jquery/no-when: [2]
- jquery/no-wrap: [2]
line-comment-position: [0]
logical-assignment-operators: [0]
max-classes-per-file: [0]
@@ -343,7 +442,7 @@ rules:
multiline-comment-style: [2, separate-lines]
new-cap: [0]
no-alert: [0]
- no-array-constructor: [2]
+ no-array-constructor: [0] # handled by @typescript-eslint/no-array-constructor
no-async-promise-executor: [0]
no-await-in-loop: [0]
no-bitwise: [0]
@@ -387,7 +486,7 @@ rules:
no-global-assign: [2]
no-implicit-coercion: [2]
no-implicit-globals: [0]
- no-implied-eval: [2]
+ no-implied-eval: [0] # handled by @typescript-eslint/no-implied-eval
no-import-assign: [2]
no-inline-comments: [0]
no-inner-declarations: [2]
@@ -493,7 +592,7 @@ rules:
no-lone-blocks: [2]
no-lonely-if: [0]
no-loop-func: [0]
- no-loss-of-precision: [2]
+ no-loss-of-precision: [0] # handled by @typescript-eslint/no-loss-of-precision
no-magic-numbers: [0]
no-misleading-character-class: [2]
no-multi-assign: [0]
@@ -515,7 +614,7 @@ rules:
no-promise-executor-return: [0]
no-proto: [2]
no-prototype-builtins: [2]
- no-redeclare: [2]
+ no-redeclare: [0] # must be disabled for typescript overloads
no-regex-spaces: [2]
no-restricted-exports: [0]
no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, 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, self, status, statusbar, stop, toolbar, top, __dirname, __filename]
@@ -548,7 +647,7 @@ rules:
no-unused-expressions: [2]
no-unused-labels: [2]
no-unused-private-class-members: [2]
- no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}]
+ no-unused-vars: [0] # handled by @typescript-eslint/no-unused-vars
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]
@@ -663,7 +762,7 @@ rules:
regexp/unicode-escape: [0]
regexp/use-ignore-case: [0]
require-atomic-updates: [0]
- require-await: [0]
+ require-await: [0] # handled by @typescript-eslint/require-await
require-unicode-regexp: [0]
require-yield: [2]
sonarjs/cognitive-complexity: [0]
@@ -740,6 +839,7 @@ rules:
unicorn/no-lonely-if: [2]
unicorn/no-magic-array-flat-depth: [0]
unicorn/no-negated-condition: [0]
+ unicorn/no-negation-in-equality-check: [2]
unicorn/no-nested-ternary: [0]
unicorn/no-new-array: [0]
unicorn/no-new-buffer: [0]
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index b752abb794..b7594a1ba7 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,9 +1,10 @@
-
+
Please check the following:
1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for backports.
2. Make sure you have read contributing guidelines: https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md .
-3. Describe what your pull request does and which issue you're targeting (if any).
-4. It is recommended to enable "Allow edits by maintainers", so maintainers can help more easily.
-5. Your input here will be included in the commit message when this PR has been merged. If you don't want some content to be included, please separate them with a line like `---`.
-6. Delete all these tips before posting.
+3. For documentations contribution, please go to https://gitea.com/gitea/docs
+4. Describe what your pull request does and which issue you're targeting (if any).
+5. It is recommended to enable "Allow edits by maintainers", so maintainers can help more easily.
+6. Your input here will be included in the commit message when this PR has been merged. If you don't want some content to be included, please separate them with a line like `---`.
+7. Delete all these tips before posting.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 04c06ffd14..60146276db 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -358,7 +358,8 @@ $REWRITTEN_PR_SUMMARY
## Documentation
-If you add a new feature or change an existing aspect of Gitea, the documentation for that feature must be created or updated in the same PR.
+If you add a new feature or change an existing aspect of Gitea, the documentation for that feature must be created or updated in another PR at [https://gitea.com/gitea/docs](https://gitea.com/gitea/docs).
+**The docs directory on main repository will be removed at some time. We will have a yaml file to store configuration file's meta data. After that completed, configuration documentation should be in the main repository.**
## API v1
diff --git a/Dockerfile b/Dockerfile
index 21a8ce0d75..6621dded9d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,11 +2,11 @@
FROM docker.io/library/golang:1.22-alpine3.20 AS build-env
ARG GOPROXY
-ENV GOPROXY ${GOPROXY:-direct}
+ENV GOPROXY=${GOPROXY:-direct}
ARG GITEA_VERSION
ARG TAGS="sqlite sqlite_unlock_notify"
-ENV TAGS "bindata timetzdata $TAGS"
+ENV TAGS="bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS
# Build deps
@@ -72,8 +72,8 @@ RUN addgroup \
git && \
echo "git:*" | chpasswd -e
-ENV USER git
-ENV GITEA_CUSTOM /data/gitea
+ENV USER=git
+ENV GITEA_CUSTOM=/data/gitea
VOLUME ["/data"]
diff --git a/Dockerfile.rootless b/Dockerfile.rootless
index b1d2368252..736cea5d05 100644
--- a/Dockerfile.rootless
+++ b/Dockerfile.rootless
@@ -2,11 +2,11 @@
FROM docker.io/library/golang:1.22-alpine3.20 AS build-env
ARG GOPROXY
-ENV GOPROXY ${GOPROXY:-direct}
+ENV GOPROXY=${GOPROXY:-direct}
ARG GITEA_VERSION
ARG TAGS="sqlite sqlite_unlock_notify"
-ENV TAGS "bindata timetzdata $TAGS"
+ENV TAGS="bindata timetzdata $TAGS"
ARG CGO_EXTRA_CFLAGS
#Build deps
@@ -75,14 +75,14 @@ COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_au
# git:git
USER 1000:1000
-ENV GITEA_WORK_DIR /var/lib/gitea
-ENV GITEA_CUSTOM /var/lib/gitea/custom
-ENV GITEA_TEMP /tmp/gitea
-ENV TMPDIR /tmp/gitea
+ENV GITEA_WORK_DIR=/var/lib/gitea
+ENV GITEA_CUSTOM=/var/lib/gitea/custom
+ENV GITEA_TEMP=/tmp/gitea
+ENV TMPDIR=/tmp/gitea
# TODO add to docs the ability to define the ini to load (useful to test and revert a config)
-ENV GITEA_APP_INI /etc/gitea/app.ini
-ENV HOME "/var/lib/gitea/git"
+ENV GITEA_APP_INI=/etc/gitea/app.ini
+ENV HOME="/var/lib/gitea/git"
VOLUME ["/var/lib/gitea", "/etc/gitea"]
WORKDIR /var/lib/gitea
diff --git a/Makefile b/Makefile
index b5a79091eb..d329a4ac3b 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@ GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.6.0
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.0
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.5.1
-SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@db51e79a0e37c572d8b59ae0c58bf2bbbbe53285
+SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.31.0
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1
@@ -375,11 +375,13 @@ 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 $(ESLINT_FILES)
+ npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES)
+ npx tsc
.PHONY: lint-js-fix
lint-js-fix: node_modules
- npx eslint --color --max-warnings=0 --ext js,vue $(ESLINT_FILES) --fix
+ npx eslint --color --max-warnings=0 --ext js,ts,vue $(ESLINT_FILES) --fix
+ npx tsc
.PHONY: lint-css
lint-css: node_modules
@@ -967,7 +969,7 @@ generate-gitignore:
.PHONY: generate-images
generate-images: | node_modules
- npm install --no-save fabric@6.0.0-beta20 imagemin-zopfli@7
+ npm install --no-save fabric@6 imagemin-zopfli@7
node tools/generate-images.js $(TAGS)
.PHONY: generate-manpage
diff --git a/README.md b/README.md
index fd96f9efbd..c280c832ac 100644
--- a/README.md
+++ b/README.md
@@ -8,9 +8,8 @@
[![](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
[![](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
[![](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT "License: MIT")
-[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/go-gitea/gitea)
+[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea)
[![](https://badges.crowdin.net/gitea/localized.svg)](https://crowdin.com/project/gitea "Crowdin")
-[![](https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main)](https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main "TODOs")
[View this document in Chinese](./README_ZH.md)
diff --git a/README_ZH.md b/README_ZH.md
index 7aa7900a47..a2e36dc22f 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -8,9 +8,8 @@
[![](https://www.codetriage.com/go-gitea/gitea/badges/users.svg)](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
[![](https://opencollective.com/gitea/tiers/backers/badge.svg?label=backers&color=brightgreen)](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
[![](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT "License: MIT")
-[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/go-gitea/gitea)
+[![Contribute with Gitpod](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod&color=green)](https://gitpod.io/#https://github.com/go-gitea/gitea)
[![](https://badges.crowdin.net/gitea/localized.svg)](https://crowdin.com/project/gitea "Crowdin")
-[![](https://badgen.net/https/api.tickgit.com/badgen/github.com/go-gitea/gitea/main)](https://www.tickgit.com/browse?repo=github.com/go-gitea/gitea&branch=main "TODOs")
[View this document in English](./README.md)
diff --git a/assets/go-licenses.json b/assets/go-licenses.json
index c013b4c482..91324146f6 100644
--- a/assets/go-licenses.json
+++ b/assets/go-licenses.json
@@ -244,6 +244,11 @@
"path": "github.com/blevesearch/zapx/v15/LICENSE",
"licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License."
},
+ {
+ "name": "github.com/blevesearch/zapx/v16",
+ "path": "github.com/blevesearch/zapx/v16/LICENSE",
+ "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License."
+ },
{
"name": "github.com/boombuler/barcode",
"path": "github.com/boombuler/barcode/LICENSE",
@@ -264,6 +269,11 @@
"path": "github.com/caddyserver/certmagic/LICENSE.txt",
"licenseText": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"{}\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright {yyyy} {name of copyright owner}\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n"
},
+ {
+ "name": "github.com/caddyserver/zerossl",
+ "path": "github.com/caddyserver/zerossl/LICENSE",
+ "licenseText": "MIT License\n\nCopyright (c) 2024 Matthew Holt\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
+ },
{
"name": "github.com/cention-sany/utf7",
"path": "github.com/cention-sany/utf7/LICENSE",
@@ -755,8 +765,8 @@
"licenseText": "MIT License\n\nCopyright (c) 2020-2024 Meili SAS\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
},
{
- "name": "github.com/mholt/acmez",
- "path": "github.com/mholt/acmez/LICENSE",
+ "name": "github.com/mholt/acmez/v2",
+ "path": "github.com/mholt/acmez/v2/LICENSE",
"licenseText": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n"
},
{
@@ -794,11 +804,6 @@
"path": "github.com/minio/minio-go/v7/LICENSE",
"licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n"
},
- {
- "name": "github.com/minio/sha256-simd",
- "path": "github.com/minio/sha256-simd/LICENSE",
- "licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright [yyyy] [name of copyright owner]\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n"
- },
{
"name": "github.com/mitchellh/mapstructure",
"path": "github.com/mitchellh/mapstructure/LICENSE",
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index e619aae729..9196180d81 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -81,6 +81,10 @@ RUN_USER = ; git
;; Overwrite the automatically generated public URL. Necessary for proxies and docker.
;ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
;;
+;; For development purpose only. It makes Gitea handle sub-path ("/sub-path/owner/repo/...") directly when debugging without a reverse proxy.
+;; DO NOT USE IT IN PRODUCTION!!!
+;USE_SUB_URL_PATH = false
+;;
;; when STATIC_URL_PREFIX is empty it will follow ROOT_URL
;STATIC_URL_PREFIX =
;;
diff --git a/docs/content/contributing/guidelines-frontend.en-us.md b/docs/content/contributing/guidelines-frontend.en-us.md
index a08098a931..5539532c52 100644
--- a/docs/content/contributing/guidelines-frontend.en-us.md
+++ b/docs/content/contributing/guidelines-frontend.en-us.md
@@ -79,6 +79,22 @@ We use htmx for simple interactions. You can see an example for simple interacti
Although mixing different frameworks is discouraged,
it should also work if the mixing is necessary and the code is well-designed and maintainable.
+### Typescript
+
+Gitea is in the process of migrating to type-safe Typescript. Here are some specific guidelines regarding Typescript in the codebase:
+
+#### Use type aliases instead of interfaces
+
+Prefer to use type aliases because they can represent any type and are generally more flexible to use than interfaces.
+
+#### Use separate type imports
+
+We use `verbatimModuleSyntax` so type and non-type imports from the same file must be split into two `import type` statements. This enables the typescript compiler to completely eliminate the type import statements during compilation.
+
+#### Use `@ts-expect-error` instead of `@ts-ignore`
+
+Both annotations should be avoided, but if you have to use them, use `@ts-expect-error` because it will not leave ineffective statements after the issue is fixed.
+
### `async` Functions
Only mark a function as `async` if and only if there are `await` calls
diff --git a/go.mod b/go.mod
index ed9d806a65..5b175ff1f5 100644
--- a/go.mod
+++ b/go.mod
@@ -15,108 +15,108 @@ require (
gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121
- github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
+ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358
github.com/ProtonMail/go-crypto v1.0.0
- github.com/PuerkitoBio/goquery v1.9.1
+ github.com/PuerkitoBio/goquery v1.9.2
github.com/alecthomas/chroma/v2 v2.14.0
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
- github.com/blevesearch/bleve/v2 v2.3.10
- github.com/buildkite/terminal-to-html/v3 v3.11.0
- github.com/caddyserver/certmagic v0.20.0
+ github.com/blevesearch/bleve/v2 v2.4.0
+ github.com/buildkite/terminal-to-html/v3 v3.12.1
+ github.com/caddyserver/certmagic v0.21.3
github.com/chi-middleware/proxy v1.1.1
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21
github.com/djherbis/buffer v1.2.0
github.com/djherbis/nio/v3 v3.0.1
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5
github.com/dustin/go-humanize v1.0.1
- github.com/editorconfig/editorconfig-core-go/v2 v2.6.1
+ github.com/editorconfig/editorconfig-core-go/v2 v2.6.2
github.com/emersion/go-imap v1.2.1
github.com/emirpasic/gods v1.18.1
github.com/ethantkoenig/rupture v1.0.1
github.com/felixge/fgprof v0.9.4
github.com/fsnotify/fsnotify v1.7.0
- github.com/gliderlabs/ssh v0.3.6
- github.com/go-ap/activitypub v0.0.0-20240316125321-b61fd6a83225
+ github.com/gliderlabs/ssh v0.3.7
+ github.com/go-ap/activitypub v0.0.0-20240408091739-ba76b44c2594
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73
- github.com/go-chi/chi/v5 v5.0.12
+ github.com/go-chi/chi/v5 v5.0.13
github.com/go-chi/cors v1.2.1
github.com/go-co-op/gocron v1.37.0
- github.com/go-enry/go-enry/v2 v2.8.7
+ github.com/go-enry/go-enry/v2 v2.8.8
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
github.com/go-git/go-billy/v5 v5.5.0
- github.com/go-git/go-git/v5 v5.11.0
+ github.com/go-git/go-git/v5 v5.12.0
github.com/go-ldap/ldap/v3 v3.4.6
- github.com/go-sql-driver/mysql v1.8.0
- github.com/go-swagger/go-swagger v0.30.5
- github.com/go-testfixtures/testfixtures/v3 v3.10.0
+ github.com/go-sql-driver/mysql v1.8.1
+ github.com/go-swagger/go-swagger v0.31.0
+ github.com/go-testfixtures/testfixtures/v3 v3.11.0
github.com/go-webauthn/webauthn v0.10.2
github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/go-github/v61 v61.0.0
- github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7
+ github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8
github.com/google/uuid v1.6.0
- github.com/gorilla/feeds v1.1.2
- github.com/gorilla/sessions v1.2.2
+ github.com/gorilla/feeds v1.2.0
+ github.com/gorilla/sessions v1.3.0
github.com/h2non/gock v1.2.0
- github.com/hashicorp/go-version v1.6.0
+ github.com/hashicorp/go-version v1.7.0
github.com/hashicorp/golang-lru/v2 v2.0.7
- github.com/huandu/xstrings v1.4.0
+ github.com/huandu/xstrings v1.5.0
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056
github.com/jhillyerd/enmime v1.2.0
github.com/json-iterator/go v1.1.12
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
- github.com/klauspost/compress v1.17.8
- github.com/klauspost/cpuid/v2 v2.2.7
+ github.com/klauspost/compress v1.17.9
+ github.com/klauspost/cpuid/v2 v2.2.8
github.com/lib/pq v1.10.9
- github.com/markbates/goth v1.79.0
+ github.com/markbates/goth v1.80.0
github.com/mattn/go-isatty v0.0.20
github.com/mattn/go-sqlite3 v1.14.22
- github.com/meilisearch/meilisearch-go v0.26.2
+ github.com/meilisearch/meilisearch-go v0.26.3
github.com/mholt/archiver/v3 v3.5.1
github.com/microcosm-cc/bluemonday v1.0.26
- github.com/microsoft/go-mssqldb v1.7.0
- github.com/minio/minio-go/v7 v7.0.69
+ github.com/microsoft/go-mssqldb v1.7.2
+ github.com/minio/minio-go/v7 v7.0.71
github.com/msteinert/pam v1.2.0
- github.com/nektos/act v0.2.52
+ github.com/nektos/act v0.2.63
github.com/niklasfasching/go-org v1.7.0
github.com/olivere/elastic/v7 v7.0.32
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0
github.com/pkg/errors v0.9.1
github.com/pquerna/otp v1.4.0
- github.com/prometheus/client_golang v1.19.0
+ github.com/prometheus/client_golang v1.19.1
github.com/quasoft/websspi v1.1.2
- github.com/redis/go-redis/v9 v9.5.1
+ github.com/redis/go-redis/v9 v9.5.3
github.com/robfig/cron/v3 v3.0.1
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
- github.com/sassoftware/go-rpmutils v0.3.0
- github.com/sergi/go-diff v1.3.1
+ github.com/sassoftware/go-rpmutils v0.4.0
+ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92
github.com/stretchr/testify v1.9.0
github.com/syndtr/goleveldb v1.0.0
github.com/tstranex/u2f v1.0.0
- github.com/ulikunitz/xz v0.5.11
- github.com/urfave/cli/v2 v2.27.1
- github.com/xanzy/go-gitlab v0.100.0
+ github.com/ulikunitz/xz v0.5.12
+ github.com/urfave/cli/v2 v2.27.2
+ github.com/xanzy/go-gitlab v0.105.0
github.com/xeipuuv/gojsonschema v1.2.0
github.com/yohcop/openid-go v1.0.1
- github.com/yuin/goldmark v1.7.0
+ github.com/yuin/goldmark v1.7.2
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
github.com/yuin/goldmark-meta v1.1.0
golang.org/x/crypto v0.24.0
- golang.org/x/image v0.15.0
+ golang.org/x/image v0.18.0
golang.org/x/net v0.26.0
- golang.org/x/oauth2 v0.18.0
+ golang.org/x/oauth2 v0.21.0
golang.org/x/sys v0.21.0
golang.org/x/text v0.16.0
- golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d
+ golang.org/x/tools v0.22.0
google.golang.org/grpc v1.62.1
- google.golang.org/protobuf v1.33.0
+ google.golang.org/protobuf v1.34.2
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.67.0
gopkg.in/yaml.v3 v3.0.1
@@ -127,20 +127,19 @@ require (
)
require (
- cloud.google.com/go/compute v1.25.1 // indirect
- cloud.google.com/go/compute/metadata v0.2.3 // indirect
+ cloud.google.com/go/compute/metadata v0.3.0 // indirect
dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
- github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 // indirect
github.com/ClickHouse/ch-go v0.61.5 // indirect
- github.com/ClickHouse/clickhouse-go/v2 v2.22.0 // indirect
+ github.com/ClickHouse/clickhouse-go/v2 v2.25.0 // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
- github.com/Microsoft/go-winio v0.6.1 // indirect
- github.com/RoaringBitmap/roaring v1.9.0 // indirect
+ github.com/Microsoft/go-winio v0.6.2 // indirect
+ github.com/RoaringBitmap/roaring v1.9.4 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
@@ -148,12 +147,13 @@ require (
github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.13.0 // indirect
- github.com/blevesearch/bleve_index_api v1.1.6 // indirect
+ github.com/blevesearch/bleve_index_api v1.1.9 // indirect
github.com/blevesearch/geo v0.1.20 // indirect
+ github.com/blevesearch/go-faiss v1.0.19 // indirect
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
github.com/blevesearch/gtreap v0.1.1 // indirect
github.com/blevesearch/mmap-go v1.0.4 // indirect
- github.com/blevesearch/scorch_segment_api/v2 v2.2.8 // indirect
+ github.com/blevesearch/scorch_segment_api/v2 v2.2.14 // indirect
github.com/blevesearch/segment v0.9.1 // indirect
github.com/blevesearch/snowballstem v0.9.0 // indirect
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
@@ -163,26 +163,28 @@ require (
github.com/blevesearch/zapx/v13 v13.3.10 // indirect
github.com/blevesearch/zapx/v14 v14.3.10 // indirect
github.com/blevesearch/zapx/v15 v15.3.13 // indirect
+ github.com/blevesearch/zapx/v16 v16.1.4 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
+ github.com/caddyserver/zerossl v0.1.3 // indirect
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
- github.com/cespare/xxhash/v2 v2.2.0 // indirect
- github.com/cloudflare/circl v1.3.7 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/cloudflare/circl v1.3.9 // indirect
github.com/couchbase/go-couchbase v0.1.1 // indirect
github.com/couchbase/gomemcached v0.3.1 // indirect
github.com/couchbase/goutils v0.1.2 // indirect
- github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
- github.com/cyphar/filepath-securejoin v0.2.4 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
+ github.com/cyphar/filepath-securejoin v0.2.5 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dlclark/regexp2 v1.11.0 // indirect
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // indirect
- github.com/fatih/color v1.16.0 // indirect
+ github.com/fatih/color v1.17.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.6.0 // indirect
github.com/go-ap/errors v0.0.0-20240304112515-6077fa9c17b0 // indirect
- github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
+ github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
github.com/go-enry/go-oniguruma v1.2.1 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.7.1 // indirect
@@ -199,7 +201,7 @@ require (
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-openapi/validate v0.24.0 // indirect
github.com/go-webauthn/x v0.1.9 // indirect
- github.com/goccy/go-json v0.10.2 // indirect
+ github.com/goccy/go-json v0.10.3 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
@@ -215,7 +217,7 @@ require (
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
- github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
+ github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
@@ -225,16 +227,15 @@ require (
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
- github.com/libdns/libdns v0.2.1 // indirect
+ github.com/libdns/libdns v0.2.2 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/markbates/going v1.0.3 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
- github.com/mholt/acmez v1.2.0 // indirect
- github.com/miekg/dns v1.1.58 // indirect
+ github.com/mholt/acmez/v2 v2.0.1 // indirect
+ github.com/miekg/dns v1.1.61 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
- github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
@@ -254,7 +255,7 @@ require (
github.com/prometheus/client_model v0.6.0 // indirect
github.com/prometheus/common v0.50.0 // indirect
github.com/prometheus/procfs v0.13.0 // indirect
- github.com/rhysd/actionlint v1.6.27 // indirect
+ github.com/rhysd/actionlint v1.7.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/xid v1.5.0 // indirect
@@ -262,7 +263,7 @@ require (
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
- github.com/shopspring/decimal v1.3.1 // indirect
+ github.com/shopspring/decimal v1.4.0 // indirect
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
@@ -276,27 +277,26 @@ require (
github.com/toqueteos/webbrowser v1.2.0 // indirect
github.com/unknwon/com v1.0.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
- github.com/valyala/fasthttp v1.52.0 // indirect
+ github.com/valyala/fasthttp v1.55.0 // indirect
github.com/valyala/fastjson v1.6.4 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
- github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
+ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
- go.etcd.io/bbolt v1.3.9 // indirect
+ go.etcd.io/bbolt v1.3.10 // indirect
go.mongodb.org/mongo-driver v1.14.0 // indirect
- go.opentelemetry.io/otel v1.24.0 // indirect
- go.opentelemetry.io/otel/trace v1.24.0 // indirect
+ go.opentelemetry.io/otel v1.27.0 // indirect
+ go.opentelemetry.io/otel/trace v1.27.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f // indirect
- golang.org/x/mod v0.17.0 // indirect
+ golang.org/x/mod v0.18.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/time v0.5.0 // indirect
- google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
@@ -309,8 +309,6 @@ replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142
replace github.com/nektos/act => gitea.com/gitea/act v0.259.1
-replace github.com/gorilla/feeds => github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5
-
// TODO: This could be removed after https://github.com/mholt/archiver/pull/396 merged
replace github.com/mholt/archiver/v3 => github.com/anchore/archiver/v3 v3.5.2
diff --git a/go.sum b/go.sum
index 11deacf916..3f1f4e3a93 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,5 @@
-cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU=
-cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls=
-cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
-cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
+cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
+cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
code.gitea.io/actions-proto-go v0.4.0 h1:OsPBPhodXuQnsspG1sQ4eRE1PeoZyofd7+i73zCwnsU=
code.gitea.io/actions-proto-go v0.4.0/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas=
code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI=
@@ -38,12 +36,12 @@ github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 h1:r3qt8PCHnfjOv9PN3H
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121/go.mod h1:Ock8XgA7pvULhIaHGAk/cDnRfNrF9Jey81nPcc403iU=
github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX90K7A8dN+R5E8GEadoP7sU=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o=
+github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0/go.mod h1:T5RfihdXtBDxt1Ch2wobif3TvzTdumDy29kahv6AV9A=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw=
@@ -54,13 +52,13 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2 h1:YUUxeiOWgdAQE3pXt
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.3.2/go.mod h1:dmXQgZuiSubAecswZE+Sm8jkvEa7kQgTPVRvwL/nd0E=
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
-github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA=
-github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
+github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4=
github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg=
-github.com/ClickHouse/clickhouse-go/v2 v2.22.0 h1:LAdk0qT125PpSPnYepFQs5X5z1EwpAtIX10SUELPgi0=
-github.com/ClickHouse/clickhouse-go/v2 v2.22.0/go.mod h1:tBhdF3f3RdP7sS59+oBAtTyhWpy0024ZxDMhgxra0QE=
+github.com/ClickHouse/clickhouse-go/v2 v2.25.0 h1:rKscwqgQHzWBTZySZDcHKxgs0Ad+xFULfZvo26W5UlY=
+github.com/ClickHouse/clickhouse-go/v2 v2.25.0/go.mod h1:iDTViXk2Fgvf1jn2dbJd1ys+fBkdD1UMRnXlwmhijhQ=
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
@@ -72,16 +70,16 @@ github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYr
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
-github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
-github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
+github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
+github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
-github.com/PuerkitoBio/goquery v1.9.1 h1:mTL6XjbJTZdpfL+Gwl5U2h1l9yEkJjhmlTeV9VPW7UI=
-github.com/PuerkitoBio/goquery v1.9.1/go.mod h1:cW1n6TmIMDoORQU5IU/P1T3tGFunOeXEpGP2WHRwkbY=
+github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE=
+github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk=
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
-github.com/RoaringBitmap/roaring v1.9.0 h1:lwKhr90/j0jVXJyh5X+vQN1VVn77rQFfYnh6RDRGCcE=
-github.com/RoaringBitmap/roaring v1.9.0/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
+github.com/RoaringBitmap/roaring v1.9.4 h1:yhEIoH4YezLYT04s1nHehNO64EKFTop/wBhxv2QzDdQ=
+github.com/RoaringBitmap/roaring v1.9.4/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE=
github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
@@ -119,13 +117,15 @@ github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
-github.com/blevesearch/bleve/v2 v2.3.10 h1:z8V0wwGoL4rp7nG/O3qVVLYxUqCbEwskMt4iRJsPLgg=
-github.com/blevesearch/bleve/v2 v2.3.10/go.mod h1:RJzeoeHC+vNHsoLR54+crS1HmOWpnH87fL70HAUCzIA=
+github.com/blevesearch/bleve/v2 v2.4.0 h1:2xyg+Wv60CFHYccXc+moGxbL+8QKT/dZK09AewHgKsg=
+github.com/blevesearch/bleve/v2 v2.4.0/go.mod h1:IhQHoFAbHgWKYavb9rQgQEJJVMuY99cKdQ0wPpst2aY=
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
-github.com/blevesearch/bleve_index_api v1.1.6 h1:orkqDFCBuNU2oHW9hN2YEJmet+TE9orml3FCGbl1cKk=
-github.com/blevesearch/bleve_index_api v1.1.6/go.mod h1:PbcwjIcRmjhGbkS/lJCpfgVSMROV6TRubGGAODaK1W8=
+github.com/blevesearch/bleve_index_api v1.1.9 h1:Cpq0Lp3As0Gfk3+PmcoNDRKeI50C5yuFNpj0YlN/bOE=
+github.com/blevesearch/bleve_index_api v1.1.9/go.mod h1:PbcwjIcRmjhGbkS/lJCpfgVSMROV6TRubGGAODaK1W8=
github.com/blevesearch/geo v0.1.20 h1:paaSpu2Ewh/tn5DKn/FB5SzvH0EWupxHEIwbCk/QPqM=
github.com/blevesearch/geo v0.1.20/go.mod h1:DVG2QjwHNMFmjo+ZgzrIq2sfCh6rIHzy9d9d0B59I6w=
+github.com/blevesearch/go-faiss v1.0.19 h1:UKoP8hS7DVsVSRRloNJb4qPfe2UQ99pP4D3oXd23g2A=
+github.com/blevesearch/go-faiss v1.0.19/go.mod h1:jrxHrbl42X/RnDPI+wBoZU8joxxuRwedrxqswQ3xfU8=
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
@@ -134,8 +134,8 @@ github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
-github.com/blevesearch/scorch_segment_api/v2 v2.2.8 h1:+OLW38LuRKio6N6V0gIk1srwFz79FJ5v2sNqHz2HVAA=
-github.com/blevesearch/scorch_segment_api/v2 v2.2.8/go.mod h1:ckbeb7knyOOvAdZinn/ASbB7EA3HoagnJkmEV3J7+sg=
+github.com/blevesearch/scorch_segment_api/v2 v2.2.14 h1:fgMLMpGWR7u2TdRm7XSZVWhPvMAcdYHh25Lq1fQ6Fjo=
+github.com/blevesearch/scorch_segment_api/v2 v2.2.14/go.mod h1:B7+a7vfpY4NsjuTkpv/eY7RZ91Xr90VaJzT2t7upZN8=
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
@@ -163,6 +163,8 @@ github.com/blevesearch/zapx/v14 v14.3.10/go.mod h1:qqyuR0u230jN1yMmE4FIAuCxmahRQ
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
github.com/blevesearch/zapx/v15 v15.3.13 h1:6EkfaZiPlAxqXz0neniq35my6S48QI94W/wyhnpDHHQ=
github.com/blevesearch/zapx/v15 v15.3.13/go.mod h1:Turk/TNRKj9es7ZpKK95PS7f6D44Y7fAFy8F4LXQtGg=
+github.com/blevesearch/zapx/v16 v16.1.4 h1:TBQfG77g2UUXwfjOVcEtB9pXkg6JBmGXkeZKI67+TiA=
+github.com/blevesearch/zapx/v16 v16.1.4/go.mod h1:+Q+Z89Iv7ewhdX2jyE6Qs/RUnN4tZuokaQ0xvTaFmx8=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
@@ -173,15 +175,17 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
-github.com/buildkite/terminal-to-html/v3 v3.11.0 h1:wMTpKgR61lqmxMz1FKjCaW5mq6DqeEgFZdJ+SU4hP30=
-github.com/buildkite/terminal-to-html/v3 v3.11.0/go.mod h1:8JACDet3vmvWLsL4IBobweQYtf19W5J+EKM3LEE1c+4=
+github.com/buildkite/terminal-to-html/v3 v3.12.1 h1:Wwec2uOu35zNPEQTzDyXQPyr/VUW6lzEwiYede1CaoE=
+github.com/buildkite/terminal-to-html/v3 v3.12.1/go.mod h1:PfNtCsLnMZs7X9X2gcngOutmgSp7/oGBUIpVzRnD09A=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
-github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
-github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
+github.com/caddyserver/certmagic v0.21.3 h1:pqRRry3yuB4CWBVq9+cUqu+Y6E2z8TswbhNx1AZeYm0=
+github.com/caddyserver/certmagic v0.21.3/go.mod h1:Zq6pklO9nVRl3DIFUw9gVUfXKdpc/0qwTUAQMBlfgtI=
+github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA=
+github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4=
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI=
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8=
-github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
-github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chi-middleware/proxy v1.1.1 h1:4HaXUp8o2+bhHr1OhVy+VjN0+L7/07JDcn6v7YrTjrQ=
github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdikvbVJVHv/M+0=
github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
@@ -191,8 +195,8 @@ github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwys
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
-github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
-github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
+github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
+github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@@ -205,12 +209,12 @@ github.com/couchbase/goutils v0.1.2 h1:gWr8B6XNWPIhfalHNog3qQKfGiYyh4K4VhO3P2o9B
github.com/couchbase/goutils v0.1.2/go.mod h1:h89Ek/tiOxxqjz30nPPlwZdQbdB8BwgnuBxeoUe/ViE=
github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
-github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
-github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
+github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
-github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
-github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
+github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo=
+github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -233,16 +237,14 @@ github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
-github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
-github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/dvyukov/go-fuzz v0.0.0-20210429054444-fca39067bc72/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
-github.com/editorconfig/editorconfig-core-go/v2 v2.6.1 h1:iPCqofzMO41WVbcS/B5Ym7AwHQg9cyQ7Ie/R2XU5L3A=
-github.com/editorconfig/editorconfig-core-go/v2 v2.6.1/go.mod h1:VY4oyqUnpULFB3SCRpl24GFDIN1PmfiQIvN/G4ScSNg=
+github.com/editorconfig/editorconfig-core-go/v2 v2.6.2 h1:dKG8sc7n321deIVRcQtwlMNoBEra7j0qQ8RwxO8RN0w=
+github.com/editorconfig/editorconfig-core-go/v2 v2.6.2/go.mod h1:7dvD3GCm7eBw53xZ/lsiq72LqobdMg3ITbMBxnmJmqY=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
@@ -258,8 +260,8 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/ethantkoenig/rupture v1.0.1 h1:6aAXghmvtnngMgQzy7SMGdicMvkV86V4n9fT0meE5E4=
github.com/ethantkoenig/rupture v1.0.1/go.mod h1:Sjqo/nbffZp1pVVXNGhpugIjsWmuS9KiIB4GtpEBur4=
-github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
-github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
+github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
+github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/felixge/fgprof v0.9.4 h1:ocDNwMFlnA0NU0zSB3I52xkO4sFXk80VK9lXjLClu88=
github.com/felixge/fgprof v0.9.4/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
@@ -274,27 +276,28 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
-github.com/gliderlabs/ssh v0.3.6 h1:ZzjlDa05TcFRICb3anf/dSPN3ewz1Zx6CMLPWgkm3b8=
-github.com/gliderlabs/ssh v0.3.6/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
+github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
+github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
-github.com/go-ap/activitypub v0.0.0-20240316125321-b61fd6a83225 h1:OoM81OclgRX7CUch4M7MmsH0NcmLWpFiSn7rhs6Y5ZU=
-github.com/go-ap/activitypub v0.0.0-20240316125321-b61fd6a83225/go.mod h1:yRUfFCoZY6C1CWalauqEQ5xYgSckzEBEO/2MBC6BOME=
+github.com/go-ap/activitypub v0.0.0-20240408091739-ba76b44c2594 h1:er3GvGCm7bJwHostjZlsRy7uiUuCquUVF9Fe0TrwiPI=
+github.com/go-ap/activitypub v0.0.0-20240408091739-ba76b44c2594/go.mod h1:yRUfFCoZY6C1CWalauqEQ5xYgSckzEBEO/2MBC6BOME=
github.com/go-ap/errors v0.0.0-20240304112515-6077fa9c17b0 h1:H9MGShwybHLSln6K8RxHPMHiLcD86Lru+5TVW2TcXHY=
github.com/go-ap/errors v0.0.0-20240304112515-6077fa9c17b0/go.mod h1:5x8a6P/dhmMGFxWLcyYlyOuJ2lRNaHGhRv+yu8BaTSI=
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 h1:GMKIYXyXPGIp+hYiWOhfqK4A023HdgisDT4YGgf99mw=
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA=
-github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
+github.com/go-asn1-ber/asn1-ber v1.5.7 h1:DTX+lbVTWaTw1hQ+PbZPlnDZPEIs0SS/GCZAl535dDk=
+github.com/go-asn1-ber/asn1-ber v1.5.7/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
-github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
-github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-chi/chi/v5 v5.0.13 h1:JlH2F2M8qnwl0N1+JFFzlX9TlKJYas3aPXdiuTmJL+w=
+github.com/go-chi/chi/v5 v5.0.13/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
-github.com/go-enry/go-enry/v2 v2.8.7 h1:vbab0pcf5Yo1cHQLzbWZ+QomUh3EfEU8EiR5n7W0lnQ=
-github.com/go-enry/go-enry/v2 v2.8.7/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
+github.com/go-enry/go-enry/v2 v2.8.8 h1:EhfxWpw4DQ3WEFB1Y77X8vKqZL0D0EDUUWYDUAIv9/4=
+github.com/go-enry/go-enry/v2 v2.8.8/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
@@ -310,8 +313,8 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
-github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
-github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
+github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
+github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A=
github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc=
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
@@ -338,17 +341,15 @@ github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3Bum
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
-github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4=
-github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
-github.com/go-swagger/go-swagger v0.30.5 h1:SQ2+xSonWjjoEMOV5tcOnZJVlfyUfCBhGQGArS1b9+U=
-github.com/go-swagger/go-swagger v0.30.5/go.mod h1:cWUhSyCNqV7J1wkkxfr5QmbcnCewetCdvEXqgPvbc/Q=
-github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
-github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
+github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
+github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
+github.com/go-swagger/go-swagger v0.31.0 h1:H8eOYQnY2u7vNKWDNykv2xJP3pBhRG/R+SOCAmKrLlc=
+github.com/go-swagger/go-swagger v0.31.0/go.mod h1:WSigRRWEig8zV6t6Sm8Y+EmUjlzA/HoaZJ5edupq7po=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
-github.com/go-testfixtures/testfixtures/v3 v3.10.0 h1:BrBwN7AuC+74g5qtk9D59TLGOaEa8Bw1WmIsf+SyzWc=
-github.com/go-testfixtures/testfixtures/v3 v3.10.0/go.mod h1:z8RoleoNtibi6Ar8ziCW7e6PQ+jWiqbUWvuv8AMe4lo=
+github.com/go-testfixtures/testfixtures/v3 v3.11.0 h1:XxQr8AnPORcZkyNd7go5UNLPD3dULN8ixYISlzrlfEQ=
+github.com/go-testfixtures/testfixtures/v3 v3.11.0/go.mod h1:THmudHF1Ixq++J2/UodcJpxUphfyEd77m83TvDtryqE=
github.com/go-webauthn/webauthn v0.10.2 h1:OG7B+DyuTytrEPFmTX503K77fqs3HDK/0Iv+z8UYbq4=
github.com/go-webauthn/webauthn v0.10.2/go.mod h1:Gd1IDsGAybuvK1NkwUTLbGmeksxuRJjVN2PE/xsPxHs=
github.com/go-webauthn/x v0.1.9 h1:v1oeLmoaa+gPOaZqUdDentu6Rl7HkSSsmOT6gxEQHhE=
@@ -358,8 +359,8 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
-github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
-github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
+github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
@@ -387,7 +388,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -411,8 +411,9 @@ github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 h1:y3N7Bm7Y9/CtpiVkw/ZWj6lSlDF3F74SfKwfTCer72Q=
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
+github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M=
+github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -426,6 +427,8 @@ github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
+github.com/gorilla/feeds v1.2.0 h1:O6pBiXJ5JHhPvqy53NsjKOThq+dNFm8+DFrxBEdzSCc=
+github.com/gorilla/feeds v1.2.0/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
@@ -436,19 +439,18 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
-github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
-github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
+github.com/gorilla/sessions v1.3.0 h1:XYlkq7KcpOB2ZhHBPv5WpjMIxrQosiZanfoy1HLZFzg=
+github.com/gorilla/sessions v1.3.0/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE=
github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
-github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
-github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
-github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
-github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
-github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
+github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
+github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
+github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -457,8 +459,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
-github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
+github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
@@ -466,20 +468,20 @@ github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+h
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
-github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q=
-github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
+github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w=
+github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0=
-github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=
+github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw=
github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
-github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0=
-github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE=
+github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA=
+github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA=
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
@@ -510,13 +512,13 @@ github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
-github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
-github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
+github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
-github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
-github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
+github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
@@ -536,8 +538,8 @@ github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
-github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
+github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
+github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 h1:F/3FfGmKdiKFa8kL3YrpZ7pe9H4l4AzA1pbaOUnRvPI=
@@ -549,8 +551,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/markbates/going v1.0.3 h1:mY45T5TvW+Xz5A6jY7lf4+NLg9D8+iuStIHyR7M8qsE=
github.com/markbates/going v1.0.3/go.mod h1:fQiT6v6yQar9UD6bd/D4Z5Afbk9J6BBVBtLiyY4gp2o=
-github.com/markbates/goth v1.79.0 h1:fUYi9R6VubVEK2bpmXvIUp7xRcxA68i8ovfUQx/i5Qc=
-github.com/markbates/goth v1.79.0/go.mod h1:RBD+tcFnXul2NnYuODhnIweOcuVPkBohLfEvutPekcU=
+github.com/markbates/goth v1.80.0 h1:NnvatczZDzOs1hn9Ug+dVYf2Viwwkp/ZDX5K+GLjan8=
+github.com/markbates/goth v1.80.0/go.mod h1:4/GYHo+W6NWisrMPZnq0Yr2Q70UntNLn7KXEFhrIdAY=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@@ -562,22 +564,20 @@ github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
-github.com/meilisearch/meilisearch-go v0.26.2 h1:3gTlmiV1dHHumVUhYdJbvh3camiNiyqQ1hNveVsU2OE=
-github.com/meilisearch/meilisearch-go v0.26.2/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0=
-github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
-github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
+github.com/meilisearch/meilisearch-go v0.26.3 h1:EYt+C1n7IvjKzgXM3xqce5iJzNBq33F7ayZOKx96TKY=
+github.com/meilisearch/meilisearch-go v0.26.3/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0=
+github.com/mholt/acmez/v2 v2.0.1 h1:3/3N0u1pLjMK4sNEAFSI+bcvzbPhRpY383sy1kLHJ6k=
+github.com/mholt/acmez/v2 v2.0.1/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGoe67e1U=
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
-github.com/microsoft/go-mssqldb v1.7.0 h1:sgMPW0HA6Ihd37Yx0MzHyKD726C2kY/8KJsQtXHNaAs=
-github.com/microsoft/go-mssqldb v1.7.0/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
-github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
-github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
+github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
+github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
+github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
+github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
-github.com/minio/minio-go/v7 v7.0.69 h1:l8AnsQFyY1xiwa/DaQskY4NXSLA2yrGsW5iD9nRPVS0=
-github.com/minio/minio-go/v7 v7.0.69/go.mod h1:XAvOPJQ5Xlzk5o3o/ArO2NMbhSGkimC+bpW/ngRKDmQ=
-github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
-github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
+github.com/minio/minio-go/v7 v7.0.71 h1:No9XfOKTYi6i0GnBj+WZwD8WP5GZfL7n7GOjRqCdAjA=
+github.com/minio/minio-go/v7 v7.0.71/go.mod h1:4yBA8v80xGA30cfM3fz0DKYMXunWl/AV/6tWEs9ryzo=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@@ -657,8 +657,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
-github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
-github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
+github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
+github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
github.com/prometheus/common v0.50.0 h1:YSZE6aa9+luNa2da6/Tik0q0A5AbR+U003TItK57CPQ=
@@ -668,12 +668,12 @@ github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43Z
github.com/quasoft/websspi v1.1.2 h1:/mA4w0LxWlE3novvsoEL6BBA1WnjJATbjkh1kFrTidw=
github.com/quasoft/websspi v1.1.2/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk=
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
-github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
+github.com/redis/go-redis/v9 v9.5.3 h1:fOAp1/uJG+ZtcITgZOfYFmTKPE7n4Vclj1wZFgRciUU=
+github.com/redis/go-redis/v9 v9.5.3/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
-github.com/rhysd/actionlint v1.6.27 h1:xxwe8YmveBcC8lydW6GoHMGmB6H/MTqUU60F2p10wjw=
-github.com/rhysd/actionlint v1.6.27/go.mod h1:m2nFUjAnOrxCMXuOMz9evYBRCLUsMnKY2IJl/N5umbk=
+github.com/rhysd/actionlint v1.7.1 h1:WJaDzyT1StBWVKGSsZPYnbV0HF9Y9/vD6KFdZQL42qE=
+github.com/rhysd/actionlint v1.7.1/go.mod h1:lNjNNlZY0BdBl8l837Z9ZiBpu8v+5lzfoJQFdSk4xss=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@@ -696,16 +696,16 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
-github.com/sassoftware/go-rpmutils v0.3.0 h1:tE4TZ8KcOXay5iIP64P291s6Qxd9MQCYhI7DU+f3gFA=
-github.com/sassoftware/go-rpmutils v0.3.0/go.mod h1:hM9wdxFsjUFR/tJ6SMsLrJuChcucCa0DsCzE9RMfwMo=
+github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg=
+github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI=
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs=
-github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
-github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
-github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
-github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
+github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
@@ -774,26 +774,26 @@ github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGB
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
-github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
-github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
+github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
-github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
-github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
+github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
+github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
-github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0=
-github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ=
+github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8=
+github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
-github.com/xanzy/go-gitlab v0.100.0 h1:jaOtYj5nWI19+9oVVmgy233pax2oYqucwetogYU46ks=
-github.com/xanzy/go-gitlab v0.100.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
+github.com/xanzy/go-gitlab v0.105.0 h1:3nyLq0ESez0crcaM19o5S//SvezOQguuIHZ3wgX64hM=
+github.com/xanzy/go-gitlab v0.105.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
@@ -809,10 +809,8 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
-github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
-github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5 h1:3seWKGVhGoc66Ht5QlhQsr4xT2caDnFegsnh2NqvENU=
-github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js=
github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBzPCRjkCNs=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
@@ -821,8 +819,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA=
-github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
+github.com/yuin/goldmark v1.7.2 h1:NjGd7lO7zrUn/A7eKwn5PEOt4ONYGqpxSEeZuduvgxc=
+github.com/yuin/goldmark v1.7.2/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
@@ -834,15 +832,15 @@ github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvv
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
-go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
-go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
+go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
+go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ=
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
-go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
-go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
-go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
-go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
+go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg=
+go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ=
+go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw=
+go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
@@ -870,16 +868,16 @@ golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f h1:3CW0unweImhOzd5FmYuRsD4Y4oQFKZIjAnKbjV4WIrw=
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
-golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
-golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
+golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
+golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
-golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
+golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -902,8 +900,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
-golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
-golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
+golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
+golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -969,7 +967,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
@@ -992,15 +989,13 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
-golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
+golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
-google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c h1:lfpJ/2rWPa/kJgxyyXM8PrNnfCzcmxJ265mADgwmvLI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
@@ -1012,10 +1007,9 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
-google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
+google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/models/activities/notification.go b/models/activities/notification.go
index dc1b8c6fae..b888adeb60 100644
--- a/models/activities/notification.go
+++ b/models/activities/notification.go
@@ -286,13 +286,14 @@ type UserIDCount struct {
Count int64
}
-// GetUIDsAndNotificationCounts between the two provided times
+// GetUIDsAndNotificationCounts returns the unread counts for every user between the two provided times.
+// It must return all user IDs which appear during the period, including count=0 for users who have read all.
func GetUIDsAndNotificationCounts(ctx context.Context, since, until timeutil.TimeStamp) ([]UserIDCount, error) {
- sql := `SELECT user_id, count(*) AS count FROM notification ` +
+ sql := `SELECT user_id, sum(case when status= ? then 1 else 0 end) AS count FROM notification ` +
`WHERE user_id IN (SELECT user_id FROM notification WHERE updated_unix >= ? AND ` +
- `updated_unix < ?) AND status = ? GROUP BY user_id`
+ `updated_unix < ?) GROUP BY user_id`
var res []UserIDCount
- return res, db.GetEngine(ctx).SQL(sql, since, until, NotificationStatusUnread).Find(&res)
+ return res, db.GetEngine(ctx).SQL(sql, NotificationStatusUnread, since, until).Find(&res)
}
// SetIssueReadBy sets issue to be read by given user.
diff --git a/models/auth/webauthn.go b/models/auth/webauthn.go
index a65d2e1e34..553130ee2e 100644
--- a/models/auth/webauthn.go
+++ b/models/auth/webauthn.go
@@ -181,7 +181,7 @@ func DeleteCredential(ctx context.Context, id, userID int64) (bool, error) {
return had > 0, err
}
-// WebAuthnCredentials implementns the webauthn.User interface
+// WebAuthnCredentials implements the webauthn.User interface
func WebAuthnCredentials(ctx context.Context, userID int64) ([]webauthn.Credential, error) {
dbCreds, err := GetWebAuthnCredentialsByUID(ctx, userID)
if err != nil {
diff --git a/models/db/search.go b/models/db/search.go
index aa577f08e0..37565f45e1 100644
--- a/models/db/search.go
+++ b/models/db/search.go
@@ -18,12 +18,6 @@ const (
SearchOrderByRecentUpdated SearchOrderBy = "updated_unix DESC"
SearchOrderByOldest SearchOrderBy = "created_unix ASC"
SearchOrderByNewest SearchOrderBy = "created_unix DESC"
- SearchOrderBySize SearchOrderBy = "size ASC"
- SearchOrderBySizeReverse SearchOrderBy = "size DESC"
- SearchOrderByGitSize SearchOrderBy = "git_size ASC"
- SearchOrderByGitSizeReverse SearchOrderBy = "git_size DESC"
- SearchOrderByLFSSize SearchOrderBy = "lfs_size ASC"
- SearchOrderByLFSSizeReverse SearchOrderBy = "lfs_size DESC"
SearchOrderByID SearchOrderBy = "id ASC"
SearchOrderByIDReverse SearchOrderBy = "id DESC"
SearchOrderByStars SearchOrderBy = "num_stars ASC"
diff --git a/models/git/protected_tag.go b/models/git/protected_tag.go
index 8a05045651..9a6646c742 100644
--- a/models/git/protected_tag.go
+++ b/models/git/protected_tag.go
@@ -110,6 +110,19 @@ func GetProtectedTagByID(ctx context.Context, id int64) (*ProtectedTag, error) {
return tag, nil
}
+// GetProtectedTagByNamePattern gets protected tag by name_pattern
+func GetProtectedTagByNamePattern(ctx context.Context, repoID int64, pattern string) (*ProtectedTag, error) {
+ tag := &ProtectedTag{NamePattern: pattern, RepoID: repoID}
+ has, err := db.GetEngine(ctx).Get(tag)
+ if err != nil {
+ return nil, err
+ }
+ if !has {
+ return nil, nil
+ }
+ return tag, nil
+}
+
// IsUserAllowedToControlTag checks if a user can control the specific tag.
// It returns true if the tag name is not protected or the user is allowed to control it.
func IsUserAllowedToControlTag(ctx context.Context, tags []*ProtectedTag, tagName string, userID int64) (bool, error) {
diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go
index c1d7d921a9..e9f116bfc6 100644
--- a/models/issues/issue_search.go
+++ b/models/issues/issue_search.go
@@ -6,6 +6,7 @@ package issues
import (
"context"
"fmt"
+ "strconv"
"strings"
"code.gitea.io/gitea/models/db"
@@ -13,6 +14,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/container"
"code.gitea.io/gitea/modules/optional"
"xorm.io/builder"
@@ -116,14 +118,30 @@ func applyLabelsCondition(sess *xorm.Session, opts *IssuesOptions) {
if opts.LabelIDs[0] == 0 {
sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_label)")
} else {
- for i, labelID := range opts.LabelIDs {
+ // deduplicate the label IDs for inclusion and exclusion
+ includedLabelIDs := make(container.Set[int64])
+ excludedLabelIDs := make(container.Set[int64])
+ for _, labelID := range opts.LabelIDs {
if labelID > 0 {
- 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))
+ includedLabelIDs.Add(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)
+ excludedLabelIDs.Add(-labelID)
}
}
+ // ... and use them in a subquery of the form :
+ // where (select count(*) from issue_label where issue_id=issue.id and label_id in (2, 4, 6)) = 3
+ // This equality is guaranteed thanks to unique index (issue_id,label_id) on table issue_label.
+ if len(includedLabelIDs) > 0 {
+ subQuery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
+ And(builder.In("label_id", includedLabelIDs.Values()))
+ sess.Where(builder.Eq{strconv.Itoa(len(includedLabelIDs)): subQuery})
+ }
+ // or (select count(*)...) = 0 for excluded labels
+ if len(excludedLabelIDs) > 0 {
+ subQuery := builder.Select("count(*)").From("issue_label").Where(builder.Expr("issue_id = issue.id")).
+ And(builder.In("label_id", excludedLabelIDs.Values()))
+ sess.Where(builder.Eq{"0": subQuery})
+ }
}
}
diff --git a/models/issues/label.go b/models/issues/label.go
index 2397a29e35..2530f71004 100644
--- a/models/issues/label.go
+++ b/models/issues/label.go
@@ -7,10 +7,12 @@ package issues
import (
"context"
"fmt"
+ "slices"
"strconv"
"strings"
"code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/label"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/timeutil"
@@ -142,28 +144,33 @@ func (l *Label) CalOpenOrgIssues(ctx context.Context, repoID, labelID int64) {
// LoadSelectedLabelsAfterClick calculates the set of selected labels when a label is clicked
func (l *Label) LoadSelectedLabelsAfterClick(currentSelectedLabels []int64, currentSelectedExclusiveScopes []string) {
- var labelQuerySlice []string
+ labelQueryParams := container.Set[string]{}
labelSelected := false
- labelID := strconv.FormatInt(l.ID, 10)
- labelScope := l.ExclusiveScope()
- for i, s := range currentSelectedLabels {
- if s == l.ID {
+ exclusiveScope := l.ExclusiveScope()
+ for i, curSel := range currentSelectedLabels {
+ if curSel == l.ID {
labelSelected = true
- } else if -s == l.ID {
+ } else if -curSel == l.ID {
labelSelected = true
l.IsExcluded = true
- } else if s != 0 {
+ } else if curSel != 0 {
// Exclude other labels in the same scope from selection
- if s < 0 || labelScope == "" || labelScope != currentSelectedExclusiveScopes[i] {
- labelQuerySlice = append(labelQuerySlice, strconv.FormatInt(s, 10))
+ if curSel < 0 || exclusiveScope == "" || exclusiveScope != currentSelectedExclusiveScopes[i] {
+ labelQueryParams.Add(strconv.FormatInt(curSel, 10))
}
}
}
+
if !labelSelected {
- labelQuerySlice = append(labelQuerySlice, labelID)
+ labelQueryParams.Add(strconv.FormatInt(l.ID, 10))
}
l.IsSelected = labelSelected
- l.QueryString = strings.Join(labelQuerySlice, ",")
+
+ // Sort and deduplicate the ids to avoid the crawlers asking for the
+ // same thing with simply a different order of parameters
+ labelQuerySliceStrings := labelQueryParams.Values()
+ slices.Sort(labelQuerySliceStrings) // the sort is still needed because the underlying map of Set doesn't guarantee order
+ l.QueryString = strings.Join(labelQuerySliceStrings, ",")
}
// BelongsToOrg returns true if label is an organization label
@@ -176,7 +183,7 @@ func (l *Label) BelongsToRepo() bool {
return l.RepoID > 0
}
-// Return scope substring of label name, or empty string if none exists
+// ExclusiveScope returns scope substring of label name, or empty string if none exists
func (l *Label) ExclusiveScope() string {
if !l.Exclusive {
return ""
diff --git a/models/issues/label_test.go b/models/issues/label_test.go
index 517a3cf1ab..396de809e1 100644
--- a/models/issues/label_test.go
+++ b/models/issues/label_test.go
@@ -23,6 +23,27 @@ func TestLabel_CalOpenIssues(t *testing.T) {
assert.EqualValues(t, 2, label.NumOpenIssues)
}
+func TestLabel_LoadSelectedLabelsAfterClick(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+ // Loading the label id:8 which have a scope and an exclusivity
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 8})
+
+ // First test : with negative and scope
+ label.LoadSelectedLabelsAfterClick([]int64{1, -8}, []string{"", "scope"})
+ assert.Equal(t, "1", label.QueryString)
+ assert.Equal(t, true, label.IsSelected)
+
+ // Second test : with duplicates
+ label.LoadSelectedLabelsAfterClick([]int64{1, 7, 1, 7, 7}, []string{"", "scope", "", "scope", "scope"})
+ assert.Equal(t, "1,8", label.QueryString)
+ assert.Equal(t, false, label.IsSelected)
+
+ // Third test : empty set
+ label.LoadSelectedLabelsAfterClick([]int64{}, []string{})
+ assert.False(t, label.IsSelected)
+ assert.Equal(t, "8", label.QueryString)
+}
+
func TestLabel_ExclusiveScope(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 7})
diff --git a/models/issues/pull_list.go b/models/issues/pull_list.go
index a1d46f8cd4..f80a2284f0 100644
--- a/models/issues/pull_list.go
+++ b/models/issues/pull_list.go
@@ -192,8 +192,10 @@ func (prs PullRequestList) LoadIssues(ctx context.Context) (IssueList, error) {
return nil, nil
}
- // Load issues.
- issueIDs := prs.GetIssueIDs()
+ // Load issues which are not loaded
+ issueIDs := container.FilterSlice(prs, func(pr *PullRequest) (int64, bool) {
+ return pr.IssueID, pr.Issue == nil && pr.IssueID > 0
+ })
issues := make(map[int64]*Issue, len(issueIDs))
if err := db.GetEngine(ctx).
In("id", issueIDs).
@@ -229,10 +231,7 @@ func (prs PullRequestList) LoadIssues(ctx context.Context) (IssueList, error) {
// GetIssueIDs returns all issue ids
func (prs PullRequestList) GetIssueIDs() []int64 {
return container.FilterSlice(prs, func(pr *PullRequest) (int64, bool) {
- if pr.Issue == nil {
- return pr.IssueID, pr.IssueID > 0
- }
- return 0, false
+ return pr.IssueID, pr.IssueID > 0
})
}
diff --git a/models/repo/avatar_test.go b/models/repo/avatar_test.go
new file mode 100644
index 0000000000..fc1f8baeca
--- /dev/null
+++ b/models/repo/avatar_test.go
@@ -0,0 +1,28 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package repo
+
+import (
+ "testing"
+
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestRepoAvatarLink(t *testing.T) {
+ defer test.MockVariableValue(&setting.AppURL, "https://localhost/")()
+ defer test.MockVariableValue(&setting.AppSubURL, "")()
+
+ repo := &Repository{ID: 1, Avatar: "avatar.png"}
+ link := repo.AvatarLink(db.DefaultContext)
+ assert.Equal(t, "https://localhost/repo-avatars/avatar.png", link)
+
+ setting.AppURL = "https://localhost/sub-path/"
+ setting.AppSubURL = "/sub-path"
+ link = repo.AvatarLink(db.DefaultContext)
+ assert.Equal(t, "https://localhost/sub-path/repo-avatars/avatar.png", link)
+}
diff --git a/models/repo/repo.go b/models/repo/repo.go
index f02c55fc89..189c4aba6c 100644
--- a/models/repo/repo.go
+++ b/models/repo/repo.go
@@ -362,7 +362,7 @@ func (repo *Repository) LoadUnits(ctx context.Context) (err error) {
if log.IsTrace() {
unitTypeStrings := make([]string, len(repo.Units))
for i, unit := range repo.Units {
- unitTypeStrings[i] = unit.Type.String()
+ unitTypeStrings[i] = unit.Type.LogString()
}
log.Trace("repo.Units, ID=%d, Types: [%s]", repo.ID, strings.Join(unitTypeStrings, ", "))
}
diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go
index eacc98e222..e22d872ae4 100644
--- a/models/repo/repo_list.go
+++ b/models/repo/repo_list.go
@@ -207,31 +207,6 @@ type SearchRepoOptions struct {
OnlyShowRelevant bool
}
-// SearchOrderBy is used to sort the result
-type SearchOrderBy string
-
-func (s SearchOrderBy) String() string {
- return string(s)
-}
-
-// Strings for sorting result
-const (
- SearchOrderByAlphabetically SearchOrderBy = "name ASC"
- SearchOrderByAlphabeticallyReverse SearchOrderBy = "name DESC"
- SearchOrderByLeastUpdated SearchOrderBy = "updated_unix ASC"
- SearchOrderByRecentUpdated SearchOrderBy = "updated_unix DESC"
- SearchOrderByOldest SearchOrderBy = "created_unix ASC"
- SearchOrderByNewest SearchOrderBy = "created_unix DESC"
- SearchOrderBySize SearchOrderBy = "size ASC"
- SearchOrderBySizeReverse SearchOrderBy = "size DESC"
- SearchOrderByID SearchOrderBy = "id ASC"
- SearchOrderByIDReverse SearchOrderBy = "id DESC"
- SearchOrderByStars SearchOrderBy = "num_stars ASC"
- SearchOrderByStarsReverse SearchOrderBy = "num_stars DESC"
- SearchOrderByForks SearchOrderBy = "num_forks ASC"
- SearchOrderByForksReverse SearchOrderBy = "num_forks DESC"
-)
-
// UserOwnedRepoCond returns user ownered repositories
func UserOwnedRepoCond(userID int64) builder.Cond {
return builder.Eq{
diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go
index fd5baa9488..cb52c2c9e2 100644
--- a/models/repo/repo_unit.go
+++ b/models/repo/repo_unit.go
@@ -33,7 +33,7 @@ func IsErrUnitTypeNotExist(err error) bool {
}
func (err ErrUnitTypeNotExist) Error() string {
- return fmt.Sprintf("Unit type does not exist: %s", err.UT.String())
+ return fmt.Sprintf("Unit type does not exist: %s", err.UT.LogString())
}
func (err ErrUnitTypeNotExist) Unwrap() error {
diff --git a/models/repo/search.go b/models/repo/search.go
index 54d6dcfb44..a73d9fc215 100644
--- a/models/repo/search.go
+++ b/models/repo/search.go
@@ -5,20 +5,48 @@ package repo
import "code.gitea.io/gitea/models/db"
-// SearchOrderByMap represents all possible search order
-var SearchOrderByMap = map[string]map[string]db.SearchOrderBy{
+// OrderByMap represents all possible search order
+var OrderByMap = map[string]map[string]db.SearchOrderBy{
"asc": {
- "alpha": "owner_name ASC, name ASC",
- "created": db.SearchOrderByOldest,
- "updated": db.SearchOrderByLeastUpdated,
- "size": db.SearchOrderBySize,
- "id": db.SearchOrderByID,
+ "alpha": "owner_name ASC, name ASC",
+ "created": db.SearchOrderByOldest,
+ "updated": db.SearchOrderByLeastUpdated,
+ "size": "size ASC",
+ "git_size": "git_size ASC",
+ "lfs_size": "lfs_size ASC",
+ "id": db.SearchOrderByID,
+ "stars": db.SearchOrderByStars,
+ "forks": db.SearchOrderByForks,
},
"desc": {
- "alpha": "owner_name DESC, name DESC",
- "created": db.SearchOrderByNewest,
- "updated": db.SearchOrderByRecentUpdated,
- "size": db.SearchOrderBySizeReverse,
- "id": db.SearchOrderByIDReverse,
+ "alpha": "owner_name DESC, name DESC",
+ "created": db.SearchOrderByNewest,
+ "updated": db.SearchOrderByRecentUpdated,
+ "size": "size DESC",
+ "git_size": "git_size DESC",
+ "lfs_size": "lfs_size DESC",
+ "id": db.SearchOrderByIDReverse,
+ "stars": db.SearchOrderByStarsReverse,
+ "forks": db.SearchOrderByForksReverse,
},
}
+
+// OrderByFlatMap is similar to OrderByMap but use human language keywords
+// to decide between asc and desc
+var OrderByFlatMap = map[string]db.SearchOrderBy{
+ "newest": OrderByMap["desc"]["created"],
+ "oldest": OrderByMap["asc"]["created"],
+ "leastupdate": OrderByMap["asc"]["updated"],
+ "reversealphabetically": OrderByMap["desc"]["alpha"],
+ "alphabetically": OrderByMap["asc"]["alpha"],
+ "reversesize": OrderByMap["desc"]["size"],
+ "size": OrderByMap["asc"]["size"],
+ "reversegitsize": OrderByMap["desc"]["git_size"],
+ "gitsize": OrderByMap["asc"]["git_size"],
+ "reverselfssize": OrderByMap["desc"]["lfs_size"],
+ "lfssize": OrderByMap["asc"]["lfs_size"],
+ "moststars": OrderByMap["desc"]["stars"],
+ "feweststars": OrderByMap["asc"]["stars"],
+ "mostforks": OrderByMap["desc"]["forks"],
+ "fewestforks": OrderByMap["asc"]["forks"],
+}
diff --git a/models/unit/unit.go b/models/unit/unit.go
index 8eedcbd347..3b62e5f982 100644
--- a/models/unit/unit.go
+++ b/models/unit/unit.go
@@ -33,39 +33,18 @@ const (
TypeActions // 10 Actions
)
-// Value returns integer value for unit type
+// Value returns integer value for unit type (used by template)
func (u Type) Value() int {
return int(u)
}
-func (u Type) String() string {
- switch u {
- case TypeCode:
- return "TypeCode"
- case TypeIssues:
- return "TypeIssues"
- case TypePullRequests:
- return "TypePullRequests"
- case TypeReleases:
- return "TypeReleases"
- case TypeWiki:
- return "TypeWiki"
- case TypeExternalWiki:
- return "TypeExternalWiki"
- case TypeExternalTracker:
- return "TypeExternalTracker"
- case TypeProjects:
- return "TypeProjects"
- case TypePackages:
- return "TypePackages"
- case TypeActions:
- return "TypeActions"
- }
- return fmt.Sprintf("Unknown Type %d", u)
-}
-
func (u Type) LogString() string {
- return fmt.Sprintf("
`))
_, err = output.Write(buf)
return err
diff --git a/modules/markup/html.go b/modules/markup/html.go
index 565bc175b7..b8069d459a 100644
--- a/modules/markup/html.go
+++ b/modules/markup/html.go
@@ -88,6 +88,10 @@ func IsFullURLString(link string) bool {
return fullURLPattern.MatchString(link)
}
+func IsNonEmptyRelativePath(link string) bool {
+ return link != "" && !IsFullURLString(link) && link[0] != '/' && link[0] != '?' && link[0] != '#'
+}
+
// regexp for full links to issues/pulls
var issueFullPattern *regexp.Regexp
@@ -144,20 +148,6 @@ func CustomLinkURLSchemes(schemes []string) {
common.LinkRegex, _ = xurls.StrictMatchingScheme(strings.Join(withAuth, "|"))
}
-// IsSameDomain checks if given url string has the same hostname as current Gitea instance
-func IsSameDomain(s string) bool {
- if strings.HasPrefix(s, "/") {
- return true
- }
- if uapp, err := url.Parse(setting.AppURL); err == nil {
- if u, err := url.Parse(s); err == nil {
- return u.Host == uapp.Host
- }
- return false
- }
- return false
-}
-
type postProcessError struct {
context string
err error
@@ -372,41 +362,6 @@ func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output
return nil
}
-func handleNodeImg(ctx *RenderContext, img *html.Node) {
- for i, attr := range img.Attr {
- if attr.Key != "src" {
- continue
- }
-
- if attr.Val != "" && !IsFullURLString(attr.Val) && !strings.HasPrefix(attr.Val, "/") {
- attr.Val = util.URLJoin(ctx.Links.ResolveMediaLink(ctx.IsWiki), attr.Val)
-
- // By default, the "" tag should also be clickable,
- // because frontend use `` to paste the re-scaled image into the markdown,
- // so it must match the default markdown image behavior.
- hasParentAnchor := false
- for p := img.Parent; p != nil; p = p.Parent {
- if hasParentAnchor = p.Type == html.ElementNode && p.Data == "a"; hasParentAnchor {
- break
- }
- }
- if !hasParentAnchor {
- imgA := &html.Node{Type: html.ElementNode, Data: "a", Attr: []html.Attribute{
- {Key: "href", Val: attr.Val},
- {Key: "target", Val: "_blank"},
- }}
- parent := img.Parent
- imgNext := img.NextSibling
- parent.RemoveChild(img)
- parent.InsertBefore(imgA, imgNext)
- imgA.AppendChild(img)
- }
- }
- attr.Val = camoHandleLink(attr.Val)
- img.Attr[i] = attr
- }
-}
-
func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Node {
// Add user-content- to IDs and "#" links if they don't already have them
for idx, attr := range node.Attr {
@@ -426,20 +381,20 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Nod
}
}
- // We ignore code and pre.
switch node.Type {
case html.TextNode:
- textNode(ctx, procs, node)
+ processTextNodes(ctx, procs, node)
case html.ElementNode:
- if node.Data == "img" {
- next := node.NextSibling
- handleNodeImg(ctx, node)
- return next
+ if node.Data == "code" || node.Data == "pre" {
+ // ignore code and pre nodes
+ return node.NextSibling
+ } else if node.Data == "img" {
+ return visitNodeImg(ctx, node)
+ } else if node.Data == "video" {
+ return visitNodeVideo(ctx, node)
} else if node.Data == "a" {
// Restrict text in links to emojis
procs = emojiProcessors
- } else if node.Data == "code" || node.Data == "pre" {
- return node.NextSibling
} else if node.Data == "i" {
for _, attr := range node.Attr {
if attr.Key != "class" {
@@ -465,15 +420,16 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Nod
for n := node.FirstChild; n != nil; {
n = visitNode(ctx, procs, n)
}
+ default:
}
return node.NextSibling
}
-// textNode runs the passed node through various processors, in order to handle
+// processTextNodes runs the passed node through various processors, in order to handle
// all kinds of special links handled by the post-processing.
-func textNode(ctx *RenderContext, procs []processor, node *html.Node) {
- for _, processor := range procs {
- processor(ctx, node)
+func processTextNodes(ctx *RenderContext, procs []processor, node *html.Node) {
+ for _, p := range procs {
+ p(ctx, node)
}
}
@@ -761,10 +717,10 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
if image {
link = strings.ReplaceAll(link, " ", "+")
} else {
- link = strings.ReplaceAll(link, " ", "-")
+ link = strings.ReplaceAll(link, " ", "-") // FIXME: it should support dashes in the link, eg: "the-dash-support.-"
}
if !strings.Contains(link, "/") {
- link = url.PathEscape(link)
+ link = url.PathEscape(link) // FIXME: it doesn't seem right and it might cause double-escaping
}
}
if image {
@@ -796,28 +752,7 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
childNode.Attr = childNode.Attr[:2]
}
} else {
- if !absoluteLink {
- var base string
- if ctx.IsWiki {
- switch ext {
- case "":
- // no file extension, create a regular wiki link
- base = ctx.Links.WikiLink()
- default:
- // we have a file extension:
- // return a regular wiki link if it's a renderable file (extension),
- // raw link otherwise
- if Type(link) != "" {
- base = ctx.Links.WikiLink()
- } else {
- base = ctx.Links.WikiRawLink()
- }
- }
- } else {
- base = ctx.Links.SrcLink()
- }
- link = util.URLJoin(base, link)
- }
+ link, _ = ResolveLink(ctx, link, "")
childNode.Type = html.TextNode
childNode.Data = name
}
@@ -939,14 +874,11 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
// Path determines the type of link that will be rendered. It's unknown at this point whether
// the linked item is actually a PR or an issue. Luckily it's of no real consequence because
// Gitea will redirect on click as appropriate.
- path := "issues"
- if ref.IsPull {
- path = "pulls"
- }
+ issuePath := util.Iif(ref.IsPull, "pulls", "issues")
if ref.Owner == "" {
- link = createLink(util.URLJoin(ctx.Links.Prefix(), ctx.Metas["user"], ctx.Metas["repo"], path, ref.Issue), reftext, "ref-issue")
+ link = createLink(util.URLJoin(ctx.Links.Prefix(), ctx.Metas["user"], ctx.Metas["repo"], issuePath, ref.Issue), reftext, "ref-issue")
} else {
- link = createLink(util.URLJoin(ctx.Links.Prefix(), ref.Owner, ref.Name, path, ref.Issue), reftext, "ref-issue")
+ link = createLink(util.URLJoin(ctx.Links.Prefix(), ref.Owner, ref.Name, issuePath, ref.Issue), reftext, "ref-issue")
}
}
@@ -1207,7 +1139,7 @@ func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
return
}
ctx.AddCancel(func() {
- closer.Close()
+ _ = closer.Close()
ctx.GitRepo = nil
})
}
diff --git a/modules/markup/html_link.go b/modules/markup/html_link.go
new file mode 100644
index 0000000000..a41b87e9fa
--- /dev/null
+++ b/modules/markup/html_link.go
@@ -0,0 +1,35 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package markup
+
+import (
+ "path"
+
+ "code.gitea.io/gitea/modules/util"
+)
+
+func ResolveLink(ctx *RenderContext, link, userContentAnchorPrefix string) (result string, resolved bool) {
+ isAnchorFragment := link != "" && link[0] == '#'
+ if !isAnchorFragment && !IsFullURLString(link) {
+ linkBase := ctx.Links.Base
+ if ctx.IsWiki {
+ if ext := path.Ext(link); ext == "" || ext == ".-" {
+ linkBase = ctx.Links.WikiLink() // the link is for a wiki page
+ } else if DetectMarkupTypeByFileName(link) != "" {
+ linkBase = ctx.Links.WikiLink() // the link is renderable as a wiki page
+ } else {
+ linkBase = ctx.Links.WikiRawLink() // otherwise, use a raw link instead to view&download medias
+ }
+ } else if ctx.Links.BranchPath != "" || ctx.Links.TreePath != "" {
+ // if there is no BranchPath, then the link will be something like "/owner/repo/src/{the-file-path}"
+ // and then this link will be handled by the "legacy-ref" code and be redirected to the default branch like "/owner/repo/src/branch/main/{the-file-path}"
+ linkBase = ctx.Links.SrcLink()
+ }
+ link, resolved = util.URLJoin(linkBase, link), true
+ }
+ if isAnchorFragment && userContentAnchorPrefix != "" {
+ link, resolved = userContentAnchorPrefix+link[1:], true
+ }
+ return link, resolved
+}
diff --git a/modules/markup/html_node.go b/modules/markup/html_node.go
new file mode 100644
index 0000000000..6d784975b9
--- /dev/null
+++ b/modules/markup/html_node.go
@@ -0,0 +1,62 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package markup
+
+import (
+ "code.gitea.io/gitea/modules/util"
+
+ "golang.org/x/net/html"
+)
+
+func visitNodeImg(ctx *RenderContext, img *html.Node) (next *html.Node) {
+ next = img.NextSibling
+ for i, attr := range img.Attr {
+ if attr.Key != "src" {
+ continue
+ }
+
+ if IsNonEmptyRelativePath(attr.Val) {
+ attr.Val = util.URLJoin(ctx.Links.ResolveMediaLink(ctx.IsWiki), attr.Val)
+
+ // By default, the "" tag should also be clickable,
+ // because frontend use `` to paste the re-scaled image into the markdown,
+ // so it must match the default markdown image behavior.
+ hasParentAnchor := false
+ for p := img.Parent; p != nil; p = p.Parent {
+ if hasParentAnchor = p.Type == html.ElementNode && p.Data == "a"; hasParentAnchor {
+ break
+ }
+ }
+ if !hasParentAnchor {
+ imgA := &html.Node{Type: html.ElementNode, Data: "a", Attr: []html.Attribute{
+ {Key: "href", Val: attr.Val},
+ {Key: "target", Val: "_blank"},
+ }}
+ parent := img.Parent
+ imgNext := img.NextSibling
+ parent.RemoveChild(img)
+ parent.InsertBefore(imgA, imgNext)
+ imgA.AppendChild(img)
+ }
+ }
+ attr.Val = camoHandleLink(attr.Val)
+ img.Attr[i] = attr
+ }
+ return next
+}
+
+func visitNodeVideo(ctx *RenderContext, node *html.Node) (next *html.Node) {
+ next = node.NextSibling
+ for i, attr := range node.Attr {
+ if attr.Key != "src" {
+ continue
+ }
+ if IsNonEmptyRelativePath(attr.Val) {
+ attr.Val = util.URLJoin(ctx.Links.ResolveMediaLink(ctx.IsWiki), attr.Val)
+ }
+ attr.Val = camoHandleLink(attr.Val)
+ node.Attr[i] = attr
+ }
+ return next
+}
diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go
index df3c2609ef..c69f3ddd64 100644
--- a/modules/markup/html_test.go
+++ b/modules/markup/html_test.go
@@ -144,17 +144,6 @@ func TestRender_CrossReferences(t *testing.T) {
``)
}
-func TestMisc_IsSameDomain(t *testing.T) {
- setting.AppURL = markup.TestAppURL
-
- sha := "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
- commit := util.URLJoin(markup.TestRepoURL, "commit", sha)
-
- assert.True(t, markup.IsSameDomain(commit))
- assert.False(t, markup.IsSameDomain("http://google.com/ncr"))
- assert.False(t, markup.IsSameDomain("favicon.ico"))
-}
-
func TestRender_links(t *testing.T) {
setting.AppURL = markup.TestAppURL
@@ -455,6 +444,10 @@ func TestRender_ShortLinks(t *testing.T) {
"[[Link]]",
``,
``)
+ test(
+ "[[Link.-]]",
+ ``,
+ ``)
test(
"[[Link.jpg]]",
``,
@@ -529,7 +522,7 @@ func TestRender_ShortLinks(t *testing.T) {
``)
}
-func TestRender_RelativeImages(t *testing.T) {
+func TestRender_RelativeMedias(t *testing.T) {
render := func(input string, isWiki bool, links markup.Links) string {
buffer, err := markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
@@ -555,6 +548,15 @@ func TestRender_RelativeImages(t *testing.T) {
out = render(``, true, markup.Links{Base: "/test-owner/test-repo", BranchPath: "test-branch"})
assert.Equal(t, ``, out)
+
+ out = render(`
space @mention-user
/just/a/path.bin
https://example.com/file.bin
-local link
+local link
remote link
local link
remote link
@@ -984,7 +996,7 @@ space
`)
+ extraClass := ""
+ if _, ok := n.(*InlineBlock); ok {
+ extraClass = "display "
+ }
+ _, _ = w.WriteString(``)
for c := n.FirstChild(); c != nil; c = c.NextSibling() {
segment := c.(*ast.Text).Segment
value := util.EscapeHTML(segment.Value(source))
@@ -43,4 +47,5 @@ func (r *InlineRenderer) renderInline(w util.BufWriter, source []byte, n ast.Nod
// RegisterFuncs registers the renderer for inline math nodes
func (r *InlineRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
reg.Register(KindInline, r.renderInline)
+ reg.Register(KindInlineBlock, r.renderInline)
}
diff --git a/modules/markup/markdown/math/math.go b/modules/markup/markdown/math/math.go
index 8a50753574..3d9f376bc6 100644
--- a/modules/markup/markdown/math/math.go
+++ b/modules/markup/markdown/math/math.go
@@ -96,7 +96,8 @@ func (e *Extension) Extend(m goldmark.Markdown) {
util.Prioritized(NewInlineBracketParser(), 501),
}
if e.parseDollarInline {
- inlines = append(inlines, util.Prioritized(NewInlineDollarParser(), 501))
+ inlines = append(inlines, util.Prioritized(NewInlineDollarParser(), 503),
+ util.Prioritized(NewInlineDualDollarParser(), 502))
}
m.Parser().AddOptions(parser.WithInlineParsers(inlines...))
diff --git a/modules/markup/markdown/prefixed_id.go b/modules/markup/markdown/prefixed_id.go
index 9c60949202..63d7fadc0a 100644
--- a/modules/markup/markdown/prefixed_id.go
+++ b/modules/markup/markdown/prefixed_id.go
@@ -9,9 +9,9 @@ import (
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/markup/common"
+ "code.gitea.io/gitea/modules/util"
"github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/util"
)
type prefixedIDs struct {
@@ -36,7 +36,7 @@ func (p *prefixedIDs) GenerateWithDefault(value, dft []byte) []byte {
if !bytes.HasPrefix(result, []byte("user-content-")) {
result = append([]byte("user-content-"), result...)
}
- if p.values.Add(util.BytesToReadOnlyString(result)) {
+ if p.values.Add(util.UnsafeBytesToString(result)) {
return result
}
for i := 1; ; i++ {
@@ -49,7 +49,7 @@ func (p *prefixedIDs) GenerateWithDefault(value, dft []byte) []byte {
// Put puts a given element id to the used ids table.
func (p *prefixedIDs) Put(value []byte) {
- p.values.Add(util.BytesToReadOnlyString(value))
+ p.values.Add(util.UnsafeBytesToString(value))
}
func newPrefixedIDs() *prefixedIDs {
diff --git a/modules/markup/markdown/transform_heading.go b/modules/markup/markdown/transform_heading.go
index 6f38abfad9..6d48f34d93 100644
--- a/modules/markup/markdown/transform_heading.go
+++ b/modules/markup/markdown/transform_heading.go
@@ -7,10 +7,10 @@ import (
"fmt"
"code.gitea.io/gitea/modules/markup"
+ "code.gitea.io/gitea/modules/util"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/text"
- "github.com/yuin/goldmark/util"
)
func (g *ASTTransformer) transformHeading(_ *markup.RenderContext, v *ast.Heading, reader text.Reader, tocList *[]markup.Header) {
@@ -21,11 +21,11 @@ func (g *ASTTransformer) transformHeading(_ *markup.RenderContext, v *ast.Headin
}
txt := v.Text(reader.Source())
header := markup.Header{
- Text: util.BytesToReadOnlyString(txt),
+ Text: util.UnsafeBytesToString(txt),
Level: v.Level,
}
if id, found := v.AttributeString("id"); found {
- header.ID = util.BytesToReadOnlyString(id.([]byte))
+ header.ID = util.UnsafeBytesToString(id.([]byte))
}
*tocList = append(*tocList, header)
g.applyElementDir(v)
diff --git a/modules/markup/markdown/transform_link.go b/modules/markup/markdown/transform_link.go
index 527a5dfc44..38fbf693ab 100644
--- a/modules/markup/markdown/transform_link.go
+++ b/modules/markup/markdown/transform_link.go
@@ -4,38 +4,13 @@
package markdown
import (
- "path/filepath"
-
"code.gitea.io/gitea/modules/markup"
- giteautil "code.gitea.io/gitea/modules/util"
"github.com/yuin/goldmark/ast"
)
func (g *ASTTransformer) transformLink(ctx *markup.RenderContext, v *ast.Link) {
- // Links need their href to munged to be a real value
- link := v.Destination
- isAnchorFragment := len(link) > 0 && link[0] == '#'
- if !isAnchorFragment && !markup.IsFullURLBytes(link) {
- base := ctx.Links.Base
- if ctx.IsWiki {
- if filepath.Ext(string(link)) == "" {
- // This link doesn't have a file extension - assume a regular wiki link
- base = ctx.Links.WikiLink()
- } else if markup.Type(string(link)) != "" {
- // If it's a file type we can render, use a regular wiki link
- base = ctx.Links.WikiLink()
- } else {
- // Otherwise, use a raw link instead
- base = ctx.Links.WikiRawLink()
- }
- } else if ctx.Links.HasBranchInfo() {
- base = ctx.Links.SrcLink()
- }
- link = []byte(giteautil.URLJoin(base, string(link)))
+ if link, resolved := markup.ResolveLink(ctx, string(v.Destination), "#user-content-"); resolved {
+ v.Destination = []byte(link)
}
- if isAnchorFragment {
- link = []byte("#user-content-" + string(link)[1:])
- }
- v.Destination = link
}
diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go
index 66e8cf611d..18bdfc9761 100644
--- a/modules/markup/renderer.go
+++ b/modules/markup/renderer.go
@@ -86,10 +86,10 @@ type RenderContext struct {
}
type Links struct {
- AbsolutePrefix bool
- Base string
- BranchPath string
- TreePath string
+ AbsolutePrefix bool // add absolute URL prefix to auto-resolved links like "#issue", but not for pre-provided links and medias
+ Base string // base prefix for pre-provided links and medias (images, videos)
+ BranchPath string // actually it is the ref path, eg: "branch/features/feat-12", "tag/v1.0"
+ TreePath string // the dir of the file, eg: "doc" if the file "doc/CHANGE.md" is being rendered
}
func (l *Links) Prefix() string {
@@ -372,22 +372,14 @@ func renderFile(ctx *RenderContext, input io.Reader, output io.Writer) error {
return ErrUnsupportedRenderExtension{extension}
}
-// Type returns if markup format via the filename
-func Type(filename string) string {
+// DetectMarkupTypeByFileName returns the possible markup format type via the filename
+func DetectMarkupTypeByFileName(filename string) string {
if parser := GetRendererByFileName(filename); parser != nil {
return parser.Name()
}
return ""
}
-// IsMarkupFile reports whether file is a markup type file
-func IsMarkupFile(name, markup string) bool {
- if parser := GetRendererByFileName(name); parser != nil {
- return parser.Name() == markup
- }
- return false
-}
-
func PreviewableExtensions() []string {
extensions := make([]string, 0, len(extRenderers))
for extension := range extRenderers {
diff --git a/modules/packages/composer/metadata.go b/modules/packages/composer/metadata.go
index 1d0f025648..2c2e9ebf27 100644
--- a/modules/packages/composer/metadata.go
+++ b/modules/packages/composer/metadata.go
@@ -6,6 +6,7 @@ package composer
import (
"archive/zip"
"io"
+ "path"
"regexp"
"strings"
@@ -36,10 +37,14 @@ type Package struct {
Metadata *Metadata
}
+// https://getcomposer.org/doc/04-schema.md
+
// Metadata represents the metadata of a Composer package
type Metadata struct {
Description string `json:"description,omitempty"`
+ Readme string `json:"readme,omitempty"`
Keywords []string `json:"keywords,omitempty"`
+ Comments Comments `json:"_comments,omitempty"`
Homepage string `json:"homepage,omitempty"`
License Licenses `json:"license,omitempty"`
Authors []Author `json:"authors,omitempty"`
@@ -74,6 +79,28 @@ func (l *Licenses) UnmarshalJSON(data []byte) error {
return nil
}
+// Comments represents the comments of a Composer package
+type Comments []string
+
+// UnmarshalJSON reads from a string or array
+func (c *Comments) UnmarshalJSON(data []byte) error {
+ switch data[0] {
+ case '"':
+ var value string
+ if err := json.Unmarshal(data, &value); err != nil {
+ return err
+ }
+ *c = Comments{value}
+ case '[':
+ values := make([]string, 0, 5)
+ if err := json.Unmarshal(data, &values); err != nil {
+ return err
+ }
+ *c = Comments(values)
+ }
+ return nil
+}
+
// Author represents an author
type Author struct {
Name string `json:"name,omitempty"`
@@ -101,14 +128,14 @@ func ParsePackage(r io.ReaderAt, size int64) (*Package, error) {
}
defer f.Close()
- return ParseComposerFile(f)
+ return ParseComposerFile(archive, path.Dir(file.Name), f)
}
}
return nil, ErrMissingComposerFile
}
// ParseComposerFile parses a composer.json file to retrieve the metadata of a Composer package
-func ParseComposerFile(r io.Reader) (*Package, error) {
+func ParseComposerFile(archive *zip.Reader, pathPrefix string, r io.Reader) (*Package, error) {
var cj struct {
Name string `json:"name"`
Version string `json:"version"`
@@ -137,6 +164,19 @@ func ParseComposerFile(r io.Reader) (*Package, error) {
cj.Type = "library"
}
+ if cj.Readme == "" {
+ cj.Readme = "README.md"
+ }
+ f, err := archive.Open(path.Join(pathPrefix, cj.Readme))
+ if err == nil {
+ // 10kb limit for readme content
+ buf, _ := io.ReadAll(io.LimitReader(f, 10*1024))
+ cj.Readme = string(buf)
+ _ = f.Close()
+ } else {
+ cj.Readme = ""
+ }
+
return &Package{
Name: cj.Name,
Version: cj.Version,
diff --git a/modules/packages/composer/metadata_test.go b/modules/packages/composer/metadata_test.go
index a0e1a77a6e..a5e317daf1 100644
--- a/modules/packages/composer/metadata_test.go
+++ b/modules/packages/composer/metadata_test.go
@@ -17,6 +17,8 @@ import (
const (
name = "gitea/composer-package"
description = "Package Description"
+ readme = "Package Readme"
+ comments = "Package Comment"
packageType = "composer-plugin"
author = "Gitea Authors"
email = "no.reply@gitea.io"
@@ -41,7 +43,8 @@ const composerContent = `{
},
"require": {
"php": ">=7.2 || ^8.0"
- }
+ },
+ "_comments": "` + comments + `"
}`
func TestLicenseUnmarshal(t *testing.T) {
@@ -54,18 +57,30 @@ func TestLicenseUnmarshal(t *testing.T) {
assert.Equal(t, "MIT", l[0])
}
+func TestCommentsUnmarshal(t *testing.T) {
+ var c Comments
+ assert.NoError(t, json.NewDecoder(strings.NewReader(`["comment"]`)).Decode(&c))
+ assert.Len(t, c, 1)
+ assert.Equal(t, "comment", c[0])
+ assert.NoError(t, json.NewDecoder(strings.NewReader(`"comment"`)).Decode(&c))
+ assert.Len(t, c, 1)
+ assert.Equal(t, "comment", c[0])
+}
+
func TestParsePackage(t *testing.T) {
- createArchive := func(name, content string) []byte {
+ createArchive := func(files map[string]string) []byte {
var buf bytes.Buffer
archive := zip.NewWriter(&buf)
- w, _ := archive.Create(name)
- w.Write([]byte(content))
+ for name, content := range files {
+ w, _ := archive.Create(name)
+ w.Write([]byte(content))
+ }
archive.Close()
return buf.Bytes()
}
t.Run("MissingComposerFile", func(t *testing.T) {
- data := createArchive("dummy.txt", "")
+ data := createArchive(map[string]string{"dummy.txt": ""})
cp, err := ParsePackage(bytes.NewReader(data), int64(len(data)))
assert.Nil(t, cp)
@@ -73,7 +88,7 @@ func TestParsePackage(t *testing.T) {
})
t.Run("MissingComposerFileInRoot", func(t *testing.T) {
- data := createArchive("sub/sub/composer.json", "")
+ data := createArchive(map[string]string{"sub/sub/composer.json": ""})
cp, err := ParsePackage(bytes.NewReader(data), int64(len(data)))
assert.Nil(t, cp)
@@ -81,43 +96,52 @@ func TestParsePackage(t *testing.T) {
})
t.Run("InvalidComposerFile", func(t *testing.T) {
- data := createArchive("composer.json", "")
+ data := createArchive(map[string]string{"composer.json": ""})
cp, err := ParsePackage(bytes.NewReader(data), int64(len(data)))
assert.Nil(t, cp)
assert.Error(t, err)
})
- t.Run("Valid", func(t *testing.T) {
- data := createArchive("composer.json", composerContent)
+ t.Run("InvalidPackageName", func(t *testing.T) {
+ data := createArchive(map[string]string{"composer.json": "{}"})
cp, err := ParsePackage(bytes.NewReader(data), int64(len(data)))
- assert.NoError(t, err)
- assert.NotNil(t, cp)
- })
-}
-
-func TestParseComposerFile(t *testing.T) {
- t.Run("InvalidPackageName", func(t *testing.T) {
- cp, err := ParseComposerFile(strings.NewReader(`{}`))
assert.Nil(t, cp)
assert.ErrorIs(t, err, ErrInvalidName)
})
t.Run("InvalidPackageVersion", func(t *testing.T) {
- cp, err := ParseComposerFile(strings.NewReader(`{"name": "gitea/composer-package", "version": "1.a.3"}`))
+ data := createArchive(map[string]string{"composer.json": `{"name": "gitea/composer-package", "version": "1.a.3"}`})
+
+ cp, err := ParsePackage(bytes.NewReader(data), int64(len(data)))
assert.Nil(t, cp)
assert.ErrorIs(t, err, ErrInvalidVersion)
})
+ t.Run("InvalidReadmePath", func(t *testing.T) {
+ data := createArchive(map[string]string{"composer.json": `{"name": "gitea/composer-package", "readme": "sub/README.md"}`})
+
+ cp, err := ParsePackage(bytes.NewReader(data), int64(len(data)))
+ assert.NoError(t, err)
+ assert.NotNil(t, cp)
+
+ assert.Empty(t, cp.Metadata.Readme)
+ })
+
t.Run("Valid", func(t *testing.T) {
- cp, err := ParseComposerFile(strings.NewReader(composerContent))
+ data := createArchive(map[string]string{"composer.json": composerContent, "README.md": readme})
+
+ cp, err := ParsePackage(bytes.NewReader(data), int64(len(data)))
assert.NoError(t, err)
assert.NotNil(t, cp)
assert.Equal(t, name, cp.Name)
assert.Empty(t, cp.Version)
assert.Equal(t, description, cp.Metadata.Description)
+ assert.Equal(t, readme, cp.Metadata.Readme)
+ assert.Len(t, cp.Metadata.Comments, 1)
+ assert.Equal(t, comments, cp.Metadata.Comments[0])
assert.Len(t, cp.Metadata.Authors, 1)
assert.Equal(t, author, cp.Metadata.Authors[0].Name)
assert.Equal(t, email, cp.Metadata.Authors[0].Email)
diff --git a/modules/references/references.go b/modules/references/references.go
index 1b656ed4cb..2889430bcf 100644
--- a/modules/references/references.go
+++ b/modules/references/references.go
@@ -14,8 +14,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup/mdstripper"
"code.gitea.io/gitea/modules/setting"
-
- "github.com/yuin/goldmark/util"
+ "code.gitea.io/gitea/modules/util"
)
var (
@@ -341,7 +340,7 @@ func FindRenderizableReferenceNumeric(content string, prOnly, crossLinkOnly bool
return false, nil
}
}
- r := getCrossReference(util.StringToReadOnlyBytes(content), match[2], match[3], false, prOnly)
+ r := getCrossReference(util.UnsafeStringToBytes(content), match[2], match[3], false, prOnly)
if r == nil {
return false, nil
}
diff --git a/modules/setting/global.go b/modules/setting/global.go
new file mode 100644
index 0000000000..55dfe485b2
--- /dev/null
+++ b/modules/setting/global.go
@@ -0,0 +1,18 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package setting
+
+// Global settings
+var (
+ // RunUser is the OS user that Gitea is running as. ini:"RUN_USER"
+ RunUser string
+ // RunMode is the running mode of Gitea, it only accepts two values: "dev" and "prod".
+ // Non-dev values will be replaced by "prod". ini: "RUN_MODE"
+ RunMode string
+ // IsProd is true if RunMode is not "dev"
+ IsProd bool
+
+ // AppName is the Application name, used in the page title. ini: "APP_NAME"
+ AppName string
+)
diff --git a/modules/setting/server.go b/modules/setting/server.go
index 7d6ece2727..d7a71578d4 100644
--- a/modules/setting/server.go
+++ b/modules/setting/server.go
@@ -40,16 +40,16 @@ const (
LandingPageLogin LandingPage = "/user/login"
)
+// Server settings
var (
- // AppName is the Application name, used in the page title.
- // It maps to ini:"APP_NAME"
- AppName string
// AppURL is the Application ROOT_URL. It always has a '/' suffix
// It maps to ini:"ROOT_URL"
AppURL string
// AppSubURL represents the sub-url mounting point for gitea. It is either "" or starts with '/' and ends without '/', such as '/{subpath}'.
// This value is empty if site does not have sub-url.
AppSubURL string
+ // UseSubURLPath makes Gitea handle requests with sub-path like "/sub-path/owner/repo/...", to make it easier to debug sub-path related problems without a reverse proxy.
+ UseSubURLPath bool
// AppDataPath is the default path for storing data.
// It maps to ini:"APP_DATA_PATH" in [server] and defaults to AppWorkPath + "/data"
AppDataPath string
@@ -59,8 +59,6 @@ var (
// AssetVersion holds a opaque value that is used for cache-busting assets
AssetVersion string
- // Server settings
-
Protocol Scheme
UseProxyProtocol bool // `ini:"USE_PROXY_PROTOCOL"`
ProxyProtocolTLSBridging bool //`ini:"PROXY_PROTOCOL_TLS_BRIDGING"`
@@ -275,9 +273,10 @@ func loadServerFrom(rootCfg ConfigProvider) {
// This should be TrimRight to ensure that there is only a single '/' at the end of AppURL.
AppURL = strings.TrimRight(appURL.String(), "/") + "/"
- // Suburl should start with '/' and end without '/', such as '/{subpath}'.
+ // AppSubURL should start with '/' and end without '/', such as '/{subpath}'.
// This value is empty if site does not have sub-url.
AppSubURL = strings.TrimSuffix(appURL.Path, "/")
+ UseSubURLPath = sec.Key("USE_SUB_URL_PATH").MustBool(false)
StaticURLPrefix = strings.TrimSuffix(sec.Key("STATIC_URL_PREFIX").MustString(AppSubURL), "/")
// Check if Domain differs from AppURL domain than update it to AppURL's domain
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index f056fbfc6c..b4f913cdae 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -25,12 +25,7 @@ var (
// AppStartTime store time gitea has started
AppStartTime time.Time
- // Other global setting objects
-
CfgProvider ConfigProvider
- RunMode string
- RunUser string
- IsProd bool
IsWindows bool
// IsInTesting indicates whether the testing is running. A lot of unreliable code causes a lot of nonsense error logs during testing
diff --git a/modules/structs/miscellaneous.go b/modules/structs/miscellaneous.go
index bff10f95b7..3b206c1dd7 100644
--- a/modules/structs/miscellaneous.go
+++ b/modules/structs/miscellaneous.go
@@ -25,7 +25,8 @@ type MarkupOption struct {
//
// in: body
Mode string
- // Context to render
+ // URL path for rendering issue, media and file links
+ // Expected format: /subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}
//
// in: body
Context string
@@ -53,7 +54,8 @@ type MarkdownOption struct {
//
// in: body
Mode string
- // Context to render
+ // URL path for rendering issue, media and file links
+ // Expected format: /subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}
//
// in: body
Context string
diff --git a/modules/structs/org_team.go b/modules/structs/org_team.go
index 78dc4abaef..f8899b236b 100644
--- a/modules/structs/org_team.go
+++ b/modules/structs/org_team.go
@@ -24,7 +24,7 @@ type Team struct {
// CreateTeamOption options for creating a team
type CreateTeamOption struct {
// required: true
- Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"`
+ Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(255)"`
Description string `json:"description" binding:"MaxSize(255)"`
IncludesAllRepositories bool `json:"includes_all_repositories"`
// enum: read,write,admin
@@ -40,7 +40,7 @@ type CreateTeamOption struct {
// EditTeamOption options for editing a team
type EditTeamOption struct {
// required: true
- Name string `json:"name" binding:"AlphaDashDot;MaxSize(30)"`
+ Name string `json:"name" binding:"AlphaDashDot;MaxSize(255)"`
Description *string `json:"description" binding:"MaxSize(255)"`
IncludesAllRepositories *bool `json:"includes_all_repositories"`
// enum: read,write,admin
diff --git a/modules/structs/repo_tag.go b/modules/structs/repo_tag.go
index 4a7d895288..5722513f4f 100644
--- a/modules/structs/repo_tag.go
+++ b/modules/structs/repo_tag.go
@@ -3,6 +3,8 @@
package structs
+import "time"
+
// Tag represents a repository tag
type Tag struct {
Name string `json:"name"`
@@ -38,3 +40,29 @@ type CreateTagOption struct {
Message string `json:"message"`
Target string `json:"target"`
}
+
+// TagProtection represents a tag protection
+type TagProtection struct {
+ ID int64 `json:"id"`
+ NamePattern string `json:"name_pattern"`
+ WhitelistUsernames []string `json:"whitelist_usernames"`
+ WhitelistTeams []string `json:"whitelist_teams"`
+ // swagger:strfmt date-time
+ Created time.Time `json:"created_at"`
+ // swagger:strfmt date-time
+ Updated time.Time `json:"updated_at"`
+}
+
+// CreateTagProtectionOption options for creating a tag protection
+type CreateTagProtectionOption struct {
+ NamePattern string `json:"name_pattern"`
+ WhitelistUsernames []string `json:"whitelist_usernames"`
+ WhitelistTeams []string `json:"whitelist_teams"`
+}
+
+// EditTagProtectionOption options for editing a tag protection
+type EditTagProtectionOption struct {
+ NamePattern *string `json:"name_pattern"`
+ WhitelistUsernames []string `json:"whitelist_usernames"`
+ WhitelistTeams []string `json:"whitelist_teams"`
+}
diff --git a/modules/system/db.go b/modules/system/db.go
index 05e9de0ae8..17178283d9 100644
--- a/modules/system/db.go
+++ b/modules/system/db.go
@@ -8,8 +8,7 @@ import (
"code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/json"
-
- "github.com/yuin/goldmark/util"
+ "code.gitea.io/gitea/modules/util"
)
// DBStore can be used to store app state items in local filesystem
@@ -24,7 +23,7 @@ func (f *DBStore) Get(ctx context.Context, item StateItem) error {
if content == "" {
return nil
}
- return json.Unmarshal(util.StringToReadOnlyBytes(content), item)
+ return json.Unmarshal(util.UnsafeStringToBytes(content), item)
}
// Set saves the state item
@@ -33,5 +32,5 @@ func (f *DBStore) Set(ctx context.Context, item StateItem) error {
if err != nil {
return err
}
- return system.SaveAppStateContent(ctx, item.Name(), util.BytesToReadOnlyString(b))
+ return system.SaveAppStateContent(ctx, item.Name(), util.UnsafeBytesToString(b))
}
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 330cbf8908..5f73e6b278 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -36,16 +36,16 @@ func NewFuncMap() template.FuncMap {
// -----------------------------------------------------------------
// html/template related functions
"dict": dict, // it's lowercase because this name has been widely used. Our other functions should have uppercase names.
- "Iif": Iif,
- "Eval": Eval,
- "SafeHTML": SafeHTML,
+ "Iif": iif,
+ "Eval": evalTokens,
+ "SafeHTML": safeHTML,
"HTMLFormat": HTMLFormat,
- "HTMLEscape": HTMLEscape,
- "QueryEscape": QueryEscape,
- "JSEscape": JSEscapeSafe,
+ "HTMLEscape": htmlEscape,
+ "QueryEscape": queryEscape,
+ "JSEscape": jsEscapeSafe,
"SanitizeHTML": SanitizeHTML,
"URLJoin": util.URLJoin,
- "DotEscape": DotEscape,
+ "DotEscape": dotEscape,
"PathEscape": url.PathEscape,
"PathEscapeSegments": util.PathEscapeSegments,
@@ -59,9 +59,9 @@ func NewFuncMap() template.FuncMap {
// svg / avatar / icon / color
"svg": svg.RenderHTML,
"EntryIcon": base.EntryIcon,
- "MigrationIcon": MigrationIcon,
- "ActionIcon": ActionIcon,
- "SortArrow": SortArrow,
+ "MigrationIcon": migrationIcon,
+ "ActionIcon": actionIcon,
+ "SortArrow": sortArrow,
"ContrastColor": util.ContrastColor,
// -----------------------------------------------------------------
@@ -139,7 +139,7 @@ func NewFuncMap() template.FuncMap {
"DisableImportLocal": func() bool {
return !setting.ImportLocalPaths
},
- "UserThemeName": UserThemeName,
+ "UserThemeName": userThemeName,
"NotificationSettings": func() map[string]any {
return map[string]any{
"MinTimeout": int(setting.UI.Notification.MinTimeout / time.Millisecond),
@@ -155,28 +155,28 @@ func NewFuncMap() template.FuncMap {
// -----------------------------------------------------------------
// render
"RenderCommitMessage": RenderCommitMessage,
- "RenderCommitMessageLinkSubject": RenderCommitMessageLinkSubject,
+ "RenderCommitMessageLinkSubject": renderCommitMessageLinkSubject,
- "RenderCommitBody": RenderCommitBody,
- "RenderCodeBlock": RenderCodeBlock,
- "RenderIssueTitle": RenderIssueTitle,
- "RenderEmoji": RenderEmoji,
- "ReactionToEmoji": ReactionToEmoji,
+ "RenderCommitBody": renderCommitBody,
+ "RenderCodeBlock": renderCodeBlock,
+ "RenderIssueTitle": renderIssueTitle,
+ "RenderEmoji": renderEmoji,
+ "ReactionToEmoji": reactionToEmoji,
"RenderMarkdownToHtml": RenderMarkdownToHtml,
- "RenderLabel": RenderLabel,
+ "RenderLabel": renderLabel,
"RenderLabels": RenderLabels,
// -----------------------------------------------------------------
// misc
"ShortSha": base.ShortSha,
"ActionContent2Commits": ActionContent2Commits,
- "IsMultilineCommitMessage": IsMultilineCommitMessage,
+ "IsMultilineCommitMessage": isMultilineCommitMessage,
"CommentMustAsDiff": gitdiff.CommentMustAsDiff,
"MirrorRemoteAddress": mirrorRemoteAddress,
- "FilenameIsImage": FilenameIsImage,
- "TabSizeClass": TabSizeClass,
+ "FilenameIsImage": filenameIsImage,
+ "TabSizeClass": tabSizeClass,
}
}
@@ -197,8 +197,8 @@ func HTMLFormat(s string, rawArgs ...any) template.HTML {
return template.HTML(fmt.Sprintf(s, args...))
}
-// SafeHTML render raw as HTML
-func SafeHTML(s any) template.HTML {
+// safeHTML render raw as HTML
+func safeHTML(s any) template.HTML {
switch v := s.(type) {
case string:
return template.HTML(v)
@@ -213,7 +213,7 @@ func SanitizeHTML(s string) template.HTML {
return template.HTML(markup.Sanitize(s))
}
-func HTMLEscape(s any) template.HTML {
+func htmlEscape(s any) template.HTML {
switch v := s.(type) {
case string:
return template.HTML(html.EscapeString(v))
@@ -223,22 +223,22 @@ func HTMLEscape(s any) template.HTML {
panic(fmt.Sprintf("unexpected type %T", s))
}
-func JSEscapeSafe(s string) template.HTML {
+func jsEscapeSafe(s string) template.HTML {
return template.HTML(template.JSEscapeString(s))
}
-func QueryEscape(s string) template.URL {
+func queryEscape(s string) template.URL {
return template.URL(url.QueryEscape(s))
}
-// DotEscape wraps a dots in names with ZWJ [U+200D] in order to prevent autolinkers from detecting these as urls
-func DotEscape(raw string) string {
+// dotEscape wraps a dots in names with ZWJ [U+200D] in order to prevent auto-linkers from detecting these as urls
+func dotEscape(raw string) string {
return strings.ReplaceAll(raw, ".", "\u200d.\u200d")
}
-// Iif is an "inline-if", similar util.Iif[T] but templates need the non-generic version,
-// and it could be simply used as "{{Iif expr trueVal}}" (omit the falseVal).
-func Iif(condition any, vals ...any) any {
+// iif is an "inline-if", similar util.Iif[T] but templates need the non-generic version,
+// and it could be simply used as "{{iif expr trueVal}}" (omit the falseVal).
+func iif(condition any, vals ...any) any {
if isTemplateTruthy(condition) {
return vals[0]
} else if len(vals) > 1 {
@@ -273,19 +273,19 @@ func isTemplateTruthy(v any) bool {
}
}
-// Eval the expression and return the result, see the comment of eval.Expr for details.
+// evalTokens evaluates the expression by tokens and returns the result, see the comment of eval.Expr for details.
// To use this helper function in templates, pass each token as a separate parameter.
//
// {{ $int64 := Eval $var "+" 1 }}
// {{ $float64 := Eval $var "+" 1.0 }}
//
// Golang's template supports comparable int types, so the int64 result can be used in later statements like {{if lt $int64 10}}
-func Eval(tokens ...any) (any, error) {
+func evalTokens(tokens ...any) (any, error) {
n, err := eval.Expr(tokens...)
return n.Value, err
}
-func UserThemeName(user *user_model.User) string {
+func userThemeName(user *user_model.User) string {
if user == nil || user.Theme == "" {
return setting.UI.DefaultTheme
}
diff --git a/modules/templates/helper_test.go b/modules/templates/helper_test.go
index ea5da7be80..b9fabb7016 100644
--- a/modules/templates/helper_test.go
+++ b/modules/templates/helper_test.go
@@ -58,7 +58,7 @@ func TestSubjectBodySeparator(t *testing.T) {
}
func TestJSEscapeSafe(t *testing.T) {
- assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, JSEscapeSafe(`&<>'"`))
+ assert.EqualValues(t, `\u0026\u003C\u003E\'\"`, jsEscapeSafe(`&<>'"`))
}
func TestHTMLFormat(t *testing.T) {
@@ -71,7 +71,7 @@ func TestSanitizeHTML(t *testing.T) {
func TestTemplateTruthy(t *testing.T) {
tmpl := template.New("test")
- tmpl.Funcs(template.FuncMap{"Iif": Iif})
+ tmpl.Funcs(template.FuncMap{"Iif": iif})
template.Must(tmpl.Parse(`{{if .Value}}true{{else}}false{{end}}:{{Iif .Value "true" "false"}}`))
cases := []any{
diff --git a/modules/templates/mailer.go b/modules/templates/mailer.go
index 7c97e1ea89..ace81bf4a5 100644
--- a/modules/templates/mailer.go
+++ b/modules/templates/mailer.go
@@ -22,7 +22,7 @@ var mailSubjectSplit = regexp.MustCompile(`(?m)^-{3,}\s*$`)
func mailSubjectTextFuncMap() texttmpl.FuncMap {
return texttmpl.FuncMap{
"dict": dict,
- "Eval": Eval,
+ "Eval": evalTokens,
"EllipsisString": base.EllipsisString,
"AppName": func() string {
diff --git a/modules/templates/util_misc.go b/modules/templates/util_misc.go
index 774385483b..d645fa013e 100644
--- a/modules/templates/util_misc.go
+++ b/modules/templates/util_misc.go
@@ -24,7 +24,7 @@ import (
"github.com/editorconfig/editorconfig-core-go/v2"
)
-func SortArrow(normSort, revSort, urlSort string, isDefault bool) template.HTML {
+func sortArrow(normSort, revSort, urlSort string, isDefault bool) template.HTML {
// if needed
if len(normSort) == 0 || len(urlSort) == 0 {
return ""
@@ -50,8 +50,8 @@ func SortArrow(normSort, revSort, urlSort string, isDefault bool) template.HTML
return ""
}
-// IsMultilineCommitMessage checks to see if a commit message contains multiple lines.
-func IsMultilineCommitMessage(msg string) bool {
+// isMultilineCommitMessage checks to see if a commit message contains multiple lines.
+func isMultilineCommitMessage(msg string) bool {
return strings.Count(strings.TrimSpace(msg), "\n") >= 1
}
@@ -69,8 +69,8 @@ type Actioner interface {
GetIssueInfos() []string
}
-// ActionIcon accepts an action operation type and returns an icon class name.
-func ActionIcon(opType activities_model.ActionType) string {
+// actionIcon accepts an action operation type and returns an icon class name.
+func actionIcon(opType activities_model.ActionType) string {
switch opType {
case activities_model.ActionCreateRepo, activities_model.ActionTransferRepo, activities_model.ActionRenameRepo:
return "repo"
@@ -126,8 +126,8 @@ func ActionContent2Commits(act Actioner) *repository.PushCommits {
return push
}
-// MigrationIcon returns a SVG name matching the service an issue/comment was migrated from
-func MigrationIcon(hostname string) string {
+// migrationIcon returns a SVG name matching the service an issue/comment was migrated from
+func migrationIcon(hostname string) string {
switch hostname {
case "github.com":
return "octicon-mark-github"
@@ -177,12 +177,12 @@ func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteNa
return ret
}
-func FilenameIsImage(filename string) bool {
+func filenameIsImage(filename string) bool {
mimeType := mime.TypeByExtension(filepath.Ext(filename))
return strings.HasPrefix(mimeType, "image/")
}
-func TabSizeClass(ec *editorconfig.Editorconfig, filename string) string {
+func tabSizeClass(ec *editorconfig.Editorconfig, filename string) string {
if ec != nil {
def, err := ec.GetDefinitionForFilename(filename)
if err == nil && def.TabWidth >= 1 && def.TabWidth <= 16 {
diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go
index b15de6521d..6eee007f34 100644
--- a/modules/templates/util_render.go
+++ b/modules/templates/util_render.go
@@ -41,12 +41,12 @@ func RenderCommitMessage(ctx context.Context, msg string, metas map[string]strin
if len(msgLines) == 0 {
return template.HTML("")
}
- return RenderCodeBlock(template.HTML(msgLines[0]))
+ return renderCodeBlock(template.HTML(msgLines[0]))
}
-// RenderCommitMessageLinkSubject renders commit message as a XSS-safe link to
+// renderCommitMessageLinkSubject renders commit message as a XSS-safe link to
// the provided default url, handling for special links without email to links.
-func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlDefault string, metas map[string]string) template.HTML {
+func renderCommitMessageLinkSubject(ctx context.Context, msg, urlDefault string, metas map[string]string) template.HTML {
msgLine := strings.TrimLeftFunc(msg, unicode.IsSpace)
lineEnd := strings.IndexByte(msgLine, '\n')
if lineEnd > 0 {
@@ -68,11 +68,11 @@ func RenderCommitMessageLinkSubject(ctx context.Context, msg, urlDefault string,
log.Error("RenderCommitMessageSubject: %v", err)
return template.HTML("")
}
- return RenderCodeBlock(template.HTML(renderedMessage))
+ return renderCodeBlock(template.HTML(renderedMessage))
}
-// RenderCommitBody extracts the body of a commit message without its title.
-func RenderCommitBody(ctx context.Context, msg string, metas map[string]string) template.HTML {
+// renderCommitBody extracts the body of a commit message without its title.
+func renderCommitBody(ctx context.Context, msg string, metas map[string]string) template.HTML {
msgLine := strings.TrimSpace(msg)
lineEnd := strings.IndexByte(msgLine, '\n')
if lineEnd > 0 {
@@ -99,14 +99,14 @@ func RenderCommitBody(ctx context.Context, msg string, metas map[string]string)
// Match text that is between back ticks.
var codeMatcher = regexp.MustCompile("`([^`]+)`")
-// RenderCodeBlock renders "`…`" as highlighted "" block, intended for issue and PR titles
-func RenderCodeBlock(htmlEscapedTextToRender template.HTML) template.HTML {
+// renderCodeBlock renders "`…`" as highlighted "" block, intended for issue and PR titles
+func renderCodeBlock(htmlEscapedTextToRender template.HTML) template.HTML {
htmlWithCodeTags := codeMatcher.ReplaceAllString(string(htmlEscapedTextToRender), `$1
`) // replace with HTML tags
return template.HTML(htmlWithCodeTags)
}
-// RenderIssueTitle renders issue/pull title with defined post processors
-func RenderIssueTitle(ctx context.Context, text string, metas map[string]string) template.HTML {
+// renderIssueTitle renders issue/pull title with defined post processors
+func renderIssueTitle(ctx context.Context, text string, metas map[string]string) template.HTML {
renderedText, err := markup.RenderIssueTitle(&markup.RenderContext{
Ctx: ctx,
Metas: metas,
@@ -118,9 +118,9 @@ func RenderIssueTitle(ctx context.Context, text string, metas map[string]string)
return template.HTML(renderedText)
}
-// RenderLabel renders a label
+// renderLabel renders a label
// locale is needed due to an import cycle with our context providing the `Tr` function
-func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_model.Label) template.HTML {
+func renderLabel(ctx context.Context, locale translation.Locale, label *issues_model.Label) template.HTML {
var extraCSSClasses string
textColor := util.ContrastColor(label.Color)
labelScope := label.ExclusiveScope()
@@ -134,12 +134,12 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m
if labelScope == "" {
// Regular label
return HTMLFormat(`%s`,
- extraCSSClasses, textColor, label.Color, descriptionText, RenderEmoji(ctx, label.Name))
+ extraCSSClasses, textColor, label.Color, descriptionText, renderEmoji(ctx, label.Name))
}
// Scoped label
- scopeHTML := RenderEmoji(ctx, labelScope)
- itemHTML := RenderEmoji(ctx, label.Name[len(labelScope)+1:])
+ scopeHTML := renderEmoji(ctx, labelScope)
+ itemHTML := renderEmoji(ctx, label.Name[len(labelScope)+1:])
// Make scope and item background colors slightly darker and lighter respectively.
// More contrast needed with higher luminance, empirically tweaked.
@@ -176,8 +176,8 @@ func RenderLabel(ctx context.Context, locale translation.Locale, label *issues_m
textColor, itemColor, itemHTML)
}
-// RenderEmoji renders html text with emoji post processors
-func RenderEmoji(ctx context.Context, text string) template.HTML {
+// renderEmoji renders html text with emoji post processors
+func renderEmoji(ctx context.Context, text string) template.HTML {
renderedText, err := markup.RenderEmoji(&markup.RenderContext{Ctx: ctx},
template.HTMLEscapeString(text))
if err != nil {
@@ -187,8 +187,8 @@ func RenderEmoji(ctx context.Context, text string) template.HTML {
return template.HTML(renderedText)
}
-// ReactionToEmoji renders emoji for use in reactions
-func ReactionToEmoji(reaction string) template.HTML {
+// reactionToEmoji renders emoji for use in reactions
+func reactionToEmoji(reaction string) template.HTML {
val := emoji.FromCode(reaction)
if val != nil {
return template.HTML(val.Emoji)
@@ -220,7 +220,7 @@ func RenderLabels(ctx context.Context, locale translation.Locale, labels []*issu
if label == nil {
continue
}
- htmlCode += fmt.Sprintf(`%s`, baseLink, label.ID, RenderLabel(ctx, locale, label))
+ htmlCode += fmt.Sprintf(`%s`, baseLink, label.ID, renderLabel(ctx, locale, label))
}
htmlCode += ""
return template.HTML(htmlCode)
diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go
index f493b899e3..ba47c34efc 100644
--- a/modules/templates/util_render_test.go
+++ b/modules/templates/util_render_test.go
@@ -103,7 +103,7 @@ func TestRenderCommitBody(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- assert.Equalf(t, tt.want, RenderCommitBody(tt.args.ctx, tt.args.msg, tt.args.metas), "RenderCommitBody(%v, %v, %v)", tt.args.ctx, tt.args.msg, tt.args.metas)
+ assert.Equalf(t, tt.want, renderCommitBody(tt.args.ctx, tt.args.msg, tt.args.metas), "RenderCommitBody(%v, %v, %v)", tt.args.ctx, tt.args.msg, tt.args.metas)
})
}
@@ -127,7 +127,7 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
#123
space`
- assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput(), testMetas))
+ assert.EqualValues(t, expected, renderCommitBody(context.Background(), testInput(), testMetas))
}
func TestRenderCommitMessage(t *testing.T) {
@@ -139,7 +139,7 @@ func TestRenderCommitMessage(t *testing.T) {
func TestRenderCommitMessageLinkSubject(t *testing.T) {
expected := `space @mention-user`
- assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput(), "https://example.com/link", testMetas))
+ assert.EqualValues(t, expected, renderCommitMessageLinkSubject(context.Background(), testInput(), "https://example.com/link", testMetas))
}
func TestRenderIssueTitle(t *testing.T) {
@@ -165,7 +165,7 @@ mail@domain.com
space
`
expected = strings.ReplaceAll(expected, "", " ")
- assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput(), testMetas))
+ assert.EqualValues(t, expected, renderIssueTitle(context.Background(), testInput(), testMetas))
}
func TestRenderMarkdownToHtml(t *testing.T) {
@@ -174,7 +174,7 @@ func TestRenderMarkdownToHtml(t *testing.T) {
https://example.com/file.bin
local link
remote link
-local link
+local link
remote link
@@ -190,7 +190,7 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
#123
space
`
- assert.EqualValues(t, expected, RenderMarkdownToHtml(context.Background(), testInput()))
+ assert.Equal(t, expected, string(RenderMarkdownToHtml(context.Background(), testInput())))
}
func TestRenderLabels(t *testing.T) {
diff --git a/modules/util/sanitize.go b/modules/util/sanitize.go
index f1ea2574f1..0dd8b342a2 100644
--- a/modules/util/sanitize.go
+++ b/modules/util/sanitize.go
@@ -6,8 +6,6 @@ package util
import (
"bytes"
"unicode"
-
- "github.com/yuin/goldmark/util"
)
type sanitizedError struct {
@@ -33,7 +31,7 @@ var schemeSep = []byte("://")
// SanitizeCredentialURLs remove all credentials in URLs (starting with "scheme://") for the input string: "https://user:pass@domain.com" => "https://sanitized-credential@domain.com"
func SanitizeCredentialURLs(s string) string {
- bs := util.StringToReadOnlyBytes(s)
+ bs := UnsafeStringToBytes(s)
schemeSepPos := bytes.Index(bs, schemeSep)
if schemeSepPos == -1 || bytes.IndexByte(bs[schemeSepPos:], '@') == -1 {
return s // fast return if there is no URL scheme or no userinfo
@@ -70,5 +68,5 @@ func SanitizeCredentialURLs(s string) string {
schemeSepPos = bytes.Index(bs, schemeSep)
}
out = append(out, bs...)
- return util.BytesToReadOnlyString(out)
+ return UnsafeBytesToString(out)
}
diff --git a/modules/util/string.go b/modules/util/string.go
index 2cf44d29b1..cf50f591c6 100644
--- a/modules/util/string.go
+++ b/modules/util/string.go
@@ -87,11 +87,11 @@ func ToSnakeCase(input string) string {
}
// UnsafeBytesToString uses Go's unsafe package to convert a byte slice to a string.
-// TODO: replace all "goldmark/util.BytesToReadOnlyString" with this official approach
func UnsafeBytesToString(b []byte) string {
return unsafe.String(unsafe.SliceData(b), len(b))
}
+// UnsafeStringToBytes uses Go's unsafe package to convert a string to a byte slice.
func UnsafeStringToBytes(s string) []byte {
return unsafe.Slice(unsafe.StringData(s), len(s))
}
diff --git a/modules/web/route.go b/modules/web/route.go
index 805fcb4411..b02f66802e 100644
--- a/modules/web/route.go
+++ b/modules/web/route.go
@@ -5,8 +5,10 @@ package web
import (
"net/http"
+ "net/url"
"strings"
+ "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/web/middleware"
"gitea.com/go-chi/binding"
@@ -34,30 +36,30 @@ func GetForm(dataStore middleware.ContextDataStore) any {
return dataStore.GetData()["__form"]
}
-// Route defines a route based on chi's router
-type Route struct {
- R chi.Router
+// Router defines a route based on chi's router
+type Router struct {
+ chiRouter chi.Router
curGroupPrefix string
curMiddlewares []any
}
-// NewRoute creates a new route
-func NewRoute() *Route {
+// NewRouter creates a new route
+func NewRouter() *Router {
r := chi.NewRouter()
- return &Route{R: r}
+ return &Router{chiRouter: r}
}
// Use supports two middlewares
-func (r *Route) Use(middlewares ...any) {
+func (r *Router) Use(middlewares ...any) {
for _, m := range middlewares {
if m != nil {
- r.R.Use(toHandlerProvider(m))
+ r.chiRouter.Use(toHandlerProvider(m))
}
}
}
// Group mounts a sub-Router along a `pattern` string.
-func (r *Route) Group(pattern string, fn func(), middlewares ...any) {
+func (r *Router) Group(pattern string, fn func(), middlewares ...any) {
previousGroupPrefix := r.curGroupPrefix
previousMiddlewares := r.curMiddlewares
r.curGroupPrefix += pattern
@@ -69,7 +71,7 @@ func (r *Route) Group(pattern string, fn func(), middlewares ...any) {
r.curMiddlewares = previousMiddlewares
}
-func (r *Route) getPattern(pattern string) string {
+func (r *Router) getPattern(pattern string) string {
newPattern := r.curGroupPrefix + pattern
if !strings.HasPrefix(newPattern, "/") {
newPattern = "/" + newPattern
@@ -80,7 +82,7 @@ func (r *Route) getPattern(pattern string) string {
return strings.TrimSuffix(newPattern, "/")
}
-func (r *Route) wrapMiddlewareAndHandler(h []any) ([]func(http.Handler) http.Handler, http.HandlerFunc) {
+func (r *Router) wrapMiddlewareAndHandler(h []any) ([]func(http.Handler) http.Handler, http.HandlerFunc) {
handlerProviders := make([]func(http.Handler) http.Handler, 0, len(r.curMiddlewares)+len(h)+1)
for _, m := range r.curMiddlewares {
if m != nil {
@@ -94,7 +96,7 @@ func (r *Route) wrapMiddlewareAndHandler(h []any) ([]func(http.Handler) http.Han
}
middlewares := handlerProviders[:len(handlerProviders)-1]
handlerFunc := handlerProviders[len(handlerProviders)-1](nil).ServeHTTP
- mockPoint := RouteMockPoint(MockAfterMiddlewares)
+ mockPoint := RouterMockPoint(MockAfterMiddlewares)
if mockPoint != nil {
middlewares = append(middlewares, mockPoint)
}
@@ -103,79 +105,134 @@ func (r *Route) wrapMiddlewareAndHandler(h []any) ([]func(http.Handler) http.Han
// Methods adds the same handlers for multiple http "methods" (separated by ",").
// If any method is invalid, the lower level router will panic.
-func (r *Route) Methods(methods, pattern string, h ...any) {
+func (r *Router) Methods(methods, pattern string, h ...any) {
middlewares, handlerFunc := r.wrapMiddlewareAndHandler(h)
fullPattern := r.getPattern(pattern)
if strings.Contains(methods, ",") {
methods := strings.Split(methods, ",")
for _, method := range methods {
- r.R.With(middlewares...).Method(strings.TrimSpace(method), fullPattern, handlerFunc)
+ r.chiRouter.With(middlewares...).Method(strings.TrimSpace(method), fullPattern, handlerFunc)
}
} else {
- r.R.With(middlewares...).Method(methods, fullPattern, handlerFunc)
+ r.chiRouter.With(middlewares...).Method(methods, fullPattern, handlerFunc)
}
}
-// Mount attaches another Route along ./pattern/*
-func (r *Route) Mount(pattern string, subR *Route) {
- subR.Use(r.curMiddlewares...)
- r.R.Mount(r.getPattern(pattern), subR.R)
+// Mount attaches another Router along ./pattern/*
+func (r *Router) Mount(pattern string, subRouter *Router) {
+ subRouter.Use(r.curMiddlewares...)
+ r.chiRouter.Mount(r.getPattern(pattern), subRouter.chiRouter)
}
// Any delegate requests for all methods
-func (r *Route) Any(pattern string, h ...any) {
+func (r *Router) Any(pattern string, h ...any) {
middlewares, handlerFunc := r.wrapMiddlewareAndHandler(h)
- r.R.With(middlewares...).HandleFunc(r.getPattern(pattern), handlerFunc)
+ r.chiRouter.With(middlewares...).HandleFunc(r.getPattern(pattern), handlerFunc)
}
// Delete delegate delete method
-func (r *Route) Delete(pattern string, h ...any) {
+func (r *Router) Delete(pattern string, h ...any) {
r.Methods("DELETE", pattern, h...)
}
// Get delegate get method
-func (r *Route) Get(pattern string, h ...any) {
+func (r *Router) Get(pattern string, h ...any) {
r.Methods("GET", pattern, h...)
}
// Head delegate head method
-func (r *Route) Head(pattern string, h ...any) {
+func (r *Router) Head(pattern string, h ...any) {
r.Methods("HEAD", pattern, h...)
}
// Post delegate post method
-func (r *Route) Post(pattern string, h ...any) {
+func (r *Router) Post(pattern string, h ...any) {
r.Methods("POST", pattern, h...)
}
// Put delegate put method
-func (r *Route) Put(pattern string, h ...any) {
+func (r *Router) Put(pattern string, h ...any) {
r.Methods("PUT", pattern, h...)
}
// Patch delegate patch method
-func (r *Route) Patch(pattern string, h ...any) {
+func (r *Router) Patch(pattern string, h ...any) {
r.Methods("PATCH", pattern, h...)
}
// ServeHTTP implements http.Handler
-func (r *Route) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- r.R.ServeHTTP(w, req)
+func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ r.normalizeRequestPath(w, req, r.chiRouter)
}
// NotFound defines a handler to respond whenever a route could not be found.
-func (r *Route) NotFound(h http.HandlerFunc) {
- r.R.NotFound(h)
+func (r *Router) NotFound(h http.HandlerFunc) {
+ r.chiRouter.NotFound(h)
+}
+
+func (r *Router) normalizeRequestPath(resp http.ResponseWriter, req *http.Request, next http.Handler) {
+ normalized := false
+ normalizedPath := req.URL.EscapedPath()
+ if normalizedPath == "" {
+ normalizedPath, normalized = "/", true
+ } else if normalizedPath != "/" {
+ normalized = strings.HasSuffix(normalizedPath, "/")
+ normalizedPath = strings.TrimRight(normalizedPath, "/")
+ }
+ removeRepeatedSlashes := strings.Contains(normalizedPath, "//")
+ normalized = normalized || removeRepeatedSlashes
+
+ // the following code block is a slow-path for replacing all repeated slashes "//" to one single "/"
+ // if the path doesn't have repeated slashes, then no need to execute it
+ if removeRepeatedSlashes {
+ buf := &strings.Builder{}
+ for i := 0; i < len(normalizedPath); i++ {
+ if i == 0 || normalizedPath[i-1] != '/' || normalizedPath[i] != '/' {
+ buf.WriteByte(normalizedPath[i])
+ }
+ }
+ normalizedPath = buf.String()
+ }
+
+ // If the config tells Gitea to use a sub-url path directly without reverse proxy,
+ // then we need to remove the sub-url path from the request URL path.
+ // But "/v2" is special for OCI container registry, it should always be in the root of the site.
+ if setting.UseSubURLPath {
+ remainingPath, ok := strings.CutPrefix(normalizedPath, setting.AppSubURL+"/")
+ if ok {
+ normalizedPath = "/" + remainingPath
+ } else if normalizedPath == setting.AppSubURL {
+ normalizedPath = "/"
+ } else if !strings.HasPrefix(normalizedPath+"/", "/v2/") {
+ // do not respond to other requests, to simulate a real sub-path environment
+ http.Error(resp, "404 page not found, sub-path is: "+setting.AppSubURL, http.StatusNotFound)
+ return
+ }
+ normalized = true
+ }
+
+ // if the path is normalized, then fill it back to the request
+ if normalized {
+ decodedPath, err := url.PathUnescape(normalizedPath)
+ if err != nil {
+ http.Error(resp, "400 Bad Request: unable to unescape path "+normalizedPath, http.StatusBadRequest)
+ return
+ }
+ req.URL.RawPath = normalizedPath
+ req.URL.Path = decodedPath
+ }
+
+ next.ServeHTTP(resp, req)
}
// Combo delegates requests to Combo
-func (r *Route) Combo(pattern string, h ...any) *Combo {
+func (r *Router) Combo(pattern string, h ...any) *Combo {
return &Combo{r, pattern, h}
}
// Combo represents a tiny group routes with same pattern
type Combo struct {
- r *Route
+ r *Router
pattern string
h []any
}
diff --git a/modules/web/route_test.go b/modules/web/route_test.go
index cc0e26a12e..6e4c309293 100644
--- a/modules/web/route_test.go
+++ b/modules/web/route_test.go
@@ -10,6 +10,9 @@ import (
"strconv"
"testing"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/test"
+
chi "github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
)
@@ -19,7 +22,7 @@ func TestRoute1(t *testing.T) {
recorder := httptest.NewRecorder()
recorder.Body = buff
- r := NewRoute()
+ r := NewRouter()
r.Get("/{username}/{reponame}/{type:issues|pulls}", func(resp http.ResponseWriter, req *http.Request) {
username := chi.URLParam(req, "username")
assert.EqualValues(t, "gitea", username)
@@ -42,7 +45,7 @@ func TestRoute2(t *testing.T) {
hit := -1
- r := NewRoute()
+ r := NewRouter()
r.Group("/{username}/{reponame}", func() {
r.Group("", func() {
r.Get("/{type:issues|pulls}", func(resp http.ResponseWriter, req *http.Request) {
@@ -118,8 +121,8 @@ func TestRoute3(t *testing.T) {
hit := -1
- m := NewRoute()
- r := NewRoute()
+ m := NewRouter()
+ r := NewRouter()
r.Mount("/api/v1", m)
m.Group("/repos", func() {
@@ -176,3 +179,44 @@ func TestRoute3(t *testing.T) {
assert.EqualValues(t, http.StatusOK, recorder.Code)
assert.EqualValues(t, 4, hit)
}
+
+func TestRouteNormalizePath(t *testing.T) {
+ type paths struct {
+ EscapedPath, RawPath, Path string
+ }
+ testPath := func(reqPath string, expectedPaths paths) {
+ recorder := httptest.NewRecorder()
+ recorder.Body = bytes.NewBuffer(nil)
+
+ actualPaths := paths{EscapedPath: "(none)", RawPath: "(none)", Path: "(none)"}
+ r := NewRouter()
+ r.Get("/*", func(resp http.ResponseWriter, req *http.Request) {
+ actualPaths.EscapedPath = req.URL.EscapedPath()
+ actualPaths.RawPath = req.URL.RawPath
+ actualPaths.Path = req.URL.Path
+ })
+
+ req, err := http.NewRequest("GET", reqPath, nil)
+ assert.NoError(t, err)
+ r.ServeHTTP(recorder, req)
+ assert.Equal(t, expectedPaths, actualPaths, "req path = %q", reqPath)
+ }
+
+ // RawPath could be empty if the EscapedPath is the same as escape(Path) and it is already normalized
+ testPath("/", paths{EscapedPath: "/", RawPath: "", Path: "/"})
+ testPath("//", paths{EscapedPath: "/", RawPath: "/", Path: "/"})
+ testPath("/%2f", paths{EscapedPath: "/%2f", RawPath: "/%2f", Path: "//"})
+ testPath("///a//b/", paths{EscapedPath: "/a/b", RawPath: "/a/b", Path: "/a/b"})
+
+ defer test.MockVariableValue(&setting.UseSubURLPath, true)()
+ defer test.MockVariableValue(&setting.AppSubURL, "/sub-path")()
+ testPath("/", paths{EscapedPath: "(none)", RawPath: "(none)", Path: "(none)"}) // 404
+ testPath("/sub-path", paths{EscapedPath: "/", RawPath: "/", Path: "/"})
+ testPath("/sub-path/", paths{EscapedPath: "/", RawPath: "/", Path: "/"})
+ testPath("/sub-path//a/b///", paths{EscapedPath: "/a/b", RawPath: "/a/b", Path: "/a/b"})
+ testPath("/sub-path/%2f/", paths{EscapedPath: "/%2f", RawPath: "/%2f", Path: "//"})
+ // "/v2" is special for OCI container registry, it should always be in the root of the site
+ testPath("/v2", paths{EscapedPath: "/v2", RawPath: "/v2", Path: "/v2"})
+ testPath("/v2/", paths{EscapedPath: "/v2", RawPath: "/v2", Path: "/v2"})
+ testPath("/v2/%2f", paths{EscapedPath: "/v2/%2f", RawPath: "/v2/%2f", Path: "/v2//"})
+}
diff --git a/modules/web/routemock.go b/modules/web/routemock.go
index cb41f63b91..e85b0db738 100644
--- a/modules/web/routemock.go
+++ b/modules/web/routemock.go
@@ -14,14 +14,14 @@ const MockAfterMiddlewares = "MockAfterMiddlewares"
var routeMockPoints = map[string]func(next http.Handler) http.Handler{}
-// RouteMockPoint registers a mock point as a middleware for testing, example:
+// RouterMockPoint registers a mock point as a middleware for testing, example:
//
-// r.Use(web.RouteMockPoint("my-mock-point-1"))
-// r.Get("/foo", middleware2, web.RouteMockPoint("my-mock-point-2"), middleware2, handler)
+// r.Use(web.RouterMockPoint("my-mock-point-1"))
+// r.Get("/foo", middleware2, web.RouterMockPoint("my-mock-point-2"), middleware2, handler)
//
// Then use web.RouteMock to mock the route execution.
// It only takes effect in testing mode (setting.IsInTesting == true).
-func RouteMockPoint(pointName string) func(next http.Handler) http.Handler {
+func RouterMockPoint(pointName string) func(next http.Handler) http.Handler {
if !setting.IsInTesting {
return nil
}
diff --git a/modules/web/routemock_test.go b/modules/web/routemock_test.go
index 04c6d1d82e..89cfaacdd1 100644
--- a/modules/web/routemock_test.go
+++ b/modules/web/routemock_test.go
@@ -16,7 +16,7 @@ import (
func TestRouteMock(t *testing.T) {
setting.IsInTesting = true
- r := NewRoute()
+ r := NewRouter()
middleware1 := func(resp http.ResponseWriter, req *http.Request) {
resp.Header().Set("X-Test-Middleware1", "m1")
}
@@ -26,7 +26,7 @@ func TestRouteMock(t *testing.T) {
handler := func(resp http.ResponseWriter, req *http.Request) {
resp.Header().Set("X-Test-Handler", "h")
}
- r.Get("/foo", middleware1, RouteMockPoint("mock-point"), middleware2, handler)
+ r.Get("/foo", middleware1, RouterMockPoint("mock-point"), middleware2, handler)
// normal request
recorder := httptest.NewRecorder()
diff --git a/options/gitignore/IAR b/options/gitignore/IAR
new file mode 100644
index 0000000000..e8938b31a4
--- /dev/null
+++ b/options/gitignore/IAR
@@ -0,0 +1,47 @@
+# Compiled binaries
+*.o
+*.bin
+*.elf
+*.hex
+*.map
+*.out
+*.obj
+
+# Trash
+*.bak
+thumbs.db
+*.~*
+
+# IAR Settings
+**/settings/*.crun
+**/settings/*.dbgdt
+**/settings/*.cspy
+**/settings/*.cspy.*
+**/settings/*.xcl
+**/settings/*.dni
+**/settings/*.wsdt
+**/settings/*.wspos
+
+# IAR Debug Exe
+**/Exe/*.sim
+
+# IAR Debug Obj
+**/Obj/*.pbd
+**/Obj/*.pbd.*
+**/Obj/*.pbi
+**/Obj/*.pbi.*
+
+# IAR project "Debug" directory
+Debug/
+
+# IAR project "Release" directory
+Release/
+
+# IAR project settings directory
+settings/
+
+# IAR backup files
+Backup*
+
+# IAR .dep files
+*.dep
\ No newline at end of file
diff --git a/options/gitignore/Objective-C b/options/gitignore/Objective-C
index 9b8cd0706f..2ebce16e6e 100644
--- a/options/gitignore/Objective-C
+++ b/options/gitignore/Objective-C
@@ -42,10 +42,3 @@ fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
-
-# Code Injection
-#
-# After new code Injection tools there's a generated folder /iOSInjectionProject
-# https://github.com/johnno1962/injectionforxcode
-
-iOSInjectionProject/
diff --git a/options/gitignore/Terraform b/options/gitignore/Terraform
index 15073ca88b..2faf43d0a1 100644
--- a/options/gitignore/Terraform
+++ b/options/gitignore/Terraform
@@ -35,6 +35,3 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc
-
-# Ignore hcl file
-.terraform.lock.hcl
diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini
index acc0d0bc27..7f65e13171 100644
--- a/options/locale/locale_cs-CZ.ini
+++ b/options/locale/locale_cs-CZ.ini
@@ -93,6 +93,7 @@ remove_all=Odstranit vše
remove_label_str=Odstranit položku „%s“
edit=Upravit
view=Zobrazit
+test=Test
enabled=Povolený
disabled=Zakázané
@@ -164,6 +165,8 @@ search=Hledat...
type_tooltip=Druh vyhledávání
fuzzy=Fuzzy
fuzzy_tooltip=Zahrnout výsledky, které také úzce odpovídají hledanému výrazu
+exact=Přesně
+exact_tooltip=Zahrnout pouze výsledky, které přesně odpovídají hledanému výrazu
repo_kind=Hledat repozitáře...
user_kind=Hledat uživatele...
org_kind=Hledat organizace...
@@ -177,6 +180,8 @@ branch_kind=Hledat větve...
commit_kind=Hledat commity...
runner_kind=Hledat runnery...
no_results=Nebyly nalezeny žádné odpovídající výsledky.
+issue_kind=Hledat úkoly...
+pull_kind=Hledat pull request...
keyword_search_unavailable=Hledání podle klíčového slova není momentálně dostupné. Obraťte se na správce webu.
[aria]
@@ -432,6 +437,7 @@ oauth_signin_submit=Propojit účet
oauth.signin.error=Došlo k chybě při zpracování žádosti o autorizaci. Pokud tato chyba přetrvává, obraťte se na správce webu.
oauth.signin.error.access_denied=Žádost o autorizaci byla zamítnuta.
oauth.signin.error.temporarily_unavailable=Autorizace se nezdařila, protože ověřovací server je dočasně nedostupný. Opakujte akci později.
+oauth_callback_unable_auto_reg=Automatická registrace je povolena, ale OAuth2 poskytovatel %[1]s vrátil chybějící pole: %[2]s, nelze vytvořit účet automaticky, vytvořte účet nebo se připojte k účtu, nebo kontaktujte správce webu.
openid_connect_submit=Připojit
openid_connect_title=Připojení k existujícímu účtu
openid_connect_desc=Zvolené OpenID URI není známé. Přidružte nový účet zde.
@@ -712,8 +718,9 @@ cancel=Zrušit
language=Jazyk
ui=Motiv vzhledu
hidden_comment_types=Skryté typy komentářů
+hidden_comment_types_description=Zde zaškrtnuté typy komentářů nebudou zobrazeny na stránkách úkolů. Zaškrtnutím položky „Štítek“ například odstraní všechny komentáře „{uživatel} přidal/odstranil {štítek}“.
hidden_comment_types.ref_tooltip=Komentáře, na které se odkazovalo z jiného úkolu/commitu/…
-hidden_comment_types.issue_ref_tooltip=Komentáře, kde uživatel změní větev/značku spojenou s problémem
+hidden_comment_types.issue_ref_tooltip=Komentáře, kde uživatel změní větev/značku spojenou s úkolem
comment_type_group_reference=Reference
comment_type_group_label=Štítek
comment_type_group_milestone=Milník
@@ -758,6 +765,8 @@ manage_themes=Vyberte výchozí motiv vzhledu
manage_openid=Správa OpenID adres
email_desc=Vaše hlavní e-mailová adresa bude použita pro oznámení, obnovení hesla, a pokud není skrytá, pro operace Gitu.
theme_desc=Toto bude váš výchozí motiv vzhledu napříč stránkou.
+theme_colorblindness_help=Podpora šablony pro barvoslepost
+theme_colorblindness_prompt=Gitea právě získala některé motivy se základní podporou barvosleposti, které mají pouze několik barev. Práce stále probíhá. Další vylepšení by bylo možné provést definováním více barev v CSS souborů.
primary=Hlavní
activated=Aktivován
requires_activation=Vyžaduje aktivaci
@@ -882,6 +891,7 @@ repo_and_org_access=Repozitář a přístup organizace
permissions_public_only=Pouze veřejnost
permissions_access_all=Vše (veřejné, soukromé a omezené)
select_permissions=Vyberte oprávnění
+permission_not_set=Není nastaveno
permission_no_access=Bez přístupu
permission_read=Přečtené
permission_write=čtení i zápis
@@ -1061,6 +1071,7 @@ watchers=Sledující
stargazers=Sledující
stars_remove_warning=Tímto odstraníte všechny hvězdičky z tohoto repozitáře.
forks=Rozštěpení
+stars=Oblíbené
reactions_more=a %d dalších
unit_disabled=Správce webu zakázal tuto sekci repozitáře.
language_other=Jiný
@@ -1108,7 +1119,7 @@ template.one_item=Musíte vybrat alespoň jednu položku šablony
template.invalid=Musíte vybrat repositář šablony
archive.title=Tento repozitář je archivovaný. Můžete prohlížet soubory, klonovat, ale nemůžete nahrávat a vytvářet nové úkoly nebo pull requesty.
-archive.title_date=Tento repositář byl archivován %s. Můžete zobrazit soubory a klonovat je, ale nemůžete nahrávat ani otevírat problémy nebo pull requesty.
+archive.title_date=Tento repositář byl archivován %s. Můžete zobrazit soubory a klonovat je, ale nemůžete nahrávat ani otevírat úkoly nebo pull requesty.
archive.issue.nocomment=Tento repozitář je archivovaný. Nemůžete komentovat úkoly.
archive.pull.nocomment=Tento repozitář je archivovaný. Nemůžete komentovat pull requesty.
@@ -1228,6 +1239,9 @@ file_view_rendered=Zobrazit vykreslené
file_view_raw=Zobrazit v surovém stavu
file_permalink=Trvalý odkaz
file_too_large=Soubor je příliš velký pro zobrazení.
+file_is_empty=Soubor je prázdný.
+code_preview_line_from_to=Řádky %[1]d do%[2]d v %[3]s
+code_preview_line_in=Řádek %[1]d v %[2]s
invisible_runes_header=`Tento soubor obsahuje neviditelné znaky Unicode`
invisible_runes_description=`Tento soubor obsahuje neviditelné Unicode znaky, které jsou pro člověka nerozeznatelné, ale mohou být zpracovány jiným způsobem. Pokud si myslíte, že je to záměrné, můžete toto varování bezpečně ignorovat. Použijte tlačítko Escape sekvence k jejich zobrazení.`
ambiguous_runes_header=`Tento soubor obsahuje nejednoznačné znaky Unicode`
@@ -1282,6 +1296,7 @@ editor.or=nebo
editor.cancel_lower=Zrušit
editor.commit_signed_changes=Odevzdat podepsané změny
editor.commit_changes=Odevzdat změny
+editor.add_tmpl=Přidán „{nazev_souboru}“
editor.add=Přidat %s
editor.update=Aktualizovat %s
editor.delete=Odstranit %s
@@ -1310,6 +1325,7 @@ editor.file_deleting_no_longer_exists=Odstraňovaný soubor „%s“ již není
editor.file_changed_while_editing=Obsah souboru byl změněn od doby, kdy jste začaly s úpravou. Klikněte zde, abyste je zobrazili, nebo potvrďte změny ještě jednou pro jejich přepsání.
editor.file_already_exists=Soubor „%s“ již existuje v tomto repozitáři.
editor.commit_id_not_matching=ID commitu se neshoduje s ID, když jsi začal/a s úpravami. Odevzdat do záplatové větve a poté sloučit.
+editor.push_out_of_date=Nahrání se zdá být zastaralé.
editor.commit_empty_file_header=Odevzdat prázdný soubor
editor.commit_empty_file_text=Soubor, který se chystáte odevzdat, je prázdný. Pokračovat?
editor.no_changes_to_show=Žádné změny k zobrazení.
@@ -1364,6 +1380,7 @@ commitstatus.success=Úspěch
ext_issues=Přístup k externím úkolům
ext_issues.desc=Odkaz na externí systém úkolů.
+projects.desc=Spravujte úkoly a pull requesty v projektech.
projects.description=Popis (volitelné)
projects.description_placeholder=Popis
projects.create=Vytvořit projekt
@@ -1391,6 +1408,7 @@ projects.column.new=Nový sloupec
projects.column.set_default=Nastavit jako výchozí
projects.column.set_default_desc=Nastavit tento sloupec jako výchozí pro nekategorizované úkoly a požadavky na natažení
projects.column.delete=Smazat sloupec
+projects.column.deletion_desc=Smazání sloupce projektu přesune všechny související úkoly do výchozího sloupce. Pokračovat?
projects.column.color=Barva
projects.open=Otevřít
projects.close=Zavřít
@@ -1426,6 +1444,7 @@ issues.new.clear_assignees=Smazat zpracovatele
issues.new.no_assignees=Bez zpracovatelů
issues.new.no_reviewers=Žádní posuzovatelé
issues.new.blocked_user=Nemůžete vytvořit úkol, protože jste zablokováni zadavatelem příspěvku nebo vlastníkem repozitáře.
+issues.edit.already_changed=Nelze uložit změny v úkolu. Zdá se, že obsah byl již změněn jiným uživatelem. Aktualizujte stránku a zkuste ji znovu problém upravit, abyste se vyhnuli přepsání jejich změn
issues.edit.blocked_user=Nemůžete upravovat obsah, protože jste zablokováni zadavatelem příspěvku nebo vlastníkem repozitáře.
issues.choose.get_started=Začínáme
issues.choose.open_external_link=Otevřít
@@ -1433,7 +1452,7 @@ issues.choose.blank=Výchozí
issues.choose.blank_about=Vytvořit úkol z výchozí šablony.
issues.choose.ignore_invalid_templates=Neplatné šablony byly ignorovány
issues.choose.invalid_templates=%v nalezených neplatných šablon
-issues.choose.invalid_config=Nastavení problému obsahuje chyby:
+issues.choose.invalid_config=Nastavení úkolu obsahuje chyby:
issues.no_ref=Není určena žádná větev/značka
issues.create=Vytvořit úkol
issues.new_label=Nový štítek
@@ -1534,10 +1553,12 @@ issues.context.reference_issue=Odkázat v novém úkolu
issues.context.edit=Upravit
issues.context.delete=Smazat
issues.no_content=K dispozici není žádný popis.
-issues.close=Zavřít problém
+issues.close=Zavřít úkol
issues.comment_pull_merged_at=sloučený commit %[1]s do %[2]s %[3]s
issues.comment_manually_pull_merged_at=ručně sloučený commit %[1]s do %[2]s %[3]s
+issues.close_comment_issue=Okomentovat a zavřít
issues.reopen_issue=Znovuotevřít
+issues.reopen_comment_issue=Znovu otevřít s komentářem
issues.create_comment=Okomentovat
issues.comment.blocked_user=Nemůžete vytvořit nebo upravovat komentář, protože jste zablokováni zadavatelem příspěvku nebo vlastníkem repozitáře.
issues.closed_at=`uzavřel/a tento úkol %[2]s`
@@ -1598,7 +1619,7 @@ issues.attachment.open_tab=`Klikněte pro zobrazení „%s“ v nové záložce`
issues.attachment.download=`Klikněte pro stažení „%s“`
issues.subscribe=Odebírat
issues.unsubscribe=Zrušit odběr
-issues.unpin_issue=Odepnout problém
+issues.unpin_issue=Odepnout úkol
issues.max_pinned=Nemůžete připnout další úkoly
issues.pin_comment=připnuto %s
issues.unpin_comment=odepnul/a tento %s
@@ -1657,7 +1678,7 @@ issues.due_date_form=rrrr-mm-dd
issues.due_date_form_add=Přidat termín dokončení
issues.due_date_form_edit=Upravit
issues.due_date_form_remove=Odstranit
-issues.due_date_not_writer=Potřebujete přístup k zápisu do tohoto repozitáře, abyste mohli aktualizovat datum dokončení problému.
+issues.due_date_not_writer=Potřebujete přístup k zápisu do tohoto repozitáře, abyste mohli aktualizovat datum dokončení úkolu.
issues.due_date_not_set=Žádný termín dokončení.
issues.due_date_added=přidal/a termín dokončení %s %s
issues.due_date_modified=upravil/a termín termínu z %[2]s na %[1]s %[3]s
@@ -1739,6 +1760,7 @@ compare.compare_head=porovnat
pulls.desc=Povolit pull requesty a posuzování kódu.
pulls.new=Nový pull request
pulls.new.blocked_user=Nemůžete vytvořit pull request, protože jste zablokování vlastníkem repozitáře.
+pulls.edit.already_changed=Nelze uložit změny v pull requestu. Zdá se, že obsah byl již změněn jiným uživatelem. Aktualizujte stránku a zkuste znovu komentář upravit, abyste se vyhnuli přepsání jejich změn
pulls.view=Zobrazit pull request
pulls.compare_changes=Nový pull request
pulls.allow_edits_from_maintainers=Povolit úpravy od správců
@@ -1858,6 +1880,7 @@ pulls.close=Zavřít pull request
pulls.closed_at=`uzavřel/a tento pull request %[2]s`
pulls.reopened_at=`znovuotevřel/a tento pull request %[2]s`
pulls.cmd_instruction_hint=`Zobrazit instrukce příkazové řádky.`
+pulls.cmd_instruction_checkout_title=Checkout
pulls.cmd_instruction_checkout_desc=Z vašeho repositáře projektu se podívejte na novou větev a vyzkoušejte změny.
pulls.cmd_instruction_merge_title=Sloučit
pulls.cmd_instruction_merge_desc=Slučte změny a aktualizujte je na Gitea.
@@ -1883,6 +1906,7 @@ pulls.recently_pushed_new_branches=Nahráli jste větev %[1]s %
pull.deleted_branch=(odstraněno):%s
+comments.edit.already_changed=Nelze uložit změny v komentáři. Zdá se, že obsah byl již změněn jiným uživatelem. Aktualizujte stránku a zkuste znovu komentář upravit, abyste se vyhnuli přepsání jejich změn
milestones.new=Nový milník
milestones.closed=Zavřen dne %s
@@ -1959,6 +1983,7 @@ wiki.page_name_desc=Zadejte název této Wiki stránky. Některé speciální n
wiki.original_git_entry_tooltip=Zobrazit originální Git soubor namísto použití přátelského odkazu.
activity=Aktivita
+activity.navbar.pulse=Pulz
activity.navbar.code_frequency=Frekvence kódu
activity.navbar.contributors=Přispěvatelé
activity.navbar.recent_commits=Nedávné commity
@@ -2052,11 +2077,13 @@ settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=Právě t
settings.mirror_settings.docs.disabled_push_mirror.info=Push zrcadla byla zakázána administrátorem vašeho webu.
settings.mirror_settings.docs.no_new_mirrors=Váš repozitář zrcadlí změny do nebo z jiného repozitáře. Mějte prosím na paměti, že v tuto chvíli nemůžete vytvořit žádná nová zrcadla.
settings.mirror_settings.docs.can_still_use=I když nemůžete upravit stávající zrcadla nebo vytvořit nová, stále můžete použít své stávající zrcadlo.
+settings.mirror_settings.docs.pull_mirror_instructions=Chcete-li nastavit zrcadlo pro natažení, konzultujte prosím:
settings.mirror_settings.docs.more_information_if_disabled=Více informací o zrcadlech pro nahrání a natažení naleznete zde:
settings.mirror_settings.docs.doc_link_title=Jak mohu zrcadlit repozitáře?
settings.mirror_settings.docs.doc_link_pull_section=sekci "stahovat ze vzdáleného úložiště" v dokumentaci.
settings.mirror_settings.docs.pulling_remote_title=Stažení ze vzdáleného úložiště
settings.mirror_settings.mirrored_repository=Zrcadlený repozitář
+settings.mirror_settings.pushed_repository=Odeslaný repozitář
settings.mirror_settings.direction=Směr
settings.mirror_settings.direction.pull=Natáhnout
settings.mirror_settings.direction.push=Nahrát
@@ -2079,6 +2106,7 @@ settings.advanced_settings=Pokročilá nastavení
settings.wiki_desc=Povolit Wiki repozitáře
settings.use_internal_wiki=Používat vestavěnou Wiki
settings.default_wiki_branch_name=Výchozí název větve Wiki
+settings.default_wiki_everyone_access=Výchozí přístupová práva pro přihlášené uživatele:
settings.failed_to_change_default_wiki_branch=Změna výchozí větve wiki se nezdařila.
settings.use_external_wiki=Používat externí Wiki
settings.external_wiki_url=URL externí Wiki
@@ -2760,6 +2788,7 @@ teams.invite.by=Pozvání od %s
teams.invite.description=Pro připojení k týmu klikněte na tlačítko níže.
[admin]
+maintenance=Údržba
dashboard=Přehled
self_check=Samokontrola
identity_access=Identita a přístup
@@ -2782,6 +2811,7 @@ settings=Nastavení správce
dashboard.new_version_hint=Gitea %s je nyní k dispozici, právě u vás běži %s. Podívej se na blogu pro více informací.
dashboard.statistic=Souhrn
+dashboard.maintenance_operations=Operace údržby
dashboard.system_status=Status systému
dashboard.operation_name=Název operace
dashboard.operation_switch=Přepnout
@@ -3067,12 +3097,14 @@ auths.tips=Tipy
auths.tips.oauth2.general=Ověřování OAuth2
auths.tips.oauth2.general.tip=Při registraci nové OAuth2 autentizace by URL callbacku/přesměrování měla být:
auths.tip.oauth2_provider=Poskytovatel OAuth2
+auths.tip.bitbucket=Vytvořte nového OAuth konzumenta na https://bitbucket.org/account/user/{vase-uzivatelske-jmeno}/oauth-consumers/new a přidejte oprávnění „Account“ - „Read“
auths.tip.nextcloud=Zaregistrujte nového OAuth konzumenta na vaší instanci pomocí následujícího menu „Nastavení -> Zabezpečení -> OAuth 2.0 klient“
auths.tip.dropbox=Vytvořte novou aplikaci na https://www.dropbox.com/developers/apps
auths.tip.facebook=Registrujte novou aplikaci na https://developers.facebook.com/apps a přidejte produkt „Facebook Login“
auths.tip.github=Registrujte novou OAuth aplikaci na https://github.com/settings/applications/new
auths.tip.gitlab_new=Zaregistrujte novou aplikaci na https://gitlab.com/-/profile/applications
auths.tip.google_plus=Získejte klientské pověření OAuth2 z Google API konzole na https://console.developers.google.com/
+auths.tip.openid_connect=Použijte OpenID Connect URL pro objevování spojení „https://{server}/.well-known/openid-configuration“ k nastavení koncových bodů
auths.tip.twitter=Jděte na https://dev.twitter.com/apps, vytvořte aplikaci a ujistěte se, že volba „Allow this application to be used to Sign in with Twitter“ je povolená
auths.tip.discord=Registrujte novou aplikaci na https://discordapp.com/developers/applications/me
auths.tip.gitea=Registrovat novou Oauth2 aplikaci. Návod naleznete na https://docs.gitea.com/development/oauth2-provider
@@ -3192,6 +3224,10 @@ config.cache_adapter=Adaptér mezipaměti
config.cache_interval=Interval mezipaměti
config.cache_conn=Připojení mezipaměti
config.cache_item_ttl=Čas vypršení položky v mezipaměti
+config.cache_test=Otestovat cache
+config.cache_test_failed=Test cache se nezdařil: %v.
+config.cache_test_slow=Test cache byl úspěšný, ale reakce je pomalá: %s.
+config.cache_test_succeeded=Test mezipaměti byl úspěšný, odpověď za %s.
config.session_config=Nastavení relace
config.session_provider=Poskytovatel relace
@@ -3256,6 +3292,7 @@ monitor.queue.name=Název
monitor.queue.type=Typ
monitor.queue.exemplar=Typ vzoru
monitor.queue.numberworkers=Počet workerů
+monitor.queue.activeworkers=Aktivní workery
monitor.queue.maxnumberworkers=Maximální počet workerů
monitor.queue.numberinqueue=Číslo ve frontě
monitor.queue.review_add=Posoudit / přidat workery
@@ -3285,11 +3322,13 @@ notices.op=Akce
notices.delete_success=Systémové upozornění bylo smazáno.
self_check.no_problem_found=Zatím nebyl nalezen žádný problém.
+self_check.startup_warnings=Upozornění při spuštění:
self_check.database_collation_mismatch=Očekávejte, že databáze použije collation: %s
self_check.database_collation_case_insensitive=Databáze používá collation %s, což je collation nerozlišující velká a malá písmena. Ačkoli s ní Gitea může pracovat, mohou se vyskytnout vzácné případy, kdy nebude fungovat podle očekávání.
self_check.database_inconsistent_collation_columns=Databáze používá collation %s, ale tyto sloupce používají chybné collation. To může způsobit neočekávané problémy.
self_check.database_fix_mysql=Pro uživatele MySQL/MariaDB můžete použít příkaz "gitea doctor convert", který opraví problémy s collation, nebo můžete také problém vyřešit příkazem "ALTER ... COLLATE ..." SQL ručně.
self_check.database_fix_mssql=Uživatelé MSSQL mohou problém vyřešit pouze pomocí příkazu "ALTER ... COLLATE ..." SQL ručně.
+self_check.location_origin_mismatch=Aktuální URL (%[1]s) se neshoduje s URL viditelnou pro Gitea (%[2]s). Pokud používáte reverzní proxy, ujistěte se, že hlavičky „Host“ a „X-Forwarded-Proto“ jsou nastaveny správně.
[action]
create_repo=vytvořil/a repozitář %s
@@ -3301,7 +3340,7 @@ reopen_issue=`znovuotevřel/a úkol %[3]s#%[2]s`
create_pull_request=`vytvořil/a pull request %[3]s#%[2]s`
close_pull_request=`uzavřel/a pull request %[3]s#%[2]s`
reopen_pull_request=`znovuotevřel/a pull request %[3]s#%[2]s`
-comment_issue=`okomentoval/a problém %[3]s#%[2]s`
+comment_issue=`okomentoval/a úkol %[3]s#%[2]s`
comment_pull=`okomentoval/a pull request %[3]s#%[2]s`
merge_pull_request=`sloučil/a pull request %[3]s#%[2]s`
auto_merge_pull_request=`automaticky sloučen pull request %[3]s#%[2]s`
@@ -3317,6 +3356,7 @@ mirror_sync_create=synchronizoval/a novou referenci %[3]s do
mirror_sync_delete=synchronizoval/a a smazal/a referenci %[2]s
v %[3]s ze zrcadla
approve_pull_request=`schválil/a %[3]s#%[2]s`
reject_pull_request=`navrhl/a změny pro %[3]s#%[2]s`
+publish_release=`vydal/a "%[4]s" v %[3]s`
review_dismissed=`zamítl/a posouzení z %[4]s pro %[3]s#%[2]s`
review_dismissed_reason=Důvod:
create_branch=vytvořil/a větev %[3]s v %[4]s
@@ -3383,6 +3423,7 @@ error.unit_not_allowed=Nejste oprávněni přistupovat k této části repozitá
title=Balíčky
desc=Správa balíčků repozitáře.
empty=Zatím nejsou žádné balíčky.
+no_metadata=Žádná metadata.
empty.documentation=Další informace o registru balíčků naleznete v dokumentaci.
empty.repo=Nahráli jste balíček, ale nezobrazil se zde? Přejděte na nastavení balíčku a propojte jej s tímto repozitářem.
registry.documentation=Další informace o registru %s naleznete v dokumentaci.
@@ -3464,6 +3505,7 @@ npm.install=Pro instalaci balíčku pomocí npm spusťte následující příkaz
npm.install2=nebo ho přidejte do souboru package.json:
npm.dependencies=Závislosti
npm.dependencies.development=Vývojové závislosti
+npm.dependencies.bundle=Vnitřní závislosti
npm.dependencies.peer=Vzájemné závislosti
npm.dependencies.optional=Volitelné závislosti
npm.details.tag=Značka
@@ -3560,6 +3602,8 @@ status.cancelled=Zrušeno
status.skipped=Přeskočeno
status.blocked=Blokováno
+runners=Runnery
+runners.runner_manage_panel=Správa runnerů
runners.new=Vytvořit nový runner
runners.new_notice=Jak spustit runner
runners.status=Status
@@ -3586,6 +3630,7 @@ runners.delete_runner_success=Runner byl úspěšně odstraněn
runners.delete_runner_failed=Odstranění runneru selhalo
runners.delete_runner_header=Potvrdit odstranění tohoto runneru
runners.delete_runner_notice=Pokud na tomto runneru běží úloha, bude ukončena a označena jako neúspěšná. Může dojít k přerušení vytváření pracovního postupu.
+runners.none=Žádné runnery nejsou k dispozici
runners.status.unspecified=Neznámý
runners.status.idle=Nečinný
runners.status.active=Aktivní
@@ -3601,6 +3646,7 @@ runs.pushed_by=náhrán
runs.invalid_workflow_helper=Konfigurační soubor pracovního postupu je neplatný. Zkontrolujte prosím konfigurační soubor: %s
runs.no_matching_online_runner_helper=Žádný odpovídající online runner s popiskem: %s
runs.no_job_without_needs=Pracovní postup musí obsahovat alespoň jednu úlohu bez závislostí.
+runs.no_job=Pracovní postup musí obsahovat alespoň jednu úlohu
runs.actor=Aktér
runs.status=Status
runs.actors_no_select=Všichni aktéři
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index fbada5472c..d10f61f2ff 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -93,6 +93,7 @@ remove_all = Remove All
remove_label_str = Remove item "%s"
edit = Edit
view = View
+test = Test
enabled = Enabled
disabled = Disabled
@@ -457,6 +458,7 @@ sspi_auth_failed = SSPI authentication failed
password_pwned = The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password and consider changing this password elsewhere too.
password_pwned_err = Could not complete request to HaveIBeenPwned
last_admin = You cannot remove the last admin. There must be at least one admin.
+signin_passkey = Sign in with a passkey
[mail]
view_it_on = View it on %s
@@ -3225,6 +3227,10 @@ config.cache_adapter = Cache Adapter
config.cache_interval = Cache Interval
config.cache_conn = Cache Connection
config.cache_item_ttl = Cache Item TTL
+config.cache_test = Test Cache
+config.cache_test_failed = Failed to probe the cache: %v.
+config.cache_test_slow = Cache test successful, but response is slow: %s.
+config.cache_test_succeeded = Cache test successful, got a response in %s.
config.session_config = Session Configuration
config.session_provider = Session Provider
diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini
index 6dcc7a4f3f..ae32b861f6 100644
--- a/options/locale/locale_fr-FR.ini
+++ b/options/locale/locale_fr-FR.ini
@@ -93,6 +93,7 @@ remove_all=Tout Retirer
remove_label_str=Supprimer l’élément « %s »
edit=Éditer
view=Voir
+test=Test
enabled=Activé
disabled=Désactivé
@@ -1238,6 +1239,7 @@ file_view_rendered=Voir le rendu
file_view_raw=Voir le Raw
file_permalink=Lien permanent
file_too_large=Le fichier est trop gros pour être affiché.
+file_is_empty=Le fichier est vide.
code_preview_line_from_to=Lignes %[1]d à %[2]d dans %[3]s
code_preview_line_in=Ligne %[1]d dans %[2]s
invisible_runes_header=`Ce fichier contient des caractères Unicode invisibles.`
@@ -1305,7 +1307,7 @@ editor.new_patch=Nouveau correctif
editor.commit_message_desc=Ajouter une description détaillée facultative…
editor.signoff_desc=Créditer l'auteur "Signed-off-by:" en pied de révision.
editor.commit_directly_to_this_branch=Réviser directement dans la branche %s.
-editor.create_new_branch=Créer une nouvelle branche pour cette révision et initier une demande d'ajout.
+editor.create_new_branch=Créer une nouvelle branche pour cette révision et initier une demande d’ajout.
editor.create_new_branch_np=Créer une nouvelle branche pour cette révision.
editor.propose_file_change=Proposer une modification du fichier
editor.new_branch_name=Nommer la nouvelle branche pour cette révision
@@ -1887,15 +1889,15 @@ pulls.clear_merge_message_hint=Effacer le message de fusion ne supprimera que le
pulls.auto_merge_button_when_succeed=(Lorsque les vérifications ont réussi)
pulls.auto_merge_when_succeed=Fusionner automatiquement si toutes les vérifications passent.
-pulls.auto_merge_newly_scheduled=La demande d'ajout était programmée pour fusionner lorsque toutes les vérifications aurait réussi.
+pulls.auto_merge_newly_scheduled=La demande d’ajout avait été programmée pour être fusionnée si toutes les vérifications avaient réussi.
pulls.auto_merge_has_pending_schedule=%[1]s Ont planifié cette demande d'ajout pour fusionner automatiquement lorsque toutes les vérifications réussissent %[2]s.
pulls.auto_merge_cancel_schedule=Annuler la fusion automatique
-pulls.auto_merge_not_scheduled=Cette demande d'ajout n'est pas planifiée pour fusionner automatiquement.
-pulls.auto_merge_canceled_schedule=La fusion automatique a été annulée pour cette demande d'ajout.
+pulls.auto_merge_not_scheduled=Cette demande d’ajout n'est pas planifiée pour fusionner automatiquement.
+pulls.auto_merge_canceled_schedule=La fusion automatique a été annulée pour cette demande d’ajout.
pulls.auto_merge_newly_scheduled_comment=`a programmé la fusion automatique de cette demande d’ajout, si toutes les vérifications passent, %[1]s.`
-pulls.auto_merge_canceled_schedule_comment=`a annulé la fusion automatique de cette demande d'ajout %[1]s.`
+pulls.auto_merge_canceled_schedule_comment=`a annulé la fusion automatique de cette demande d’ajout %[1]s.`
pulls.delete.title=Supprimer cette demande d'ajout ?
pulls.delete.text=Voulez-vous vraiment supprimer cet demande d'ajout ? (Cela supprimera définitivement tout le contenu. Envisagez de le fermer à la place, si vous avez l'intention de le garder archivé)
@@ -2560,7 +2562,7 @@ release.stable=Stable
release.compare=Comparer
release.edit=Éditer
release.ahead.commits=%d révisions
-release.ahead.target=à %s depuis cette publication
+release.ahead.target=sur %s depuis cette publication
tag.ahead.target=à %s depuis cette étiquette
release.source_code=Code source
release.new_subheader=Les publications vous aide à organiser les versions marquantes de votre projet.
@@ -3223,6 +3225,10 @@ config.cache_adapter=Adaptateur du Cache
config.cache_interval=Intervales du Cache
config.cache_conn=Liaison du Cache
config.cache_item_ttl=Durée de vie des éléments dans le cache
+config.cache_test=Test du cache
+config.cache_test_failed=Impossible d’interroger le cache : %v.
+config.cache_test_slow=Test du cache réussi, mais la réponse est lente : %s.
+config.cache_test_succeeded=Test du cache réussi, réponse obtenue en %s.
config.session_config=Configuration de session
config.session_provider=Fournisseur de session
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index d85ffb4694..acce73b0af 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -1238,6 +1238,7 @@ file_view_rendered=レンダリング表示
file_view_raw=Rawデータを見る
file_permalink=パーマリンク
file_too_large=このファイルは大きすぎるため、表示できません。
+file_is_empty=ファイルは空です。
code_preview_line_from_to=%[1]d 行目から %[2]d 行目 in %[3]s
code_preview_line_in=%[1]d 行目 in %[2]s
invisible_runes_header=このファイルには不可視のUnicode文字が含まれています
@@ -1442,6 +1443,7 @@ issues.new.clear_assignees=担当者をクリア
issues.new.no_assignees=担当者なし
issues.new.no_reviewers=レビューアなし
issues.new.blocked_user=リポジトリのオーナーがあなたをブロックしているため、イシューを作成できません。
+issues.edit.already_changed=イシューの変更を保存できません。 他のユーザーによって内容がすでに変更されているようです。 変更を上書きしないようにするため、ページを更新してからもう一度編集してください
issues.edit.blocked_user=投稿者またはリポジトリのオーナーがあなたをブロックしているため、内容を編集できません。
issues.choose.get_started=始める
issues.choose.open_external_link=オープン
@@ -1757,6 +1759,7 @@ compare.compare_head=比較
pulls.desc=プルリクエストとコードレビューの有効化。
pulls.new=新しいプルリクエスト
pulls.new.blocked_user=リポジトリのオーナーがあなたをブロックしているため、プルリクエストを作成できません。
+pulls.edit.already_changed=プルリクエストの変更を保存できません。 他のユーザーによって内容がすでに変更されているようです。 変更を上書きしないようにするため、ページを更新してからもう一度編集してください
pulls.view=プルリクエストを表示
pulls.compare_changes=新規プルリクエスト
pulls.allow_edits_from_maintainers=メンテナーからの編集を許可する
@@ -1902,6 +1905,7 @@ pulls.recently_pushed_new_branches=%[2]s 、あなたはブランチ %[1
pull.deleted_branch=(削除済み):%s
+comments.edit.already_changed=コメントの変更を保存できません。 他のユーザーによって内容がすでに変更されているようです。 変更を上書きしないようにするため、ページを更新してからもう一度編集してください
milestones.new=新しいマイルストーン
milestones.closed=%s にクローズ
diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini
index f444cf6072..b6ce9adcb3 100644
--- a/options/locale/locale_pt-PT.ini
+++ b/options/locale/locale_pt-PT.ini
@@ -93,6 +93,7 @@ remove_all=Remover tudo
remove_label_str=`Remover item "%s"`
edit=Editar
view=Ver
+test=Teste
enabled=Habilitado
disabled=Desabilitado
@@ -457,6 +458,7 @@ sspi_auth_failed=Falhou a autenticação SSPI
password_pwned=A senha utilizada está numa lista de senhas roubadas anteriormente expostas em fugas de dados públicas. Tente novamente com uma senha diferente e considere também mudar esta senha nos outros sítios.
password_pwned_err=Não foi possível completar o pedido ao HaveIBeenPwned
last_admin=Não pode remover o último administrador. Tem que existir pelo menos um administrador.
+signin_passkey=Iniciar sessão com uma passkey
[mail]
view_it_on=Ver em %s
@@ -1238,6 +1240,7 @@ file_view_rendered=Ver resultado processado
file_view_raw=Ver em bruto
file_permalink=Ligação permanente
file_too_large=O ficheiro é demasiado grande para ser apresentado.
+file_is_empty=O ficheiro está vazio.
code_preview_line_from_to=Linhas %[1]d até %[2]d em %[3]s
code_preview_line_in=Linha %[1]d em %[2]s
invisible_runes_header=`Este ficheiro contém caracteres Unicode invisíveis`
@@ -1554,7 +1557,9 @@ issues.no_content=Nenhuma descrição fornecida.
issues.close=Encerrar questão
issues.comment_pull_merged_at=cometimento %[1]s integrado em %[2]s %[3]s
issues.comment_manually_pull_merged_at=cometimento %[1]s integrado manualmente em %[2]s %[3]s
+issues.close_comment_issue=Fechar com comentário
issues.reopen_issue=Reabrir
+issues.reopen_comment_issue=Reabrir com comentário
issues.create_comment=Comentar
issues.comment.blocked_user=Não pode criar ou editar o comentário porque foi bloqueado/a pelo remetente ou pelo/a proprietário/a do repositório.
issues.closed_at=`encerrou esta questão %[2]s`
@@ -3221,6 +3226,10 @@ config.cache_adapter=Adaptador de cache
config.cache_interval=Intervalo de cache
config.cache_conn=Conexão de cache
config.cache_item_ttl=TTL do item de cache
+config.cache_test=Teste da cache
+config.cache_test_failed=Fahou ao sondar a cache: %v.
+config.cache_test_slow=O teste da cache foi bem sucedido, mas a resposta é lenta: %s.
+config.cache_test_succeeded=O teste da cache foi bem sucedido, obtive resposta em %s.
config.session_config=Configuração de sessão
config.session_provider=Fornecedor da sessão
diff --git a/package-lock.json b/package-lock.json
index 56c6f8643e..502489e726 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,19 +5,19 @@
"packages": {
"": {
"dependencies": {
- "@citation-js/core": "0.7.11",
- "@citation-js/plugin-bibtex": "0.7.12",
- "@citation-js/plugin-csl": "0.7.11",
+ "@citation-js/core": "0.7.14",
+ "@citation-js/plugin-bibtex": "0.7.14",
+ "@citation-js/plugin-csl": "0.7.14",
"@citation-js/plugin-software-formats": "0.6.1",
"@github/markdown-toolbar-element": "2.2.3",
"@github/relative-time-element": "4.4.2",
- "@github/text-expander-element": "2.6.1",
+ "@github/text-expander-element": "2.7.1",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
"@primer/octicons": "19.9.0",
"@silverwind/vue3-calendar-heatmap": "2.0.6",
"add-asset-webpack-plugin": "3.0.0",
"ansi_up": "6.0.2",
- "asciinema-player": "3.7.1",
+ "asciinema-player": "3.8.0",
"chart.js": "4.4.3",
"chartjs-adapter-dayjs-4": "1.0.4",
"chartjs-plugin-zoom": "2.0.1",
@@ -26,10 +26,10 @@
"dayjs": "1.11.11",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
- "esbuild-loader": "4.1.0",
+ "esbuild-loader": "4.2.0",
"escape-goat": "4.0.0",
"fast-glob": "3.3.2",
- "htmx.org": "1.9.12",
+ "htmx.org": "2.0.0",
"idiomorph": "0.3.0",
"jquery": "3.7.1",
"katex": "0.16.10",
@@ -44,21 +44,22 @@
"postcss-loader": "8.1.1",
"postcss-nesting": "12.1.5",
"sortablejs": "1.15.2",
- "swagger-ui-dist": "5.17.13",
- "tailwindcss": "3.4.3",
- "temporal-polyfill": "0.2.4",
+ "swagger-ui-dist": "5.17.14",
+ "tailwindcss": "3.4.4",
+ "temporal-polyfill": "0.2.5",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",
"toastify-js": "1.12.0",
"tributejs": "5.1.3",
+ "typescript": "5.5.2",
"uint8-to-base64": "0.2.0",
"vanilla-colorful": "0.7.2",
- "vue": "3.4.27",
+ "vue": "3.4.29",
"vue-bar-graph": "2.0.0",
"vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
- "webpack": "5.91.0",
+ "webpack": "5.92.0",
"webpack-cli": "5.1.4",
"wrap-ansi": "9.0.0"
},
@@ -66,34 +67,38 @@
"@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
"@playwright/test": "1.44.1",
"@stoplight/spectral-cli": "6.11.1",
- "@stylistic/eslint-plugin-js": "2.1.0",
+ "@stylistic/eslint-plugin-js": "2.2.1",
"@stylistic/stylelint-plugin": "2.1.2",
- "@vitejs/plugin-vue": "5.0.4",
+ "@typescript-eslint/eslint-plugin": "7.14.1",
+ "@typescript-eslint/parser": "7.14.1",
+ "@vitejs/plugin-vue": "5.0.5",
"eslint": "8.57.0",
+ "eslint-import-resolver-typescript": "3.6.1",
"eslint-plugin-array-func": "4.0.0",
- "eslint-plugin-github": "5.0.0-2",
+ "eslint-plugin-deprecation": "3.0.0",
+ "eslint-plugin-github": "5.0.1",
"eslint-plugin-i": "2.29.1",
- "eslint-plugin-jquery": "1.5.1",
- "eslint-plugin-no-jquery": "2.7.0",
+ "eslint-plugin-no-jquery": "3.0.1",
"eslint-plugin-no-use-extend-native": "0.5.0",
+ "eslint-plugin-playwright": "1.6.2",
"eslint-plugin-regexp": "2.6.0",
"eslint-plugin-sonarjs": "1.0.3",
- "eslint-plugin-unicorn": "53.0.0",
+ "eslint-plugin-unicorn": "54.0.0",
"eslint-plugin-vitest": "0.4.1",
"eslint-plugin-vitest-globals": "1.5.0",
"eslint-plugin-vue": "9.26.0",
"eslint-plugin-vue-scoped-css": "2.8.0",
"eslint-plugin-wc": "2.1.0",
- "happy-dom": "14.11.1",
+ "happy-dom": "14.12.0",
"markdownlint-cli": "0.41.0",
"postcss-html": "1.7.0",
- "stylelint": "16.6.0",
+ "stylelint": "16.6.1",
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
"stylelint-declaration-strict-value": "1.10.4",
"stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "3.3.2",
- "updates": "16.1.1",
- "vite-string-plugin": "1.3.1",
+ "updates": "16.2.0",
+ "vite-string-plugin": "1.3.4",
"vitest": "1.6.0"
},
"engines": {
@@ -121,11 +126,11 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz",
- "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
+ "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
"dependencies": {
- "@babel/highlight": "^7.24.6",
+ "@babel/highlight": "^7.24.7",
"picocolors": "^1.0.0"
},
"engines": {
@@ -133,19 +138,19 @@
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz",
- "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
+ "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz",
- "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
+ "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.24.6",
+ "@babel/helper-validator-identifier": "^7.24.7",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
@@ -224,9 +229,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz",
- "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
+ "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==",
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -235,9 +240,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.6.tgz",
- "integrity": "sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz",
+ "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -251,9 +256,9 @@
"integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A=="
},
"node_modules/@citation-js/core": {
- "version": "0.7.11",
- "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.11.tgz",
- "integrity": "sha512-evQtyzeW+Gbmq+xWciIq9sbcvXXDbm8q32orD/HDd5ay6RQFKoW/BKxBLp+Nmpxgspb9sxTJn3iFK7+jxOTNTw==",
+ "version": "0.7.14",
+ "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.14.tgz",
+ "integrity": "sha512-dgeGqYDSQmn2MtnWZkwPGpJQPh43yr1lAAr9jl1NJ9pIY1RXUQxtlAUZVur0V9PHdbfQC+kkvB1KC3VpgVV3MA==",
"dependencies": {
"@citation-js/date": "^0.5.0",
"@citation-js/name": "^0.4.2",
@@ -281,9 +286,9 @@
}
},
"node_modules/@citation-js/plugin-bibtex": {
- "version": "0.7.12",
- "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.12.tgz",
- "integrity": "sha512-cvby0llm1a1kjvvN9ivKO3dCFoyljKx2Rn9mMsUm43JTJZ4rP0emAZ8qzRL4cL3IIUaCRgkN36O+uz9yPktC5Q==",
+ "version": "0.7.14",
+ "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.14.tgz",
+ "integrity": "sha512-xHOHqhF6dthLRv46N9U+mQgYLiiWQHLvQWK9+mcBKz+/3NWge62Xb1oBouNWwLEPd5FV/8gp9fp7SOp93T0dUg==",
"dependencies": {
"@citation-js/date": "^0.5.0",
"@citation-js/name": "^0.4.2",
@@ -309,9 +314,9 @@
}
},
"node_modules/@citation-js/plugin-csl": {
- "version": "0.7.11",
- "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.11.tgz",
- "integrity": "sha512-4OGZ9wHZDfpgiPU2cOXWGuKt7P+ndGWAeLG95nOG+DXe5U+f9EEZTXfaM4C99x8Ri+g6JklR96A3kuYZxYLllg==",
+ "version": "0.7.14",
+ "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.14.tgz",
+ "integrity": "sha512-7AKB8lMz1IqdtoE33NnWIpteLYMuSl3xqT+Cax7sQKwAIJEoq2HBmb43Ja8xQQ36nREAupQJv1V6XksIAmYnCg==",
"dependencies": {
"@citation-js/date": "^0.5.0",
"citeproc": "^2.4.6"
@@ -510,9 +515,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
- "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
"cpu": [
"ppc64"
],
@@ -525,9 +530,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
- "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
"cpu": [
"arm"
],
@@ -540,9 +545,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
- "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
"cpu": [
"arm64"
],
@@ -555,9 +560,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
- "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
"cpu": [
"x64"
],
@@ -570,9 +575,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
- "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
"cpu": [
"arm64"
],
@@ -585,9 +590,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
- "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
"cpu": [
"x64"
],
@@ -600,9 +605,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
- "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
"cpu": [
"arm64"
],
@@ -615,9 +620,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
- "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
"cpu": [
"x64"
],
@@ -630,9 +635,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
- "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
"cpu": [
"arm"
],
@@ -645,9 +650,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
- "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
"cpu": [
"arm64"
],
@@ -660,9 +665,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
- "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
"cpu": [
"ia32"
],
@@ -675,9 +680,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
- "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
"cpu": [
"loong64"
],
@@ -690,9 +695,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
- "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
"cpu": [
"mips64el"
],
@@ -705,9 +710,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
- "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
"cpu": [
"ppc64"
],
@@ -720,9 +725,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
- "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
"cpu": [
"riscv64"
],
@@ -735,9 +740,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
- "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
"cpu": [
"s390x"
],
@@ -750,9 +755,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
- "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
"cpu": [
"x64"
],
@@ -765,9 +770,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
- "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
"cpu": [
"x64"
],
@@ -780,9 +785,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
- "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
"cpu": [
"x64"
],
@@ -795,9 +800,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
- "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
"cpu": [
"x64"
],
@@ -810,9 +815,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
- "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
"cpu": [
"arm64"
],
@@ -825,9 +830,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
- "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
"cpu": [
"ia32"
],
@@ -840,9 +845,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
- "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
"cpu": [
"x64"
],
@@ -898,9 +903,9 @@
}
},
"node_modules/@eslint-community/regexpp": {
- "version": "4.10.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
- "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz",
+ "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==",
"dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
@@ -1033,17 +1038,19 @@
"integrity": "sha512-wTXunu3hmuGljA5CHaaoUIKV0oI35wno0FKJl2yqKplTRnsCA5bPNj4bDeVIubkuskql6jwionWLlGM1Y6QLaw=="
},
"node_modules/@github/text-expander-element": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.6.1.tgz",
- "integrity": "sha512-i6krPGXJRABfKXut0WArFd365Je4PT0MljtDoXUoCOEp+lGrmdosDMxmO0EfOYc97jBn+Hd2XO1mMsuI5+fwmQ==",
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.7.1.tgz",
+ "integrity": "sha512-CWxfYxJRkeWVCUhJveproLs6pHsPrWtK8TsjL8ByYVcSCs8CJmNzF8b7ZawrUgfai0F2jb4aIdw2FoBTykj9XA==",
"dependencies": {
- "@github/combobox-nav": "^2.0.2"
+ "@github/combobox-nav": "^2.0.2",
+ "dom-input-range": "^1.1.6"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
+ "deprecated": "Use @eslint/config-array instead",
"dev": true,
"dependencies": {
"@humanwhocodes/object-schema": "^2.0.2",
@@ -1093,6 +1100,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
"dev": true
},
"node_modules/@isaacs/cliui": {
@@ -1933,9 +1941,9 @@
}
},
"node_modules/@stoplight/spectral-functions": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.2.tgz",
- "integrity": "sha512-f+61/FtIkQeIo+a269CeaeqjpyRsgDyIk6DGr7iS4hyuk1PPk7Uf6MNRDs9FEIBh7CpdEJ+HSHbMLwgpymWTIw==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.8.0.tgz",
+ "integrity": "sha512-ZrAkYA/ZGbuQ6EyG1gisF4yQ5nWP/+glcqVoGmS6kH6ekaynz2Yp6FL0oIamWj3rWedFUN7ppwTRUdo+9f/uCw==",
"dev": true,
"dependencies": {
"@stoplight/better-ajv-errors": "1.0.3",
@@ -2072,9 +2080,9 @@
"dev": true
},
"node_modules/@stoplight/spectral-rulesets": {
- "version": "1.18.1",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.18.1.tgz",
- "integrity": "sha512-buLzYi4rHjZOG2d5LC/s3YpySrCGrwR4irKDyrxLlbbqmB8BDOsrdO+7G9UGvRCJwAy/xs1VWcjokzGnG68K+Q==",
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.19.1.tgz",
+ "integrity": "sha512-rfGK87Y1JJCEeLC8MVdLkjUkRH+Y6VnSF388D+UWihfU9xuq2eNB9phWpTFkG+AG4HLRyGx963BmO6PyM9dBag==",
"dev": true,
"dependencies": {
"@asyncapi/specs": "^4.1.0",
@@ -2086,9 +2094,10 @@
"@stoplight/spectral-runtime": "^1.1.1",
"@stoplight/types": "^13.6.0",
"@types/json-schema": "^7.0.7",
- "ajv": "^8.8.2",
+ "ajv": "^8.12.0",
"ajv-formats": "~2.1.0",
"json-schema-traverse": "^1.0.0",
+ "leven": "3.1.0",
"lodash": "~4.17.21",
"tslib": "^2.3.0"
},
@@ -2175,9 +2184,9 @@
}
},
"node_modules/@stylistic/eslint-plugin-js": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.1.0.tgz",
- "integrity": "sha512-gdXUjGNSsnY6nPyqxu6lmDTtVrwCOjun4x8PUn0x04d5ucLI74N3MT1Q0UhdcOR9No3bo5PGDyBgXK+KmD787A==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.2.1.tgz",
+ "integrity": "sha512-M2dQkKw2R4R+b1SJ/xElJ9bDVq/vCI31VpIIxkZD9KXCqbUHvtsGpZH3eO6MzmFWOZj4PfNdEQdP332MtqjCPg==",
"dev": true,
"dependencies": {
"@types/eslint": "^8.56.10",
@@ -2324,9 +2333,9 @@
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
},
"node_modules/@types/node": {
- "version": "20.12.12",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
- "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
+ "version": "20.14.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.3.tgz",
+ "integrity": "sha512-Nuzqa6WAxeGnve6SXqiPAM9rA++VQs+iLZ1DDd56y0gdvygSZlQvZuvdFPR3yLqkVxPu4WrO02iDEyH1g+wazw==",
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -2363,16 +2372,17 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.10.0.tgz",
- "integrity": "sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz",
+ "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "7.10.0",
- "@typescript-eslint/type-utils": "7.10.0",
- "@typescript-eslint/utils": "7.10.0",
- "@typescript-eslint/visitor-keys": "7.10.0",
+ "@typescript-eslint/scope-manager": "7.14.1",
+ "@typescript-eslint/type-utils": "7.14.1",
+ "@typescript-eslint/utils": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
@@ -2396,15 +2406,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.10.0.tgz",
- "integrity": "sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz",
+ "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/scope-manager": "7.10.0",
- "@typescript-eslint/types": "7.10.0",
- "@typescript-eslint/typescript-estree": "7.10.0",
- "@typescript-eslint/visitor-keys": "7.10.0",
+ "@typescript-eslint/scope-manager": "7.14.1",
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/typescript-estree": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1",
"debug": "^4.3.4"
},
"engines": {
@@ -2424,13 +2435,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz",
- "integrity": "sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz",
+ "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "7.10.0",
- "@typescript-eslint/visitor-keys": "7.10.0"
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2441,13 +2453,14 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.10.0.tgz",
- "integrity": "sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz",
+ "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "7.10.0",
- "@typescript-eslint/utils": "7.10.0",
+ "@typescript-eslint/typescript-estree": "7.14.1",
+ "@typescript-eslint/utils": "7.14.1",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
},
@@ -2468,10 +2481,11 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.10.0.tgz",
- "integrity": "sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz",
+ "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "^18.18.0 || >=20.0.0"
},
@@ -2481,13 +2495,14 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.10.0.tgz",
- "integrity": "sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz",
+ "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/types": "7.10.0",
- "@typescript-eslint/visitor-keys": "7.10.0",
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/visitor-keys": "7.14.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -2509,15 +2524,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz",
- "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz",
+ "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "7.10.0",
- "@typescript-eslint/types": "7.10.0",
- "@typescript-eslint/typescript-estree": "7.10.0"
+ "@typescript-eslint/scope-manager": "7.14.1",
+ "@typescript-eslint/types": "7.14.1",
+ "@typescript-eslint/typescript-estree": "7.14.1"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -2531,12 +2547,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz",
- "integrity": "sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==",
+ "version": "7.14.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz",
+ "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "7.10.0",
+ "@typescript-eslint/types": "7.14.1",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
@@ -2552,6 +2569,7 @@
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -2566,9 +2584,9 @@
"dev": true
},
"node_modules/@vitejs/plugin-vue": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
- "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==",
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz",
+ "integrity": "sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==",
"dev": true,
"engines": {
"node": "^18.0.0 || >=20.0.0"
@@ -2699,36 +2717,36 @@
}
},
"node_modules/@vue/compiler-core": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz",
- "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==",
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.29.tgz",
+ "integrity": "sha512-TFKiRkKKsRCKvg/jTSSKK7mYLJEQdUiUfykbG49rubC9SfDyvT2JrzTReopWlz2MxqeLyxh9UZhvxEIBgAhtrg==",
"dependencies": {
- "@babel/parser": "^7.24.4",
- "@vue/shared": "3.4.27",
+ "@babel/parser": "^7.24.7",
+ "@vue/shared": "3.4.29",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-dom": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz",
- "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==",
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.29.tgz",
+ "integrity": "sha512-A6+iZ2fKIEGnfPJejdB7b1FlJzgiD+Y/sxxKwJWg1EbJu6ZPgzaPQQ51ESGNv0CP6jm6Z7/pO6Ia8Ze6IKrX7w==",
"dependencies": {
- "@vue/compiler-core": "3.4.27",
- "@vue/shared": "3.4.27"
+ "@vue/compiler-core": "3.4.29",
+ "@vue/shared": "3.4.29"
}
},
"node_modules/@vue/compiler-sfc": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz",
- "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==",
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.29.tgz",
+ "integrity": "sha512-zygDcEtn8ZimDlrEQyLUovoWgKQic6aEQqRXce2WXBvSeHbEbcAsXyCk9oG33ZkyWH4sl9D3tkYc1idoOkdqZQ==",
"dependencies": {
- "@babel/parser": "^7.24.4",
- "@vue/compiler-core": "3.4.27",
- "@vue/compiler-dom": "3.4.27",
- "@vue/compiler-ssr": "3.4.27",
- "@vue/shared": "3.4.27",
+ "@babel/parser": "^7.24.7",
+ "@vue/compiler-core": "3.4.29",
+ "@vue/compiler-dom": "3.4.29",
+ "@vue/compiler-ssr": "3.4.29",
+ "@vue/shared": "3.4.29",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.10",
"postcss": "^8.4.38",
@@ -2744,57 +2762,58 @@
}
},
"node_modules/@vue/compiler-ssr": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz",
- "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==",
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.29.tgz",
+ "integrity": "sha512-rFbwCmxJ16tDp3N8XCx5xSQzjhidYjXllvEcqX/lopkoznlNPz3jyy0WGJCyhAaVQK677WWFt3YO/WUEkMMUFQ==",
"dependencies": {
- "@vue/compiler-dom": "3.4.27",
- "@vue/shared": "3.4.27"
+ "@vue/compiler-dom": "3.4.29",
+ "@vue/shared": "3.4.29"
}
},
"node_modules/@vue/reactivity": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz",
- "integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==",
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.29.tgz",
+ "integrity": "sha512-w8+KV+mb1a8ornnGQitnMdLfE0kXmteaxLdccm2XwdFxXst4q/Z7SEboCV5SqJNpZbKFeaRBBJBhW24aJyGINg==",
"dependencies": {
- "@vue/shared": "3.4.27"
+ "@vue/shared": "3.4.29"
}
},
"node_modules/@vue/runtime-core": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz",
- "integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==",
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.29.tgz",
+ "integrity": "sha512-s8fmX3YVR/Rk5ig0ic0NuzTNjK2M7iLuVSZyMmCzN/+Mjuqqif1JasCtEtmtoJWF32pAtUjyuT2ljNKNLeOmnQ==",
"dependencies": {
- "@vue/reactivity": "3.4.27",
- "@vue/shared": "3.4.27"
+ "@vue/reactivity": "3.4.29",
+ "@vue/shared": "3.4.29"
}
},
"node_modules/@vue/runtime-dom": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz",
- "integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==",
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.29.tgz",
+ "integrity": "sha512-gI10atCrtOLf/2MPPMM+dpz3NGulo9ZZR9d1dWo4fYvm+xkfvRrw1ZmJ7mkWtiJVXSsdmPbcK1p5dZzOCKDN0g==",
"dependencies": {
- "@vue/runtime-core": "3.4.27",
- "@vue/shared": "3.4.27",
+ "@vue/reactivity": "3.4.29",
+ "@vue/runtime-core": "3.4.29",
+ "@vue/shared": "3.4.29",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz",
- "integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==",
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.29.tgz",
+ "integrity": "sha512-HMLCmPI2j/k8PVkSBysrA2RxcxC5DgBiCdj7n7H2QtR8bQQPqKAe8qoaxLcInzouBmzwJ+J0x20ygN/B5mYBng==",
"dependencies": {
- "@vue/compiler-ssr": "3.4.27",
- "@vue/shared": "3.4.27"
+ "@vue/compiler-ssr": "3.4.29",
+ "@vue/shared": "3.4.29"
},
"peerDependencies": {
- "vue": "3.4.27"
+ "vue": "3.4.29"
}
},
"node_modules/@vue/shared": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz",
- "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA=="
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.29.tgz",
+ "integrity": "sha512-hQ2gAQcBO/CDpC82DCrinJNgOHI2v+FA7BDW4lMSPeBpQ7sRe2OLHWe5cph1s7D8DUQAwRt18dBDfJJ220APEA=="
},
"node_modules/@webassemblyjs/ast": {
"version": "1.12.1",
@@ -2991,9 +3010,9 @@
}
},
"node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
+ "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
"bin": {
"acorn": "bin/acorn"
},
@@ -3001,10 +3020,10 @@
"node": ">=0.4.0"
}
},
- "node_modules/acorn-import-assertions": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
- "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
+ "node_modules/acorn-import-attributes": {
+ "version": "1.9.5",
+ "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
+ "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
"peerDependencies": {
"acorn": "^8"
}
@@ -3019,10 +3038,13 @@
}
},
"node_modules/acorn-walk": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz",
- "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==",
+ "version": "8.3.3",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz",
+ "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==",
"dev": true,
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
"engines": {
"node": ">=0.4.0"
}
@@ -3042,9 +3064,9 @@
}
},
"node_modules/ajv": {
- "version": "8.14.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.14.0.tgz",
- "integrity": "sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==",
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz",
+ "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"json-schema-traverse": "^1.0.0",
@@ -3313,9 +3335,9 @@
}
},
"node_modules/asciinema-player": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.7.1.tgz",
- "integrity": "sha512-zDJteGjBzNQhHEnD0aG7GqV3E53sOyKb1WCxKNRm2PquU70Lq3s4xxb91wyDS0hBJ3J/TB8aY3y8gjGPN+T23A==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.8.0.tgz",
+ "integrity": "sha512-yFoAcjFK9WJ0D+aagkT0YXOWRbyXoOe/TQHq07oQP6prItXQkWn46fdvUb6zqJu2AywmY8VjBEwZ6ciL8IbezQ==",
"dependencies": {
"@babel/runtime": "^7.21.0",
"solid-js": "^1.3.0"
@@ -3480,9 +3502,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.23.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
- "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
+ "version": "4.23.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz",
+ "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
"funding": [
{
"type": "opencollective",
@@ -3498,10 +3520,10 @@
}
],
"dependencies": {
- "caniuse-lite": "^1.0.30001587",
- "electron-to-chromium": "^1.4.668",
+ "caniuse-lite": "^1.0.30001629",
+ "electron-to-chromium": "^1.4.796",
"node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.13"
+ "update-browserslist-db": "^1.0.16"
},
"bin": {
"browserslist": "cli.js"
@@ -3601,9 +3623,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001623",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001623.tgz",
- "integrity": "sha512-X/XhAVKlpIxWPpgRTnlgZssJrF0m6YtRA0QDWgsBNT12uZM6LPRydR7ip405Y3t1LamD8cP2TZFEDZFBf5ApcA==",
+ "version": "1.0.30001636",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz",
+ "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==",
"funding": [
{
"type": "opencollective",
@@ -3742,9 +3764,9 @@
}
},
"node_modules/chrome-trace-event": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
- "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
+ "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
"engines": {
"node": ">=6.0"
}
@@ -4634,9 +4656,9 @@
"integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg=="
},
"node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+ "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
"dependencies": {
"ms": "2.1.2"
},
@@ -4671,9 +4693,9 @@
}
},
"node_modules/deep-eql": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
- "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==",
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
+ "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
"dev": true,
"dependencies": {
"type-detect": "^4.0.0"
@@ -4807,6 +4829,14 @@
"node": ">=6.0.0"
}
},
+ "node_modules/dom-input-range": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/dom-input-range/-/dom-input-range-1.1.6.tgz",
+ "integrity": "sha512-4o/SkTpscD0n81BeErrrtmE58lG8vTks++92vk//ld0NmkQTb4AVJ2rexh2yor6rtBf5IMte26u+fF3EgCppPQ==",
+ "workspaces": [
+ "demos"
+ ]
+ },
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
@@ -4849,9 +4879,9 @@
}
},
"node_modules/dompurify": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.4.tgz",
- "integrity": "sha512-2gnshi6OshmuKil8rMZuQCGiUF3cUxHY3NGDzUAdUx/NPEe5DVnO8BDoAQouvgwnx0R/+a6jUn36Z0FSdq8vww=="
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.5.tgz",
+ "integrity": "sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA=="
},
"node_modules/domutils": {
"version": "3.1.0",
@@ -4894,9 +4924,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.783",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.783.tgz",
- "integrity": "sha512-bT0jEz/Xz1fahQpbZ1D7LgmPYZ3iHVY39NcWWro1+hA2IvjiPeaXtfSqrQ+nXjApMvQRE2ASt1itSLRrebHMRQ=="
+ "version": "1.4.803",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.803.tgz",
+ "integrity": "sha512-61H9mLzGOCLLVsnLiRzCbc63uldP0AniRYPV3hbGVtONA1pI7qSGILdbofR7A8TMbOypDocEAjH/e+9k1QIe3g=="
},
"node_modules/elkjs": {
"version": "0.9.3",
@@ -4917,9 +4947,9 @@
}
},
"node_modules/enhanced-resolve": {
- "version": "5.16.1",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz",
- "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==",
+ "version": "5.17.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz",
+ "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==",
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@@ -5152,9 +5182,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
- "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@@ -5163,37 +5193,37 @@
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.20.2",
- "@esbuild/android-arm": "0.20.2",
- "@esbuild/android-arm64": "0.20.2",
- "@esbuild/android-x64": "0.20.2",
- "@esbuild/darwin-arm64": "0.20.2",
- "@esbuild/darwin-x64": "0.20.2",
- "@esbuild/freebsd-arm64": "0.20.2",
- "@esbuild/freebsd-x64": "0.20.2",
- "@esbuild/linux-arm": "0.20.2",
- "@esbuild/linux-arm64": "0.20.2",
- "@esbuild/linux-ia32": "0.20.2",
- "@esbuild/linux-loong64": "0.20.2",
- "@esbuild/linux-mips64el": "0.20.2",
- "@esbuild/linux-ppc64": "0.20.2",
- "@esbuild/linux-riscv64": "0.20.2",
- "@esbuild/linux-s390x": "0.20.2",
- "@esbuild/linux-x64": "0.20.2",
- "@esbuild/netbsd-x64": "0.20.2",
- "@esbuild/openbsd-x64": "0.20.2",
- "@esbuild/sunos-x64": "0.20.2",
- "@esbuild/win32-arm64": "0.20.2",
- "@esbuild/win32-ia32": "0.20.2",
- "@esbuild/win32-x64": "0.20.2"
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
}
},
"node_modules/esbuild-loader": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.1.0.tgz",
- "integrity": "sha512-543TtIvqbqouEMlOHg4xKoDQkmdImlwIpyAIgpUtDPvMuklU/c2k+Qt2O3VeDBgAwozxmlEbjOzV+F8CZ0g+Bw==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.2.0.tgz",
+ "integrity": "sha512-BhwHchuDknxIa69AqOPeZh2fIFqj2AzZKC1E3RBRvXSuyk5drsqMrwsgYZJufX41yrauLYjDM3KBmruoGl1NWQ==",
"dependencies": {
- "esbuild": "^0.20.0",
+ "esbuild": "^0.21.0",
"get-tsconfig": "^4.7.0",
"loader-utils": "^2.0.4",
"webpack-sources": "^1.4.3"
@@ -5292,9 +5322,9 @@
}
},
"node_modules/eslint-compat-utils": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz",
- "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==",
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz",
+ "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==",
"dev": true,
"dependencies": {
"semver": "^7.5.4"
@@ -5338,6 +5368,31 @@
"ms": "^2.1.1"
}
},
+ "node_modules/eslint-import-resolver-typescript": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz",
+ "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4",
+ "enhanced-resolve": "^5.12.0",
+ "eslint-module-utils": "^2.7.4",
+ "fast-glob": "^3.3.1",
+ "get-tsconfig": "^4.5.0",
+ "is-core-module": "^2.11.0",
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "eslint-plugin-import": "*"
+ }
+ },
"node_modules/eslint-module-utils": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz",
@@ -5376,6 +5431,22 @@
"eslint": ">=8.40.0"
}
},
+ "node_modules/eslint-plugin-deprecation": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-deprecation/-/eslint-plugin-deprecation-3.0.0.tgz",
+ "integrity": "sha512-JuVLdNg/uf0Adjg2tpTyYoYaMbwQNn/c78P1HcccokvhtRphgnRjZDKmhlxbxYptppex03zO76f97DD/yQHv7A==",
+ "dev": true,
+ "license": "LGPL-3.0-or-later",
+ "dependencies": {
+ "@typescript-eslint/utils": "^7.0.0",
+ "ts-api-utils": "^1.3.0",
+ "tslib": "^2.3.1"
+ },
+ "peerDependencies": {
+ "eslint": "^8.0.0",
+ "typescript": "^4.2.4 || ^5.0.0"
+ }
+ },
"node_modules/eslint-plugin-escompat": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-escompat/-/eslint-plugin-escompat-3.4.0.tgz",
@@ -5432,9 +5503,9 @@
}
},
"node_modules/eslint-plugin-github": {
- "version": "5.0.0-2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-github/-/eslint-plugin-github-5.0.0-2.tgz",
- "integrity": "sha512-oQUFAF1wMBvRMGLvGWxVhZ46JNjKbPuuDufmUDZ3ZYyovWHCqqR5HLHTpTfmZQcyEXmjv9TWdsgfdMlod2fGMQ==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-github/-/eslint-plugin-github-5.0.1.tgz",
+ "integrity": "sha512-qbXG3wL5Uh2JB92EKeX2hPtO9c/t75qVxQjVLYuTFfhHifLZzv9CBvLCvoaBhLrAC/xTMVht7DK/NofYK8X4Dg==",
"dev": true,
"dependencies": {
"@github/browserslist-config": "^1.0.0",
@@ -5601,15 +5672,6 @@
"semver": "bin/semver.js"
}
},
- "node_modules/eslint-plugin-jquery": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-jquery/-/eslint-plugin-jquery-1.5.1.tgz",
- "integrity": "sha512-L7v1eaK5t80C0lvUXPFP9MKnBOqPSKhCOYyzy4LZ0+iK+TJwN8S9gAkzzP1AOhypRIwA88HF6phQ9C7jnOpW8w==",
- "dev": true,
- "peerDependencies": {
- "eslint": ">=5.4.0"
- }
- },
"node_modules/eslint-plugin-jsx-a11y": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz",
@@ -5663,12 +5725,12 @@
}
},
"node_modules/eslint-plugin-no-jquery": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz",
- "integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.0.1.tgz",
+ "integrity": "sha512-GrzdjIxox/3x8hpSwpxiMuEQFipiJHTGiVsp0T1TI6GH+KVSbXa4z/56xTV1WiIe66u3iRgvCIipu9CRthecpQ==",
"dev": true,
"peerDependencies": {
- "eslint": ">=2.3.0"
+ "eslint": ">=8.0.0"
}
},
"node_modules/eslint-plugin-no-only-tests": {
@@ -5695,6 +5757,30 @@
"node": ">=6.0.0"
}
},
+ "node_modules/eslint-plugin-playwright": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-1.6.2.tgz",
+ "integrity": "sha512-mraN4Em3b5jLt01q7qWPyLg0Q5v3KAWfJSlEWwldyUXoa7DSPrBR4k6B6LROLqipsG8ndkwWMdjl1Ffdh15tag==",
+ "dev": true,
+ "workspaces": [
+ "examples"
+ ],
+ "dependencies": {
+ "globals": "^13.23.0"
+ },
+ "engines": {
+ "node": ">=16.6.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=8.40.0",
+ "eslint-plugin-jest": ">=25"
+ },
+ "peerDependenciesMeta": {
+ "eslint-plugin-jest": {
+ "optional": true
+ }
+ }
+ },
"node_modules/eslint-plugin-prettier": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
@@ -5759,9 +5845,9 @@
}
},
"node_modules/eslint-plugin-unicorn": {
- "version": "53.0.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-53.0.0.tgz",
- "integrity": "sha512-kuTcNo9IwwUCfyHGwQFOK/HjJAYzbODHN3wP0PgqbW+jbXqpNWxNVpVhj2tO9SixBwuAdmal8rVcWKBxwFnGuw==",
+ "version": "54.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-54.0.0.tgz",
+ "integrity": "sha512-XxYLRiYtAWiAjPv6z4JREby1TAE2byBC7wlh0V4vWDCpccOSU1KovWV//jqPXF6bq3WKxqX9rdjoRQ1EhdmNdQ==",
"dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.24.5",
@@ -6072,12 +6158,12 @@
}
},
"node_modules/espree": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz",
- "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==",
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
+ "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==",
"dev": true,
"dependencies": {
- "acorn": "^8.11.3",
+ "acorn": "^8.12.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^4.0.0"
},
@@ -6347,9 +6433,9 @@
}
},
"node_modules/foreground-child": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
- "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
+ "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
"dependencies": {
"cross-spawn": "^7.0.0",
"signal-exit": "^4.0.1"
@@ -6741,9 +6827,9 @@
}
},
"node_modules/happy-dom": {
- "version": "14.11.1",
- "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.11.1.tgz",
- "integrity": "sha512-JuaGMxD3QlQei6LdAM9mMY9am/cHa978uFbkOpjN5x83DG+QQp/NLyVV4Ru7KOjs70XYZ4KbI0TNiO81nM7uQQ==",
+ "version": "14.12.0",
+ "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.12.0.tgz",
+ "integrity": "sha512-dHcnlGFY2o2CdxfuYpqwSrBrpj/Kuzv4u4f3TU5yHW1GL24dKij4pv1BRjXnXc3uWo8qsCbToF9weaDsm/He8A==",
"dev": true,
"dependencies": {
"entities": "^4.5.0",
@@ -6885,9 +6971,9 @@
}
},
"node_modules/htmx.org": {
- "version": "1.9.12",
- "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-1.9.12.tgz",
- "integrity": "sha512-VZAohXyF7xPGS52IM8d1T1283y+X4D+Owf3qY1NZ9RuBypyu9l8cGsxUMAG5fEAb/DhT7rDoJ9Hpu5/HxFD3cw=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.0.tgz",
+ "integrity": "sha512-N0r1VjrqeCpig0mTi2/sooDZBeQlp1RBohnWQ/ufqc7ICaI0yjs04fNGhawm6+/HWhJFlcXn8MqOjWI9QGG2lQ=="
},
"node_modules/human-signals": {
"version": "5.0.0",
@@ -7566,9 +7652,9 @@
}
},
"node_modules/jackspeak": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz",
- "integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==",
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz",
+ "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
@@ -7610,9 +7696,9 @@
}
},
"node_modules/jiti": {
- "version": "1.21.0",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
- "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
+ "version": "1.21.6",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
+ "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
"bin": {
"jiti": "bin/jiti.js"
}
@@ -8870,14 +8956,14 @@
}
},
"node_modules/mlly": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.0.tgz",
- "integrity": "sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==",
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz",
+ "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==",
"dev": true,
"dependencies": {
"acorn": "^8.11.3",
"pathe": "^1.1.2",
- "pkg-types": "^1.1.0",
+ "pkg-types": "^1.1.1",
"ufo": "^1.5.3"
}
},
@@ -9631,6 +9717,51 @@
"postcss": "^8.4.21"
}
},
+ "node_modules/postcss-load-config": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
+ "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "lilconfig": "^3.0.0",
+ "yaml": "^2.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-load-config/node_modules/lilconfig": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
+ "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
"node_modules/postcss-loader": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz",
@@ -9854,9 +9985,9 @@
}
},
"node_modules/prettier": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
- "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
+ "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@@ -10654,9 +10785,9 @@
}
},
"node_modules/smol-toml": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.2.0.tgz",
- "integrity": "sha512-KObxdQANC/xje3OoatMbSwQf2XAvJ0RbK+4nmQRszFNZptbNRnMWqbLF/zb4sMi9xJ6HNyhWXeuZ9zC/I/XY7w==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.2.1.tgz",
+ "integrity": "sha512-OtZKrVrGIT+m++lxyF0z5n68nkwdgZotPhy89bfA4T7nSWe0xeQtfbjM1z5VLTilJdWXH46g8i0oAcpQNkzZTg==",
"dev": true,
"engines": {
"node": ">= 18",
@@ -10983,9 +11114,9 @@
"dev": true
},
"node_modules/stylelint": {
- "version": "16.6.0",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.6.0.tgz",
- "integrity": "sha512-vjWYlDEgOS3Z/IcXagQwi8PFJyPro1DxBYOnTML1PAqnrYUHs8owleGStv20sgt0OhW8r9zZm6MK7IT2+l2B6A==",
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.6.1.tgz",
+ "integrity": "sha512-yNgz2PqWLkhH2hw6X9AweV9YvoafbAD5ZsFdKN9BvSDVwGvPh+AUIrn7lYwy1S7IHmtFin75LLfX1m0D2tHu8Q==",
"dev": true,
"funding": [
{
@@ -11011,7 +11142,7 @@
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^8.0.0",
+ "file-entry-cache": "^9.0.0",
"global-modules": "^2.0.0",
"globby": "^11.1.0",
"globjoin": "^0.1.4",
@@ -11022,7 +11153,7 @@
"known-css-properties": "^0.31.0",
"mathml-tag-names": "^2.1.3",
"meow": "^13.2.0",
- "micromatch": "^4.0.5",
+ "micromatch": "^4.0.7",
"normalize-path": "^3.0.0",
"picocolors": "^1.0.1",
"postcss": "^8.4.38",
@@ -11104,28 +11235,28 @@
"dev": true
},
"node_modules/stylelint/node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz",
+ "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==",
"dev": true,
"dependencies": {
- "flat-cache": "^4.0.0"
+ "flat-cache": "^5.0.0"
},
"engines": {
- "node": ">=16.0.0"
+ "node": ">=18"
}
},
"node_modules/stylelint/node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz",
+ "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==",
"dev": true,
"dependencies": {
- "flatted": "^3.2.9",
+ "flatted": "^3.3.1",
"keyv": "^4.5.4"
},
"engines": {
- "node": ">=16"
+ "node": ">=18"
}
},
"node_modules/stylelint/node_modules/postcss-safe-parser": {
@@ -11353,9 +11484,9 @@
}
},
"node_modules/swagger-ui-dist": {
- "version": "5.17.13",
- "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.13.tgz",
- "integrity": "sha512-dyR3HAjwjK9oTd5ELzFh7rJEoMUyqfgaAQEwn0NGhLpOwg7IEbee17qjp50QIVE3sUA8J2d6ySw4IF50nUrKog=="
+ "version": "5.17.14",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz",
+ "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw=="
},
"node_modules/sync-fetch": {
"version": "0.4.5",
@@ -11402,9 +11533,9 @@
}
},
"node_modules/tailwindcss": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
- "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==",
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
+ "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
@@ -11437,51 +11568,6 @@
"node": ">=14.0.0"
}
},
- "node_modules/tailwindcss/node_modules/postcss-load-config": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
- "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "lilconfig": "^3.0.0",
- "yaml": "^2.3.4"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "postcss": ">=8.0.9",
- "ts-node": ">=9.0.0"
- },
- "peerDependenciesMeta": {
- "postcss": {
- "optional": true
- },
- "ts-node": {
- "optional": true
- }
- }
- },
- "node_modules/tailwindcss/node_modules/postcss-load-config/node_modules/lilconfig": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
- "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
- }
- },
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@@ -11491,9 +11577,9 @@
}
},
"node_modules/temporal-polyfill": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.2.4.tgz",
- "integrity": "sha512-WA5p0CjQTkMjF9m8sP4wSYgpqI8m2d4q7wPUyaJOWhy4bI9mReLb2yGvTV4qf/DPMTe6H6M/Dig5KmTMB7ev6Q==",
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.2.5.tgz",
+ "integrity": "sha512-ye47xp8Cb0nDguAhrrDS1JT1SzwEV9e26sSsrWzVu+yPZ7LzceEcH0i2gci9jWfOfSCCgM3Qv5nOYShVUUFUXA==",
"dependencies": {
"temporal-spec": "^0.2.4"
}
@@ -11504,9 +11590,9 @@
"integrity": "sha512-lDMFv4nKQrSjlkHKAlHVqKrBG4DyFfa9F74cmBZ3Iy3ed8yvWnlWSIdi4IKfSqwmazAohBNwiN64qGx4y5Q3IQ=="
},
"node_modules/terser": {
- "version": "5.31.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz",
- "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==",
+ "version": "5.31.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz",
+ "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.8.2",
@@ -11749,9 +11835,9 @@
}
},
"node_modules/tslib": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
- "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
+ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
"dev": true
},
"node_modules/type-check": {
@@ -11861,11 +11947,10 @@
}
},
"node_modules/typescript": {
- "version": "5.4.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
- "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
- "devOptional": true,
- "peer": true,
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
+ "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
+ "license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -11967,12 +12052,12 @@
}
},
"node_modules/updates": {
- "version": "16.1.1",
- "resolved": "https://registry.npmjs.org/updates/-/updates-16.1.1.tgz",
- "integrity": "sha512-h0Qtbmd9RCi6+99D5o7ACq4h7GxdYjeHFlxd4s0iO3lUOUDo1VnOsbNNIyjHpieVEctaEm/zoEjVggCgAcO/vg==",
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/updates/-/updates-16.2.0.tgz",
+ "integrity": "sha512-9F+tkT12B6f1+zzMKY9CrJx18LwnEh2HLQXtuJgtXobi5BwSQ9BH0b+ZnhwyQuY0lmgLFCsE6QxO98OZJiLX6Q==",
"dev": true,
"bin": {
- "updates": "dist/updates.js"
+ "updates": "dist/index.js"
},
"engines": {
"node": ">=18"
@@ -12060,12 +12145,12 @@
"integrity": "sha512-z2YZusTFC6KnLERx1cgoIRX2CjPRP0W75N+3CC6gbvdX5Ch47rZkEMGO2Xnf+IEmi3RiFLxS18gayMA27iU7Kg=="
},
"node_modules/vite": {
- "version": "5.2.11",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz",
- "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz",
+ "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==",
"dev": true,
"dependencies": {
- "esbuild": "^0.20.1",
+ "esbuild": "^0.21.3",
"postcss": "^8.4.38",
"rollup": "^4.13.0"
},
@@ -12137,9 +12222,9 @@
}
},
"node_modules/vite-string-plugin": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/vite-string-plugin/-/vite-string-plugin-1.3.1.tgz",
- "integrity": "sha512-0Wu9yNw4QlSVM4SlwozzxR0geMoKFrAIpMldgPuzDvV8lWT1v+0pFXYt+t48qocYXBaxiuVRE3qcsEwFDHBAmA==",
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/vite-string-plugin/-/vite-string-plugin-1.3.4.tgz",
+ "integrity": "sha512-mHvcooHgZ0nVbHtj9o+c5dzD2/nclr/SOG023EFYF/zRnO8bxB63bV9WUA9X+njlgLpOwCJ3LI2IdihKoi0gZQ==",
"dev": true
},
"node_modules/vite/node_modules/@types/estree": {
@@ -12272,15 +12357,15 @@
}
},
"node_modules/vue": {
- "version": "3.4.27",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz",
- "integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==",
+ "version": "3.4.29",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.29.tgz",
+ "integrity": "sha512-8QUYfRcYzNlYuzKPfge1UWC6nF9ym0lx7mpGVPJYNhddxEf3DD0+kU07NTL0sXuiT2HuJuKr/iEO8WvXvT0RSQ==",
"dependencies": {
- "@vue/compiler-dom": "3.4.27",
- "@vue/compiler-sfc": "3.4.27",
- "@vue/runtime-dom": "3.4.27",
- "@vue/server-renderer": "3.4.27",
- "@vue/shared": "3.4.27"
+ "@vue/compiler-dom": "3.4.29",
+ "@vue/compiler-sfc": "3.4.29",
+ "@vue/runtime-dom": "3.4.29",
+ "@vue/server-renderer": "3.4.29",
+ "@vue/shared": "3.4.29"
},
"peerDependencies": {
"typescript": "*"
@@ -12310,9 +12395,9 @@
}
},
"node_modules/vue-eslint-parser": {
- "version": "9.4.2",
- "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
- "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
+ "version": "9.4.3",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
+ "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==",
"dev": true,
"dependencies": {
"debug": "^4.3.4",
@@ -12410,9 +12495,9 @@
}
},
"node_modules/webpack": {
- "version": "5.91.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz",
- "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==",
+ "version": "5.92.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.0.tgz",
+ "integrity": "sha512-Bsw2X39MYIgxouNATyVpCNVWBCuUwDgWtN78g6lSdPJRLaQ/PUVm/oXcaRAyY/sMFoKFQrsPeqvTizWtq7QPCA==",
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^1.0.5",
@@ -12420,10 +12505,10 @@
"@webassemblyjs/wasm-edit": "^1.12.1",
"@webassemblyjs/wasm-parser": "^1.12.1",
"acorn": "^8.7.1",
- "acorn-import-assertions": "^1.9.0",
+ "acorn-import-attributes": "^1.9.5",
"browserslist": "^4.21.10",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.16.0",
+ "enhanced-resolve": "^5.17.0",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
@@ -12880,9 +12965,9 @@
}
},
"node_modules/yaml": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz",
- "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==",
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz",
+ "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==",
"bin": {
"yaml": "bin.mjs"
},
diff --git a/package.json b/package.json
index a0f9b343b4..e44415ee32 100644
--- a/package.json
+++ b/package.json
@@ -4,19 +4,19 @@
"node": ">= 18.0.0"
},
"dependencies": {
- "@citation-js/core": "0.7.11",
- "@citation-js/plugin-bibtex": "0.7.12",
- "@citation-js/plugin-csl": "0.7.11",
+ "@citation-js/core": "0.7.14",
+ "@citation-js/plugin-bibtex": "0.7.14",
+ "@citation-js/plugin-csl": "0.7.14",
"@citation-js/plugin-software-formats": "0.6.1",
"@github/markdown-toolbar-element": "2.2.3",
"@github/relative-time-element": "4.4.2",
- "@github/text-expander-element": "2.6.1",
+ "@github/text-expander-element": "2.7.1",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
"@primer/octicons": "19.9.0",
"@silverwind/vue3-calendar-heatmap": "2.0.6",
"add-asset-webpack-plugin": "3.0.0",
"ansi_up": "6.0.2",
- "asciinema-player": "3.7.1",
+ "asciinema-player": "3.8.0",
"chart.js": "4.4.3",
"chartjs-adapter-dayjs-4": "1.0.4",
"chartjs-plugin-zoom": "2.0.1",
@@ -25,10 +25,10 @@
"dayjs": "1.11.11",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
- "esbuild-loader": "4.1.0",
+ "esbuild-loader": "4.2.0",
"escape-goat": "4.0.0",
"fast-glob": "3.3.2",
- "htmx.org": "1.9.12",
+ "htmx.org": "2.0.0",
"idiomorph": "0.3.0",
"jquery": "3.7.1",
"katex": "0.16.10",
@@ -43,21 +43,22 @@
"postcss-loader": "8.1.1",
"postcss-nesting": "12.1.5",
"sortablejs": "1.15.2",
- "swagger-ui-dist": "5.17.13",
- "tailwindcss": "3.4.3",
- "temporal-polyfill": "0.2.4",
+ "swagger-ui-dist": "5.17.14",
+ "tailwindcss": "3.4.4",
+ "temporal-polyfill": "0.2.5",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",
"toastify-js": "1.12.0",
"tributejs": "5.1.3",
+ "typescript": "5.5.2",
"uint8-to-base64": "0.2.0",
"vanilla-colorful": "0.7.2",
- "vue": "3.4.27",
+ "vue": "3.4.29",
"vue-bar-graph": "2.0.0",
"vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
- "webpack": "5.91.0",
+ "webpack": "5.92.0",
"webpack-cli": "5.1.4",
"wrap-ansi": "9.0.0"
},
@@ -65,34 +66,38 @@
"@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
"@playwright/test": "1.44.1",
"@stoplight/spectral-cli": "6.11.1",
- "@stylistic/eslint-plugin-js": "2.1.0",
+ "@stylistic/eslint-plugin-js": "2.2.1",
"@stylistic/stylelint-plugin": "2.1.2",
- "@vitejs/plugin-vue": "5.0.4",
+ "@typescript-eslint/eslint-plugin": "7.14.1",
+ "@typescript-eslint/parser": "7.14.1",
+ "@vitejs/plugin-vue": "5.0.5",
"eslint": "8.57.0",
+ "eslint-import-resolver-typescript": "3.6.1",
"eslint-plugin-array-func": "4.0.0",
- "eslint-plugin-github": "5.0.0-2",
+ "eslint-plugin-deprecation": "3.0.0",
+ "eslint-plugin-github": "5.0.1",
"eslint-plugin-i": "2.29.1",
- "eslint-plugin-jquery": "1.5.1",
- "eslint-plugin-no-jquery": "2.7.0",
+ "eslint-plugin-no-jquery": "3.0.1",
"eslint-plugin-no-use-extend-native": "0.5.0",
+ "eslint-plugin-playwright": "1.6.2",
"eslint-plugin-regexp": "2.6.0",
"eslint-plugin-sonarjs": "1.0.3",
- "eslint-plugin-unicorn": "53.0.0",
+ "eslint-plugin-unicorn": "54.0.0",
"eslint-plugin-vitest": "0.4.1",
"eslint-plugin-vitest-globals": "1.5.0",
"eslint-plugin-vue": "9.26.0",
"eslint-plugin-vue-scoped-css": "2.8.0",
"eslint-plugin-wc": "2.1.0",
- "happy-dom": "14.11.1",
+ "happy-dom": "14.12.0",
"markdownlint-cli": "0.41.0",
"postcss-html": "1.7.0",
- "stylelint": "16.6.0",
+ "stylelint": "16.6.1",
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
"stylelint-declaration-strict-value": "1.10.4",
"stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "3.3.2",
- "updates": "16.1.1",
- "vite-string-plugin": "1.3.1",
+ "updates": "16.2.0",
+ "vite-string-plugin": "1.3.4",
"vitest": "1.6.0"
},
"browserslist": [
diff --git a/playwright.config.js b/playwright.config.ts
similarity index 81%
rename from playwright.config.js
rename to playwright.config.ts
index bdd303ae25..d1cd299e25 100644
--- a/playwright.config.js
+++ b/playwright.config.ts
@@ -1,15 +1,12 @@
-// @ts-check
import {devices} from '@playwright/test';
+import {env} from 'node:process';
+import type {PlaywrightTestConfig} from '@playwright/test';
-const BASE_URL = process.env.GITEA_URL?.replace?.(/\/$/g, '') || 'http://localhost:3000';
+const BASE_URL = env.GITEA_URL?.replace?.(/\/$/g, '') || 'http://localhost:3000';
-/**
- * @see https://playwright.dev/docs/test-configuration
- * @type {import('@playwright/test').PlaywrightTestConfig}
- */
export default {
testDir: './tests/e2e/',
- testMatch: /.*\.test\.e2e\.js/, // Match any .test.e2e.js files
+ testMatch: /.*\.test\.e2e\.ts/, // Match any .test.e2e.ts files
/* Maximum time one test can run for. */
timeout: 30 * 1000,
@@ -24,13 +21,13 @@ export default {
},
/* Fail the build on CI if you accidentally left test.only in the source code. */
- forbidOnly: Boolean(process.env.CI),
+ forbidOnly: Boolean(env.CI),
/* Retry on CI only */
- retries: process.env.CI ? 2 : 0,
+ retries: env.CI ? 2 : 0,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
- reporter: process.env.CI ? 'list' : [['list'], ['html', {outputFolder: 'tests/e2e/reports/', open: 'never'}]],
+ reporter: env.CI ? 'list' : [['list'], ['html', {outputFolder: 'tests/e2e/reports/', open: 'never'}]],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
@@ -98,4 +95,4 @@ export default {
outputDir: 'tests/e2e/test-artifacts/',
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
snapshotDir: 'tests/e2e/test-snapshots/',
-};
+} satisfies PlaywrightTestConfig;
diff --git a/public/assets/img/404.png b/public/assets/img/404.png
deleted file mode 100644
index 8b66c971f4..0000000000
Binary files a/public/assets/img/404.png and /dev/null differ
diff --git a/public/assets/img/500.png b/public/assets/img/500.png
deleted file mode 100644
index dab69206ad..0000000000
Binary files a/public/assets/img/500.png and /dev/null differ
diff --git a/routers/api/actions/actions.go b/routers/api/actions/actions.go
index a418b3a1c4..6f03f290ea 100644
--- a/routers/api/actions/actions.go
+++ b/routers/api/actions/actions.go
@@ -11,8 +11,8 @@ import (
"code.gitea.io/gitea/routers/api/actions/runner"
)
-func Routes(prefix string) *web.Route {
- m := web.NewRoute()
+func Routes(prefix string) *web.Router {
+ m := web.NewRouter()
path, handler := ping.NewPingServiceHandler()
m.Post(path+"*", http.StripPrefix(prefix, handler).ServeHTTP)
diff --git a/routers/api/actions/artifacts.go b/routers/api/actions/artifacts.go
index 72a2a26c47..da5850589f 100644
--- a/routers/api/actions/artifacts.go
+++ b/routers/api/actions/artifacts.go
@@ -101,8 +101,8 @@ func init() {
})
}
-func ArtifactsRoutes(prefix string) *web.Route {
- m := web.NewRoute()
+func ArtifactsRoutes(prefix string) *web.Router {
+ m := web.NewRouter()
m.Use(ArtifactContexter())
r := artifactRoutes{
@@ -457,7 +457,7 @@ func (ar artifactRoutes) downloadArtifact(ctx *ArtifactContext) {
return
}
- artifactID := ctx.ParamsInt64("artifact_id")
+ artifactID := ctx.PathParamInt64("artifact_id")
artifact, exist, err := db.GetByID[actions.ActionArtifact](ctx, artifactID)
if err != nil {
log.Error("Error getting artifact: %v", err)
diff --git a/routers/api/actions/artifacts_utils.go b/routers/api/actions/artifacts_utils.go
index 3517d57f78..a4ca5797dc 100644
--- a/routers/api/actions/artifacts_utils.go
+++ b/routers/api/actions/artifacts_utils.go
@@ -34,7 +34,7 @@ func validateArtifactName(ctx *ArtifactContext, artifactName string) bool {
func validateRunID(ctx *ArtifactContext) (*actions.ActionTask, int64, bool) {
task := ctx.ActionTask
- runID := ctx.ParamsInt64("run_id")
+ runID := ctx.PathParamInt64("run_id")
if task.Job.RunID != runID {
log.Error("Error runID not match")
ctx.Error(http.StatusBadRequest, "run-id does not match")
@@ -55,7 +55,7 @@ func validateRunIDV4(ctx *ArtifactContext, rawRunID string) (*actions.ActionTask
}
func validateArtifactHash(ctx *ArtifactContext, artifactName string) bool {
- paramHash := ctx.Params("artifact_hash")
+ paramHash := ctx.PathParam("artifact_hash")
// use artifact name to create upload url
artifactHash := fmt.Sprintf("%x", md5.Sum([]byte(artifactName)))
if paramHash == artifactHash {
diff --git a/routers/api/actions/artifactsv4.go b/routers/api/actions/artifactsv4.go
index 2ace9f915f..e78ed7a0c2 100644
--- a/routers/api/actions/artifactsv4.go
+++ b/routers/api/actions/artifactsv4.go
@@ -129,8 +129,8 @@ func ArtifactV4Contexter() func(next http.Handler) http.Handler {
}
}
-func ArtifactsV4Routes(prefix string) *web.Route {
- m := web.NewRoute()
+func ArtifactsV4Routes(prefix string) *web.Router {
+ m := web.NewRouter()
r := artifactV4Routes{
prefix: prefix,
diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go
index 5127319807..4b652c9ecc 100644
--- a/routers/api/packages/alpine/alpine.go
+++ b/routers/api/packages/alpine/alpine.go
@@ -73,7 +73,7 @@ func GetRepositoryFile(ctx *context.Context) {
pv,
&packages_service.PackageFileInfo{
Filename: alpine_service.IndexArchiveFilename,
- CompositeKey: fmt.Sprintf("%s|%s|%s", ctx.Params("branch"), ctx.Params("repository"), ctx.Params("architecture")),
+ CompositeKey: fmt.Sprintf("%s|%s|%s", ctx.PathParam("branch"), ctx.PathParam("repository"), ctx.PathParam("architecture")),
},
)
if err != nil {
@@ -89,8 +89,8 @@ func GetRepositoryFile(ctx *context.Context) {
}
func UploadPackageFile(ctx *context.Context) {
- branch := strings.TrimSpace(ctx.Params("branch"))
- repository := strings.TrimSpace(ctx.Params("repository"))
+ branch := strings.TrimSpace(ctx.PathParam("branch"))
+ repository := strings.TrimSpace(ctx.PathParam("repository"))
if branch == "" || repository == "" {
apiError(ctx, http.StatusBadRequest, "invalid branch or repository")
return
@@ -182,14 +182,14 @@ func UploadPackageFile(ctx *context.Context) {
}
func DownloadPackageFile(ctx *context.Context) {
- branch := ctx.Params("branch")
- repository := ctx.Params("repository")
- architecture := ctx.Params("architecture")
+ branch := ctx.PathParam("branch")
+ repository := ctx.PathParam("repository")
+ architecture := ctx.PathParam("architecture")
opts := &packages_model.PackageFileSearchOptions{
OwnerID: ctx.Package.Owner.ID,
PackageType: packages_model.TypeAlpine,
- Query: ctx.Params("filename"),
+ Query: ctx.PathParam("filename"),
CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, architecture),
}
pfs, _, err := packages_model.SearchFiles(ctx, opts)
@@ -230,12 +230,12 @@ func DownloadPackageFile(ctx *context.Context) {
}
func DeletePackageFile(ctx *context.Context) {
- branch, repository, architecture := ctx.Params("branch"), ctx.Params("repository"), ctx.Params("architecture")
+ branch, repository, architecture := ctx.PathParam("branch"), ctx.PathParam("repository"), ctx.PathParam("architecture")
pfs, _, err := packages_model.SearchFiles(ctx, &packages_model.PackageFileSearchOptions{
OwnerID: ctx.Package.Owner.ID,
PackageType: packages_model.TypeAlpine,
- Query: ctx.Params("filename"),
+ Query: ctx.PathParam("filename"),
CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, architecture),
})
if err != nil {
diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go
index 5e3cbac8f9..0f42e8f59e 100644
--- a/routers/api/packages/api.go
+++ b/routers/api/packages/api.go
@@ -74,7 +74,7 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
}
}
-func verifyAuth(r *web.Route, authMethods []auth.Method) {
+func verifyAuth(r *web.Router, authMethods []auth.Method) {
if setting.Service.EnableReverseProxyAuth {
authMethods = append(authMethods, &auth.ReverseProxy{})
}
@@ -94,8 +94,8 @@ func verifyAuth(r *web.Route, authMethods []auth.Method) {
// CommonRoutes provide endpoints for most package managers (except containers - see below)
// These are mounted on `/api/packages` (not `/api/v1/packages`)
-func CommonRoutes() *web.Route {
- r := web.NewRoute()
+func CommonRoutes() *web.Router {
+ r := web.NewRouter()
r.Use(context.PackageContexter())
@@ -264,15 +264,15 @@ func CommonRoutes() *web.Route {
)
r.Get("/*", func(ctx *context.Context) {
- m := downloadPattern.FindStringSubmatch(ctx.Params("*"))
+ m := downloadPattern.FindStringSubmatch(ctx.PathParam("*"))
if len(m) == 0 {
ctx.Status(http.StatusNotFound)
return
}
- ctx.SetParams("channel", strings.TrimSuffix(m[1], "/"))
- ctx.SetParams("architecture", m[2])
- ctx.SetParams("filename", m[3])
+ ctx.SetPathParam("channel", strings.TrimSuffix(m[1], "/"))
+ ctx.SetPathParam("architecture", m[2])
+ ctx.SetPathParam("filename", m[3])
switch m[3] {
case "repodata.json", "repodata.json.bz2", "current_repodata.json", "current_repodata.json.bz2":
@@ -282,14 +282,14 @@ func CommonRoutes() *web.Route {
}
})
r.Put("/*", reqPackageAccess(perm.AccessModeWrite), func(ctx *context.Context) {
- m := uploadPattern.FindStringSubmatch(ctx.Params("*"))
+ m := uploadPattern.FindStringSubmatch(ctx.PathParam("*"))
if len(m) == 0 {
ctx.Status(http.StatusNotFound)
return
}
- ctx.SetParams("channel", strings.TrimSuffix(m[1], "/"))
- ctx.SetParams("filename", m[2])
+ ctx.SetPathParam("channel", strings.TrimSuffix(m[1], "/"))
+ ctx.SetPathParam("filename", m[2])
conda.UploadPackageFile(ctx)
})
@@ -339,11 +339,11 @@ func CommonRoutes() *web.Route {
// Manual mapping of routes because the package name contains slashes which chi does not support
// https://go.dev/ref/mod#goproxy-protocol
r.Get("/*", func(ctx *context.Context) {
- path := ctx.Params("*")
+ path := ctx.PathParam("*")
if strings.HasSuffix(path, "/@latest") {
- ctx.SetParams("name", path[:len(path)-len("/@latest")])
- ctx.SetParams("version", "latest")
+ ctx.SetPathParam("name", path[:len(path)-len("/@latest")])
+ ctx.SetPathParam("version", "latest")
goproxy.PackageVersionMetadata(ctx)
return
@@ -355,7 +355,7 @@ func CommonRoutes() *web.Route {
return
}
- ctx.SetParams("name", parts[0])
+ ctx.SetPathParam("name", parts[0])
// /@v/list
if parts[1] == "list" {
@@ -365,21 +365,21 @@ func CommonRoutes() *web.Route {
// /@v/.zip
if strings.HasSuffix(parts[1], ".zip") {
- ctx.SetParams("version", parts[1][:len(parts[1])-len(".zip")])
+ ctx.SetPathParam("version", parts[1][:len(parts[1])-len(".zip")])
goproxy.DownloadPackageFile(ctx)
return
}
// /@v/.info
if strings.HasSuffix(parts[1], ".info") {
- ctx.SetParams("version", parts[1][:len(parts[1])-len(".info")])
+ ctx.SetPathParam("version", parts[1][:len(parts[1])-len(".info")])
goproxy.PackageVersionMetadata(ctx)
return
}
// /@v/.mod
if strings.HasSuffix(parts[1], ".mod") {
- ctx.SetParams("version", parts[1][:len(parts[1])-len(".mod")])
+ ctx.SetPathParam("version", parts[1][:len(parts[1])-len(".mod")])
goproxy.PackageVersionGoModContent(ctx)
return
@@ -525,7 +525,7 @@ func CommonRoutes() *web.Route {
)
r.Methods("HEAD,GET,PUT,DELETE", "*", func(ctx *context.Context) {
- path := ctx.Params("*")
+ path := ctx.PathParam("*")
isHead := ctx.Req.Method == "HEAD"
isGetHead := ctx.Req.Method == "HEAD" || ctx.Req.Method == "GET"
isPut := ctx.Req.Method == "PUT"
@@ -533,15 +533,15 @@ func CommonRoutes() *web.Route {
m := repoPattern.FindStringSubmatch(path)
if len(m) == 2 && isGetHead {
- ctx.SetParams("group", strings.Trim(m[1], "/"))
+ ctx.SetPathParam("group", strings.Trim(m[1], "/"))
rpm.GetRepositoryConfig(ctx)
return
}
m = repoFilePattern.FindStringSubmatch(path)
if len(m) == 3 && isGetHead {
- ctx.SetParams("group", strings.Trim(m[1], "/"))
- ctx.SetParams("filename", m[2])
+ ctx.SetPathParam("group", strings.Trim(m[1], "/"))
+ ctx.SetPathParam("filename", m[2])
if isHead {
rpm.CheckRepositoryFileExistence(ctx)
} else {
@@ -556,17 +556,17 @@ func CommonRoutes() *web.Route {
if ctx.Written() {
return
}
- ctx.SetParams("group", strings.Trim(m[1], "/"))
+ ctx.SetPathParam("group", strings.Trim(m[1], "/"))
rpm.UploadPackageFile(ctx)
return
}
m = filePattern.FindStringSubmatch(path)
if len(m) == 6 && (isGetHead || isDelete) {
- ctx.SetParams("group", strings.Trim(m[1], "/"))
- ctx.SetParams("name", m[2])
- ctx.SetParams("version", m[3])
- ctx.SetParams("architecture", m[4])
+ ctx.SetPathParam("group", strings.Trim(m[1], "/"))
+ ctx.SetPathParam("name", m[2])
+ ctx.SetPathParam("version", m[3])
+ ctx.SetPathParam("architecture", m[4])
if isGetHead {
rpm.DownloadPackageFile(ctx)
} else {
@@ -588,6 +588,8 @@ func CommonRoutes() *web.Route {
r.Get("/prerelease_specs.4.8.gz", rubygems.EnumeratePackagesPreRelease)
r.Get("/quick/Marshal.4.8/{filename}", rubygems.ServePackageSpecification)
r.Get("/gems/{filename}", rubygems.DownloadPackageFile)
+ r.Get("/info/{packagename}", rubygems.GetPackageInfo)
+ r.Get("/versions", rubygems.GetAllPackagesVersions)
r.Group("/api/v1/gems", func() {
r.Post("/", rubygems.UploadPackageFile)
r.Delete("/yank", rubygems.DeletePackage)
@@ -605,13 +607,13 @@ func CommonRoutes() *web.Route {
r.Get("", func(ctx *context.Context) {
// Can't use normal routes here: https://github.com/go-chi/chi/issues/781
- version := ctx.Params("version")
+ version := ctx.PathParam("version")
if strings.HasSuffix(version, ".zip") {
swift.CheckAcceptMediaType(swift.AcceptZip)(ctx)
if ctx.Written() {
return
}
- ctx.SetParams("version", version[:len(version)-4])
+ ctx.SetPathParam("version", version[:len(version)-4])
swift.DownloadPackageFile(ctx)
} else {
swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx)
@@ -619,7 +621,7 @@ func CommonRoutes() *web.Route {
return
}
if strings.HasSuffix(version, ".json") {
- ctx.SetParams("version", version[:len(version)-5])
+ ctx.SetPathParam("version", version[:len(version)-5])
}
swift.PackageVersionMetadata(ctx)
}
@@ -649,8 +651,8 @@ func CommonRoutes() *web.Route {
// ContainerRoutes provides endpoints that implement the OCI API to serve containers
// These have to be mounted on `/v2/...` to comply with the OCI spec:
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md
-func ContainerRoutes() *web.Route {
- r := web.NewRoute()
+func ContainerRoutes() *web.Router {
+ r := web.NewRouter()
r.Use(context.PackageContexter())
@@ -698,7 +700,7 @@ func ContainerRoutes() *web.Route {
// Manual mapping of routes because {image} can contain slashes which chi does not support
r.Methods("HEAD,GET,POST,PUT,PATCH,DELETE", "/*", func(ctx *context.Context) {
- path := ctx.Params("*")
+ path := ctx.PathParam("*")
isHead := ctx.Req.Method == "HEAD"
isGet := ctx.Req.Method == "GET"
isPost := ctx.Req.Method == "POST"
@@ -712,7 +714,7 @@ func ContainerRoutes() *web.Route {
return
}
- ctx.SetParams("image", path[:len(path)-14])
+ ctx.SetPathParam("image", path[:len(path)-14])
container.VerifyImageName(ctx)
if ctx.Written() {
return
@@ -722,7 +724,7 @@ func ContainerRoutes() *web.Route {
return
}
if isGet && strings.HasSuffix(path, "/tags/list") {
- ctx.SetParams("image", path[:len(path)-10])
+ ctx.SetPathParam("image", path[:len(path)-10])
container.VerifyImageName(ctx)
if ctx.Written() {
return
@@ -739,13 +741,13 @@ func ContainerRoutes() *web.Route {
return
}
- ctx.SetParams("image", m[1])
+ ctx.SetPathParam("image", m[1])
container.VerifyImageName(ctx)
if ctx.Written() {
return
}
- ctx.SetParams("uuid", m[2])
+ ctx.SetPathParam("uuid", m[2])
if isGet {
container.GetUploadBlob(ctx)
@@ -760,13 +762,13 @@ func ContainerRoutes() *web.Route {
}
m = blobsPattern.FindStringSubmatch(path)
if len(m) == 3 && (isHead || isGet || isDelete) {
- ctx.SetParams("image", m[1])
+ ctx.SetPathParam("image", m[1])
container.VerifyImageName(ctx)
if ctx.Written() {
return
}
- ctx.SetParams("digest", m[2])
+ ctx.SetPathParam("digest", m[2])
if isHead {
container.HeadBlob(ctx)
@@ -783,13 +785,13 @@ func ContainerRoutes() *web.Route {
}
m = manifestsPattern.FindStringSubmatch(path)
if len(m) == 3 && (isHead || isGet || isPut || isDelete) {
- ctx.SetParams("image", m[1])
+ ctx.SetPathParam("image", m[1])
container.VerifyImageName(ctx)
if ctx.Written() {
return
}
- ctx.SetParams("reference", m[2])
+ ctx.SetPathParam("reference", m[2])
if isHead {
container.HeadManifest(ctx)
diff --git a/routers/api/packages/cargo/cargo.go b/routers/api/packages/cargo/cargo.go
index 140e532efd..3d8407e6b6 100644
--- a/routers/api/packages/cargo/cargo.go
+++ b/routers/api/packages/cargo/cargo.go
@@ -55,7 +55,7 @@ func RepositoryConfig(ctx *context.Context) {
}
func EnumeratePackageVersions(ctx *context.Context) {
- p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.TypeCargo, ctx.Params("package"))
+ p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.TypeCargo, ctx.PathParam("package"))
if err != nil {
if errors.Is(err, util.ErrNotExist) {
apiError(ctx, http.StatusNotFound, err)
@@ -173,11 +173,11 @@ func DownloadPackageFile(ctx *context.Context) {
&packages_service.PackageInfo{
Owner: ctx.Package.Owner,
PackageType: packages_model.TypeCargo,
- Name: ctx.Params("package"),
- Version: ctx.Params("version"),
+ Name: ctx.PathParam("package"),
+ Version: ctx.PathParam("version"),
},
&packages_service.PackageFileInfo{
- Filename: strings.ToLower(fmt.Sprintf("%s-%s.crate", ctx.Params("package"), ctx.Params("version"))),
+ Filename: strings.ToLower(fmt.Sprintf("%s-%s.crate", ctx.PathParam("package"), ctx.PathParam("version"))),
},
)
if err != nil {
@@ -274,7 +274,7 @@ func UnyankPackage(ctx *context.Context) {
}
func yankPackage(ctx *context.Context, yank bool) {
- pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeCargo, ctx.Params("package"), ctx.Params("version"))
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeCargo, ctx.PathParam("package"), ctx.PathParam("version"))
if err != nil {
if err == packages_model.ErrPackageNotExist {
apiError(ctx, http.StatusNotFound, err)
diff --git a/routers/api/packages/chef/chef.go b/routers/api/packages/chef/chef.go
index b49f4e9d0a..b3cdf12697 100644
--- a/routers/api/packages/chef/chef.go
+++ b/routers/api/packages/chef/chef.go
@@ -150,7 +150,7 @@ func EnumeratePackages(ctx *context.Context) {
// https://github.com/chef/chef/blob/main/knife/lib/chef/knife/supermarket_show.rb
func PackageMetadata(ctx *context.Context) {
- packageName := ctx.Params("name")
+ packageName := ctx.PathParam("name")
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, packageName)
if err != nil {
@@ -211,8 +211,8 @@ func PackageMetadata(ctx *context.Context) {
// https://github.com/chef/chef/blob/main/knife/lib/chef/knife/supermarket_show.rb
func PackageVersionMetadata(ctx *context.Context) {
- packageName := ctx.Params("name")
- packageVersion := strings.ReplaceAll(ctx.Params("version"), "_", ".") // Chef calls this endpoint with "_" instead of "."?!
+ packageName := ctx.PathParam("name")
+ packageVersion := strings.ReplaceAll(ctx.PathParam("version"), "_", ".") // Chef calls this endpoint with "_" instead of "."?!
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, packageName, packageVersion)
if err != nil {
@@ -325,7 +325,7 @@ func UploadPackage(ctx *context.Context) {
// https://github.com/chef/chef/blob/main/knife/lib/chef/knife/supermarket_download.rb
func DownloadPackage(ctx *context.Context) {
- pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, ctx.Params("name"), ctx.Params("version"))
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, ctx.PathParam("name"), ctx.PathParam("version"))
if err != nil {
if err == packages_model.ErrPackageNotExist {
apiError(ctx, http.StatusNotFound, err)
@@ -354,8 +354,8 @@ func DownloadPackage(ctx *context.Context) {
// https://github.com/chef/chef/blob/main/knife/lib/chef/knife/supermarket_unshare.rb
func DeletePackageVersion(ctx *context.Context) {
- packageName := ctx.Params("name")
- packageVersion := ctx.Params("version")
+ packageName := ctx.PathParam("name")
+ packageVersion := ctx.PathParam("version")
err := packages_service.RemovePackageVersionByNameAndVersion(
ctx,
@@ -381,7 +381,7 @@ func DeletePackageVersion(ctx *context.Context) {
// https://github.com/chef/chef/blob/main/knife/lib/chef/knife/supermarket_unshare.rb
func DeletePackage(ctx *context.Context) {
- pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, ctx.Params("name"))
+ pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, ctx.PathParam("name"))
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go
index a045da40de..40f72f6484 100644
--- a/routers/api/packages/composer/composer.go
+++ b/routers/api/packages/composer/composer.go
@@ -134,8 +134,8 @@ func EnumeratePackages(ctx *context.Context) {
// PackageMetadata returns the metadata for a single package
// https://packagist.org/apidoc#get-package-data
func PackageMetadata(ctx *context.Context) {
- vendorName := ctx.Params("vendorname")
- projectName := ctx.Params("projectname")
+ vendorName := ctx.PathParam("vendorname")
+ projectName := ctx.PathParam("projectname")
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeComposer, vendorName+"/"+projectName)
if err != nil {
@@ -168,11 +168,11 @@ func DownloadPackageFile(ctx *context.Context) {
&packages_service.PackageInfo{
Owner: ctx.Package.Owner,
PackageType: packages_model.TypeComposer,
- Name: ctx.Params("package"),
- Version: ctx.Params("version"),
+ Name: ctx.PathParam("package"),
+ Version: ctx.PathParam("version"),
},
&packages_service.PackageFileInfo{
- Filename: ctx.Params("filename"),
+ Filename: ctx.PathParam("filename"),
},
)
if err != nil {
diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go
index 07ea3eda34..7afca2fab1 100644
--- a/routers/api/packages/conan/conan.go
+++ b/routers/api/packages/conan/conan.go
@@ -72,11 +72,11 @@ func baseURL(ctx *context.Context) string {
// ExtractPathParameters is a middleware to extract common parameters from path
func ExtractPathParameters(ctx *context.Context) {
rref, err := conan_module.NewRecipeReference(
- ctx.Params("name"),
- ctx.Params("version"),
- ctx.Params("user"),
- ctx.Params("channel"),
- ctx.Params("recipe_revision"),
+ ctx.PathParam("name"),
+ ctx.PathParam("version"),
+ ctx.PathParam("user"),
+ ctx.PathParam("channel"),
+ ctx.PathParam("recipe_revision"),
)
if err != nil {
apiError(ctx, http.StatusBadRequest, err)
@@ -85,14 +85,14 @@ func ExtractPathParameters(ctx *context.Context) {
ctx.Data[recipeReferenceKey] = rref
- reference := ctx.Params("package_reference")
+ reference := ctx.PathParam("package_reference")
var pref *conan_module.PackageReference
if reference != "" {
pref, err = conan_module.NewPackageReference(
rref,
reference,
- ctx.Params("package_revision"),
+ ctx.PathParam("package_revision"),
)
if err != nil {
apiError(ctx, http.StatusBadRequest, err)
@@ -304,7 +304,7 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
pref := ctx.Data[packageReferenceKey].(*conan_module.PackageReference)
- filename := ctx.Params("filename")
+ filename := ctx.PathParam("filename")
if !fileFilter.Contains(filename) {
apiError(ctx, http.StatusBadRequest, nil)
return
@@ -444,7 +444,7 @@ func DownloadPackageFile(ctx *context.Context) {
func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKey string) {
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
- filename := ctx.Params("filename")
+ filename := ctx.PathParam("filename")
if !fileFilter.Contains(filename) {
apiError(ctx, http.StatusBadRequest, nil)
return
diff --git a/routers/api/packages/conda/conda.go b/routers/api/packages/conda/conda.go
index c7e4544d52..7a46681235 100644
--- a/routers/api/packages/conda/conda.go
+++ b/routers/api/packages/conda/conda.go
@@ -66,7 +66,7 @@ func EnumeratePackages(ctx *context.Context) {
repoData := &RepoData{
Info: Info{
- Subdir: ctx.Params("architecture"),
+ Subdir: ctx.PathParam("architecture"),
},
Packages: make(map[string]*PackageInfo),
PackagesConda: make(map[string]*PackageInfo),
@@ -75,7 +75,7 @@ func EnumeratePackages(ctx *context.Context) {
pfs, err := conda_model.SearchFiles(ctx, &conda_model.FileSearchOptions{
OwnerID: ctx.Package.Owner.ID,
- Channel: ctx.Params("channel"),
+ Channel: ctx.PathParam("channel"),
Subdir: repoData.Info.Subdir,
})
if err != nil {
@@ -151,7 +151,7 @@ func EnumeratePackages(ctx *context.Context) {
var w io.Writer = resp
- if strings.HasSuffix(ctx.Params("filename"), ".json") {
+ if strings.HasSuffix(ctx.PathParam("filename"), ".json") {
resp.Header().Set("Content-Type", "application/json")
} else {
resp.Header().Set("Content-Type", "application/x-bzip2")
@@ -191,7 +191,7 @@ func UploadPackageFile(ctx *context.Context) {
defer buf.Close()
var pck *conda_module.Package
- if strings.HasSuffix(strings.ToLower(ctx.Params("filename")), ".tar.bz2") {
+ if strings.HasSuffix(strings.ToLower(ctx.PathParam("filename")), ".tar.bz2") {
pck, err = conda_module.ParsePackageBZ2(buf)
} else {
pck, err = conda_module.ParsePackageConda(buf, buf.Size())
@@ -212,7 +212,7 @@ func UploadPackageFile(ctx *context.Context) {
fullName := pck.Name
- channel := ctx.Params("channel")
+ channel := ctx.PathParam("channel")
if channel != "" {
fullName = channel + "/" + pck.Name
}
@@ -277,9 +277,9 @@ func UploadPackageFile(ctx *context.Context) {
func DownloadPackageFile(ctx *context.Context) {
pfs, err := conda_model.SearchFiles(ctx, &conda_model.FileSearchOptions{
OwnerID: ctx.Package.Owner.ID,
- Channel: ctx.Params("channel"),
- Subdir: ctx.Params("architecture"),
- Filename: ctx.Params("filename"),
+ Channel: ctx.PathParam("channel"),
+ Subdir: ctx.PathParam("architecture"),
+ Filename: ctx.PathParam("filename"),
})
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go
index b0c4458d51..74a3295f09 100644
--- a/routers/api/packages/container/container.go
+++ b/routers/api/packages/container/container.go
@@ -117,7 +117,7 @@ func apiErrorDefined(ctx *context.Context, err *namedError) {
func apiUnauthorizedError(ctx *context.Context) {
// container registry requires that the "/v2" must be in the root, so the sub-path in AppURL should be removed
- realmURL := strings.TrimSuffix(httplib.GuessCurrentAppURL(ctx), setting.AppSubURL+"/") + "/v2/token"
+ realmURL := httplib.GuessCurrentHostURL(ctx) + "/v2/token"
ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+realmURL+`",service="container_registry",scope="*"`)
apiErrorDefined(ctx, errUnauthorized)
}
@@ -131,7 +131,7 @@ func ReqContainerAccess(ctx *context.Context) {
// VerifyImageName is a middleware which checks if the image name is allowed
func VerifyImageName(ctx *context.Context) {
- if !imageNamePattern.MatchString(ctx.Params("image")) {
+ if !imageNamePattern.MatchString(ctx.PathParam("image")) {
apiErrorDefined(ctx, errNameInvalid)
}
}
@@ -216,7 +216,7 @@ func GetRepositoryList(ctx *context.Context) {
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
func InitiateUploadBlob(ctx *context.Context) {
- image := ctx.Params("image")
+ image := ctx.PathParam("image")
mount := ctx.FormTrim("mount")
from := ctx.FormTrim("from")
@@ -305,7 +305,7 @@ func InitiateUploadBlob(ctx *context.Context) {
// https://docs.docker.com/registry/spec/api/#get-blob-upload
func GetUploadBlob(ctx *context.Context) {
- uuid := ctx.Params("uuid")
+ uuid := ctx.PathParam("uuid")
upload, err := packages_model.GetBlobUploadByID(ctx, uuid)
if err != nil {
@@ -326,9 +326,9 @@ func GetUploadBlob(ctx *context.Context) {
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
func UploadBlob(ctx *context.Context) {
- image := ctx.Params("image")
+ image := ctx.PathParam("image")
- uploader, err := container_service.NewBlobUploader(ctx, ctx.Params("uuid"))
+ uploader, err := container_service.NewBlobUploader(ctx, ctx.PathParam("uuid"))
if err != nil {
if err == packages_model.ErrPackageBlobUploadNotExist {
apiErrorDefined(ctx, errBlobUploadUnknown)
@@ -371,7 +371,7 @@ func UploadBlob(ctx *context.Context) {
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
func EndUploadBlob(ctx *context.Context) {
- image := ctx.Params("image")
+ image := ctx.PathParam("image")
digest := ctx.FormTrim("digest")
if digest == "" {
@@ -379,7 +379,7 @@ func EndUploadBlob(ctx *context.Context) {
return
}
- uploader, err := container_service.NewBlobUploader(ctx, ctx.Params("uuid"))
+ uploader, err := container_service.NewBlobUploader(ctx, ctx.PathParam("uuid"))
if err != nil {
if err == packages_model.ErrPackageBlobUploadNotExist {
apiErrorDefined(ctx, errBlobUploadUnknown)
@@ -446,7 +446,7 @@ func EndUploadBlob(ctx *context.Context) {
// https://docs.docker.com/registry/spec/api/#delete-blob-upload
func CancelUploadBlob(ctx *context.Context) {
- uuid := ctx.Params("uuid")
+ uuid := ctx.PathParam("uuid")
_, err := packages_model.GetBlobUploadByID(ctx, uuid)
if err != nil {
@@ -469,7 +469,7 @@ func CancelUploadBlob(ctx *context.Context) {
}
func getBlobFromContext(ctx *context.Context) (*packages_model.PackageFileDescriptor, error) {
- d := ctx.Params("digest")
+ d := ctx.PathParam("digest")
if digest.Digest(d).Validate() != nil {
return nil, container_model.ErrContainerBlobNotExist
@@ -477,7 +477,7 @@ func getBlobFromContext(ctx *context.Context) (*packages_model.PackageFileDescri
return workaroundGetContainerBlob(ctx, &container_model.BlobSearchOptions{
OwnerID: ctx.Package.Owner.ID,
- Image: ctx.Params("image"),
+ Image: ctx.PathParam("image"),
Digest: d,
})
}
@@ -518,14 +518,14 @@ func GetBlob(ctx *context.Context) {
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#deleting-blobs
func DeleteBlob(ctx *context.Context) {
- d := ctx.Params("digest")
+ d := ctx.PathParam("digest")
if digest.Digest(d).Validate() != nil {
apiErrorDefined(ctx, errBlobUnknown)
return
}
- if err := deleteBlob(ctx, ctx.Package.Owner.ID, ctx.Params("image"), d); err != nil {
+ if err := deleteBlob(ctx, ctx.Package.Owner.ID, ctx.PathParam("image"), d); err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
@@ -537,13 +537,13 @@ func DeleteBlob(ctx *context.Context) {
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-manifests
func UploadManifest(ctx *context.Context) {
- reference := ctx.Params("reference")
+ reference := ctx.PathParam("reference")
mci := &manifestCreationInfo{
MediaType: ctx.Req.Header.Get("Content-Type"),
Owner: ctx.Package.Owner,
Creator: ctx.Doer,
- Image: ctx.Params("image"),
+ Image: ctx.PathParam("image"),
Reference: reference,
IsTagged: digest.Digest(reference).Validate() != nil,
}
@@ -592,11 +592,11 @@ func UploadManifest(ctx *context.Context) {
}
func getBlobSearchOptionsFromContext(ctx *context.Context) (*container_model.BlobSearchOptions, error) {
- reference := ctx.Params("reference")
+ reference := ctx.PathParam("reference")
opts := &container_model.BlobSearchOptions{
OwnerID: ctx.Package.Owner.ID,
- Image: ctx.Params("image"),
+ Image: ctx.PathParam("image"),
IsManifest: true,
}
@@ -719,7 +719,7 @@ func serveBlob(ctx *context.Context, pfd *packages_model.PackageFileDescriptor)
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#content-discovery
func GetTagList(ctx *context.Context) {
- image := ctx.Params("image")
+ image := ctx.PathParam("image")
if _, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.TypeContainer, image); err != nil {
if err == packages_model.ErrPackageNotExist {
diff --git a/routers/api/packages/cran/cran.go b/routers/api/packages/cran/cran.go
index f1d616724a..8a20072cb6 100644
--- a/routers/api/packages/cran/cran.go
+++ b/routers/api/packages/cran/cran.go
@@ -28,18 +28,18 @@ func apiError(ctx *context.Context, status int, obj any) {
}
func EnumerateSourcePackages(ctx *context.Context) {
- enumeratePackages(ctx, ctx.Params("format"), &cran_model.SearchOptions{
+ enumeratePackages(ctx, ctx.PathParam("format"), &cran_model.SearchOptions{
OwnerID: ctx.Package.Owner.ID,
FileType: cran_module.TypeSource,
})
}
func EnumerateBinaryPackages(ctx *context.Context) {
- enumeratePackages(ctx, ctx.Params("format"), &cran_model.SearchOptions{
+ enumeratePackages(ctx, ctx.PathParam("format"), &cran_model.SearchOptions{
OwnerID: ctx.Package.Owner.ID,
FileType: cran_module.TypeBinary,
- Platform: ctx.Params("platform"),
- RVersion: ctx.Params("rversion"),
+ Platform: ctx.PathParam("platform"),
+ RVersion: ctx.PathParam("rversion"),
})
}
@@ -225,7 +225,7 @@ func DownloadSourcePackageFile(ctx *context.Context) {
downloadPackageFile(ctx, &cran_model.SearchOptions{
OwnerID: ctx.Package.Owner.ID,
FileType: cran_module.TypeSource,
- Filename: ctx.Params("filename"),
+ Filename: ctx.PathParam("filename"),
})
}
@@ -233,9 +233,9 @@ func DownloadBinaryPackageFile(ctx *context.Context) {
downloadPackageFile(ctx, &cran_model.SearchOptions{
OwnerID: ctx.Package.Owner.ID,
FileType: cran_module.TypeBinary,
- Platform: ctx.Params("platform"),
- RVersion: ctx.Params("rversion"),
- Filename: ctx.Params("filename"),
+ Platform: ctx.PathParam("platform"),
+ RVersion: ctx.PathParam("rversion"),
+ Filename: ctx.PathParam("filename"),
})
}
diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go
index 8c05476cbc..162122ccbd 100644
--- a/routers/api/packages/debian/debian.go
+++ b/routers/api/packages/debian/debian.go
@@ -51,10 +51,10 @@ func GetRepositoryFile(ctx *context.Context) {
return
}
- key := ctx.Params("distribution")
+ key := ctx.PathParam("distribution")
- component := ctx.Params("component")
- architecture := strings.TrimPrefix(ctx.Params("architecture"), "binary-")
+ component := ctx.PathParam("component")
+ architecture := strings.TrimPrefix(ctx.PathParam("architecture"), "binary-")
if component != "" && architecture != "" {
key += "|" + component + "|" + architecture
}
@@ -63,7 +63,7 @@ func GetRepositoryFile(ctx *context.Context) {
ctx,
pv,
&packages_service.PackageFileInfo{
- Filename: ctx.Params("filename"),
+ Filename: ctx.PathParam("filename"),
CompositeKey: key,
},
)
@@ -87,14 +87,14 @@ func GetRepositoryFileByHash(ctx *context.Context) {
return
}
- algorithm := strings.ToLower(ctx.Params("algorithm"))
+ algorithm := strings.ToLower(ctx.PathParam("algorithm"))
if algorithm == "md5sum" {
algorithm = "md5"
}
pfs, _, err := packages_model.SearchFiles(ctx, &packages_model.PackageFileSearchOptions{
VersionID: pv.ID,
- Hash: strings.ToLower(ctx.Params("hash")),
+ Hash: strings.ToLower(ctx.PathParam("hash")),
HashAlgorithm: algorithm,
})
if err != nil {
@@ -120,8 +120,8 @@ func GetRepositoryFileByHash(ctx *context.Context) {
}
func UploadPackageFile(ctx *context.Context) {
- distribution := strings.TrimSpace(ctx.Params("distribution"))
- component := strings.TrimSpace(ctx.Params("component"))
+ distribution := strings.TrimSpace(ctx.PathParam("distribution"))
+ component := strings.TrimSpace(ctx.PathParam("component"))
if distribution == "" || component == "" {
apiError(ctx, http.StatusBadRequest, "invalid distribution or component")
return
@@ -207,8 +207,8 @@ func UploadPackageFile(ctx *context.Context) {
}
func DownloadPackageFile(ctx *context.Context) {
- name := ctx.Params("name")
- version := ctx.Params("version")
+ name := ctx.PathParam("name")
+ version := ctx.PathParam("version")
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
ctx,
@@ -219,8 +219,8 @@ func DownloadPackageFile(ctx *context.Context) {
Version: version,
},
&packages_service.PackageFileInfo{
- Filename: fmt.Sprintf("%s_%s_%s.deb", name, version, ctx.Params("architecture")),
- CompositeKey: fmt.Sprintf("%s|%s", ctx.Params("distribution"), ctx.Params("component")),
+ Filename: fmt.Sprintf("%s_%s_%s.deb", name, version, ctx.PathParam("architecture")),
+ CompositeKey: fmt.Sprintf("%s|%s", ctx.PathParam("distribution"), ctx.PathParam("component")),
},
)
if err != nil {
@@ -240,11 +240,11 @@ func DownloadPackageFile(ctx *context.Context) {
}
func DeletePackageFile(ctx *context.Context) {
- distribution := ctx.Params("distribution")
- component := ctx.Params("component")
- name := ctx.Params("name")
- version := ctx.Params("version")
- architecture := ctx.Params("architecture")
+ distribution := ctx.PathParam("distribution")
+ component := ctx.PathParam("component")
+ name := ctx.PathParam("name")
+ version := ctx.PathParam("version")
+ architecture := ctx.PathParam("architecture")
owner := ctx.Package.Owner
diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go
index e66f3ee676..868caf9cf0 100644
--- a/routers/api/packages/generic/generic.go
+++ b/routers/api/packages/generic/generic.go
@@ -36,11 +36,11 @@ func DownloadPackageFile(ctx *context.Context) {
&packages_service.PackageInfo{
Owner: ctx.Package.Owner,
PackageType: packages_model.TypeGeneric,
- Name: ctx.Params("packagename"),
- Version: ctx.Params("packageversion"),
+ Name: ctx.PathParam("packagename"),
+ Version: ctx.PathParam("packageversion"),
},
&packages_service.PackageFileInfo{
- Filename: ctx.Params("filename"),
+ Filename: ctx.PathParam("filename"),
},
)
if err != nil {
@@ -71,8 +71,8 @@ func isValidFileName(filename string) bool {
// UploadPackage uploads the specific generic package.
// Duplicated packages get rejected.
func UploadPackage(ctx *context.Context) {
- packageName := ctx.Params("packagename")
- filename := ctx.Params("filename")
+ packageName := ctx.PathParam("packagename")
+ filename := ctx.PathParam("filename")
if !isValidPackageName(packageName) {
apiError(ctx, http.StatusBadRequest, errors.New("invalid package name"))
@@ -84,7 +84,7 @@ func UploadPackage(ctx *context.Context) {
return
}
- packageVersion := ctx.Params("packageversion")
+ packageVersion := ctx.PathParam("packageversion")
if packageVersion != strings.TrimSpace(packageVersion) {
apiError(ctx, http.StatusBadRequest, errors.New("invalid package version"))
return
@@ -150,8 +150,8 @@ func DeletePackage(ctx *context.Context) {
&packages_service.PackageInfo{
Owner: ctx.Package.Owner,
PackageType: packages_model.TypeGeneric,
- Name: ctx.Params("packagename"),
- Version: ctx.Params("packageversion"),
+ Name: ctx.PathParam("packagename"),
+ Version: ctx.PathParam("packageversion"),
},
)
if err != nil {
@@ -169,12 +169,12 @@ func DeletePackage(ctx *context.Context) {
// DeletePackageFile deletes the specific file of a generic package.
func DeletePackageFile(ctx *context.Context) {
pv, pf, err := func() (*packages_model.PackageVersion, *packages_model.PackageFile, error) {
- pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeGeneric, ctx.Params("packagename"), ctx.Params("packageversion"))
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeGeneric, ctx.PathParam("packagename"), ctx.PathParam("packageversion"))
if err != nil {
return nil, nil, err
}
- pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, ctx.Params("filename"), packages_model.EmptyFileKey)
+ pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, ctx.PathParam("filename"), packages_model.EmptyFileKey)
if err != nil {
return nil, nil, err
}
diff --git a/routers/api/packages/goproxy/goproxy.go b/routers/api/packages/goproxy/goproxy.go
index 56a07dbd43..bde29df739 100644
--- a/routers/api/packages/goproxy/goproxy.go
+++ b/routers/api/packages/goproxy/goproxy.go
@@ -28,7 +28,7 @@ func apiError(ctx *context.Context, status int, obj any) {
}
func EnumeratePackageVersions(ctx *context.Context) {
- pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeGo, ctx.Params("name"))
+ pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeGo, ctx.PathParam("name"))
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
@@ -50,7 +50,7 @@ func EnumeratePackageVersions(ctx *context.Context) {
}
func PackageVersionMetadata(ctx *context.Context) {
- pv, err := resolvePackage(ctx, ctx.Package.Owner.ID, ctx.Params("name"), ctx.Params("version"))
+ pv, err := resolvePackage(ctx, ctx.Package.Owner.ID, ctx.PathParam("name"), ctx.PathParam("version"))
if err != nil {
if errors.Is(err, util.ErrNotExist) {
apiError(ctx, http.StatusNotFound, err)
@@ -70,7 +70,7 @@ func PackageVersionMetadata(ctx *context.Context) {
}
func PackageVersionGoModContent(ctx *context.Context) {
- pv, err := resolvePackage(ctx, ctx.Package.Owner.ID, ctx.Params("name"), ctx.Params("version"))
+ pv, err := resolvePackage(ctx, ctx.Package.Owner.ID, ctx.PathParam("name"), ctx.PathParam("version"))
if err != nil {
if errors.Is(err, util.ErrNotExist) {
apiError(ctx, http.StatusNotFound, err)
@@ -90,7 +90,7 @@ func PackageVersionGoModContent(ctx *context.Context) {
}
func DownloadPackageFile(ctx *context.Context) {
- pv, err := resolvePackage(ctx, ctx.Package.Owner.ID, ctx.Params("name"), ctx.Params("version"))
+ pv, err := resolvePackage(ctx, ctx.Package.Owner.ID, ctx.PathParam("name"), ctx.PathParam("version"))
if err != nil {
if errors.Is(err, util.ErrNotExist) {
apiError(ctx, http.StatusNotFound, err)
diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go
index efdb83ec0e..cb30a20074 100644
--- a/routers/api/packages/helm/helm.go
+++ b/routers/api/packages/helm/helm.go
@@ -101,14 +101,14 @@ func Index(ctx *context.Context) {
// DownloadPackageFile serves the content of a package
func DownloadPackageFile(ctx *context.Context) {
- filename := ctx.Params("filename")
+ filename := ctx.PathParam("filename")
pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
OwnerID: ctx.Package.Owner.ID,
Type: packages_model.TypeHelm,
Name: packages_model.SearchValue{
ExactMatch: true,
- Value: ctx.Params("package"),
+ Value: ctx.PathParam("package"),
},
HasFileWithName: filename,
IsInternal: optional.Some(false),
diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go
index cb15eae682..1486e83c57 100644
--- a/routers/api/packages/maven/maven.go
+++ b/routers/api/packages/maven/maven.go
@@ -385,7 +385,7 @@ type parameters struct {
}
func extractPathParameters(ctx *context.Context) (parameters, error) {
- parts := strings.Split(ctx.Params("*"), "/")
+ parts := strings.Split(ctx.PathParam("*"), "/")
p := parameters{
Filename: parts[len(parts)-1],
diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go
index 84acfffae2..284723e0d7 100644
--- a/routers/api/packages/npm/npm.go
+++ b/routers/api/packages/npm/npm.go
@@ -43,8 +43,8 @@ func apiError(ctx *context.Context, status int, obj any) {
// packageNameFromParams gets the package name from the url parameters
// Variations: /name/, /@scope/name/, /@scope%2Fname/
func packageNameFromParams(ctx *context.Context) string {
- scope := ctx.Params("scope")
- id := ctx.Params("id")
+ scope := ctx.PathParam("scope")
+ id := ctx.PathParam("id")
if scope != "" {
return fmt.Sprintf("@%s/%s", scope, id)
}
@@ -82,8 +82,8 @@ func PackageMetadata(ctx *context.Context) {
// DownloadPackageFile serves the content of a package
func DownloadPackageFile(ctx *context.Context) {
packageName := packageNameFromParams(ctx)
- packageVersion := ctx.Params("version")
- filename := ctx.Params("filename")
+ packageVersion := ctx.PathParam("version")
+ filename := ctx.PathParam("filename")
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
ctx,
@@ -111,7 +111,7 @@ func DownloadPackageFile(ctx *context.Context) {
// DownloadPackageFileByName finds the version and serves the contents of a package
func DownloadPackageFileByName(ctx *context.Context) {
- filename := ctx.Params("filename")
+ filename := ctx.PathParam("filename")
pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
OwnerID: ctx.Package.Owner.ID,
@@ -254,7 +254,7 @@ func DeletePreview(ctx *context.Context) {
// DeletePackageVersion deletes the package version
func DeletePackageVersion(ctx *context.Context) {
packageName := packageNameFromParams(ctx)
- packageVersion := ctx.Params("version")
+ packageVersion := ctx.PathParam("version")
err := packages_service.RemovePackageVersionByNameAndVersion(
ctx,
@@ -349,7 +349,7 @@ func AddPackageTag(ctx *context.Context) {
return
}
- if err := setPackageTag(ctx, ctx.Params("tag"), pv, false); err != nil {
+ if err := setPackageTag(ctx, ctx.PathParam("tag"), pv, false); err != nil {
if err == errInvalidTagName {
apiError(ctx, http.StatusBadRequest, err)
return
@@ -370,7 +370,7 @@ func DeletePackageTag(ctx *context.Context) {
}
if len(pvs) != 0 {
- if err := setPackageTag(ctx, ctx.Params("tag"), pvs[0], true); err != nil {
+ if err := setPackageTag(ctx, ctx.PathParam("tag"), pvs[0], true); err != nil {
if err == errInvalidTagName {
apiError(ctx, http.StatusBadRequest, err)
return
diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go
index 0d7212d7f7..70b95e6a77 100644
--- a/routers/api/packages/nuget/nuget.go
+++ b/routers/api/packages/nuget/nuget.go
@@ -226,7 +226,7 @@ func SearchServiceV3(ctx *context.Context) {
// https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource#registration-index
func RegistrationIndex(ctx *context.Context) {
- packageName := ctx.Params("id")
+ packageName := ctx.PathParam("id")
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName)
if err != nil {
@@ -254,8 +254,8 @@ func RegistrationIndex(ctx *context.Context) {
// https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Protocol/LegacyFeed/V2FeedQueryBuilder.cs
func RegistrationLeafV2(ctx *context.Context) {
- packageName := ctx.Params("id")
- packageVersion := ctx.Params("version")
+ packageName := ctx.PathParam("id")
+ packageVersion := ctx.PathParam("version")
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion)
if err != nil {
@@ -283,8 +283,8 @@ func RegistrationLeafV2(ctx *context.Context) {
// https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource#registration-leaf
func RegistrationLeafV3(ctx *context.Context) {
- packageName := ctx.Params("id")
- packageVersion := strings.TrimSuffix(ctx.Params("version"), ".json")
+ packageName := ctx.PathParam("id")
+ packageVersion := strings.TrimSuffix(ctx.PathParam("version"), ".json")
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion)
if err != nil {
@@ -381,7 +381,7 @@ func EnumeratePackageVersionsV2Count(ctx *context.Context) {
// https://docs.microsoft.com/en-us/nuget/api/package-base-address-resource#enumerate-package-versions
func EnumeratePackageVersionsV3(ctx *context.Context) {
- packageName := ctx.Params("id")
+ packageName := ctx.PathParam("id")
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName)
if err != nil {
@@ -401,9 +401,9 @@ func EnumeratePackageVersionsV3(ctx *context.Context) {
// https://learn.microsoft.com/en-us/nuget/api/package-base-address-resource#download-package-manifest-nuspec
// https://learn.microsoft.com/en-us/nuget/api/package-base-address-resource#download-package-content-nupkg
func DownloadPackageFile(ctx *context.Context) {
- packageName := ctx.Params("id")
- packageVersion := ctx.Params("version")
- filename := ctx.Params("filename")
+ packageName := ctx.PathParam("id")
+ packageVersion := ctx.PathParam("version")
+ filename := ctx.PathParam("filename")
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
ctx,
@@ -643,9 +643,9 @@ func processUploadedFile(ctx *context.Context, expectedType nuget_module.Package
// https://github.com/dotnet/symstore/blob/main/docs/specs/Simple_Symbol_Query_Protocol.md#request
func DownloadSymbolFile(ctx *context.Context) {
- filename := ctx.Params("filename")
- guid := ctx.Params("guid")[:32]
- filename2 := ctx.Params("filename2")
+ filename := ctx.PathParam("filename")
+ guid := ctx.PathParam("guid")[:32]
+ filename2 := ctx.PathParam("filename2")
if filename != filename2 {
apiError(ctx, http.StatusBadRequest, nil)
@@ -685,8 +685,8 @@ func DownloadSymbolFile(ctx *context.Context) {
// DeletePackage hard deletes the package
// https://docs.microsoft.com/en-us/nuget/api/package-publish-resource#delete-a-package
func DeletePackage(ctx *context.Context) {
- packageName := ctx.Params("id")
- packageVersion := ctx.Params("version")
+ packageName := ctx.PathParam("id")
+ packageVersion := ctx.PathParam("version")
err := packages_service.RemovePackageVersionByNameAndVersion(
ctx,
diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go
index f87df52a29..2be27323fd 100644
--- a/routers/api/packages/pub/pub.go
+++ b/routers/api/packages/pub/pub.go
@@ -81,7 +81,7 @@ func baseURL(ctx *context.Context) string {
// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#list-all-versions-of-a-package
func EnumeratePackageVersions(ctx *context.Context) {
- packageName := ctx.Params("id")
+ packageName := ctx.PathParam("id")
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName)
if err != nil {
@@ -119,8 +119,8 @@ func EnumeratePackageVersions(ctx *context.Context) {
// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#deprecated-inspect-a-specific-version-of-a-package
func PackageVersionMetadata(ctx *context.Context) {
- packageName := ctx.Params("id")
- packageVersion := ctx.Params("version")
+ packageName := ctx.PathParam("id")
+ packageVersion := ctx.PathParam("version")
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion)
if err != nil {
@@ -228,8 +228,8 @@ func UploadPackageFile(ctx *context.Context) {
// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#publishing-packages
func FinalizePackage(ctx *context.Context) {
- packageName := ctx.Params("id")
- packageVersion := ctx.Params("version")
+ packageName := ctx.PathParam("id")
+ packageVersion := ctx.PathParam("version")
_, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion)
if err != nil {
@@ -253,8 +253,8 @@ func FinalizePackage(ctx *context.Context) {
// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#deprecated-download-a-specific-version-of-a-package
func DownloadPackageFile(ctx *context.Context) {
- packageName := ctx.Params("id")
- packageVersion := strings.TrimSuffix(ctx.Params("version"), ".tar.gz")
+ packageName := ctx.PathParam("id")
+ packageVersion := strings.TrimSuffix(ctx.PathParam("version"), ".tar.gz")
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion)
if err != nil {
diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go
index 7824db1823..5ea86071a9 100644
--- a/routers/api/packages/pypi/pypi.go
+++ b/routers/api/packages/pypi/pypi.go
@@ -45,7 +45,7 @@ func apiError(ctx *context.Context, status int, obj any) {
// PackageMetadata returns the metadata for a single package
func PackageMetadata(ctx *context.Context) {
- packageName := normalizer.Replace(ctx.Params("id"))
+ packageName := normalizer.Replace(ctx.PathParam("id"))
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypePyPI, packageName)
if err != nil {
@@ -76,9 +76,9 @@ func PackageMetadata(ctx *context.Context) {
// DownloadPackageFile serves the content of a package
func DownloadPackageFile(ctx *context.Context) {
- packageName := normalizer.Replace(ctx.Params("id"))
- packageVersion := ctx.Params("version")
- filename := ctx.Params("filename")
+ packageName := normalizer.Replace(ctx.PathParam("id"))
+ packageVersion := ctx.PathParam("version")
+ filename := ctx.PathParam("filename")
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
ctx,
diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go
index c59366992c..11d7729eec 100644
--- a/routers/api/packages/rpm/rpm.go
+++ b/routers/api/packages/rpm/rpm.go
@@ -33,7 +33,7 @@ func apiError(ctx *context.Context, status int, obj any) {
// https://dnf.readthedocs.io/en/latest/conf_ref.html
func GetRepositoryConfig(ctx *context.Context) {
- group := ctx.Params("group")
+ group := ctx.PathParam("group")
var groupParts []string
if group != "" {
@@ -71,7 +71,7 @@ func CheckRepositoryFileExistence(ctx *context.Context) {
return
}
- pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, ctx.Params("filename"), ctx.Params("group"))
+ pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, ctx.PathParam("filename"), ctx.PathParam("group"))
if err != nil {
if errors.Is(err, util.ErrNotExist) {
ctx.Status(http.StatusNotFound)
@@ -100,8 +100,8 @@ func GetRepositoryFile(ctx *context.Context) {
ctx,
pv,
&packages_service.PackageFileInfo{
- Filename: ctx.Params("filename"),
- CompositeKey: ctx.Params("group"),
+ Filename: ctx.PathParam("filename"),
+ CompositeKey: ctx.PathParam("group"),
},
)
if err != nil {
@@ -153,7 +153,7 @@ func UploadPackageFile(ctx *context.Context) {
apiError(ctx, http.StatusInternalServerError, err)
return
}
- group := ctx.Params("group")
+ group := ctx.PathParam("group")
_, _, err = packages_service.CreatePackageOrAddFileToExisting(
ctx,
&packages_service.PackageCreationInfo{
@@ -202,8 +202,8 @@ func UploadPackageFile(ctx *context.Context) {
}
func DownloadPackageFile(ctx *context.Context) {
- name := ctx.Params("name")
- version := ctx.Params("version")
+ name := ctx.PathParam("name")
+ version := ctx.PathParam("version")
s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
ctx,
@@ -214,8 +214,8 @@ func DownloadPackageFile(ctx *context.Context) {
Version: version,
},
&packages_service.PackageFileInfo{
- Filename: fmt.Sprintf("%s-%s.%s.rpm", name, version, ctx.Params("architecture")),
- CompositeKey: ctx.Params("group"),
+ Filename: fmt.Sprintf("%s-%s.%s.rpm", name, version, ctx.PathParam("architecture")),
+ CompositeKey: ctx.PathParam("group"),
},
)
if err != nil {
@@ -231,10 +231,10 @@ func DownloadPackageFile(ctx *context.Context) {
}
func DeletePackageFile(webctx *context.Context) {
- group := webctx.Params("group")
- name := webctx.Params("name")
- version := webctx.Params("version")
- architecture := webctx.Params("architecture")
+ group := webctx.PathParam("group")
+ name := webctx.PathParam("name")
+ version := webctx.PathParam("version")
+ architecture := webctx.PathParam("architecture")
var pd *packages_model.PackageDescriptor
diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go
index ba5f4de080..958063e70a 100644
--- a/routers/api/packages/rubygems/rubygems.go
+++ b/routers/api/packages/rubygems/rubygems.go
@@ -6,6 +6,7 @@ package rubygems
import (
"compress/gzip"
"compress/zlib"
+ "crypto/md5"
"errors"
"fmt"
"io"
@@ -94,7 +95,7 @@ func enumeratePackages(ctx *context.Context, filename string, pvs []*packages_mo
// ServePackageSpecification serves the compressed Gemspec file of a package
func ServePackageSpecification(ctx *context.Context) {
- filename := ctx.Params("filename")
+ filename := ctx.PathParam("filename")
if !strings.HasSuffix(filename, ".gemspec.rz") {
apiError(ctx, http.StatusNotImplemented, nil)
@@ -163,7 +164,7 @@ func ServePackageSpecification(ctx *context.Context) {
// DownloadPackageFile serves the content of a package
func DownloadPackageFile(ctx *context.Context) {
- filename := ctx.Params("filename")
+ filename := ctx.PathParam("filename")
pvs, err := getVersionsByFilename(ctx, filename)
if err != nil {
@@ -227,12 +228,7 @@ func UploadPackageFile(ctx *context.Context) {
return
}
- var filename string
- if rp.Metadata.Platform == "" || rp.Metadata.Platform == "ruby" {
- filename = strings.ToLower(fmt.Sprintf("%s-%s.gem", rp.Name, rp.Version))
- } else {
- filename = strings.ToLower(fmt.Sprintf("%s-%s-%s.gem", rp.Name, rp.Version, rp.Metadata.Platform))
- }
+ filename := makeGemFullFileName(rp.Name, rp.Version, rp.Metadata.Platform)
_, _, err = packages_service.CreatePackageAndAddFile(
ctx,
@@ -300,6 +296,136 @@ func DeletePackage(ctx *context.Context) {
}
}
+// GetPackageInfo returns a custom text based format for the single rubygem with a line for each version of the rubygem
+// ref: https://guides.rubygems.org/rubygems-org-compact-index-api/
+func GetPackageInfo(ctx *context.Context) {
+ packageName := ctx.PathParam("packagename")
+ versions, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems, packageName)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ if len(versions) == 0 {
+ apiError(ctx, http.StatusNotFound, nil)
+ return
+ }
+ infoContent, err := makePackageInfo(ctx, versions)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ ctx.PlainText(http.StatusOK, infoContent)
+}
+
+// GetAllPackagesVersions returns a custom text based format containing information about all versions of all rubygems.
+// ref: https://guides.rubygems.org/rubygems-org-compact-index-api/
+func GetAllPackagesVersions(ctx *context.Context) {
+ packages, err := packages_model.GetPackagesByType(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ out := &strings.Builder{}
+ out.WriteString("---\n")
+ for _, pkg := range packages {
+ versions, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems, pkg.Name)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ if len(versions) == 0 {
+ continue
+ }
+
+ info, err := makePackageInfo(ctx, versions)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ // format: RUBYGEM [-]VERSION_PLATFORM[,VERSION_PLATFORM],...] MD5
+ _, _ = fmt.Fprintf(out, "%s ", pkg.Name)
+ for i, v := range versions {
+ sep := util.Iif(i == len(versions)-1, "", ",")
+ _, _ = fmt.Fprintf(out, "%s%s", v.Version, sep)
+ }
+ _, _ = fmt.Fprintf(out, " %x\n", md5.Sum([]byte(info)))
+ }
+
+ ctx.PlainText(http.StatusOK, out.String())
+}
+
+func writePackageVersionRequirements(prefix string, reqs []rubygems_module.VersionRequirement, out *strings.Builder) {
+ out.WriteString(prefix)
+ if len(reqs) == 0 {
+ reqs = []rubygems_module.VersionRequirement{{Restriction: ">=", Version: "0"}}
+ }
+ for i, req := range reqs {
+ sep := util.Iif(i == 0, "", "&")
+ _, _ = fmt.Fprintf(out, "%s%s %s", sep, req.Restriction, req.Version)
+ }
+}
+
+func makePackageVersionDependency(ctx *context.Context, version *packages_model.PackageVersion) (string, error) {
+ // format: VERSION[-PLATFORM] [DEPENDENCY[,DEPENDENCY,...]]|REQUIREMENT[,REQUIREMENT,...]
+ // DEPENDENCY: GEM:CONSTRAINT[&CONSTRAINT]
+ // REQUIREMENT: KEY:VALUE (always contains "checksum")
+ pd, err := packages_model.GetPackageDescriptor(ctx, version)
+ if err != nil {
+ return "", err
+ }
+
+ metadata := pd.Metadata.(*rubygems_module.Metadata)
+ fullFilename := makeGemFullFileName(pd.Package.Name, version.Version, metadata.Platform)
+ file, err := packages_model.GetFileForVersionByName(ctx, version.ID, fullFilename, "")
+ if err != nil {
+ return "", err
+ }
+ blob, err := packages_model.GetBlobByID(ctx, file.BlobID)
+ if err != nil {
+ return "", err
+ }
+
+ buf := &strings.Builder{}
+ buf.WriteString(version.Version)
+ buf.WriteByte(' ')
+ for i, dep := range metadata.RuntimeDependencies {
+ sep := util.Iif(i == 0, "", ",")
+ writePackageVersionRequirements(fmt.Sprintf("%s%s:", sep, dep.Name), dep.Version, buf)
+ }
+ _, _ = fmt.Fprintf(buf, "|checksum:%s", blob.HashSHA256)
+ if len(metadata.RequiredRubyVersion) != 0 {
+ writePackageVersionRequirements(",ruby:", metadata.RequiredRubyVersion, buf)
+ }
+ if len(metadata.RequiredRubygemsVersion) != 0 {
+ writePackageVersionRequirements(",rubygems:", metadata.RequiredRubygemsVersion, buf)
+ }
+ return buf.String(), nil
+}
+
+func makePackageInfo(ctx *context.Context, versions []*packages_model.PackageVersion) (string, error) {
+ ret := "---\n"
+ for _, v := range versions {
+ dep, err := makePackageVersionDependency(ctx, v)
+ if err != nil {
+ return "", err
+ }
+ ret += dep + "\n"
+ }
+ return ret, nil
+}
+
+func makeGemFullFileName(gemName, version, platform string) string {
+ var basename string
+ if platform == "" || platform == "ruby" {
+ basename = fmt.Sprintf("%s-%s", gemName, version)
+ } else {
+ basename = fmt.Sprintf("%s-%s-%s", gemName, version, platform)
+ }
+ return strings.ToLower(basename) + ".gem"
+}
+
func getVersionsByFilename(ctx *context.Context, filename string) ([]*packages_model.PackageVersion, error) {
pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
OwnerID: ctx.Package.Owner.ID,
diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go
index a9da3ea9c2..d5d4d4e9d1 100644
--- a/routers/api/packages/swift/swift.go
+++ b/routers/api/packages/swift/swift.go
@@ -115,8 +115,8 @@ type EnumeratePackageVersionsResponse struct {
// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#41-list-package-releases
func EnumeratePackageVersions(ctx *context.Context) {
- packageScope := ctx.Params("scope")
- packageName := ctx.Params("name")
+ packageScope := ctx.PathParam("scope")
+ packageName := ctx.PathParam("name")
pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(packageScope, packageName))
if err != nil {
@@ -172,9 +172,9 @@ type PackageVersionMetadataResponse struct {
// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-2
func PackageVersionMetadata(ctx *context.Context) {
- id := buildPackageID(ctx.Params("scope"), ctx.Params("name"))
+ id := buildPackageID(ctx.PathParam("scope"), ctx.PathParam("name"))
- pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, id, ctx.Params("version"))
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, id, ctx.PathParam("version"))
if err != nil {
if errors.Is(err, util.ErrNotExist) {
apiError(ctx, http.StatusNotFound, err)
@@ -230,9 +230,9 @@ func PackageVersionMetadata(ctx *context.Context) {
// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#43-fetch-manifest-for-a-package-release
func DownloadManifest(ctx *context.Context) {
- packageScope := ctx.Params("scope")
- packageName := ctx.Params("name")
- packageVersion := ctx.Params("version")
+ packageScope := ctx.PathParam("scope")
+ packageName := ctx.PathParam("name")
+ packageVersion := ctx.PathParam("version")
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(packageScope, packageName), packageVersion)
if err != nil {
@@ -282,10 +282,10 @@ func DownloadManifest(ctx *context.Context) {
// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-6
func UploadPackageFile(ctx *context.Context) {
- packageScope := ctx.Params("scope")
- packageName := ctx.Params("name")
+ packageScope := ctx.PathParam("scope")
+ packageName := ctx.PathParam("name")
- v, err := version.NewVersion(ctx.Params("version"))
+ v, err := version.NewVersion(ctx.PathParam("version"))
if !scopePattern.MatchString(packageScope) || !namePattern.MatchString(packageName) || err != nil {
apiError(ctx, http.StatusBadRequest, err)
@@ -381,7 +381,7 @@ func UploadPackageFile(ctx *context.Context) {
// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-4
func DownloadPackageFile(ctx *context.Context) {
- pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(ctx.Params("scope"), ctx.Params("name")), ctx.Params("version"))
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(ctx.PathParam("scope"), ctx.PathParam("name")), ctx.PathParam("version"))
if err != nil {
if errors.Is(err, util.ErrNotExist) {
apiError(ctx, http.StatusNotFound, err)
diff --git a/routers/api/packages/vagrant/vagrant.go b/routers/api/packages/vagrant/vagrant.go
index 98a81da368..1daf2a0527 100644
--- a/routers/api/packages/vagrant/vagrant.go
+++ b/routers/api/packages/vagrant/vagrant.go
@@ -44,7 +44,7 @@ func CheckAuthenticate(ctx *context.Context) {
}
func CheckBoxAvailable(ctx *context.Context) {
- pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeVagrant, ctx.Params("name"))
+ pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeVagrant, ctx.PathParam("name"))
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
@@ -101,7 +101,7 @@ func packageDescriptorToMetadata(baseURL string, pd *packages_model.PackageDescr
}
func EnumeratePackageVersions(ctx *context.Context) {
- pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeVagrant, ctx.Params("name"))
+ pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeVagrant, ctx.PathParam("name"))
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
@@ -136,14 +136,14 @@ func EnumeratePackageVersions(ctx *context.Context) {
}
func UploadPackageFile(ctx *context.Context) {
- boxName := ctx.Params("name")
- boxVersion := ctx.Params("version")
+ boxName := ctx.PathParam("name")
+ boxVersion := ctx.PathParam("version")
_, err := version.NewSemver(boxVersion)
if err != nil {
apiError(ctx, http.StatusBadRequest, err)
return
}
- boxProvider := ctx.Params("provider")
+ boxProvider := ctx.PathParam("provider")
if !strings.HasSuffix(boxProvider, ".box") {
apiError(ctx, http.StatusBadRequest, err)
return
@@ -222,11 +222,11 @@ func DownloadPackageFile(ctx *context.Context) {
&packages_service.PackageInfo{
Owner: ctx.Package.Owner,
PackageType: packages_model.TypeVagrant,
- Name: ctx.Params("name"),
- Version: ctx.Params("version"),
+ Name: ctx.PathParam("name"),
+ Version: ctx.PathParam("version"),
},
&packages_service.PackageFileInfo{
- Filename: ctx.Params("provider"),
+ Filename: ctx.PathParam("provider"),
},
)
if err != nil {
diff --git a/routers/api/v1/admin/adopt.go b/routers/api/v1/admin/adopt.go
index a4708fe032..613d123494 100644
--- a/routers/api/v1/admin/adopt.go
+++ b/routers/api/v1/admin/adopt.go
@@ -80,8 +80,8 @@ func AdoptRepository(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
// "403":
// "$ref": "#/responses/forbidden"
- ownerName := ctx.Params(":username")
- repoName := ctx.Params(":reponame")
+ ownerName := ctx.PathParam(":username")
+ repoName := ctx.PathParam(":reponame")
ctxUser, err := user_model.GetUserByName(ctx, ownerName)
if err != nil {
@@ -142,8 +142,8 @@ func DeleteUnadoptedRepository(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
- ownerName := ctx.Params(":username")
- repoName := ctx.Params(":reponame")
+ ownerName := ctx.PathParam(":username")
+ repoName := ctx.PathParam(":reponame")
ctxUser, err := user_model.GetUserByName(ctx, ownerName)
if err != nil {
diff --git a/routers/api/v1/admin/cron.go b/routers/api/v1/admin/cron.go
index e1ca6048c9..fba9d33f25 100644
--- a/routers/api/v1/admin/cron.go
+++ b/routers/api/v1/admin/cron.go
@@ -74,7 +74,7 @@ func PostCronTask(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "404":
// "$ref": "#/responses/notFound"
- task := cron.GetTask(ctx.Params(":task"))
+ task := cron.GetTask(ctx.PathParam(":task"))
if task == nil {
ctx.NotFound()
return
diff --git a/routers/api/v1/admin/email.go b/routers/api/v1/admin/email.go
index ba963e9f69..6fe418249b 100644
--- a/routers/api/v1/admin/email.go
+++ b/routers/api/v1/admin/email.go
@@ -38,7 +38,7 @@ func GetAllEmails(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx)
emails, maxResults, err := user_model.SearchEmails(ctx, &user_model.SearchEmailOptions{
- Keyword: ctx.Params(":email"),
+ Keyword: ctx.PathParam(":email"),
ListOptions: listOptions,
})
if err != nil {
@@ -82,6 +82,6 @@ func SearchEmail(ctx *context.APIContext) {
// "403":
// "$ref": "#/responses/forbidden"
- ctx.SetParams(":email", ctx.FormTrim("q"))
+ ctx.SetPathParam(":email", ctx.FormTrim("q"))
GetAllEmails(ctx)
}
diff --git a/routers/api/v1/admin/hooks.go b/routers/api/v1/admin/hooks.go
index 4c168b55bf..fa60836b7e 100644
--- a/routers/api/v1/admin/hooks.go
+++ b/routers/api/v1/admin/hooks.go
@@ -73,7 +73,7 @@ func GetHook(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/Hook"
- hookID := ctx.ParamsInt64(":id")
+ hookID := ctx.PathParamInt64(":id")
hook, err := webhook.GetSystemOrDefaultWebhook(ctx, hookID)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
@@ -142,7 +142,7 @@ func EditHook(ctx *context.APIContext) {
form := web.GetForm(ctx).(*api.EditHookOption)
// TODO in body params
- hookID := ctx.ParamsInt64(":id")
+ hookID := ctx.PathParamInt64(":id")
utils.EditSystemHook(ctx, form, hookID)
}
@@ -164,7 +164,7 @@ func DeleteHook(ctx *context.APIContext) {
// "204":
// "$ref": "#/responses/empty"
- hookID := ctx.ParamsInt64(":id")
+ hookID := ctx.PathParamInt64(":id")
if err := webhook.DeleteDefaultSystemWebhook(ctx, hookID); err != nil {
if errors.Is(err, util.ErrNotExist) {
ctx.NotFound()
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
index be907805d6..3e2fefc6da 100644
--- a/routers/api/v1/admin/user.go
+++ b/routers/api/v1/admin/user.go
@@ -373,7 +373,7 @@ func DeleteUserPublicKey(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- if err := asymkey_service.DeletePublicKey(ctx, ctx.ContextUser, ctx.ParamsInt64(":id")); err != nil {
+ if err := asymkey_service.DeletePublicKey(ctx, ctx.ContextUser, ctx.PathParamInt64(":id")); err != nil {
if asymkey_model.IsErrKeyNotExist(err) {
ctx.NotFound()
} else if asymkey_model.IsErrKeyAccessDenied(err) {
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 74062c44ac..be67ec1695 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -136,8 +136,8 @@ func sudo() func(ctx *context.APIContext) {
func repoAssignment() func(ctx *context.APIContext) {
return func(ctx *context.APIContext) {
- userName := ctx.Params("username")
- repoName := ctx.Params("reponame")
+ userName := ctx.PathParam("username")
+ repoName := ctx.PathParam("reponame")
var (
owner *user_model.User
@@ -555,12 +555,12 @@ func orgAssignment(args ...bool) func(ctx *context.APIContext) {
var err error
if assignOrg {
- ctx.Org.Organization, err = organization.GetOrgByName(ctx, ctx.Params(":org"))
+ ctx.Org.Organization, err = organization.GetOrgByName(ctx, ctx.PathParam(":org"))
if err != nil {
if organization.IsErrOrgNotExist(err) {
- redirectUserID, err := user_model.LookupUserRedirect(ctx, ctx.Params(":org"))
+ redirectUserID, err := user_model.LookupUserRedirect(ctx, ctx.PathParam(":org"))
if err == nil {
- context.RedirectToUser(ctx.Base, ctx.Params(":org"), redirectUserID)
+ context.RedirectToUser(ctx.Base, ctx.PathParam(":org"), redirectUserID)
} else if user_model.IsErrUserRedirectNotExist(err) {
ctx.NotFound("GetOrgByName", err)
} else {
@@ -575,7 +575,7 @@ func orgAssignment(args ...bool) func(ctx *context.APIContext) {
}
if assignTeam {
- ctx.Org.Team, err = organization.GetTeamByID(ctx, ctx.ParamsInt64(":teamid"))
+ ctx.Org.Team, err = organization.GetTeamByID(ctx, ctx.PathParamInt64(":teamid"))
if err != nil {
if organization.IsErrTeamNotExist(err) {
ctx.NotFound()
@@ -812,8 +812,8 @@ func checkDeprecatedAuthMethods(ctx *context.APIContext) {
}
// Routes registers all v1 APIs routes to web application.
-func Routes() *web.Route {
- m := web.NewRoute()
+func Routes() *web.Router {
+ m := web.NewRouter()
m.Use(securityHeaders())
if setting.CORSConfig.Enabled {
@@ -837,7 +837,7 @@ func Routes() *web.Route {
}))
addActionsRoutes := func(
- m *web.Route,
+ m *web.Router,
reqChecker func(ctx *context.APIContext),
act actions.API,
) {
@@ -1168,6 +1168,15 @@ func Routes() *web.Route {
m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateTagOption{}), repo.CreateTag)
m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.DeleteTag)
}, reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(true))
+ m.Group("/tag_protections", func() {
+ m.Combo("").Get(repo.ListTagProtection).
+ Post(bind(api.CreateTagProtectionOption{}), mustNotBeArchived, repo.CreateTagProtection)
+ m.Group("/{id}", func() {
+ m.Combo("").Get(repo.GetTagProtection).
+ Patch(bind(api.EditTagProtectionOption{}), mustNotBeArchived, repo.EditTagProtection).
+ Delete(repo.DeleteTagProtection)
+ })
+ }, reqToken(), reqAdmin())
m.Group("/actions", func() {
m.Get("/tasks", repo.ListActionTasks)
}, reqRepoReader(unit.TypeActions), context.ReferencesGitRepo(true))
diff --git a/routers/api/v1/misc/gitignore.go b/routers/api/v1/misc/gitignore.go
index dffd771752..b0bf00a921 100644
--- a/routers/api/v1/misc/gitignore.go
+++ b/routers/api/v1/misc/gitignore.go
@@ -44,7 +44,7 @@ func GetGitignoreTemplateInfo(ctx *context.APIContext) {
// "$ref": "#/responses/GitignoreTemplateInfo"
// "404":
// "$ref": "#/responses/notFound"
- name := util.PathJoinRelX(ctx.Params("name"))
+ name := util.PathJoinRelX(ctx.PathParam("name"))
text, err := options.Gitignore(name)
if err != nil {
diff --git a/routers/api/v1/misc/label_templates.go b/routers/api/v1/misc/label_templates.go
index cc11f37626..f105b4c684 100644
--- a/routers/api/v1/misc/label_templates.go
+++ b/routers/api/v1/misc/label_templates.go
@@ -48,7 +48,7 @@ func GetLabelTemplate(ctx *context.APIContext) {
// "$ref": "#/responses/LabelTemplateInfo"
// "404":
// "$ref": "#/responses/notFound"
- name := util.PathJoinRelX(ctx.Params("name"))
+ name := util.PathJoinRelX(ctx.PathParam("name"))
labels, err := repo_module.LoadTemplateLabelsByDisplayName(name)
if err != nil {
diff --git a/routers/api/v1/misc/licenses.go b/routers/api/v1/misc/licenses.go
index 2a980f5084..d99b276232 100644
--- a/routers/api/v1/misc/licenses.go
+++ b/routers/api/v1/misc/licenses.go
@@ -55,7 +55,7 @@ func GetLicenseTemplateInfo(ctx *context.APIContext) {
// "$ref": "#/responses/LicenseTemplateInfo"
// "404":
// "$ref": "#/responses/notFound"
- name := util.PathJoinRelX(ctx.Params("name"))
+ name := util.PathJoinRelX(ctx.PathParam("name"))
text, err := options.License(name)
if err != nil {
diff --git a/routers/api/v1/misc/markup_test.go b/routers/api/v1/misc/markup_test.go
index 5236fd06ae..e2ab7141b7 100644
--- a/routers/api/v1/misc/markup_test.go
+++ b/routers/api/v1/misc/markup_test.go
@@ -7,6 +7,7 @@ import (
go_context "context"
"io"
"net/http"
+ "path"
"strings"
"testing"
@@ -19,36 +20,40 @@ import (
"github.com/stretchr/testify/assert"
)
-const (
- AppURL = "http://localhost:3000/"
- Repo = "gogits/gogs"
- FullURL = AppURL + Repo + "/"
-)
+const AppURL = "http://localhost:3000/"
-func testRenderMarkup(t *testing.T, mode, filePath, text, responseBody string, responseCode int) {
+func testRenderMarkup(t *testing.T, mode string, wiki bool, filePath, text, expectedBody string, expectedCode int) {
setting.AppURL = AppURL
+ context := "/gogits/gogs"
+ if !wiki {
+ context += path.Join("/src/branch/main", path.Dir(filePath))
+ }
options := api.MarkupOption{
Mode: mode,
Text: text,
- Context: Repo,
- Wiki: true,
+ Context: context,
+ Wiki: wiki,
FilePath: filePath,
}
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markup")
web.SetForm(ctx, &options)
Markup(ctx)
- assert.Equal(t, responseBody, resp.Body.String())
- assert.Equal(t, responseCode, resp.Code)
+ assert.Equal(t, expectedBody, resp.Body.String())
+ assert.Equal(t, expectedCode, resp.Code)
resp.Body.Reset()
}
-func testRenderMarkdown(t *testing.T, mode, text, responseBody string, responseCode int) {
+func testRenderMarkdown(t *testing.T, mode string, wiki bool, text, responseBody string, responseCode int) {
setting.AppURL = AppURL
+ context := "/gogits/gogs"
+ if !wiki {
+ context += "/src/branch/main"
+ }
options := api.MarkdownOption{
Mode: mode,
Text: text,
- Context: Repo,
- Wiki: true,
+ Context: context,
+ Wiki: wiki,
}
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markdown")
web.SetForm(ctx, &options)
@@ -65,7 +70,7 @@ func TestAPI_RenderGFM(t *testing.T) {
},
})
- testCasesCommon := []string{
+ testCasesWiki := []string{
// dear imgui wiki markdown extract: special wiki syntax
`Wiki! Enjoy :)
- [[Links, Language bindings, Engine bindings|Links]]
@@ -74,20 +79,20 @@ func TestAPI_RenderGFM(t *testing.T) {
// rendered
`Wiki! Enjoy :)
-- Links, Language bindings, Engine bindings
-- Tips
-- Bezier widget (by @r-lyeh) https://github.com/ocornut/imgui/issues/786
+- Links, Language bindings, Engine bindings
+- Tips
+- Bezier widget (by @r-lyeh) https://github.com/ocornut/imgui/issues/786
`,
// Guard wiki sidebar: special syntax
`[[Guardfile-DSL / Configuring-Guard|Guardfile-DSL---Configuring-Guard]]`,
// rendered
- `Guardfile-DSL / Configuring-Guard
+ `Guardfile-DSL / Configuring-Guard
`,
// special syntax
`[[Name|Link]]`,
// rendered
- `
+ `
`,
// empty
``,
@@ -95,7 +100,7 @@ func TestAPI_RenderGFM(t *testing.T) {
``,
}
- testCasesDocument := []string{
+ testCasesWikiDocument := []string{
// wine-staging wiki home extract: special wiki syntax, images
`## What is Wine Staging?
**Wine Staging** on website [wine-staging.com](http://wine-staging.com).
@@ -111,31 +116,48 @@ Here are some links to the most important topics. You can find the full list of
Wine Staging on website wine-staging.com.
Quick Links
Here are some links to the most important topics. You can find the full list of pages at the sidebar.
-
+
`,
}
- for i := 0; i < len(testCasesCommon); i += 2 {
- text := testCasesCommon[i]
- response := testCasesCommon[i+1]
- testRenderMarkdown(t, "gfm", text, response, http.StatusOK)
- testRenderMarkup(t, "gfm", "", text, response, http.StatusOK)
- testRenderMarkdown(t, "comment", text, response, http.StatusOK)
- testRenderMarkup(t, "comment", "", text, response, http.StatusOK)
- testRenderMarkup(t, "file", "path/test.md", text, response, http.StatusOK)
+ for i := 0; i < len(testCasesWiki); i += 2 {
+ text := testCasesWiki[i]
+ response := testCasesWiki[i+1]
+ testRenderMarkdown(t, "gfm", true, text, response, http.StatusOK)
+ testRenderMarkup(t, "gfm", true, "", text, response, http.StatusOK)
+ testRenderMarkdown(t, "comment", true, text, response, http.StatusOK)
+ testRenderMarkup(t, "comment", true, "", text, response, http.StatusOK)
+ testRenderMarkup(t, "file", true, "path/test.md", text, response, http.StatusOK)
}
- for i := 0; i < len(testCasesDocument); i += 2 {
- text := testCasesDocument[i]
- response := testCasesDocument[i+1]
- testRenderMarkdown(t, "gfm", text, response, http.StatusOK)
- testRenderMarkup(t, "gfm", "", text, response, http.StatusOK)
- testRenderMarkup(t, "file", "path/test.md", text, response, http.StatusOK)
+ for i := 0; i < len(testCasesWikiDocument); i += 2 {
+ text := testCasesWikiDocument[i]
+ response := testCasesWikiDocument[i+1]
+ testRenderMarkdown(t, "gfm", true, text, response, http.StatusOK)
+ testRenderMarkup(t, "gfm", true, "", text, response, http.StatusOK)
+ testRenderMarkup(t, "file", true, "path/test.md", text, response, http.StatusOK)
}
- testRenderMarkup(t, "file", "path/test.unknown", "## Test", "Unsupported render extension: .unknown\n", http.StatusUnprocessableEntity)
- testRenderMarkup(t, "unknown", "", "## Test", "Unknown mode: unknown\n", http.StatusUnprocessableEntity)
+ input := "[Link](test.md)\n![Image](image.png)"
+ testRenderMarkdown(t, "gfm", false, input, `Link
+
+`, http.StatusOK)
+
+ testRenderMarkdown(t, "gfm", false, input, `Link
+
+`, http.StatusOK)
+
+ testRenderMarkup(t, "gfm", false, "", input, `Link
+
+`, http.StatusOK)
+
+ testRenderMarkup(t, "file", false, "path/new-file.md", input, `Link
+
+`, http.StatusOK)
+
+ testRenderMarkup(t, "file", true, "path/test.unknown", "## Test", "Unsupported render extension: .unknown\n", http.StatusUnprocessableEntity)
+ testRenderMarkup(t, "unknown", true, "", "## Test", "Unknown mode: unknown\n", http.StatusUnprocessableEntity)
}
var simpleCases = []string{
@@ -160,7 +182,7 @@ func TestAPI_RenderSimple(t *testing.T) {
options := api.MarkdownOption{
Mode: "markdown",
Text: "",
- Context: Repo,
+ Context: "/gogits/gogs",
}
ctx, resp := contexttest.MockAPIContext(t, "POST /api/v1/markdown")
for i := 0; i < len(simpleCases); i += 2 {
diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go
index 8e12d359cb..0761e684a3 100644
--- a/routers/api/v1/notify/threads.go
+++ b/routers/api/v1/notify/threads.go
@@ -101,7 +101,7 @@ func ReadThread(ctx *context.APIContext) {
}
func getThread(ctx *context.APIContext) *activities_model.Notification {
- n, err := activities_model.GetNotificationByID(ctx, ctx.ParamsInt64(":id"))
+ n, err := activities_model.GetNotificationByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if db.IsErrNotExist(err) {
ctx.Error(http.StatusNotFound, "GetNotificationByID", err)
diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go
index 03a1fa8ccc..199ee7d777 100644
--- a/routers/api/v1/org/action.go
+++ b/routers/api/v1/org/action.go
@@ -106,7 +106,7 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) {
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
- _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.Params("secretname"), opt.Data)
+ _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"), opt.Data)
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
@@ -153,7 +153,7 @@ func (Action) DeleteSecret(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- err := secret_service.DeleteSecretByName(ctx, ctx.Org.Organization.ID, 0, ctx.Params("secretname"))
+ err := secret_service.DeleteSecretByName(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"))
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "DeleteSecret", err)
@@ -269,7 +269,7 @@ func (Action) GetVariable(ctx *context.APIContext) {
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
OwnerID: ctx.Org.Organization.ID,
- Name: ctx.Params("variablename"),
+ Name: ctx.PathParam("variablename"),
})
if err != nil {
if errors.Is(err, util.ErrNotExist) {
@@ -320,7 +320,7 @@ func (Action) DeleteVariable(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- if err := actions_service.DeleteVariableByName(ctx, ctx.Org.Organization.ID, 0, ctx.Params("variablename")); err != nil {
+ if err := actions_service.DeleteVariableByName(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("variablename")); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "DeleteVariableByName", err)
} else if errors.Is(err, util.ErrNotExist) {
@@ -371,7 +371,7 @@ func (Action) CreateVariable(ctx *context.APIContext) {
opt := web.GetForm(ctx).(*api.CreateVariableOption)
ownerID := ctx.Org.Organization.ID
- variableName := ctx.Params("variablename")
+ variableName := ctx.PathParam("variablename")
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
OwnerID: ownerID,
@@ -436,7 +436,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
OwnerID: ctx.Org.Organization.ID,
- Name: ctx.Params("variablename"),
+ Name: ctx.PathParam("variablename"),
})
if err != nil {
if errors.Is(err, util.ErrNotExist) {
@@ -448,7 +448,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
}
if opt.Name == "" {
- opt.Name = ctx.Params("variablename")
+ opt.Name = ctx.PathParam("variablename")
}
if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
diff --git a/routers/api/v1/org/hook.go b/routers/api/v1/org/hook.go
index c1dc0519ea..df82f4e5a2 100644
--- a/routers/api/v1/org/hook.go
+++ b/routers/api/v1/org/hook.go
@@ -71,7 +71,7 @@ func GetHook(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- hook, err := utils.GetOwnerHook(ctx, ctx.ContextUser.ID, ctx.ParamsInt64("id"))
+ hook, err := utils.GetOwnerHook(ctx, ctx.ContextUser.ID, ctx.PathParamInt64("id"))
if err != nil {
return
}
@@ -152,7 +152,7 @@ func EditHook(ctx *context.APIContext) {
ctx,
ctx.ContextUser,
web.GetForm(ctx).(*api.EditHookOption),
- ctx.ParamsInt64("id"),
+ ctx.PathParamInt64("id"),
)
}
@@ -184,6 +184,6 @@ func DeleteHook(ctx *context.APIContext) {
utils.DeleteOwnerHook(
ctx,
ctx.ContextUser,
- ctx.ParamsInt64("id"),
+ ctx.PathParamInt64("id"),
)
}
diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go
index b5ec54ccf4..24ee4ed642 100644
--- a/routers/api/v1/org/label.go
+++ b/routers/api/v1/org/label.go
@@ -139,7 +139,7 @@ func GetLabel(ctx *context.APIContext) {
label *issues_model.Label
err error
)
- strID := ctx.Params(":id")
+ strID := ctx.PathParam(":id")
if intID, err2 := strconv.ParseInt(strID, 10, 64); err2 != nil {
label, err = issues_model.GetLabelInOrgByName(ctx, ctx.Org.Organization.ID, strID)
} else {
@@ -190,7 +190,7 @@ func EditLabel(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
form := web.GetForm(ctx).(*api.EditLabelOption)
- l, err := issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, ctx.ParamsInt64(":id"))
+ l, err := issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrOrgLabelNotExist(err) {
ctx.NotFound()
@@ -249,7 +249,7 @@ func DeleteLabel(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- if err := issues_model.DeleteLabel(ctx, ctx.Org.Organization.ID, ctx.ParamsInt64(":id")); err != nil {
+ if err := issues_model.DeleteLabel(ctx, ctx.Org.Organization.ID, ctx.PathParamInt64(":id")); err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteLabel", err)
return
}
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index 015af774e3..c55837ff44 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -453,7 +453,7 @@ func GetTeamMember(ctx *context.APIContext) {
if ctx.Written() {
return
}
- teamID := ctx.ParamsInt64("teamid")
+ teamID := ctx.PathParamInt64("teamid")
isTeamMember, err := organization.IsUserInTeams(ctx, u.ID, []int64{teamID})
if err != nil {
ctx.Error(http.StatusInternalServerError, "IsUserInTeams", err)
@@ -645,7 +645,7 @@ func GetTeamRepo(ctx *context.APIContext) {
// getRepositoryByParams get repository by a team's organization ID and repo name
func getRepositoryByParams(ctx *context.APIContext) *repo_model.Repository {
- repo, err := repo_model.GetRepositoryByName(ctx, ctx.Org.Team.OrgID, ctx.Params(":reponame"))
+ repo, err := repo_model.GetRepositoryByName(ctx, ctx.Org.Team.OrgID, ctx.PathParam(":reponame"))
if err != nil {
if repo_model.IsErrRepoNotExist(err) {
ctx.NotFound()
diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go
index f6656d89c6..48ba35ac21 100644
--- a/routers/api/v1/repo/action.go
+++ b/routers/api/v1/repo/action.go
@@ -122,7 +122,7 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) {
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
- _, created, err := secret_service.CreateOrUpdateSecret(ctx, owner.ID, repo.ID, ctx.Params("secretname"), opt.Data)
+ _, created, err := secret_service.CreateOrUpdateSecret(ctx, owner.ID, repo.ID, ctx.PathParam("secretname"), opt.Data)
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
@@ -177,7 +177,7 @@ func (Action) DeleteSecret(ctx *context.APIContext) {
owner := ctx.Repo.Owner
repo := ctx.Repo.Repository
- err := secret_service.DeleteSecretByName(ctx, owner.ID, repo.ID, ctx.Params("secretname"))
+ err := secret_service.DeleteSecretByName(ctx, owner.ID, repo.ID, ctx.PathParam("secretname"))
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "DeleteSecret", err)
@@ -224,7 +224,7 @@ func (Action) GetVariable(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
RepoID: ctx.Repo.Repository.ID,
- Name: ctx.Params("variablename"),
+ Name: ctx.PathParam("variablename"),
})
if err != nil {
if errors.Is(err, util.ErrNotExist) {
@@ -280,7 +280,7 @@ func (Action) DeleteVariable(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- if err := actions_service.DeleteVariableByName(ctx, 0, ctx.Repo.Repository.ID, ctx.Params("variablename")); err != nil {
+ if err := actions_service.DeleteVariableByName(ctx, 0, ctx.Repo.Repository.ID, ctx.PathParam("variablename")); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "DeleteVariableByName", err)
} else if errors.Is(err, util.ErrNotExist) {
@@ -334,7 +334,7 @@ func (Action) CreateVariable(ctx *context.APIContext) {
opt := web.GetForm(ctx).(*api.CreateVariableOption)
repoID := ctx.Repo.Repository.ID
- variableName := ctx.Params("variablename")
+ variableName := ctx.PathParam("variablename")
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
RepoID: repoID,
@@ -402,7 +402,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
RepoID: ctx.Repo.Repository.ID,
- Name: ctx.Params("variablename"),
+ Name: ctx.PathParam("variablename"),
})
if err != nil {
if errors.Is(err, util.ErrNotExist) {
@@ -414,7 +414,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
}
if opt.Name == "" {
- opt.Name = ctx.Params("variablename")
+ opt.Name = ctx.PathParam("variablename")
}
if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
diff --git a/routers/api/v1/repo/blob.go b/routers/api/v1/repo/blob.go
index 3b116666ea..f38086954b 100644
--- a/routers/api/v1/repo/blob.go
+++ b/routers/api/v1/repo/blob.go
@@ -41,7 +41,7 @@ func GetBlob(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- sha := ctx.Params("sha")
+ sha := ctx.PathParam("sha")
if len(sha) == 0 {
ctx.Error(http.StatusBadRequest, "", "sha not provided")
return
diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go
index baab486e52..652fcd9441 100644
--- a/routers/api/v1/repo/branch.go
+++ b/routers/api/v1/repo/branch.go
@@ -56,7 +56,7 @@ func GetBranch(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- branchName := ctx.Params("*")
+ branchName := ctx.PathParam("*")
branch, err := ctx.Repo.GitRepo.GetBranch(branchName)
if err != nil {
@@ -131,7 +131,7 @@ func DeleteBranch(ctx *context.APIContext) {
return
}
- branchName := ctx.Params("*")
+ branchName := ctx.PathParam("*")
if ctx.Repo.Repository.IsEmpty {
ctx.Error(http.StatusForbidden, "", "Git Repository is empty.")
@@ -426,7 +426,7 @@ func GetBranchProtection(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
repo := ctx.Repo.Repository
- bpName := ctx.Params(":name")
+ bpName := ctx.PathParam(":name")
bp, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err)
@@ -724,7 +724,7 @@ func EditBranchProtection(ctx *context.APIContext) {
// "$ref": "#/responses/repoArchivedError"
form := web.GetForm(ctx).(*api.EditBranchProtectionOption)
repo := ctx.Repo.Repository
- bpName := ctx.Params(":name")
+ bpName := ctx.PathParam(":name")
protectBranch, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err)
@@ -992,7 +992,7 @@ func DeleteBranchProtection(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
repo := ctx.Repo.Repository
- bpName := ctx.Params(":name")
+ bpName := ctx.PathParam(":name")
bp, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err)
diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go
index 4ce14f7d01..39c9ba527d 100644
--- a/routers/api/v1/repo/collaborators.go
+++ b/routers/api/v1/repo/collaborators.go
@@ -102,7 +102,7 @@ func IsCollaborator(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
- user, err := user_model.GetUserByName(ctx, ctx.Params(":collaborator"))
+ user, err := user_model.GetUserByName(ctx, ctx.PathParam(":collaborator"))
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
@@ -162,7 +162,7 @@ func AddCollaborator(ctx *context.APIContext) {
form := web.GetForm(ctx).(*api.AddCollaboratorOption)
- collaborator, err := user_model.GetUserByName(ctx, ctx.Params(":collaborator"))
+ collaborator, err := user_model.GetUserByName(ctx, ctx.PathParam(":collaborator"))
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
@@ -227,7 +227,7 @@ func DeleteCollaborator(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
- collaborator, err := user_model.GetUserByName(ctx, ctx.Params(":collaborator"))
+ collaborator, err := user_model.GetUserByName(ctx, ctx.PathParam(":collaborator"))
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
@@ -275,12 +275,12 @@ func GetRepoPermissions(ctx *context.APIContext) {
// "403":
// "$ref": "#/responses/forbidden"
- if !ctx.Doer.IsAdmin && ctx.Doer.LoginName != ctx.Params(":collaborator") && !ctx.IsUserRepoAdmin() {
+ if !ctx.Doer.IsAdmin && ctx.Doer.LoginName != ctx.PathParam(":collaborator") && !ctx.IsUserRepoAdmin() {
ctx.Error(http.StatusForbidden, "User", "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own")
return
}
- collaborator, err := user_model.GetUserByName(ctx, ctx.Params(":collaborator"))
+ collaborator, err := user_model.GetUserByName(ctx, ctx.PathParam(":collaborator"))
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.Error(http.StatusNotFound, "GetUserByName", err)
diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go
index d06a3b4e49..d33be9d80a 100644
--- a/routers/api/v1/repo/commits.go
+++ b/routers/api/v1/repo/commits.go
@@ -63,7 +63,7 @@ func GetSingleCommit(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- sha := ctx.Params(":sha")
+ sha := ctx.PathParam(":sha")
if !git.IsValidRefPattern(sha) {
ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha))
return
@@ -312,8 +312,8 @@ func DownloadCommitDiffOrPatch(ctx *context.APIContext) {
// "$ref": "#/responses/string"
// "404":
// "$ref": "#/responses/notFound"
- sha := ctx.Params(":sha")
- diffType := git.RawDiffType(ctx.Params(":diffType"))
+ sha := ctx.PathParam(":sha")
+ diffType := git.RawDiffType(ctx.PathParam(":diffType"))
if err := git.GetRawDiff(ctx.Repo.GitRepo, sha, diffType, ctx.Resp); err != nil {
if git.IsErrNotExist(err) {
@@ -354,7 +354,7 @@ func GetCommitPullRequest(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- pr, err := issues_model.GetPullRequestByMergedCommit(ctx, ctx.Repo.Repository.ID, ctx.Params(":sha"))
+ pr, err := issues_model.GetPullRequestByMergedCommit(ctx, ctx.Repo.Repository.ID, ctx.PathParam(":sha"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.Error(http.StatusNotFound, "GetPullRequestByMergedCommit", err)
diff --git a/routers/api/v1/repo/compare.go b/routers/api/v1/repo/compare.go
index 429145c714..38e5330b3a 100644
--- a/routers/api/v1/repo/compare.go
+++ b/routers/api/v1/repo/compare.go
@@ -53,7 +53,7 @@ func CompareDiff(ctx *context.APIContext) {
defer gitRepo.Close()
}
- infoPath := ctx.Params("*")
+ infoPath := ctx.PathParam("*")
infos := []string{ctx.Repo.Repository.DefaultBranch, ctx.Repo.Repository.DefaultBranch}
if infoPath != "" {
infos = strings.SplitN(infoPath, "...", 2)
diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go
index 6ecdc1ff67..42483291fc 100644
--- a/routers/api/v1/repo/file.go
+++ b/routers/api/v1/repo/file.go
@@ -294,7 +294,7 @@ func GetArchive(ctx *context.APIContext) {
}
func archiveDownload(ctx *context.APIContext) {
- uri := ctx.Params("*")
+ uri := ctx.PathParam("*")
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
if err != nil {
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
@@ -393,7 +393,7 @@ func GetEditorconfig(ctx *context.APIContext) {
return
}
- fileName := ctx.Params("filename")
+ fileName := ctx.PathParam("filename")
def, err := ec.GetDefinitionForFilename(fileName)
if def == nil {
ctx.NotFound(err)
@@ -577,7 +577,7 @@ func CreateFile(ctx *context.APIContext) {
Files: []*files_service.ChangeRepoFile{
{
Operation: "create",
- TreePath: ctx.Params("*"),
+ TreePath: ctx.PathParam("*"),
ContentReader: contentReader,
},
},
@@ -681,7 +681,7 @@ func UpdateFile(ctx *context.APIContext) {
ContentReader: contentReader,
SHA: apiOpts.SHA,
FromTreePath: apiOpts.FromPath,
- TreePath: ctx.Params("*"),
+ TreePath: ctx.PathParam("*"),
},
},
Message: apiOpts.Message,
@@ -840,7 +840,7 @@ func DeleteFile(ctx *context.APIContext) {
{
Operation: "delete",
SHA: apiOpts.SHA,
- TreePath: ctx.Params("*"),
+ TreePath: ctx.PathParam("*"),
},
},
Message: apiOpts.Message,
@@ -935,7 +935,7 @@ func GetContents(ctx *context.APIContext) {
return
}
- treePath := ctx.Params("*")
+ treePath := ctx.PathParam("*")
ref := ctx.FormTrim("ref")
if fileList, err := files_service.GetContentsOrList(ctx, ctx.Repo.Repository, treePath, ref); err != nil {
diff --git a/routers/api/v1/repo/git_hook.go b/routers/api/v1/repo/git_hook.go
index 26ae84d08d..0887a90096 100644
--- a/routers/api/v1/repo/git_hook.go
+++ b/routers/api/v1/repo/git_hook.go
@@ -79,7 +79,7 @@ func GetGitHook(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- hookID := ctx.Params(":id")
+ hookID := ctx.PathParam(":id")
hook, err := ctx.Repo.GitRepo.GetHook(hookID)
if err != nil {
if err == git.ErrNotValidHook {
@@ -126,7 +126,7 @@ func EditGitHook(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
form := web.GetForm(ctx).(*api.EditGitHookOption)
- hookID := ctx.Params(":id")
+ hookID := ctx.PathParam(":id")
hook, err := ctx.Repo.GitRepo.GetHook(hookID)
if err != nil {
if err == git.ErrNotValidHook {
@@ -175,7 +175,7 @@ func DeleteGitHook(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- hookID := ctx.Params(":id")
+ hookID := ctx.PathParam(":id")
hook, err := ctx.Repo.GitRepo.GetHook(hookID)
if err != nil {
if err == git.ErrNotValidHook {
diff --git a/routers/api/v1/repo/git_ref.go b/routers/api/v1/repo/git_ref.go
index 0fa58425b8..1743c0fc20 100644
--- a/routers/api/v1/repo/git_ref.go
+++ b/routers/api/v1/repo/git_ref.go
@@ -71,7 +71,7 @@ func GetGitRefs(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- getGitRefsInternal(ctx, ctx.Params("*"))
+ getGitRefsInternal(ctx, ctx.PathParam("*"))
}
func getGitRefsInternal(ctx *context.APIContext, filter string) {
diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go
index ffd2313591..9ef57da1b9 100644
--- a/routers/api/v1/repo/hook.go
+++ b/routers/api/v1/repo/hook.go
@@ -109,7 +109,7 @@ func GetHook(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
repo := ctx.Repo
- hookID := ctx.ParamsInt64(":id")
+ hookID := ctx.PathParamInt64(":id")
hook, err := utils.GetRepoHook(ctx, repo.Repository.ID, hookID)
if err != nil {
return
@@ -168,7 +168,7 @@ func TestHook(ctx *context.APIContext) {
ref = r
}
- hookID := ctx.ParamsInt64(":id")
+ hookID := ctx.PathParamInt64(":id")
hook, err := utils.GetRepoHook(ctx, ctx.Repo.Repository.ID, hookID)
if err != nil {
return
@@ -263,7 +263,7 @@ func EditHook(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
form := web.GetForm(ctx).(*api.EditHookOption)
- hookID := ctx.ParamsInt64(":id")
+ hookID := ctx.PathParamInt64(":id")
utils.EditRepoHook(ctx, form, hookID)
}
@@ -296,7 +296,7 @@ func DeleteHook(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "404":
// "$ref": "#/responses/notFound"
- if err := webhook.DeleteWebhookByRepoID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil {
+ if err := webhook.DeleteWebhookByRepoID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":id")); err != nil {
if webhook.IsErrWebhookNotExist(err) {
ctx.NotFound()
} else {
diff --git a/routers/api/v1/repo/hook_test.go b/routers/api/v1/repo/hook_test.go
index 37cf61c1ed..c2f3a972ef 100644
--- a/routers/api/v1/repo/hook_test.go
+++ b/routers/api/v1/repo/hook_test.go
@@ -18,7 +18,7 @@ func TestTestHook(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockAPIContext(t, "user2/repo1/wiki/_pages")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index ddfc36f17d..108504ebb4 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -599,7 +599,7 @@ func GetIssue(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -779,7 +779,7 @@ func EditIssue(ctx *context.APIContext) {
// "$ref": "#/responses/error"
form := web.GetForm(ctx).(*api.EditIssueOption)
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -942,7 +942,7 @@ func DeleteIssue(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound(err)
@@ -998,7 +998,7 @@ func UpdateIssueDeadline(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
form := web.GetForm(ctx).(*api.EditDeadlineOption)
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
diff --git a/routers/api/v1/repo/issue_attachment.go b/routers/api/v1/repo/issue_attachment.go
index ef846a43a3..27c7af2282 100644
--- a/routers/api/v1/repo/issue_attachment.go
+++ b/routers/api/v1/repo/issue_attachment.go
@@ -320,7 +320,7 @@ func DeleteIssueAttachment(ctx *context.APIContext) {
}
func getIssueFromContext(ctx *context.APIContext) *issues_model.Issue {
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64("index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index"))
if err != nil {
ctx.NotFoundOrServerError("GetIssueByIndex", issues_model.IsErrIssueNotExist, err)
return nil
@@ -345,7 +345,7 @@ func getIssueAttachmentSafeWrite(ctx *context.APIContext) *repo_model.Attachment
}
func getIssueAttachmentSafeRead(ctx *context.APIContext, issue *issues_model.Issue) *repo_model.Attachment {
- attachment, err := repo_model.GetAttachmentByID(ctx, ctx.ParamsInt64("attachment_id"))
+ attachment, err := repo_model.GetAttachmentByID(ctx, ctx.PathParamInt64("attachment_id"))
if err != nil {
ctx.NotFoundOrServerError("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err)
return nil
diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go
index 910cc1ce74..f9b5aa816b 100644
--- a/routers/api/v1/repo/issue_comment.go
+++ b/routers/api/v1/repo/issue_comment.go
@@ -68,7 +68,7 @@ func ListIssueComments(ctx *context.APIContext) {
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
return
}
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err)
return
@@ -172,7 +172,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) {
ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err)
return
}
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err)
return
@@ -380,7 +380,7 @@ func CreateIssueComment(ctx *context.APIContext) {
// "$ref": "#/responses/repoArchivedError"
form := web.GetForm(ctx).(*api.CreateIssueCommentOption)
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err)
return
@@ -445,7 +445,7 @@ func GetIssueComment(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrCommentNotExist(err) {
ctx.NotFound(err)
@@ -579,7 +579,7 @@ func EditIssueCommentDeprecated(ctx *context.APIContext) {
}
func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) {
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrCommentNotExist(err) {
ctx.NotFound(err)
@@ -696,7 +696,7 @@ func DeleteIssueCommentDeprecated(ctx *context.APIContext) {
}
func deleteIssueComment(ctx *context.APIContext) {
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrCommentNotExist(err) {
ctx.NotFound(err)
diff --git a/routers/api/v1/repo/issue_comment_attachment.go b/routers/api/v1/repo/issue_comment_attachment.go
index 1ec758ec2c..0863ebd182 100644
--- a/routers/api/v1/repo/issue_comment_attachment.go
+++ b/routers/api/v1/repo/issue_comment_attachment.go
@@ -331,7 +331,7 @@ func DeleteIssueCommentAttachment(ctx *context.APIContext) {
}
func getIssueCommentSafe(ctx *context.APIContext) *issues_model.Comment {
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64("id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64("id"))
if err != nil {
ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err)
return nil
@@ -376,7 +376,7 @@ func canUserWriteIssueCommentAttachment(ctx *context.APIContext, comment *issues
}
func getIssueCommentAttachmentSafeRead(ctx *context.APIContext, comment *issues_model.Comment) *repo_model.Attachment {
- attachment, err := repo_model.GetAttachmentByID(ctx, ctx.ParamsInt64("attachment_id"))
+ attachment, err := repo_model.GetAttachmentByID(ctx, ctx.PathParamInt64("attachment_id"))
if err != nil {
ctx.NotFoundOrServerError("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err)
return nil
diff --git a/routers/api/v1/repo/issue_dependency.go b/routers/api/v1/repo/issue_dependency.go
index c40e92c01b..712c71a682 100644
--- a/routers/api/v1/repo/issue_dependency.go
+++ b/routers/api/v1/repo/issue_dependency.go
@@ -61,7 +61,7 @@ func GetIssueDependencies(ctx *context.APIContext) {
return
}
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound("IsErrIssueNotExist", err)
@@ -499,7 +499,7 @@ func RemoveIssueBlocking(ctx *context.APIContext) {
}
func getParamsIssue(ctx *context.APIContext) *issues_model.Issue {
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound("IsErrIssueNotExist", err)
diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go
index 413693c5ed..2f5ea8931b 100644
--- a/routers/api/v1/repo/issue_label.go
+++ b/routers/api/v1/repo/issue_label.go
@@ -47,7 +47,7 @@ func ListIssueLabels(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -163,7 +163,7 @@ func DeleteIssueLabel(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -178,7 +178,7 @@ func DeleteIssueLabel(ctx *context.APIContext) {
return
}
- label, err := issues_model.GetLabelByID(ctx, ctx.ParamsInt64(":id"))
+ label, err := issues_model.GetLabelByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrLabelNotExist(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
@@ -285,7 +285,7 @@ func ClearIssueLabels(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -309,7 +309,7 @@ func ClearIssueLabels(ctx *context.APIContext) {
}
func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) (*issues_model.Issue, []*issues_model.Label, error) {
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
diff --git a/routers/api/v1/repo/issue_pin.go b/routers/api/v1/repo/issue_pin.go
index af3e06332a..0ef9033291 100644
--- a/routers/api/v1/repo/issue_pin.go
+++ b/routers/api/v1/repo/issue_pin.go
@@ -41,7 +41,7 @@ func PinIssue(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -98,7 +98,7 @@ func UnpinIssue(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -159,7 +159,7 @@ func MoveIssuePin(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -169,7 +169,7 @@ func MoveIssuePin(ctx *context.APIContext) {
return
}
- err = issue.MovePin(ctx, int(ctx.ParamsInt64(":position")))
+ err = issue.MovePin(ctx, int(ctx.PathParamInt64(":position")))
if err != nil {
ctx.Error(http.StatusInternalServerError, "MovePin", err)
return
diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go
index 3ff3d19f13..8d43cd518b 100644
--- a/routers/api/v1/repo/issue_reaction.go
+++ b/routers/api/v1/repo/issue_reaction.go
@@ -51,7 +51,7 @@ func GetIssueCommentReactions(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrCommentNotExist(err) {
ctx.NotFound(err)
@@ -188,7 +188,7 @@ func DeleteIssueCommentReaction(ctx *context.APIContext) {
}
func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOption, isCreateType bool) {
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrCommentNotExist(err) {
ctx.NotFound(err)
@@ -295,7 +295,7 @@ func GetIssueReactions(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -419,7 +419,7 @@ func DeleteIssueReaction(ctx *context.APIContext) {
}
func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, isCreateType bool) {
- issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go
index d9054e8f77..4605ae2110 100644
--- a/routers/api/v1/repo/issue_stopwatch.go
+++ b/routers/api/v1/repo/issue_stopwatch.go
@@ -161,7 +161,7 @@ func DeleteIssueStopwatch(ctx *context.APIContext) {
}
func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*issues_model.Issue, error) {
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go
index a535172462..e51baad0b6 100644
--- a/routers/api/v1/repo/issue_subscription.go
+++ b/routers/api/v1/repo/issue_subscription.go
@@ -104,7 +104,7 @@ func DelIssueSubscription(ctx *context.APIContext) {
}
func setIssueSubscription(ctx *context.APIContext, watch bool) {
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -115,7 +115,7 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) {
return
}
- user, err := user_model.GetUserByName(ctx, ctx.Params(":user"))
+ user, err := user_model.GetUserByName(ctx, ctx.PathParam(":user"))
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.NotFound()
@@ -185,7 +185,7 @@ func CheckIssueSubscription(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
@@ -251,7 +251,7 @@ func GetIssueSubscribers(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound()
diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go
index f83855efac..8d5e9fdad4 100644
--- a/routers/api/v1/repo/issue_tracked_time.go
+++ b/routers/api/v1/repo/issue_tracked_time.go
@@ -75,7 +75,7 @@ func ListTrackedTimes(ctx *context.APIContext) {
ctx.NotFound("Timetracker is disabled")
return
}
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound(err)
@@ -181,7 +181,7 @@ func AddTime(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
form := web.GetForm(ctx).(*api.AddTimeOption)
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound(err)
@@ -264,7 +264,7 @@ func ResetIssueTime(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound(err)
@@ -337,7 +337,7 @@ func DeleteTime(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound(err)
@@ -356,7 +356,7 @@ func DeleteTime(ctx *context.APIContext) {
return
}
- time, err := issues_model.GetTrackedTimeByID(ctx, ctx.ParamsInt64(":id"))
+ time, err := issues_model.GetTrackedTimeByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if db.IsErrNotExist(err) {
ctx.NotFound(err)
@@ -422,7 +422,7 @@ func ListTrackedTimesByUser(ctx *context.APIContext) {
ctx.Error(http.StatusBadRequest, "", "time tracking disabled")
return
}
- user, err := user_model.GetUserByName(ctx, ctx.Params(":timetrackingusername"))
+ user, err := user_model.GetUserByName(ctx, ctx.PathParam(":timetrackingusername"))
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.NotFound(err)
diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go
index 88444a2625..e5115980eb 100644
--- a/routers/api/v1/repo/key.go
+++ b/routers/api/v1/repo/key.go
@@ -143,7 +143,7 @@ func GetDeployKey(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- key, err := asymkey_model.GetDeployKeyByID(ctx, ctx.ParamsInt64(":id"))
+ key, err := asymkey_model.GetDeployKeyByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if asymkey_model.IsErrDeployKeyNotExist(err) {
ctx.NotFound()
@@ -279,7 +279,7 @@ func DeleteDeploykey(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- if err := asymkey_service.DeleteDeployKey(ctx, ctx.Doer, ctx.ParamsInt64(":id")); err != nil {
+ if err := asymkey_service.DeleteDeployKey(ctx, ctx.Doer, ctx.PathParamInt64(":id")); err != nil {
if asymkey_model.IsErrKeyAccessDenied(err) {
ctx.Error(http.StatusForbidden, "", "You do not have access to this key")
} else {
diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go
index b6eb51fd20..c2c43db6a4 100644
--- a/routers/api/v1/repo/label.go
+++ b/routers/api/v1/repo/label.go
@@ -99,7 +99,7 @@ func GetLabel(ctx *context.APIContext) {
l *issues_model.Label
err error
)
- strID := ctx.Params(":id")
+ strID := ctx.PathParam(":id")
if intID, err2 := strconv.ParseInt(strID, 10, 64); err2 != nil {
l, err = issues_model.GetLabelInRepoByName(ctx, ctx.Repo.Repository.ID, strID)
} else {
@@ -212,7 +212,7 @@ func EditLabel(ctx *context.APIContext) {
// "$ref": "#/responses/validationError"
form := web.GetForm(ctx).(*api.EditLabelOption)
- l, err := issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
+ l, err := issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrRepoLabelNotExist(err) {
ctx.NotFound()
@@ -276,7 +276,7 @@ func DeleteLabel(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- if err := issues_model.DeleteLabel(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil {
+ if err := issues_model.DeleteLabel(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":id")); err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteLabel", err)
return
}
diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go
index b9534016e4..abe9e4006a 100644
--- a/routers/api/v1/repo/milestone.go
+++ b/routers/api/v1/repo/milestone.go
@@ -282,7 +282,7 @@ func DeleteMilestone(ctx *context.APIContext) {
// getMilestoneByIDOrName get milestone by ID and if not available by name
func getMilestoneByIDOrName(ctx *context.APIContext) *issues_model.Milestone {
- mile := ctx.Params(":id")
+ mile := ctx.PathParam(":id")
mileID, _ := strconv.ParseInt(mile, 0, 64)
if mileID != 0 {
diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go
index eddd449206..310b82881e 100644
--- a/routers/api/v1/repo/mirror.go
+++ b/routers/api/v1/repo/mirror.go
@@ -224,7 +224,7 @@ func GetPushMirrorByName(ctx *context.APIContext) {
return
}
- mirrorName := ctx.Params(":name")
+ mirrorName := ctx.PathParam(":name")
// Get push mirror of a specific repo by remoteName
pushMirror, exist, err := db.Get[repo_model.PushMirror](ctx, repo_model.PushMirrorOptions{
RepoID: ctx.Repo.Repository.ID,
@@ -325,7 +325,7 @@ func DeletePushMirrorByRemoteName(ctx *context.APIContext) {
return
}
- remoteName := ctx.Params(":name")
+ remoteName := ctx.PathParam(":name")
// Delete push mirror on repo by name.
err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{RepoID: ctx.Repo.Repository.ID, RemoteName: remoteName})
if err != nil {
diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go
index a4a1d4eab7..8689d25e15 100644
--- a/routers/api/v1/repo/notes.go
+++ b/routers/api/v1/repo/notes.go
@@ -52,7 +52,7 @@ func GetNote(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- sha := ctx.Params(":sha")
+ sha := ctx.PathParam(":sha")
if !git.IsValidRefPattern(sha) {
ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha))
return
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index 1fc94708da..ebe876da64 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -187,7 +187,7 @@ func GetPullRequest(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound()
@@ -244,7 +244,7 @@ func GetPullRequestByBaseHead(ctx *context.APIContext) {
var headRepoID int64
var headBranch string
- head := ctx.Params("*")
+ head := ctx.PathParam("*")
if strings.Contains(head, ":") {
split := strings.SplitN(head, ":", 2)
headBranch = split[1]
@@ -272,7 +272,7 @@ func GetPullRequestByBaseHead(ctx *context.APIContext) {
headBranch = head
}
- pr, err := issues_model.GetPullRequestByBaseHeadInfo(ctx, ctx.Repo.Repository.ID, headRepoID, ctx.Params(":base"), headBranch)
+ pr, err := issues_model.GetPullRequestByBaseHeadInfo(ctx, ctx.Repo.Repository.ID, headRepoID, ctx.PathParam(":base"), headBranch)
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound()
@@ -332,7 +332,7 @@ func DownloadPullDiffOrPatch(ctx *context.APIContext) {
// "$ref": "#/responses/string"
// "404":
// "$ref": "#/responses/notFound"
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound()
@@ -342,7 +342,7 @@ func DownloadPullDiffOrPatch(ctx *context.APIContext) {
return
}
var patch bool
- if ctx.Params(":diffType") == "diff" {
+ if ctx.PathParam(":diffType") == "diff" {
patch = false
} else {
patch = true
@@ -590,7 +590,7 @@ func EditPullRequest(ctx *context.APIContext) {
// "$ref": "#/responses/validationError"
form := web.GetForm(ctx).(*api.EditPullRequestOption)
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound()
@@ -804,7 +804,7 @@ func IsPullRequestMerged(ctx *context.APIContext) {
// "404":
// description: pull request has not been merged
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound()
@@ -862,7 +862,7 @@ func MergePullRequest(ctx *context.APIContext) {
form := web.GetForm(ctx).(*forms.MergePullRequestForm)
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound("GetPullRequestByIndex", err)
@@ -1221,7 +1221,7 @@ func UpdatePullRequest(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound()
@@ -1320,7 +1320,7 @@ func CancelScheduledAutoMerge(ctx *context.APIContext) {
// "423":
// "$ref": "#/responses/repoArchivedError"
- pullIndex := ctx.ParamsInt64(":index")
+ pullIndex := ctx.PathParamInt64(":index")
pull, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pullIndex)
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
@@ -1406,7 +1406,7 @@ func GetPullRequestCommits(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound()
@@ -1529,7 +1529,7 @@ func GetPullRequestFiles(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound()
diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go
index 4b481790fb..c2e4966498 100644
--- a/routers/api/v1/repo/pull_review.go
+++ b/routers/api/v1/repo/pull_review.go
@@ -61,7 +61,7 @@ func ListPullReviews(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound("GetPullRequestByIndex", err)
@@ -307,7 +307,7 @@ func CreatePullReview(ctx *context.APIContext) {
// "$ref": "#/responses/validationError"
opts := web.GetForm(ctx).(*api.CreatePullReviewOptions)
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound("GetPullRequestByIndex", err)
@@ -534,7 +534,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest
// prepareSingleReview return review, related pull and false or nil, nil and true if an error happen
func prepareSingleReview(ctx *context.APIContext) (*issues_model.Review, *issues_model.PullRequest, bool) {
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound("GetPullRequestByIndex", err)
@@ -544,7 +544,7 @@ func prepareSingleReview(ctx *context.APIContext) (*issues_model.Review, *issues
return nil, nil, true
}
- review, err := issues_model.GetReviewByID(ctx, ctx.ParamsInt64(":id"))
+ review, err := issues_model.GetReviewByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrReviewNotExist(err) {
ctx.NotFound("GetReviewByID", err)
@@ -658,7 +658,7 @@ func DeleteReviewRequests(ctx *context.APIContext) {
}
func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions, isAdd bool) {
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound("GetPullRequestByIndex", err)
diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go
index f92fb86f5c..ef587f6274 100644
--- a/routers/api/v1/repo/release.go
+++ b/routers/api/v1/repo/release.go
@@ -50,7 +50,7 @@ func GetRelease(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- id := ctx.ParamsInt64(":id")
+ id := ctx.PathParamInt64(":id")
release, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err)
@@ -317,7 +317,7 @@ func EditRelease(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
form := web.GetForm(ctx).(*api.EditReleaseOption)
- id := ctx.ParamsInt64(":id")
+ id := ctx.PathParamInt64(":id")
rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err)
@@ -394,7 +394,7 @@ func DeleteRelease(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
- id := ctx.ParamsInt64(":id")
+ id := ctx.PathParamInt64(":id")
rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err)
diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go
index 59fd83e3a2..4a2371e012 100644
--- a/routers/api/v1/repo/release_attachment.go
+++ b/routers/api/v1/repo/release_attachment.go
@@ -72,12 +72,12 @@ func GetReleaseAttachment(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- releaseID := ctx.ParamsInt64(":id")
+ releaseID := ctx.PathParamInt64(":id")
if !checkReleaseMatchRepo(ctx, releaseID) {
return
}
- attachID := ctx.ParamsInt64(":attachment_id")
+ attachID := ctx.PathParamInt64(":attachment_id")
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
if err != nil {
if repo_model.IsErrAttachmentNotExist(err) {
@@ -126,7 +126,7 @@ func ListReleaseAttachments(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- releaseID := ctx.ParamsInt64(":id")
+ releaseID := ctx.PathParamInt64(":id")
release, err := repo_model.GetReleaseByID(ctx, releaseID)
if err != nil {
if repo_model.IsErrReleaseNotExist(err) {
@@ -199,7 +199,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) {
}
// Check if release exists an load release
- releaseID := ctx.ParamsInt64(":id")
+ releaseID := ctx.PathParamInt64(":id")
if !checkReleaseMatchRepo(ctx, releaseID) {
return
}
@@ -297,12 +297,12 @@ func EditReleaseAttachment(ctx *context.APIContext) {
form := web.GetForm(ctx).(*api.EditAttachmentOptions)
// Check if release exists an load release
- releaseID := ctx.ParamsInt64(":id")
+ releaseID := ctx.PathParamInt64(":id")
if !checkReleaseMatchRepo(ctx, releaseID) {
return
}
- attachID := ctx.ParamsInt64(":attachment_id")
+ attachID := ctx.PathParamInt64(":attachment_id")
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
if err != nil {
if repo_model.IsErrAttachmentNotExist(err) {
@@ -365,12 +365,12 @@ func DeleteReleaseAttachment(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
// Check if release exists an load release
- releaseID := ctx.ParamsInt64(":id")
+ releaseID := ctx.PathParamInt64(":id")
if !checkReleaseMatchRepo(ctx, releaseID) {
return
}
- attachID := ctx.ParamsInt64(":attachment_id")
+ attachID := ctx.PathParamInt64(":attachment_id")
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
if err != nil {
if repo_model.IsErrAttachmentNotExist(err) {
diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go
index f845fad53b..6df47af8d9 100644
--- a/routers/api/v1/repo/release_tags.go
+++ b/routers/api/v1/repo/release_tags.go
@@ -42,7 +42,7 @@ func GetReleaseByTag(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- tag := ctx.Params(":tag")
+ tag := ctx.PathParam(":tag")
release, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tag)
if err != nil {
@@ -95,7 +95,7 @@ func DeleteReleaseByTag(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
- tag := ctx.Params(":tag")
+ tag := ctx.PathParam(":tag")
release, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tag)
if err != nil {
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 594f2d86f6..1bcec8fcf7 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -107,7 +107,7 @@ func Search(ctx *context.APIContext) {
// - name: sort
// in: query
// description: sort repos by attribute. Supported values are
- // "alpha", "created", "updated", "size", and "id".
+ // "alpha", "created", "updated", "size", "git_size", "lfs_size", "stars", "forks" and "id".
// Default is "alpha"
// type: string
// - name: order
@@ -184,7 +184,7 @@ func Search(ctx *context.APIContext) {
if len(sortOrder) == 0 {
sortOrder = "asc"
}
- if searchModeMap, ok := repo_model.SearchOrderByMap[sortOrder]; ok {
+ if searchModeMap, ok := repo_model.OrderByMap[sortOrder]; ok {
if orderBy, ok := searchModeMap[sortMode]; ok {
opts.OrderBy = orderBy
} else {
@@ -491,7 +491,7 @@ func CreateOrgRepo(ctx *context.APIContext) {
// "403":
// "$ref": "#/responses/forbidden"
opt := web.GetForm(ctx).(*api.CreateRepoOption)
- org, err := organization.GetOrgByName(ctx, ctx.Params(":org"))
+ org, err := organization.GetOrgByName(ctx, ctx.PathParam(":org"))
if err != nil {
if organization.IsErrOrgNotExist(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
@@ -571,7 +571,7 @@ func GetByID(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- repo, err := repo_model.GetRepositoryByID(ctx, ctx.ParamsInt64(":id"))
+ repo, err := repo_model.GetRepositoryByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if repo_model.IsErrRepoNotExist(err) {
ctx.NotFound()
diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go
index 9e36ea0aed..8c910a68f9 100644
--- a/routers/api/v1/repo/status.go
+++ b/routers/api/v1/repo/status.go
@@ -53,7 +53,7 @@ func NewCommitStatus(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
form := web.GetForm(ctx).(*api.CreateStatusOption)
- sha := ctx.Params("sha")
+ sha := ctx.PathParam("sha")
if len(sha) == 0 {
ctx.Error(http.StatusBadRequest, "sha not given", nil)
return
@@ -123,7 +123,7 @@ func GetCommitStatuses(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- getCommitStatuses(ctx, ctx.Params("sha"))
+ getCommitStatuses(ctx, ctx.PathParam("sha"))
}
// GetCommitStatusesByRef returns all statuses for any given commit ref
@@ -177,7 +177,7 @@ func GetCommitStatusesByRef(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- filter := utils.ResolveRefOrSha(ctx, ctx.Params("ref"))
+ filter := utils.ResolveRefOrSha(ctx, ctx.PathParam("ref"))
if ctx.Written() {
return
}
@@ -257,7 +257,7 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- sha := utils.ResolveRefOrSha(ctx, ctx.Params("ref"))
+ sha := utils.ResolveRefOrSha(ctx, ctx.PathParam("ref"))
if ctx.Written() {
return
}
diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go
index 8577a0e896..a72df78666 100644
--- a/routers/api/v1/repo/tag.go
+++ b/routers/api/v1/repo/tag.go
@@ -7,9 +7,13 @@ import (
"errors"
"fmt"
"net/http"
+ "strings"
"code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
+ "code.gitea.io/gitea/models/organization"
repo_model "code.gitea.io/gitea/models/repo"
+ user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
@@ -98,7 +102,7 @@ func GetAnnotatedTag(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- sha := ctx.Params("sha")
+ sha := ctx.PathParam("sha")
if len(sha) == 0 {
ctx.Error(http.StatusBadRequest, "", "SHA not provided")
return
@@ -143,7 +147,7 @@ func GetTag(ctx *context.APIContext) {
// "$ref": "#/responses/Tag"
// "404":
// "$ref": "#/responses/notFound"
- tagName := ctx.Params("*")
+ tagName := ctx.PathParam("*")
tag, err := ctx.Repo.GitRepo.GetTag(tagName)
if err != nil {
@@ -259,7 +263,7 @@ func DeleteTag(ctx *context.APIContext) {
// "$ref": "#/responses/validationError"
// "423":
// "$ref": "#/responses/repoArchivedError"
- tagName := ctx.Params("*")
+ tagName := ctx.PathParam("*")
tag, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tagName)
if err != nil {
@@ -287,3 +291,349 @@ func DeleteTag(ctx *context.APIContext) {
ctx.Status(http.StatusNoContent)
}
+
+// ListTagProtection lists tag protections for a repo
+func ListTagProtection(ctx *context.APIContext) {
+ // swagger:operation GET /repos/{owner}/{repo}/tag_protections repository repoListTagProtection
+ // ---
+ // summary: List tag protections for a repository
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/TagProtectionList"
+
+ repo := ctx.Repo.Repository
+ pts, err := git_model.GetProtectedTags(ctx, repo.ID)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetProtectedTags", err)
+ return
+ }
+ apiPts := make([]*api.TagProtection, len(pts))
+ for i := range pts {
+ apiPts[i] = convert.ToTagProtection(ctx, pts[i], repo)
+ }
+
+ ctx.JSON(http.StatusOK, apiPts)
+}
+
+// GetTagProtection gets a tag protection
+func GetTagProtection(ctx *context.APIContext) {
+ // swagger:operation GET /repos/{owner}/{repo}/tag_protections/{id} repository repoGetTagProtection
+ // ---
+ // summary: Get a specific tag protection for the repository
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: id
+ // in: path
+ // description: id of the tag protect to get
+ // type: integer
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/TagProtection"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ repo := ctx.Repo.Repository
+ id := ctx.PathParamInt64(":id")
+ pt, err := git_model.GetProtectedTagByID(ctx, id)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err)
+ return
+ }
+
+ if pt == nil || repo.ID != pt.RepoID {
+ ctx.NotFound()
+ return
+ }
+
+ ctx.JSON(http.StatusOK, convert.ToTagProtection(ctx, pt, repo))
+}
+
+// CreateTagProtection creates a tag protection for a repo
+func CreateTagProtection(ctx *context.APIContext) {
+ // swagger:operation POST /repos/{owner}/{repo}/tag_protections repository repoCreateTagProtection
+ // ---
+ // summary: Create a tag protections for a repository
+ // consumes:
+ // - application/json
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: body
+ // in: body
+ // schema:
+ // "$ref": "#/definitions/CreateTagProtectionOption"
+ // responses:
+ // "201":
+ // "$ref": "#/responses/TagProtection"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+ // "423":
+ // "$ref": "#/responses/repoArchivedError"
+
+ form := web.GetForm(ctx).(*api.CreateTagProtectionOption)
+ repo := ctx.Repo.Repository
+
+ namePattern := strings.TrimSpace(form.NamePattern)
+ if namePattern == "" {
+ ctx.Error(http.StatusBadRequest, "name_pattern are empty", "name_pattern are empty")
+ return
+ }
+
+ if len(form.WhitelistUsernames) == 0 && len(form.WhitelistTeams) == 0 {
+ ctx.Error(http.StatusBadRequest, "both whitelist_usernames and whitelist_teams are empty", "both whitelist_usernames and whitelist_teams are empty")
+ return
+ }
+
+ pt, err := git_model.GetProtectedTagByNamePattern(ctx, repo.ID, namePattern)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetProtectTagOfRepo", err)
+ return
+ } else if pt != nil {
+ ctx.Error(http.StatusForbidden, "Create tag protection", "Tag protection already exist")
+ return
+ }
+
+ var whitelistUsers, whitelistTeams []int64
+ whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.WhitelistUsernames, false)
+ if err != nil {
+ if user_model.IsErrUserNotExist(err) {
+ ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
+ return
+ }
+ ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
+ return
+ }
+
+ if repo.Owner.IsOrganization() {
+ whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.WhitelistTeams, false)
+ if err != nil {
+ if organization.IsErrTeamNotExist(err) {
+ ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
+ return
+ }
+ ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
+ return
+ }
+ }
+
+ protectTag := &git_model.ProtectedTag{
+ RepoID: repo.ID,
+ NamePattern: strings.TrimSpace(namePattern),
+ AllowlistUserIDs: whitelistUsers,
+ AllowlistTeamIDs: whitelistTeams,
+ }
+ if err := git_model.InsertProtectedTag(ctx, protectTag); err != nil {
+ ctx.Error(http.StatusInternalServerError, "InsertProtectedTag", err)
+ return
+ }
+
+ pt, err = git_model.GetProtectedTagByID(ctx, protectTag.ID)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err)
+ return
+ }
+
+ if pt == nil || pt.RepoID != repo.ID {
+ ctx.Error(http.StatusInternalServerError, "New tag protection not found", err)
+ return
+ }
+
+ ctx.JSON(http.StatusCreated, convert.ToTagProtection(ctx, pt, repo))
+}
+
+// EditTagProtection edits a tag protection for a repo
+func EditTagProtection(ctx *context.APIContext) {
+ // swagger:operation PATCH /repos/{owner}/{repo}/tag_protections/{id} repository repoEditTagProtection
+ // ---
+ // summary: Edit a tag protections for a repository. Only fields that are set will be changed
+ // consumes:
+ // - application/json
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: id
+ // in: path
+ // description: id of protected tag
+ // type: integer
+ // required: true
+ // - name: body
+ // in: body
+ // schema:
+ // "$ref": "#/definitions/EditTagProtectionOption"
+ // responses:
+ // "200":
+ // "$ref": "#/responses/TagProtection"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+ // "423":
+ // "$ref": "#/responses/repoArchivedError"
+
+ repo := ctx.Repo.Repository
+ form := web.GetForm(ctx).(*api.EditTagProtectionOption)
+
+ id := ctx.PathParamInt64(":id")
+ pt, err := git_model.GetProtectedTagByID(ctx, id)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err)
+ return
+ }
+
+ if pt == nil || pt.RepoID != repo.ID {
+ ctx.NotFound()
+ return
+ }
+
+ if form.NamePattern != nil {
+ pt.NamePattern = *form.NamePattern
+ }
+
+ var whitelistUsers, whitelistTeams []int64
+ if form.WhitelistTeams != nil {
+ if repo.Owner.IsOrganization() {
+ whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.WhitelistTeams, false)
+ if err != nil {
+ if organization.IsErrTeamNotExist(err) {
+ ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err)
+ return
+ }
+ ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err)
+ return
+ }
+ }
+ pt.AllowlistTeamIDs = whitelistTeams
+ }
+
+ if form.WhitelistUsernames != nil {
+ whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.WhitelistUsernames, false)
+ if err != nil {
+ if user_model.IsErrUserNotExist(err) {
+ ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err)
+ return
+ }
+ ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err)
+ return
+ }
+ pt.AllowlistUserIDs = whitelistUsers
+ }
+
+ err = git_model.UpdateProtectedTag(ctx, pt)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "UpdateProtectedTag", err)
+ return
+ }
+
+ pt, err = git_model.GetProtectedTagByID(ctx, id)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err)
+ return
+ }
+
+ if pt == nil || pt.RepoID != repo.ID {
+ ctx.Error(http.StatusInternalServerError, "New tag protection not found", "New tag protection not found")
+ return
+ }
+
+ ctx.JSON(http.StatusOK, convert.ToTagProtection(ctx, pt, repo))
+}
+
+// DeleteTagProtection
+func DeleteTagProtection(ctx *context.APIContext) {
+ // swagger:operation DELETE /repos/{owner}/{repo}/tag_protections/{id} repository repoDeleteTagProtection
+ // ---
+ // summary: Delete a specific tag protection for the repository
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: id
+ // in: path
+ // description: id of protected tag
+ // type: integer
+ // required: true
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ repo := ctx.Repo.Repository
+ id := ctx.PathParamInt64(":id")
+ pt, err := git_model.GetProtectedTagByID(ctx, id)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err)
+ return
+ }
+
+ if pt == nil || pt.RepoID != repo.ID {
+ ctx.NotFound()
+ return
+ }
+
+ err = git_model.DeleteProtectedTag(ctx, pt)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "DeleteProtectedTag", err)
+ return
+ }
+
+ ctx.Status(http.StatusNoContent)
+}
diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go
index 0ecf3a39d8..ddd325482d 100644
--- a/routers/api/v1/repo/teams.go
+++ b/routers/api/v1/repo/teams.go
@@ -222,7 +222,7 @@ func changeRepoTeam(ctx *context.APIContext, add bool) {
}
func getTeamByParam(ctx *context.APIContext) *organization.Team {
- team, err := organization.GetTeam(ctx, ctx.Repo.Owner.ID, ctx.Params(":team"))
+ team, err := organization.GetTeam(ctx, ctx.Repo.Owner.ID, ctx.PathParam(":team"))
if err != nil {
if organization.IsErrTeamNotExist(err) {
ctx.Error(http.StatusNotFound, "TeamNotExit", err)
diff --git a/routers/api/v1/repo/topic.go b/routers/api/v1/repo/topic.go
index 9852caa989..6b9eedf6e0 100644
--- a/routers/api/v1/repo/topic.go
+++ b/routers/api/v1/repo/topic.go
@@ -162,7 +162,7 @@ func AddTopic(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/invalidTopicsError"
- topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic")))
+ topicName := strings.TrimSpace(strings.ToLower(ctx.PathParam(":topic")))
if !repo_model.ValidateTopic(topicName) {
ctx.JSON(http.StatusUnprocessableEntity, map[string]any{
@@ -229,7 +229,7 @@ func DeleteTopic(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/invalidTopicsError"
- topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic")))
+ topicName := strings.TrimSpace(strings.ToLower(ctx.PathParam(":topic")))
if !repo_model.ValidateTopic(topicName) {
ctx.JSON(http.StatusUnprocessableEntity, map[string]any{
diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go
index 353a996d5b..efb247c19e 100644
--- a/routers/api/v1/repo/tree.go
+++ b/routers/api/v1/repo/tree.go
@@ -56,7 +56,7 @@ func GetTree(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- sha := ctx.Params(":sha")
+ sha := ctx.PathParam(":sha")
if len(sha) == 0 {
ctx.Error(http.StatusBadRequest, "", "sha not provided")
return
diff --git a/routers/api/v1/shared/block.go b/routers/api/v1/shared/block.go
index a1e65625ed..490a48f81c 100644
--- a/routers/api/v1/shared/block.go
+++ b/routers/api/v1/shared/block.go
@@ -40,7 +40,7 @@ func ListBlocks(ctx *context.APIContext, blocker *user_model.User) {
}
func CheckUserBlock(ctx *context.APIContext, blocker *user_model.User) {
- blockee, err := user_model.GetUserByName(ctx, ctx.Params("username"))
+ blockee, err := user_model.GetUserByName(ctx, ctx.PathParam("username"))
if err != nil {
ctx.NotFound("GetUserByName", err)
return
@@ -60,7 +60,7 @@ func CheckUserBlock(ctx *context.APIContext, blocker *user_model.User) {
}
func BlockUser(ctx *context.APIContext, blocker *user_model.User) {
- blockee, err := user_model.GetUserByName(ctx, ctx.Params("username"))
+ blockee, err := user_model.GetUserByName(ctx, ctx.PathParam("username"))
if err != nil {
ctx.NotFound("GetUserByName", err)
return
@@ -79,7 +79,7 @@ func BlockUser(ctx *context.APIContext, blocker *user_model.User) {
}
func UnblockUser(ctx *context.APIContext, doer, blocker *user_model.User) {
- blockee, err := user_model.GetUserByName(ctx, ctx.Params("username"))
+ blockee, err := user_model.GetUserByName(ctx, ctx.PathParam("username"))
if err != nil {
ctx.NotFound("GetUserByName", err)
return
diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go
index cd551cbdfa..1de58632d5 100644
--- a/routers/api/v1/swagger/options.go
+++ b/routers/api/v1/swagger/options.go
@@ -170,6 +170,12 @@ type swaggerParameterBodies struct {
// in:body
CreateTagOption api.CreateTagOption
+ // in:body
+ CreateTagProtectionOption api.CreateTagProtectionOption
+
+ // in:body
+ EditTagProtectionOption api.EditTagProtectionOption
+
// in:body
CreateAccessTokenOption api.CreateAccessTokenOption
diff --git a/routers/api/v1/swagger/repo.go b/routers/api/v1/swagger/repo.go
index fcd34a63a9..345835f9a5 100644
--- a/routers/api/v1/swagger/repo.go
+++ b/routers/api/v1/swagger/repo.go
@@ -70,6 +70,20 @@ type swaggerResponseAnnotatedTag struct {
Body api.AnnotatedTag `json:"body"`
}
+// TagProtectionList
+// swagger:response TagProtectionList
+type swaggerResponseTagProtectionList struct {
+ // in:body
+ Body []api.TagProtection `json:"body"`
+}
+
+// TagProtection
+// swagger:response TagProtection
+type swaggerResponseTagProtection struct {
+ // in:body
+ Body api.TagProtection `json:"body"`
+}
+
// Reference
// swagger:response Reference
type swaggerResponseReference struct {
diff --git a/routers/api/v1/user/action.go b/routers/api/v1/user/action.go
index bf78c2c864..22707196f4 100644
--- a/routers/api/v1/user/action.go
+++ b/routers/api/v1/user/action.go
@@ -49,7 +49,7 @@ func CreateOrUpdateSecret(ctx *context.APIContext) {
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
- _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Doer.ID, 0, ctx.Params("secretname"), opt.Data)
+ _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Doer.ID, 0, ctx.PathParam("secretname"), opt.Data)
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
@@ -91,7 +91,7 @@ func DeleteSecret(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- err := secret_service.DeleteSecretByName(ctx, ctx.Doer.ID, 0, ctx.Params("secretname"))
+ err := secret_service.DeleteSecretByName(ctx, ctx.Doer.ID, 0, ctx.PathParam("secretname"))
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "DeleteSecret", err)
@@ -138,7 +138,7 @@ func CreateVariable(ctx *context.APIContext) {
opt := web.GetForm(ctx).(*api.CreateVariableOption)
ownerID := ctx.Doer.ID
- variableName := ctx.Params("variablename")
+ variableName := ctx.PathParam("variablename")
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
OwnerID: ownerID,
@@ -198,7 +198,7 @@ func UpdateVariable(ctx *context.APIContext) {
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
OwnerID: ctx.Doer.ID,
- Name: ctx.Params("variablename"),
+ Name: ctx.PathParam("variablename"),
})
if err != nil {
if errors.Is(err, util.ErrNotExist) {
@@ -210,7 +210,7 @@ func UpdateVariable(ctx *context.APIContext) {
}
if opt.Name == "" {
- opt.Name = ctx.Params("variablename")
+ opt.Name = ctx.PathParam("variablename")
}
if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
@@ -247,7 +247,7 @@ func DeleteVariable(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- if err := actions_service.DeleteVariableByName(ctx, ctx.Doer.ID, 0, ctx.Params("variablename")); err != nil {
+ if err := actions_service.DeleteVariableByName(ctx, ctx.Doer.ID, 0, ctx.PathParam("variablename")); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "DeleteVariableByName", err)
} else if errors.Is(err, util.ErrNotExist) {
@@ -284,7 +284,7 @@ func GetVariable(ctx *context.APIContext) {
v, err := actions_service.GetVariable(ctx, actions_model.FindVariablesOpts{
OwnerID: ctx.Doer.ID,
- Name: ctx.Params("variablename"),
+ Name: ctx.PathParam("variablename"),
})
if err != nil {
if errors.Is(err, util.ErrNotExist) {
diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go
index 88e314ed31..60354b1f26 100644
--- a/routers/api/v1/user/app.go
+++ b/routers/api/v1/user/app.go
@@ -160,7 +160,7 @@ func DeleteAccessToken(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/error"
- token := ctx.Params(":id")
+ token := ctx.PathParam(":id")
tokenID, _ := strconv.ParseInt(token, 0, 64)
if tokenID == 0 {
@@ -300,7 +300,7 @@ func DeleteOauth2Application(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "404":
// "$ref": "#/responses/notFound"
- appID := ctx.ParamsInt64(":id")
+ appID := ctx.PathParamInt64(":id")
if err := auth_model.DeleteOAuth2Application(ctx, appID, ctx.Doer.ID); err != nil {
if auth_model.IsErrOAuthApplicationNotFound(err) {
ctx.NotFound()
@@ -332,7 +332,7 @@ func GetOauth2Application(ctx *context.APIContext) {
// "$ref": "#/responses/OAuth2Application"
// "404":
// "$ref": "#/responses/notFound"
- appID := ctx.ParamsInt64(":id")
+ appID := ctx.PathParamInt64(":id")
app, err := auth_model.GetOAuth2ApplicationByID(ctx, appID)
if err != nil {
if auth_model.IsErrOauthClientIDInvalid(err) || auth_model.IsErrOAuthApplicationNotFound(err) {
@@ -376,7 +376,7 @@ func UpdateOauth2Application(ctx *context.APIContext) {
// "$ref": "#/responses/OAuth2Application"
// "404":
// "$ref": "#/responses/notFound"
- appID := ctx.ParamsInt64(":id")
+ appID := ctx.PathParamInt64(":id")
data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions)
diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go
index 5a2f995e1b..ba5c0fdc45 100644
--- a/routers/api/v1/user/gpg_key.go
+++ b/routers/api/v1/user/gpg_key.go
@@ -116,7 +116,7 @@ func GetGPGKey(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- key, err := asymkey_model.GetGPGKeyForUserByID(ctx, ctx.Doer.ID, ctx.ParamsInt64(":id"))
+ key, err := asymkey_model.GetGPGKeyForUserByID(ctx, ctx.Doer.ID, ctx.PathParamInt64(":id"))
if err != nil {
if asymkey_model.IsErrGPGKeyNotExist(err) {
ctx.NotFound()
@@ -280,7 +280,7 @@ func DeleteGPGKey(ctx *context.APIContext) {
return
}
- if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.ParamsInt64(":id")); err != nil {
+ if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.PathParamInt64(":id")); err != nil {
if asymkey_model.IsErrGPGKeyAccessDenied(err) {
ctx.Error(http.StatusForbidden, "", "You do not have access to this key")
} else {
diff --git a/routers/api/v1/user/helper.go b/routers/api/v1/user/helper.go
index 8b5c64e291..23a526cd67 100644
--- a/routers/api/v1/user/helper.go
+++ b/routers/api/v1/user/helper.go
@@ -12,7 +12,7 @@ import (
// GetUserByParamsName get user by name
func GetUserByParamsName(ctx *context.APIContext, name string) *user_model.User {
- username := ctx.Params(name)
+ username := ctx.PathParam(name)
user, err := user_model.GetUserByName(ctx, username)
if err != nil {
if user_model.IsErrUserNotExist(err) {
diff --git a/routers/api/v1/user/hook.go b/routers/api/v1/user/hook.go
index 9d9ca5bf01..b4605c8a29 100644
--- a/routers/api/v1/user/hook.go
+++ b/routers/api/v1/user/hook.go
@@ -57,7 +57,7 @@ func GetHook(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/Hook"
- hook, err := utils.GetOwnerHook(ctx, ctx.Doer.ID, ctx.ParamsInt64("id"))
+ hook, err := utils.GetOwnerHook(ctx, ctx.Doer.ID, ctx.PathParamInt64("id"))
if err != nil {
return
}
@@ -129,7 +129,7 @@ func EditHook(ctx *context.APIContext) {
ctx,
ctx.Doer,
web.GetForm(ctx).(*api.EditHookOption),
- ctx.ParamsInt64("id"),
+ ctx.PathParamInt64("id"),
)
}
@@ -154,6 +154,6 @@ func DeleteHook(ctx *context.APIContext) {
utils.DeleteOwnerHook(
ctx,
ctx.Doer,
- ctx.ParamsInt64("id"),
+ ctx.PathParamInt64("id"),
)
}
diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go
index d9456e7ec6..e4278c2ec0 100644
--- a/routers/api/v1/user/key.go
+++ b/routers/api/v1/user/key.go
@@ -55,7 +55,7 @@ func listPublicKeys(ctx *context.APIContext, user *user_model.User) {
var count int
fingerprint := ctx.FormString("fingerprint")
- username := ctx.Params("username")
+ username := ctx.PathParam("username")
if fingerprint != "" {
var userID int64 // Unrestricted
@@ -179,7 +179,7 @@ func GetPublicKey(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- key, err := asymkey_model.GetPublicKeyByID(ctx, ctx.ParamsInt64(":id"))
+ key, err := asymkey_model.GetPublicKeyByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if asymkey_model.IsErrKeyNotExist(err) {
ctx.NotFound()
@@ -274,7 +274,7 @@ func DeletePublicKey(ctx *context.APIContext) {
return
}
- id := ctx.ParamsInt64(":id")
+ id := ctx.PathParamInt64(":id")
externallyManaged, err := asymkey_model.PublicKeyIsExternallyManaged(ctx, id)
if err != nil {
if asymkey_model.IsErrKeyNotExist(err) {
diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go
index 09147cd2ae..fedad87fc4 100644
--- a/routers/api/v1/user/user.go
+++ b/routers/api/v1/user/user.go
@@ -113,7 +113,7 @@ func GetInfo(ctx *context.APIContext) {
if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) {
// fake ErrUserNotExist error message to not leak information about existence
- ctx.NotFound("GetUserByName", user_model.ErrUserNotExist{Name: ctx.Params(":username")})
+ ctx.NotFound("GetUserByName", user_model.ErrUserNotExist{Name: ctx.PathParam(":username")})
return
}
ctx.JSON(http.StatusOK, convert.ToUser(ctx, ctx.ContextUser, ctx.Doer))
diff --git a/routers/common/markup.go b/routers/common/markup.go
index f7d096008a..0a00eac7d4 100644
--- a/routers/common/markup.go
+++ b/routers/common/markup.go
@@ -7,63 +7,67 @@ package common
import (
"fmt"
"net/http"
+ "path"
"strings"
repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/context"
-
- "mvdan.cc/xurls/v2"
)
// RenderMarkup renders markup text for the /markup and /markdown endpoints
-func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPrefix, filePath string, wiki bool) {
- var markupType string
- relativePath := ""
+func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPathContext, filePath string, wiki bool) {
+ // urlPathContext format is "/subpath/{user}/{repo}/src/{branch, commit, tag}/{identifier/path}/{file/dir}"
+ // filePath is the path of the file to render if the end user is trying to preview a repo file (mode == "file")
+ // filePath will be used as RenderContext.RelativePath
- if len(text) == 0 {
- _, _ = ctx.Write([]byte(""))
- return
+ // for example, when previewing file "/gitea/owner/repo/src/branch/features/feat-123/doc/CHANGE.md", then filePath is "doc/CHANGE.md"
+ // and the urlPathContext is "/gitea/owner/repo/src/branch/features/feat-123/doc"
+
+ var markupType, relativePath string
+
+ links := markup.Links{AbsolutePrefix: true}
+ if urlPathContext != "" {
+ links.Base = fmt.Sprintf("%s%s", httplib.GuessCurrentHostURL(ctx), urlPathContext)
}
switch mode {
case "markdown":
// Raw markdown
if err := markdown.RenderRaw(&markup.RenderContext{
- Ctx: ctx,
- Links: markup.Links{
- AbsolutePrefix: true,
- Base: urlPrefix,
- },
+ Ctx: ctx,
+ Links: links,
}, strings.NewReader(text), ctx.Resp); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
}
return
case "comment":
- // Comment as markdown
+ // Issue & comment content
markupType = markdown.MarkupName
case "gfm":
- // Github Flavored Markdown as document
+ // GitHub Flavored Markdown
markupType = markdown.MarkupName
case "file":
- // File as document based on file extension
- markupType = ""
+ markupType = "" // render the repo file content by its extension
relativePath = filePath
default:
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", mode))
return
}
- if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) {
- // check if urlPrefix is already set to a URL
- linkRegex, _ := xurls.StrictMatchingScheme("https?://")
- m := linkRegex.FindStringIndex(urlPrefix)
- if m == nil {
- urlPrefix = util.URLJoin(setting.AppURL, urlPrefix)
- }
+ fields := strings.SplitN(strings.TrimPrefix(urlPathContext, setting.AppSubURL+"/"), "/", 5)
+ if len(fields) == 5 && fields[2] == "src" && (fields[3] == "branch" || fields[3] == "commit" || fields[3] == "tag") {
+ // absolute base prefix is something like "https://host/subpath/{user}/{repo}"
+ absoluteBasePrefix := fmt.Sprintf("%s%s/%s", httplib.GuessCurrentAppURL(ctx), fields[0], fields[1])
+
+ fileDir := path.Dir(filePath) // it is "doc" if filePath is "doc/CHANGE.md"
+ refPath := strings.Join(fields[3:], "/") // it is "branch/features/feat-12/doc"
+ refPath = strings.TrimSuffix(refPath, "/"+fileDir) // now we get the correct branch path: "branch/features/feat-12"
+
+ links = markup.Links{AbsolutePrefix: true, Base: absoluteBasePrefix, BranchPath: refPath, TreePath: fileDir}
}
meta := map[string]string{}
@@ -81,12 +85,9 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
}
if err := markup.Render(&markup.RenderContext{
- Ctx: ctx,
- Repo: repoCtx,
- Links: markup.Links{
- AbsolutePrefix: true,
- Base: urlPrefix,
- },
+ Ctx: ctx,
+ Repo: repoCtx,
+ Links: links,
Metas: meta,
IsWiki: wiki,
Type: markupType,
diff --git a/routers/common/middleware.go b/routers/common/middleware.go
index 8b661993bb..51e42d87a0 100644
--- a/routers/common/middleware.go
+++ b/routers/common/middleware.go
@@ -19,13 +19,23 @@ import (
"gitea.com/go-chi/session"
"github.com/chi-middleware/proxy"
- chi "github.com/go-chi/chi/v5"
+ "github.com/go-chi/chi/v5"
)
// ProtocolMiddlewares returns HTTP protocol related middlewares, and it provides a global panic recovery
func ProtocolMiddlewares() (handlers []any) {
- // first, normalize the URL path
- handlers = append(handlers, stripSlashesMiddleware)
+ // make sure chi uses EscapedPath(RawPath) as RoutePath, then "%2f" could be handled correctly
+ handlers = append(handlers, func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
+ ctx := chi.RouteContext(req.Context())
+ if req.URL.RawPath == "" {
+ ctx.RoutePath = req.URL.EscapedPath()
+ } else {
+ ctx.RoutePath = req.URL.RawPath
+ }
+ next.ServeHTTP(resp, req)
+ })
+ })
// prepare the ContextData and panic recovery
handlers = append(handlers, func(next http.Handler) http.Handler {
@@ -75,35 +85,6 @@ func ProtocolMiddlewares() (handlers []any) {
return handlers
}
-func stripSlashesMiddleware(next http.Handler) http.Handler {
- return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
- // First of all escape the URL RawPath to ensure that all routing is done using a correctly escaped URL
- req.URL.RawPath = req.URL.EscapedPath()
-
- urlPath := req.URL.RawPath
- rctx := chi.RouteContext(req.Context())
- if rctx != nil && rctx.RoutePath != "" {
- urlPath = rctx.RoutePath
- }
-
- sanitizedPath := &strings.Builder{}
- prevWasSlash := false
- for _, chr := range strings.TrimRight(urlPath, "/") {
- if chr != '/' || !prevWasSlash {
- sanitizedPath.WriteRune(chr)
- }
- prevWasSlash = chr == '/'
- }
-
- if rctx == nil {
- req.URL.Path = sanitizedPath.String()
- } else {
- rctx.RoutePath = sanitizedPath.String()
- }
- next.ServeHTTP(resp, req)
- })
-}
-
func Sessioner() func(next http.Handler) http.Handler {
return session.Sessioner(session.Options{
Provider: setting.SessionConfig.Provider,
diff --git a/routers/common/middleware_test.go b/routers/common/middleware_test.go
deleted file mode 100644
index f16b9374ec..0000000000
--- a/routers/common/middleware_test.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-package common
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestStripSlashesMiddleware(t *testing.T) {
- type test struct {
- name string
- expectedPath string
- inputPath string
- }
-
- tests := []test{
- {
- name: "path with multiple slashes",
- inputPath: "https://github.com///go-gitea//gitea.git",
- expectedPath: "/go-gitea/gitea.git",
- },
- {
- name: "path with no slashes",
- inputPath: "https://github.com/go-gitea/gitea.git",
- expectedPath: "/go-gitea/gitea.git",
- },
- {
- name: "path with slashes in the middle",
- inputPath: "https://git.data.coop//halfd/new-website.git",
- expectedPath: "/halfd/new-website.git",
- },
- {
- name: "path with slashes in the middle",
- inputPath: "https://git.data.coop//halfd/new-website.git",
- expectedPath: "/halfd/new-website.git",
- },
- {
- name: "path with slashes in the end",
- inputPath: "/user2//repo1/",
- expectedPath: "/user2/repo1",
- },
- {
- name: "path with slashes and query params",
- inputPath: "/repo//migrate?service_type=3",
- expectedPath: "/repo/migrate",
- },
- {
- name: "path with encoded slash",
- inputPath: "/user2/%2F%2Frepo1",
- expectedPath: "/user2/%2F%2Frepo1",
- },
- }
-
- for _, tt := range tests {
- testMiddleware := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- assert.Equal(t, tt.expectedPath, r.URL.Path)
- })
-
- // pass the test middleware to validate the changes
- handlerToTest := stripSlashesMiddleware(testMiddleware)
- // create a mock request to use
- req := httptest.NewRequest("GET", tt.inputPath, nil)
- // call the handler using a mock response recorder
- handlerToTest.ServeHTTP(httptest.NewRecorder(), req)
- }
-}
diff --git a/routers/init.go b/routers/init.go
index 56c95cd1ca..e21f763c1e 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -177,9 +177,9 @@ func InitWebInstalled(ctx context.Context) {
}
// NormalRoutes represents non install routes
-func NormalRoutes() *web.Route {
+func NormalRoutes() *web.Router {
_ = templates.HTMLRenderer()
- r := web.NewRoute()
+ r := web.NewRouter()
r.Use(common.ProtocolMiddlewares()...)
r.Mount("/", web_routers.Routes())
@@ -191,7 +191,8 @@ func NormalRoutes() *web.Route {
if setting.Packages.Enabled {
// This implements package support for most package managers
r.Mount("/api/packages", packages_router.CommonRoutes())
- // This implements the OCI API (Note this is not preceded by /api but is instead /v2)
+ // This implements the OCI API, this container registry "/v2" endpoint must be in the root of the site.
+ // If site admin deploys Gitea in a sub-path, they must configure their reverse proxy to map the "https://host/v2" endpoint to Gitea.
r.Mount("/v2", packages_router.ContainerRoutes())
}
diff --git a/routers/install/routes.go b/routers/install/routes.go
index 06c9d389a6..7309a405d4 100644
--- a/routers/install/routes.go
+++ b/routers/install/routes.go
@@ -17,12 +17,12 @@ import (
)
// Routes registers the installation routes
-func Routes() *web.Route {
- base := web.NewRoute()
+func Routes() *web.Router {
+ base := web.NewRouter()
base.Use(common.ProtocolMiddlewares()...)
base.Methods("GET, HEAD", "/assets/*", public.FileHandlerFunc())
- r := web.NewRoute()
+ r := web.NewRouter()
r.Use(common.Sessioner(), Contexter())
r.Get("/", Install) // it must be on the root, because the "install.js" use the window.location to replace the "localhost" AppURL
r.Post("/", web.Bind(forms.InstallForm{}), SubmitInstall)
diff --git a/routers/private/default_branch.go b/routers/private/default_branch.go
index 33890be6a9..7be909f955 100644
--- a/routers/private/default_branch.go
+++ b/routers/private/default_branch.go
@@ -16,9 +16,9 @@ import (
// SetDefaultBranch updates the default branch
func SetDefaultBranch(ctx *gitea_context.PrivateContext) {
- ownerName := ctx.Params(":owner")
- repoName := ctx.Params(":repo")
- branch := ctx.Params(":branch")
+ ownerName := ctx.PathParam(":owner")
+ repoName := ctx.PathParam(":repo")
+ branch := ctx.PathParam(":branch")
ctx.Repo.Repository.DefaultBranch = branch
if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch); err != nil {
diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go
index 0c2c1836ed..2d1688523c 100644
--- a/routers/private/hook_post_receive.go
+++ b/routers/private/hook_post_receive.go
@@ -40,8 +40,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
// b) our update function will likely change the repository in the db so we will need to refresh it
// c) we don't always need the repo
- ownerName := ctx.Params(":owner")
- repoName := ctx.Params(":repo")
+ ownerName := ctx.PathParam(":owner")
+ repoName := ctx.PathParam(":repo")
// defer getting the repository at this point - as we should only retrieve it if we're going to call update
var (
diff --git a/routers/private/internal.go b/routers/private/internal.go
index ede310113c..61e604b7a9 100644
--- a/routers/private/internal.go
+++ b/routers/private/internal.go
@@ -48,8 +48,8 @@ func bind[T any](_ T) any {
// Routes registers all internal APIs routes to web application.
// These APIs will be invoked by internal commands for example `gitea serv` and etc.
-func Routes() *web.Route {
- r := web.NewRoute()
+func Routes() *web.Router {
+ r := web.NewRouter()
r.Use(context.PrivateContexter())
r.Use(CheckInternalToken)
// Log the real ip address of the request from SSH is really helpful for diagnosing sometimes.
diff --git a/routers/private/internal_repo.go b/routers/private/internal_repo.go
index e8ee8ba8ac..aad0a3fb1a 100644
--- a/routers/private/internal_repo.go
+++ b/routers/private/internal_repo.go
@@ -19,8 +19,8 @@ import (
// RepoAssignment assigns the repository and gitrepository to the private context
func RepoAssignment(ctx *gitea_context.PrivateContext) context.CancelFunc {
- ownerName := ctx.Params(":owner")
- repoName := ctx.Params(":repo")
+ ownerName := ctx.PathParam(":owner")
+ repoName := ctx.PathParam(":repo")
repo := loadRepository(ctx, ownerName, repoName)
if ctx.Written() {
diff --git a/routers/private/key.go b/routers/private/key.go
index 5b8f238a83..063db76520 100644
--- a/routers/private/key.go
+++ b/routers/private/key.go
@@ -14,8 +14,8 @@ import (
// UpdatePublicKeyInRepo update public key and deploy key updates
func UpdatePublicKeyInRepo(ctx *context.PrivateContext) {
- keyID := ctx.ParamsInt64(":id")
- repoID := ctx.ParamsInt64(":repoid")
+ keyID := ctx.PathParamInt64(":id")
+ repoID := ctx.PathParamInt64(":repoid")
if err := asymkey_model.UpdatePublicKeyUpdated(ctx, keyID); err != nil {
ctx.JSON(http.StatusInternalServerError, private.Response{
Err: err.Error(),
diff --git a/routers/private/manager.go b/routers/private/manager.go
index a6aa03e4ec..c712bbcf21 100644
--- a/routers/private/manager.go
+++ b/routers/private/manager.go
@@ -88,8 +88,8 @@ func SetLogSQL(ctx *context.PrivateContext) {
// RemoveLogger removes a logger
func RemoveLogger(ctx *context.PrivateContext) {
- logger := ctx.Params("logger")
- writer := ctx.Params("writer")
+ logger := ctx.PathParam("logger")
+ writer := ctx.PathParam("writer")
err := log.GetManager().GetLogger(logger).RemoveWriter(writer)
if err != nil {
ctx.JSON(http.StatusInternalServerError, private.Response{
diff --git a/routers/private/serv.go b/routers/private/serv.go
index 1c309865d7..dbb28cc2bb 100644
--- a/routers/private/serv.go
+++ b/routers/private/serv.go
@@ -25,7 +25,7 @@ import (
// ServNoCommand returns information about the provided keyid
func ServNoCommand(ctx *context.PrivateContext) {
- keyID := ctx.ParamsInt64(":keyid")
+ keyID := ctx.PathParamInt64(":keyid")
if keyID <= 0 {
ctx.JSON(http.StatusBadRequest, private.Response{
UserMsg: fmt.Sprintf("Bad key id: %d", keyID),
@@ -77,9 +77,9 @@ func ServNoCommand(ctx *context.PrivateContext) {
// ServCommand returns information about the provided keyid
func ServCommand(ctx *context.PrivateContext) {
- keyID := ctx.ParamsInt64(":keyid")
- ownerName := ctx.Params(":owner")
- repoName := ctx.Params(":repo")
+ keyID := ctx.PathParamInt64(":keyid")
+ ownerName := ctx.PathParam(":owner")
+ repoName := ctx.PathParam(":repo")
mode := perm.AccessMode(ctx.FormInt("mode"))
// Set the basic parts of the results to return
diff --git a/routers/web/admin/admin.go b/routers/web/admin/admin.go
index dee1650b5a..6fc97c949e 100644
--- a/routers/web/admin/admin.go
+++ b/routers/web/admin/admin.go
@@ -15,6 +15,7 @@ import (
activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/json"
@@ -222,6 +223,14 @@ func SelfCheck(ctx *context.Context) {
ctx.Data["DatabaseCheckHasProblems"] = hasProblem
}
+
+ elapsed, err := cache.Test()
+ if err != nil {
+ ctx.Data["CacheError"] = err
+ } else if elapsed > cache.SlowCacheThreshold {
+ ctx.Data["CacheSlow"] = fmt.Sprint(elapsed)
+ }
+
ctx.HTML(http.StatusOK, tplSelfCheck)
}
diff --git a/routers/web/admin/auths.go b/routers/web/admin/auths.go
index ba487d1045..3b89be0f8f 100644
--- a/routers/web/admin/auths.go
+++ b/routers/web/admin/auths.go
@@ -337,7 +337,7 @@ func EditAuthSource(ctx *context.Context) {
oauth2providers := oauth2.GetSupportedOAuth2Providers()
ctx.Data["OAuth2Providers"] = oauth2providers
- source, err := auth.GetSourceByID(ctx, ctx.ParamsInt64(":authid"))
+ source, err := auth.GetSourceByID(ctx, ctx.PathParamInt64(":authid"))
if err != nil {
ctx.ServerError("auth.GetSourceByID", err)
return
@@ -371,7 +371,7 @@ func EditAuthSourcePost(ctx *context.Context) {
oauth2providers := oauth2.GetSupportedOAuth2Providers()
ctx.Data["OAuth2Providers"] = oauth2providers
- source, err := auth.GetSourceByID(ctx, ctx.ParamsInt64(":authid"))
+ source, err := auth.GetSourceByID(ctx, ctx.PathParamInt64(":authid"))
if err != nil {
ctx.ServerError("auth.GetSourceByID", err)
return
@@ -442,7 +442,7 @@ func EditAuthSourcePost(ctx *context.Context) {
// DeleteAuthSource response for deleting an auth source
func DeleteAuthSource(ctx *context.Context) {
- source, err := auth.GetSourceByID(ctx, ctx.ParamsInt64(":authid"))
+ source, err := auth.GetSourceByID(ctx, ctx.PathParamInt64(":authid"))
if err != nil {
ctx.ServerError("auth.GetSourceByID", err)
return
@@ -454,7 +454,7 @@ func DeleteAuthSource(ctx *context.Context) {
} else {
ctx.Flash.Error(fmt.Sprintf("auth_service.DeleteSource: %v", err))
}
- ctx.JSONRedirect(setting.AppSubURL + "/admin/auths/" + url.PathEscape(ctx.Params(":authid")))
+ ctx.JSONRedirect(setting.AppSubURL + "/admin/auths/" + url.PathEscape(ctx.PathParam(":authid")))
return
}
log.Trace("Authentication deleted by admin(%s): %d", ctx.Doer.Name, source.ID)
diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go
index 2a842cff82..2ae93e9cac 100644
--- a/routers/web/admin/config.go
+++ b/routers/web/admin/config.go
@@ -12,6 +12,7 @@ import (
system_model "code.gitea.io/gitea/models/system"
"code.gitea.io/gitea/modules/base"
+ "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
@@ -42,6 +43,22 @@ func SendTestMail(ctx *context.Context) {
ctx.Redirect(setting.AppSubURL + "/admin/config")
}
+// TestCache test the cache settings
+func TestCache(ctx *context.Context) {
+ elapsed, err := cache.Test()
+ if err != nil {
+ ctx.Flash.Error(ctx.Tr("admin.config.cache_test_failed", err))
+ } else {
+ if elapsed > cache.SlowCacheThreshold {
+ ctx.Flash.Warning(ctx.Tr("admin.config.cache_test_slow", elapsed))
+ } else {
+ ctx.Flash.Info(ctx.Tr("admin.config.cache_test_succeeded", elapsed))
+ }
+ }
+
+ ctx.Redirect(setting.AppSubURL + "/admin/config")
+}
+
func shadowPasswordKV(cfgItem, splitter string) string {
fields := strings.Split(cfgItem, splitter)
for i := 0; i < len(fields); i++ {
diff --git a/routers/web/admin/queue.go b/routers/web/admin/queue.go
index d8c50730b1..dce8f8077f 100644
--- a/routers/web/admin/queue.go
+++ b/routers/web/admin/queue.go
@@ -24,7 +24,7 @@ func Queues(ctx *context.Context) {
// QueueManage shows details for a specific queue
func QueueManage(ctx *context.Context) {
- qid := ctx.ParamsInt64("qid")
+ qid := ctx.PathParamInt64("qid")
mq := queue.GetManager().GetManagedQueue(qid)
if mq == nil {
ctx.Status(http.StatusNotFound)
@@ -38,7 +38,7 @@ func QueueManage(ctx *context.Context) {
// QueueSet sets the maximum number of workers and other settings for this queue
func QueueSet(ctx *context.Context) {
- qid := ctx.ParamsInt64("qid")
+ qid := ctx.PathParamInt64("qid")
mq := queue.GetManager().GetManagedQueue(qid)
if mq == nil {
ctx.Status(http.StatusNotFound)
@@ -72,7 +72,7 @@ func QueueRemoveAllItems(ctx *context.Context) {
// Gitea's queue doesn't have transaction support
// So in rare cases, the queue could be corrupted/out-of-sync
// Site admin could remove all items from the queue to make it work again
- qid := ctx.ParamsInt64("qid")
+ qid := ctx.PathParamInt64("qid")
mq := queue.GetManager().GetManagedQueue(qid)
if mq == nil {
ctx.Status(http.StatusNotFound)
diff --git a/routers/web/admin/stacktrace.go b/routers/web/admin/stacktrace.go
index d6def94bb4..b3b635af5b 100644
--- a/routers/web/admin/stacktrace.go
+++ b/routers/web/admin/stacktrace.go
@@ -40,7 +40,7 @@ func Stacktrace(ctx *context.Context) {
// StacktraceCancel cancels a process
func StacktraceCancel(ctx *context.Context) {
- pid := ctx.Params("pid")
+ pid := ctx.PathParam("pid")
process.GetManager().Cancel(process.IDType(pid))
ctx.JSONRedirect(setting.AppSubURL + "/admin/monitor/stacktrace")
}
diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go
index d2330d5fa1..623b39b4ef 100644
--- a/routers/web/admin/users.go
+++ b/routers/web/admin/users.go
@@ -219,7 +219,7 @@ func NewUserPost(ctx *context.Context) {
}
func prepareUserInfo(ctx *context.Context) *user_model.User {
- u, err := user_model.GetUserByID(ctx, ctx.ParamsInt64(":userid"))
+ u, err := user_model.GetUserByID(ctx, ctx.PathParamInt64(":userid"))
if err != nil {
if user_model.IsErrUserNotExist(err) {
ctx.Redirect(setting.AppSubURL + "/admin/users")
@@ -481,12 +481,12 @@ func EditUserPost(ctx *context.Context) {
}
ctx.Flash.Success(ctx.Tr("admin.users.update_profile_success"))
- ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
+ ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.PathParam(":userid")))
}
// DeleteUser response for deleting a user
func DeleteUser(ctx *context.Context) {
- u, err := user_model.GetUserByID(ctx, ctx.ParamsInt64(":userid"))
+ u, err := user_model.GetUserByID(ctx, ctx.PathParamInt64(":userid"))
if err != nil {
ctx.ServerError("GetUserByID", err)
return
@@ -495,7 +495,7 @@ func DeleteUser(ctx *context.Context) {
// admin should not delete themself
if u.ID == ctx.Doer.ID {
ctx.Flash.Error(ctx.Tr("admin.users.cannot_delete_self"))
- ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
+ ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.PathParam(":userid")))
return
}
@@ -503,16 +503,16 @@ func DeleteUser(ctx *context.Context) {
switch {
case models.IsErrUserOwnRepos(err):
ctx.Flash.Error(ctx.Tr("admin.users.still_own_repo"))
- ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
+ ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.PathParam(":userid")))
case models.IsErrUserHasOrgs(err):
ctx.Flash.Error(ctx.Tr("admin.users.still_has_org"))
- ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
+ ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.PathParam(":userid")))
case models.IsErrUserOwnPackages(err):
ctx.Flash.Error(ctx.Tr("admin.users.still_own_packages"))
- ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
+ ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.PathParam(":userid")))
case models.IsErrDeleteLastAdminUser(err):
ctx.Flash.Error(ctx.Tr("auth.last_admin"))
- ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.Params(":userid")))
+ ctx.Redirect(setting.AppSubURL + "/admin/users/" + url.PathEscape(ctx.PathParam(":userid")))
default:
ctx.ServerError("DeleteUser", err)
}
diff --git a/routers/web/auth/auth_test.go b/routers/web/auth/auth_test.go
index 45525a5c6f..cbcb2a5222 100644
--- a/routers/web/auth/auth_test.go
+++ b/routers/web/auth/auth_test.go
@@ -71,7 +71,7 @@ func TestSignUpOAuth2ButMissingFields(t *testing.T) {
mockOpt := contexttest.MockContextOption{SessionStore: session.NewMockStore("dummy-sid")}
ctx, resp := contexttest.MockContext(t, "/user/oauth2/dummy-auth-source/callback?code=dummy-code", mockOpt)
- ctx.SetParams("provider", "dummy-auth-source")
+ ctx.SetPathParam("provider", "dummy-auth-source")
SignInOAuthCallback(ctx)
assert.Equal(t, http.StatusSeeOther, resp.Code)
assert.Equal(t, "/user/link_account", test.RedirectURL(resp))
diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go
index b337b6b156..50f0dff2b6 100644
--- a/routers/web/auth/oauth.go
+++ b/routers/web/auth/oauth.go
@@ -865,7 +865,7 @@ func handleAuthorizeError(ctx *context.Context, authErr AuthorizeError, redirect
// SignInOAuth handles the OAuth2 login buttons
func SignInOAuth(ctx *context.Context) {
- provider := ctx.Params(":provider")
+ provider := ctx.PathParam(":provider")
authSource, err := auth.GetActiveOAuth2SourceByName(ctx, provider)
if err != nil {
@@ -904,7 +904,7 @@ func SignInOAuth(ctx *context.Context) {
// SignInOAuthCallback handles the callback from the given provider
func SignInOAuthCallback(ctx *context.Context) {
- provider := ctx.Params(":provider")
+ provider := ctx.PathParam(":provider")
if ctx.Req.FormValue("error") != "" {
var errorKeyValues []string
diff --git a/routers/web/auth/webauthn.go b/routers/web/auth/webauthn.go
index 1079f44a08..3160c5e23f 100644
--- a/routers/web/auth/webauthn.go
+++ b/routers/web/auth/webauthn.go
@@ -4,6 +4,7 @@
package auth
import (
+ "encoding/binary"
"errors"
"net/http"
@@ -47,6 +48,104 @@ func WebAuthn(ctx *context.Context) {
ctx.HTML(http.StatusOK, tplWebAuthn)
}
+// WebAuthnPasskeyAssertion submits a WebAuthn challenge for the passkey login to the browser
+func WebAuthnPasskeyAssertion(ctx *context.Context) {
+ assertion, sessionData, err := wa.WebAuthn.BeginDiscoverableLogin()
+ if err != nil {
+ ctx.ServerError("webauthn.BeginDiscoverableLogin", err)
+ return
+ }
+
+ if err := ctx.Session.Set("webauthnPasskeyAssertion", sessionData); err != nil {
+ ctx.ServerError("Session.Set", err)
+ return
+ }
+
+ ctx.JSON(http.StatusOK, assertion)
+}
+
+// WebAuthnPasskeyLogin handles the WebAuthn login process using a Passkey
+func WebAuthnPasskeyLogin(ctx *context.Context) {
+ sessionData, okData := ctx.Session.Get("webauthnPasskeyAssertion").(*webauthn.SessionData)
+ if !okData || sessionData == nil {
+ ctx.ServerError("ctx.Session.Get", errors.New("not in WebAuthn session"))
+ return
+ }
+ defer func() {
+ _ = ctx.Session.Delete("webauthnPasskeyAssertion")
+ }()
+
+ // Validate the parsed response.
+ var user *user_model.User
+ cred, err := wa.WebAuthn.FinishDiscoverableLogin(func(rawID, userHandle []byte) (webauthn.User, error) {
+ userID, n := binary.Varint(userHandle)
+ if n <= 0 {
+ return nil, errors.New("invalid rawID")
+ }
+
+ var err error
+ user, err = user_model.GetUserByID(ctx, userID)
+ if err != nil {
+ return nil, err
+ }
+
+ return (*wa.User)(user), nil
+ }, *sessionData, ctx.Req)
+ if err != nil {
+ // Failed authentication attempt.
+ log.Info("Failed authentication attempt for passkey from %s: %v", ctx.RemoteAddr(), err)
+ ctx.Status(http.StatusForbidden)
+ return
+ }
+
+ if !cred.Flags.UserPresent {
+ ctx.Status(http.StatusBadRequest)
+ return
+ }
+
+ if user == nil {
+ ctx.Status(http.StatusBadRequest)
+ return
+ }
+
+ // Ensure that the credential wasn't cloned by checking if CloneWarning is set.
+ // (This is set if the sign counter is less than the one we have stored.)
+ if cred.Authenticator.CloneWarning {
+ log.Info("Failed authentication attempt for %s from %s: cloned credential", user.Name, ctx.RemoteAddr())
+ ctx.Status(http.StatusForbidden)
+ return
+ }
+
+ // Success! Get the credential and update the sign count with the new value we received.
+ dbCred, err := auth.GetWebAuthnCredentialByCredID(ctx, user.ID, cred.ID)
+ if err != nil {
+ ctx.ServerError("GetWebAuthnCredentialByCredID", err)
+ return
+ }
+
+ dbCred.SignCount = cred.Authenticator.SignCount
+ if err := dbCred.UpdateSignCount(ctx); err != nil {
+ ctx.ServerError("UpdateSignCount", err)
+ return
+ }
+
+ // Now handle account linking if that's requested
+ if ctx.Session.Get("linkAccount") != nil {
+ if err := externalaccount.LinkAccountFromStore(ctx, ctx.Session, user); err != nil {
+ ctx.ServerError("LinkAccountFromStore", err)
+ return
+ }
+ }
+
+ remember := false // TODO: implement remember me
+ redirect := handleSignInFull(ctx, user, remember, false)
+ if redirect == "" {
+ redirect = setting.AppSubURL + "/"
+ }
+
+ ctx.JSONRedirect(redirect)
+}
+
// WebAuthnLoginAssertion submits a WebAuthn challenge to the browser
func WebAuthnLoginAssertion(ctx *context.Context) {
// Ensure user is in a WebAuthn session.
diff --git a/routers/web/devtest/devtest.go b/routers/web/devtest/devtest.go
index dd20663f94..8c343197d9 100644
--- a/routers/web/devtest/devtest.go
+++ b/routers/web/devtest/devtest.go
@@ -62,5 +62,5 @@ func Tmpl(ctx *context.Context) {
time.Sleep(2 * time.Second)
}
- ctx.HTML(http.StatusOK, base.TplName("devtest"+path.Clean("/"+ctx.Params("sub"))))
+ ctx.HTML(http.StatusOK, base.TplName("devtest"+path.Clean("/"+ctx.PathParam("sub"))))
}
diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go
index 66477a255c..67f138aca9 100644
--- a/routers/web/explore/repo.go
+++ b/routers/web/explore/repo.go
@@ -6,6 +6,7 @@ package explore
import (
"fmt"
"net/http"
+ "strings"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
@@ -36,8 +37,8 @@ type RepoSearchOptions struct {
// This function is also used to render the Admin Repository Management page.
func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
// Sitemap index for sitemap paths
- page := int(ctx.ParamsInt64("idx"))
- isSitemap := ctx.Params("idx") != ""
+ page := int(ctx.PathParamInt64("idx"))
+ isSitemap := ctx.PathParam("idx") != ""
if page <= 1 {
page = ctx.FormInt("page")
}
@@ -57,47 +58,18 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
orderBy db.SearchOrderBy
)
- sortOrder := ctx.FormString("sort")
+ sortOrder := strings.ToLower(ctx.FormString("sort"))
if sortOrder == "" {
sortOrder = setting.UI.ExploreDefaultSort
}
- ctx.Data["SortType"] = sortOrder
- switch sortOrder {
- case "newest":
- orderBy = db.SearchOrderByNewest
- case "oldest":
- orderBy = db.SearchOrderByOldest
- case "leastupdate":
- orderBy = db.SearchOrderByLeastUpdated
- case "reversealphabetically":
- orderBy = db.SearchOrderByAlphabeticallyReverse
- case "alphabetically":
- orderBy = db.SearchOrderByAlphabetically
- case "reversesize":
- orderBy = db.SearchOrderBySizeReverse
- case "size":
- orderBy = db.SearchOrderBySize
- case "reversegitsize":
- orderBy = db.SearchOrderByGitSizeReverse
- case "gitsize":
- orderBy = db.SearchOrderByGitSize
- case "reverselfssize":
- orderBy = db.SearchOrderByLFSSizeReverse
- case "lfssize":
- orderBy = db.SearchOrderByLFSSize
- case "moststars":
- orderBy = db.SearchOrderByStarsReverse
- case "feweststars":
- orderBy = db.SearchOrderByStars
- case "mostforks":
- orderBy = db.SearchOrderByForksReverse
- case "fewestforks":
- orderBy = db.SearchOrderByForks
- default:
- ctx.Data["SortType"] = "recentupdate"
+ if order, ok := repo_model.OrderByFlatMap[sortOrder]; ok {
+ orderBy = order
+ } else {
+ sortOrder = "recentupdate"
orderBy = db.SearchOrderByRecentUpdated
}
+ ctx.Data["SortType"] = sortOrder
keyword := ctx.FormTrim("q")
diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go
index b79a79fb2c..18337aff48 100644
--- a/routers/web/explore/user.go
+++ b/routers/web/explore/user.go
@@ -33,8 +33,8 @@ func isKeywordValid(keyword string) bool {
// RenderUserSearch render user search page
func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions, tplName base.TplName) {
// Sitemap index for sitemap paths
- opts.Page = int(ctx.ParamsInt64("idx"))
- isSitemap := ctx.Params("idx") != ""
+ opts.Page = int(ctx.PathParamInt64("idx"))
+ isSitemap := ctx.PathParam("idx") != ""
if opts.Page <= 1 {
opts.Page = ctx.FormInt("page")
}
diff --git a/routers/web/feed/render.go b/routers/web/feed/render.go
index a41808c24a..f975fc7cb2 100644
--- a/routers/web/feed/render.go
+++ b/routers/web/feed/render.go
@@ -9,7 +9,7 @@ import (
// RenderBranchFeed render format for branch or file
func RenderBranchFeed(ctx *context.Context) {
- _, _, showFeedType := GetFeedType(ctx.Params(":reponame"), ctx.Req)
+ _, _, showFeedType := GetFeedType(ctx.PathParam(":reponame"), ctx.Req)
if ctx.Repo.TreePath == "" {
ShowBranchFeed(ctx, ctx.Repo.Repository, showFeedType)
} else {
diff --git a/routers/web/githttp.go b/routers/web/githttp.go
index 5f1dedce76..102c92e120 100644
--- a/routers/web/githttp.go
+++ b/routers/web/githttp.go
@@ -25,7 +25,7 @@ func requireSignIn(ctx *context.Context) {
}
}
-func gitHTTPRouters(m *web.Route) {
+func gitHTTPRouters(m *web.Router) {
m.Group("", func() {
m.Methods("POST,OPTIONS", "/git-upload-pack", repo.ServiceUploadPack)
m.Methods("POST,OPTIONS", "/git-receive-pack", repo.ServiceReceivePack)
diff --git a/routers/web/org/home.go b/routers/web/org/home.go
index 846b1de18a..c3fc4e099a 100644
--- a/routers/web/org/home.go
+++ b/routers/web/org/home.go
@@ -28,14 +28,14 @@ const (
// Home show organization home page
func Home(ctx *context.Context) {
- uname := ctx.Params(":username")
+ uname := ctx.PathParam(":username")
if strings.HasSuffix(uname, ".keys") || strings.HasSuffix(uname, ".gpg") {
ctx.NotFound("", nil)
return
}
- ctx.SetParams(":org", uname)
+ ctx.SetPathParam(":org", uname)
context.HandleOrgAssignment(ctx)
if ctx.Written() {
return
diff --git a/routers/web/org/members.go b/routers/web/org/members.go
index 63ac57cf0d..58d0b9b8c4 100644
--- a/routers/web/org/members.go
+++ b/routers/web/org/members.go
@@ -90,7 +90,7 @@ func MembersAction(ctx *context.Context) {
org := ctx.Org.Organization
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "private":
if ctx.Doer.ID != member.ID && !ctx.Org.IsOwner {
ctx.Error(http.StatusNotFound)
@@ -131,7 +131,7 @@ func MembersAction(ctx *context.Context) {
}
if err != nil {
- log.Error("Action(%s): %v", ctx.Params(":action"), err)
+ log.Error("Action(%s): %v", ctx.PathParam(":action"), err)
ctx.JSON(http.StatusOK, map[string]any{
"ok": false,
"err": err.Error(),
@@ -140,7 +140,7 @@ func MembersAction(ctx *context.Context) {
}
redirect := ctx.Org.OrgLink + "/members"
- if ctx.Params(":action") == "leave" {
+ if ctx.PathParam(":action") == "leave" {
redirect = setting.AppSubURL + "/"
}
diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go
index 9ab3c21cb2..eea539f6d9 100644
--- a/routers/web/org/projects.go
+++ b/routers/web/org/projects.go
@@ -194,7 +194,7 @@ func NewProjectPost(ctx *context.Context) {
// ChangeProjectStatus updates the status of a project between "open" and "close"
func ChangeProjectStatus(ctx *context.Context) {
var toClose bool
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "open":
toClose = false
case "close":
@@ -203,7 +203,7 @@ func ChangeProjectStatus(ctx *context.Context) {
ctx.JSONRedirect(ctx.ContextUser.HomeLink() + "/-/projects")
return
}
- id := ctx.ParamsInt64(":id")
+ id := ctx.PathParamInt64(":id")
if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx, 0, id, toClose); err != nil {
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
@@ -214,7 +214,7 @@ func ChangeProjectStatus(ctx *context.Context) {
// DeleteProject delete a project
func DeleteProject(ctx *context.Context) {
- p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ p, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetProjectByID", project_model.IsErrProjectNotExist, err)
return
@@ -243,7 +243,7 @@ func RenderEditProject(ctx *context.Context) {
shared_user.RenderUserHeader(ctx)
- p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ p, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetProjectByID", project_model.IsErrProjectNotExist, err)
return
@@ -267,7 +267,7 @@ func RenderEditProject(ctx *context.Context) {
// EditProjectPost response for editing a project
func EditProjectPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.CreateProjectForm)
- projectID := ctx.ParamsInt64(":id")
+ projectID := ctx.PathParamInt64(":id")
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true
ctx.Data["PageIsViewProjects"] = true
@@ -316,7 +316,7 @@ func EditProjectPost(ctx *context.Context) {
// ViewProject renders the project with board view for a project
func ViewProject(ctx *context.Context) {
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetProjectByID", project_model.IsErrProjectNotExist, err)
return
@@ -398,18 +398,18 @@ func DeleteProjectColumn(ctx *context.Context) {
return
}
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetProjectByID", project_model.IsErrProjectNotExist, err)
return
}
- pb, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
+ pb, err := project_model.GetColumn(ctx, ctx.PathParamInt64(":columnID"))
if err != nil {
ctx.ServerError("GetProjectColumn", err)
return
}
- if pb.ProjectID != ctx.ParamsInt64(":id") {
+ if pb.ProjectID != ctx.PathParamInt64(":id") {
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
"message": fmt.Sprintf("ProjectColumn[%d] is not in Project[%d] as expected", pb.ID, project.ID),
})
@@ -423,7 +423,7 @@ func DeleteProjectColumn(ctx *context.Context) {
return
}
- if err := project_model.DeleteColumnByID(ctx, ctx.ParamsInt64(":columnID")); err != nil {
+ if err := project_model.DeleteColumnByID(ctx, ctx.PathParamInt64(":columnID")); err != nil {
ctx.ServerError("DeleteProjectColumnByID", err)
return
}
@@ -435,7 +435,7 @@ func DeleteProjectColumn(ctx *context.Context) {
func AddColumnToProjectPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.EditProjectColumnForm)
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetProjectByID", project_model.IsErrProjectNotExist, err)
return
@@ -463,18 +463,18 @@ func CheckProjectColumnChangePermissions(ctx *context.Context) (*project_model.P
return nil, nil
}
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetProjectByID", project_model.IsErrProjectNotExist, err)
return nil, nil
}
- column, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
+ column, err := project_model.GetColumn(ctx, ctx.PathParamInt64(":columnID"))
if err != nil {
ctx.ServerError("GetProjectColumn", err)
return nil, nil
}
- if column.ProjectID != ctx.ParamsInt64(":id") {
+ if column.ProjectID != ctx.PathParamInt64(":id") {
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
"message": fmt.Sprintf("ProjectColumn[%d] is not in Project[%d] as expected", column.ID, project.ID),
})
@@ -538,7 +538,7 @@ func MoveIssues(ctx *context.Context) {
return
}
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetProjectByID", project_model.IsErrProjectNotExist, err)
return
@@ -548,7 +548,7 @@ func MoveIssues(ctx *context.Context) {
return
}
- column, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
+ column, err := project_model.GetColumn(ctx, ctx.PathParamInt64(":columnID"))
if err != nil {
ctx.NotFoundOrServerError("GetProjectColumn", project_model.IsErrProjectColumnNotExist, err)
return
diff --git a/routers/web/org/projects_test.go b/routers/web/org/projects_test.go
index ab419cc878..c52cb7ed4c 100644
--- a/routers/web/org/projects_test.go
+++ b/routers/web/org/projects_test.go
@@ -18,8 +18,8 @@ func TestCheckProjectColumnChangePermissions(t *testing.T) {
ctx, _ := contexttest.MockContext(t, "user2/-/projects/4/4")
contexttest.LoadUser(t, ctx, 2)
ctx.ContextUser = ctx.Doer // user2
- ctx.SetParams(":id", "4")
- ctx.SetParams(":columnID", "4")
+ ctx.SetPathParam(":id", "4")
+ ctx.SetPathParam(":columnID", "4")
project, column := org.CheckProjectColumnChangePermissions(ctx)
assert.NotNil(t, project)
diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go
index 144d9b1b43..aaac1177ae 100644
--- a/routers/web/org/teams.go
+++ b/routers/web/org/teams.go
@@ -72,7 +72,7 @@ func Teams(ctx *context.Context) {
func TeamsAction(ctx *context.Context) {
page := ctx.FormString("page")
var err error
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "join":
if !ctx.Org.IsOwner {
ctx.Error(http.StatusNotFound)
@@ -85,7 +85,7 @@ func TeamsAction(ctx *context.Context) {
if org_model.IsErrLastOrgOwner(err) {
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
} else {
- log.Error("Action(%s): %v", ctx.Params(":action"), err)
+ log.Error("Action(%s): %v", ctx.PathParam(":action"), err)
ctx.JSON(http.StatusOK, map[string]any{
"ok": false,
"err": err.Error(),
@@ -112,7 +112,7 @@ func TeamsAction(ctx *context.Context) {
if org_model.IsErrLastOrgOwner(err) {
ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
} else {
- log.Error("Action(%s): %v", ctx.Params(":action"), err)
+ log.Error("Action(%s): %v", ctx.PathParam(":action"), err)
ctx.JSON(http.StatusOK, map[string]any{
"ok": false,
"err": err.Error(),
@@ -179,7 +179,7 @@ func TeamsAction(ctx *context.Context) {
}
if err := org_model.RemoveInviteByID(ctx, iid, ctx.Org.Team.ID); err != nil {
- log.Error("Action(%s): %v", ctx.Params(":action"), err)
+ log.Error("Action(%s): %v", ctx.PathParam(":action"), err)
ctx.ServerError("RemoveInviteByID", err)
return
}
@@ -193,7 +193,7 @@ func TeamsAction(ctx *context.Context) {
} else if errors.Is(err, user_model.ErrBlockedUser) {
ctx.Flash.Error(ctx.Tr("org.teams.members.blocked_user"))
} else {
- log.Error("Action(%s): %v", ctx.Params(":action"), err)
+ log.Error("Action(%s): %v", ctx.PathParam(":action"), err)
ctx.JSON(http.StatusOK, map[string]any{
"ok": false,
"err": err.Error(),
@@ -234,7 +234,7 @@ func TeamsRepoAction(ctx *context.Context) {
}
var err error
- action := ctx.Params(":action")
+ action := ctx.PathParam(":action")
switch action {
case "add":
repoName := path.Base(ctx.FormString("repo_name"))
@@ -259,7 +259,7 @@ func TeamsRepoAction(ctx *context.Context) {
}
if err != nil {
- log.Error("Action(%s): '%s' %v", ctx.Params(":action"), ctx.Org.Team.Name, err)
+ log.Error("Action(%s): '%s' %v", ctx.PathParam(":action"), ctx.Org.Team.Name, err)
ctx.ServerError("TeamsRepoAction", err)
return
}
@@ -606,7 +606,7 @@ func TeamInvitePost(ctx *context.Context) {
}
func getTeamInviteFromContext(ctx *context.Context) (*org_model.TeamInvite, *org_model.Organization, *org_model.Team, *user_model.User, error) {
- invite, err := org_model.GetInviteByToken(ctx, ctx.Params("token"))
+ invite, err := org_model.GetInviteByToken(ctx, ctx.PathParam("token"))
if err != nil {
return nil, nil, nil, nil, err
}
diff --git a/routers/web/repo/actions/badge.go b/routers/web/repo/actions/badge.go
index 6fa951826c..e920ecaf58 100644
--- a/routers/web/repo/actions/badge.go
+++ b/routers/web/repo/actions/badge.go
@@ -17,7 +17,7 @@ import (
)
func GetWorkflowBadge(ctx *context.Context) {
- workflowFile := ctx.Params("workflow_name")
+ workflowFile := ctx.PathParam("workflow_name")
branch := ctx.Req.URL.Query().Get("branch")
if branch == "" {
branch = ctx.Repo.Repository.DefaultBranch
diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go
index 7cc12c90e6..2c62c8d9ec 100644
--- a/routers/web/repo/actions/view.go
+++ b/routers/web/repo/actions/view.go
@@ -35,8 +35,8 @@ import (
func View(ctx *context_module.Context) {
ctx.Data["PageIsActions"] = true
- runIndex := ctx.ParamsInt64("run")
- jobIndex := ctx.ParamsInt64("job")
+ runIndex := ctx.PathParamInt64("run")
+ jobIndex := ctx.PathParamInt64("job")
ctx.Data["RunIndex"] = runIndex
ctx.Data["JobIndex"] = jobIndex
ctx.Data["ActionsURL"] = ctx.Repo.RepoLink + "/actions"
@@ -130,8 +130,8 @@ type ViewStepLogLine struct {
func ViewPost(ctx *context_module.Context) {
req := web.GetForm(ctx).(*ViewRequest)
- runIndex := ctx.ParamsInt64("run")
- jobIndex := ctx.ParamsInt64("job")
+ runIndex := ctx.PathParamInt64("run")
+ jobIndex := ctx.PathParamInt64("job")
current, jobs := getRunJobs(ctx, runIndex, jobIndex)
if ctx.Written() {
@@ -268,8 +268,8 @@ func ViewPost(ctx *context_module.Context) {
// Rerun will rerun jobs in the given run
// If jobIndexStr is a blank string, it means rerun all jobs
func Rerun(ctx *context_module.Context) {
- runIndex := ctx.ParamsInt64("run")
- jobIndexStr := ctx.Params("job")
+ runIndex := ctx.PathParamInt64("run")
+ jobIndexStr := ctx.PathParam("job")
var jobIndex int64
if jobIndexStr != "" {
jobIndex, _ = strconv.ParseInt(jobIndexStr, 10, 64)
@@ -358,8 +358,8 @@ func rerunJob(ctx *context_module.Context, job *actions_model.ActionRunJob, shou
}
func Logs(ctx *context_module.Context) {
- runIndex := ctx.ParamsInt64("run")
- jobIndex := ctx.ParamsInt64("job")
+ runIndex := ctx.PathParamInt64("run")
+ jobIndex := ctx.PathParamInt64("job")
job, _ := getRunJobs(ctx, runIndex, jobIndex)
if ctx.Written() {
@@ -407,7 +407,7 @@ func Logs(ctx *context_module.Context) {
}
func Cancel(ctx *context_module.Context) {
- runIndex := ctx.ParamsInt64("run")
+ runIndex := ctx.PathParamInt64("run")
_, jobs := getRunJobs(ctx, runIndex, -1)
if ctx.Written() {
@@ -448,7 +448,7 @@ func Cancel(ctx *context_module.Context) {
}
func Approve(ctx *context_module.Context) {
- runIndex := ctx.ParamsInt64("run")
+ runIndex := ctx.PathParamInt64("run")
current, jobs := getRunJobs(ctx, runIndex, -1)
if ctx.Written() {
@@ -529,7 +529,7 @@ type ArtifactsViewItem struct {
}
func ArtifactsView(ctx *context_module.Context) {
- runIndex := ctx.ParamsInt64("run")
+ runIndex := ctx.PathParamInt64("run")
run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
@@ -567,8 +567,8 @@ func ArtifactsDeleteView(ctx *context_module.Context) {
return
}
- runIndex := ctx.ParamsInt64("run")
- artifactName := ctx.Params("artifact_name")
+ runIndex := ctx.PathParamInt64("run")
+ artifactName := ctx.PathParam("artifact_name")
run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex)
if err != nil {
@@ -585,8 +585,8 @@ func ArtifactsDeleteView(ctx *context_module.Context) {
}
func ArtifactsDownloadView(ctx *context_module.Context) {
- runIndex := ctx.ParamsInt64("run")
- artifactName := ctx.Params("artifact_name")
+ runIndex := ctx.PathParamInt64("run")
+ artifactName := ctx.PathParam("artifact_name")
run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex)
if err != nil {
diff --git a/routers/web/repo/activity.go b/routers/web/repo/activity.go
index 6f6641cc65..c8fa60f77a 100644
--- a/routers/web/repo/activity.go
+++ b/routers/web/repo/activity.go
@@ -24,7 +24,7 @@ func Activity(ctx *context.Context) {
ctx.Data["PageIsPulse"] = true
- ctx.Data["Period"] = ctx.Params("period")
+ ctx.Data["Period"] = ctx.PathParam("period")
timeUntil := time.Now()
var timeFrom time.Time
@@ -75,7 +75,7 @@ func ActivityAuthors(ctx *context.Context) {
timeUntil := time.Now()
var timeFrom time.Time
- switch ctx.Params("period") {
+ switch ctx.PathParam("period") {
case "daily":
timeFrom = timeUntil.Add(-time.Hour * 24)
case "halfweekly":
diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go
index 6437c39a57..0df2efeac7 100644
--- a/routers/web/repo/attachment.go
+++ b/routers/web/repo/attachment.go
@@ -154,5 +154,5 @@ func ServeAttachment(ctx *context.Context, uuid string) {
// GetAttachment serve attachments
func GetAttachment(ctx *context.Context) {
- ServeAttachment(ctx, ctx.Params(":uuid"))
+ ServeAttachment(ctx, ctx.PathParam(":uuid"))
}
diff --git a/routers/web/repo/cherry_pick.go b/routers/web/repo/cherry_pick.go
index 088f8d889d..61aff78d49 100644
--- a/routers/web/repo/cherry_pick.go
+++ b/routers/web/repo/cherry_pick.go
@@ -25,8 +25,8 @@ var tplCherryPick base.TplName = "repo/editor/cherry_pick"
// CherryPick handles cherrypick GETs
func CherryPick(ctx *context.Context) {
- ctx.Data["SHA"] = ctx.Params(":sha")
- cherryPickCommit, err := ctx.Repo.GitRepo.GetCommit(ctx.Params(":sha"))
+ ctx.Data["SHA"] = ctx.PathParam(":sha")
+ cherryPickCommit, err := ctx.Repo.GitRepo.GetCommit(ctx.PathParam(":sha"))
if err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound("Missing Commit", err)
@@ -38,7 +38,7 @@ func CherryPick(ctx *context.Context) {
if ctx.FormString("cherry-pick-type") == "revert" {
ctx.Data["CherryPickType"] = "revert"
- ctx.Data["commit_summary"] = "revert " + ctx.Params(":sha")
+ ctx.Data["commit_summary"] = "revert " + ctx.PathParam(":sha")
ctx.Data["commit_message"] = "revert " + cherryPickCommit.Message()
} else {
ctx.Data["CherryPickType"] = "cherry-pick"
@@ -67,7 +67,7 @@ func CherryPick(ctx *context.Context) {
func CherryPickPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.CherryPickForm)
- sha := ctx.Params(":sha")
+ sha := ctx.PathParam(":sha")
ctx.Data["SHA"] = sha
if form.Revert {
ctx.Data["CherryPickType"] = "revert"
@@ -141,7 +141,7 @@ func CherryPickPost(ctx *context.Context) {
if form.Revert {
if err := git.GetReverseRawDiff(ctx, ctx.Repo.Repository.RepoPath(), sha, buf); err != nil {
if git.IsErrNotExist(err) {
- ctx.NotFound("GetRawDiff", errors.New("commit "+ctx.Params(":sha")+" does not exist."))
+ ctx.NotFound("GetRawDiff", errors.New("commit "+ctx.PathParam(":sha")+" does not exist."))
return
}
ctx.ServerError("GetRawDiff", err)
@@ -150,7 +150,7 @@ func CherryPickPost(ctx *context.Context) {
} else {
if err := git.GetRawDiff(ctx.Repo.GitRepo, sha, git.RawDiffType("patch"), buf); err != nil {
if git.IsErrNotExist(err) {
- ctx.NotFound("GetRawDiff", errors.New("commit "+ctx.Params(":sha")+" does not exist."))
+ ctx.NotFound("GetRawDiff", errors.New("commit "+ctx.PathParam(":sha")+" does not exist."))
return
}
ctx.ServerError("GetRawDiff", err)
diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go
index 7b5e72593f..dae6063908 100644
--- a/routers/web/repo/commit.go
+++ b/routers/web/repo/commit.go
@@ -257,12 +257,12 @@ func FileHistory(ctx *context.Context) {
}
func LoadBranchesAndTags(ctx *context.Context) {
- response, err := git_service.LoadBranchesAndTags(ctx, ctx.Repo, ctx.Params("sha"))
+ response, err := git_service.LoadBranchesAndTags(ctx, ctx.Repo, ctx.PathParam("sha"))
if err == nil {
ctx.JSON(http.StatusOK, response)
return
}
- ctx.NotFoundOrServerError(fmt.Sprintf("could not load branches and tags the commit %s belongs to", ctx.Params("sha")), git.IsErrNotExist, err)
+ ctx.NotFoundOrServerError(fmt.Sprintf("could not load branches and tags the commit %s belongs to", ctx.PathParam("sha")), git.IsErrNotExist, err)
}
// Diff show different from current commit to previous commit
@@ -271,7 +271,7 @@ func Diff(ctx *context.Context) {
userName := ctx.Repo.Owner.Name
repoName := ctx.Repo.Repository.Name
- commitID := ctx.Params(":sha")
+ commitID := ctx.PathParam(":sha")
var (
gitRepo *git.Repository
err error
@@ -420,13 +420,13 @@ func RawDiff(ctx *context.Context) {
}
if err := git.GetRawDiff(
gitRepo,
- ctx.Params(":sha"),
- git.RawDiffType(ctx.Params(":ext")),
+ ctx.PathParam(":sha"),
+ git.RawDiffType(ctx.PathParam(":ext")),
ctx.Resp,
); err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound("GetRawDiff",
- errors.New("commit "+ctx.Params(":sha")+" does not exist."))
+ errors.New("commit "+ctx.PathParam(":sha")+" does not exist."))
return
}
ctx.ServerError("GetRawDiff", err)
diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go
index 818dc4d50f..65e23bf751 100644
--- a/routers/web/repo/compare.go
+++ b/routers/web/repo/compare.go
@@ -203,7 +203,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
// 5. /{:baseOwner}/{:baseRepoName}/compare/{:headOwner}:{:headBranch}
// 6. /{:baseOwner}/{:baseRepoName}/compare/{:headOwner}/{:headRepoName}:{:headBranch}
//
- // Here we obtain the infoPath "{:baseBranch}...[{:headOwner}/{:headRepoName}:]{:headBranch}" as ctx.Params("*")
+ // Here we obtain the infoPath "{:baseBranch}...[{:headOwner}/{:headRepoName}:]{:headBranch}" as ctx.PathParam("*")
// with the :baseRepo in ctx.Repo.
//
// Note: Generally :headRepoName is not provided here - we are only passed :headOwner.
@@ -225,7 +225,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
err error
)
- infoPath = ctx.Params("*")
+ infoPath = ctx.PathParam("*")
var infos []string
if infoPath == "" {
infos = []string{baseRepo.DefaultBranch, baseRepo.DefaultBranch}
@@ -850,7 +850,7 @@ func CompareDiff(ctx *context.Context) {
// ExcerptBlob render blob excerpt contents
func ExcerptBlob(ctx *context.Context) {
- commitID := ctx.Params("sha")
+ commitID := ctx.PathParam("sha")
lastLeft := ctx.FormInt("last_left")
lastRight := ctx.FormInt("last_right")
idxLeft := ctx.FormInt("left")
diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go
index 802e8e6a62..8c4da34060 100644
--- a/routers/web/repo/download.go
+++ b/routers/web/repo/download.go
@@ -139,7 +139,7 @@ func SingleDownloadOrLFS(ctx *context.Context) {
// DownloadByID download a file by sha1 ID
func DownloadByID(ctx *context.Context) {
- blob, err := ctx.Repo.GitRepo.GetBlob(ctx.Params("sha"))
+ blob, err := ctx.Repo.GitRepo.GetBlob(ctx.PathParam("sha"))
if err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound("GetBlob", nil)
@@ -155,7 +155,7 @@ func DownloadByID(ctx *context.Context) {
// DownloadByIDOrLFS download a file by sha1 ID taking account of LFS
func DownloadByIDOrLFS(ctx *context.Context) {
- blob, err := ctx.Repo.GitRepo.GetBlob(ctx.Params("sha"))
+ blob, err := ctx.Repo.GitRepo.GetBlob(ctx.PathParam("sha"))
if err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound("GetBlob", nil)
diff --git a/routers/web/repo/editor_test.go b/routers/web/repo/editor_test.go
index 313fcfe33a..68d69408ac 100644
--- a/routers/web/repo/editor_test.go
+++ b/routers/web/repo/editor_test.go
@@ -43,7 +43,7 @@ func TestCleanUploadName(t *testing.T) {
func TestGetUniquePatchBranchName(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
@@ -58,7 +58,7 @@ func TestGetUniquePatchBranchName(t *testing.T) {
func TestGetClosestParentWithFiles(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
diff --git a/routers/web/repo/find.go b/routers/web/repo/find.go
index 9da4237c1e..2c44552f9c 100644
--- a/routers/web/repo/find.go
+++ b/routers/web/repo/find.go
@@ -17,7 +17,7 @@ const (
// FindFiles render the page to find repository files
func FindFiles(ctx *context.Context) {
- path := ctx.Params("*")
+ path := ctx.PathParam("*")
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/githttp.go b/routers/web/repo/githttp.go
index f0579b56ea..bb85df1a86 100644
--- a/routers/web/repo/githttp.go
+++ b/routers/web/repo/githttp.go
@@ -57,8 +57,8 @@ func CorsHandler() func(next http.Handler) http.Handler {
// httpBase implementation git smart HTTP protocol
func httpBase(ctx *context.Context) *serviceHandler {
- username := ctx.Params(":username")
- reponame := strings.TrimSuffix(ctx.Params(":reponame"), ".git")
+ username := ctx.PathParam(":username")
+ reponame := strings.TrimSuffix(ctx.PathParam(":reponame"), ".git")
if ctx.FormString("go-get") == "1" {
context.EarlyResponseForGoGetMeta(ctx)
@@ -550,7 +550,7 @@ func GetTextFile(p string) func(*context.Context) {
h := httpBase(ctx)
if h != nil {
setHeaderNoCache(ctx)
- file := ctx.Params("file")
+ file := ctx.PathParam("file")
if file != "" {
h.sendFile(ctx, "text/plain", "objects/info/"+file)
} else {
@@ -575,7 +575,7 @@ func GetLooseObject(ctx *context.Context) {
if h != nil {
setHeaderCacheForever(ctx)
h.sendFile(ctx, "application/x-git-loose-object", fmt.Sprintf("objects/%s/%s",
- ctx.Params("head"), ctx.Params("hash")))
+ ctx.PathParam("head"), ctx.PathParam("hash")))
}
}
@@ -584,7 +584,7 @@ func GetPackFile(ctx *context.Context) {
h := httpBase(ctx)
if h != nil {
setHeaderCacheForever(ctx)
- h.sendFile(ctx, "application/x-git-packed-objects", "objects/pack/pack-"+ctx.Params("file")+".pack")
+ h.sendFile(ctx, "application/x-git-packed-objects", "objects/pack/pack-"+ctx.PathParam("file")+".pack")
}
}
@@ -593,6 +593,6 @@ func GetIdxFile(ctx *context.Context) {
h := httpBase(ctx)
if h != nil {
setHeaderCacheForever(ctx)
- h.sendFile(ctx, "application/x-git-packed-objects-toc", "objects/pack/pack-"+ctx.Params("file")+".idx")
+ h.sendFile(ctx, "application/x-git-packed-objects-toc", "objects/pack/pack-"+ctx.PathParam("file")+".idx")
}
}
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index e7ad02c0c2..7c4e3e36f3 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -495,7 +495,7 @@ func issueIDsFromSearch(ctx *context.Context, keyword string, opts *issues_model
// Issues render issues page
func Issues(ctx *context.Context) {
- isPullList := ctx.Params(":type") == "pulls"
+ isPullList := ctx.PathParam(":type") == "pulls"
if isPullList {
MustAllowPulls(ctx)
if ctx.Written() {
@@ -1365,13 +1365,13 @@ func getBranchData(ctx *context.Context, issue *issues_model.Issue) {
// ViewIssue render issue view page
func ViewIssue(ctx *context.Context) {
- if ctx.Params(":type") == "issues" {
+ if ctx.PathParam(":type") == "issues" {
// If issue was requested we check if repo has external tracker and redirect
extIssueUnit, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypeExternalTracker)
if err == nil && extIssueUnit != nil {
if extIssueUnit.ExternalTrackerConfig().ExternalTrackerStyle == markup.IssueNameStyleNumeric || extIssueUnit.ExternalTrackerConfig().ExternalTrackerStyle == "" {
metas := ctx.Repo.Repository.ComposeMetas(ctx)
- metas["index"] = ctx.Params(":index")
+ metas["index"] = ctx.PathParam(":index")
res, err := vars.Expand(extIssueUnit.ExternalTrackerConfig().ExternalTrackerFormat, metas)
if err != nil {
log.Error("unable to expand template vars for issue url. issue: %s, err: %v", metas["index"], err)
@@ -1387,7 +1387,7 @@ func ViewIssue(ctx *context.Context) {
}
}
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound("GetIssueByIndex", err)
@@ -1401,10 +1401,10 @@ func ViewIssue(ctx *context.Context) {
}
// Make sure type and URL matches.
- if ctx.Params(":type") == "issues" && issue.IsPull {
+ if ctx.PathParam(":type") == "issues" && issue.IsPull {
ctx.Redirect(issue.Link())
return
- } else if ctx.Params(":type") == "pulls" && !issue.IsPull {
+ } else if ctx.PathParam(":type") == "pulls" && !issue.IsPull {
ctx.Redirect(issue.Link())
return
}
@@ -2092,7 +2092,7 @@ func sortDependencyInfo(blockers []*issues_model.DependencyInfo) {
// GetActionIssue will return the issue which is used in the context.
func GetActionIssue(ctx *context.Context) *issues_model.Issue {
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
ctx.NotFoundOrServerError("GetIssueByIndex", issues_model.IsErrIssueNotExist, err)
return nil
@@ -2157,7 +2157,7 @@ func getActionIssues(ctx *context.Context) issues_model.IssueList {
// GetIssueInfo get an issue of a repository
func GetIssueInfo(ctx *context.Context) {
- issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.Error(http.StatusNotFound)
@@ -2298,7 +2298,7 @@ func UpdateIssueContent(ctx *context.Context) {
// UpdateIssueDeadline updates an issue deadline
func UpdateIssueDeadline(ctx *context.Context) {
form := web.GetForm(ctx).(*api.EditDeadlineOption)
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound("GetIssueByIndex", err)
@@ -3137,7 +3137,7 @@ func NewComment(ctx *context.Context) {
// UpdateCommentContent change comment of issue's content
func UpdateCommentContent(ctx *context.Context) {
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err)
return
@@ -3222,7 +3222,7 @@ func UpdateCommentContent(ctx *context.Context) {
// DeleteComment delete comment of issue
func DeleteComment(ctx *context.Context) {
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err)
return
@@ -3290,7 +3290,7 @@ func ChangeIssueReaction(ctx *context.Context) {
return
}
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "react":
reaction, err := issue_service.CreateIssueReaction(ctx, ctx.Doer, issue, form.Content)
if err != nil {
@@ -3324,7 +3324,7 @@ func ChangeIssueReaction(ctx *context.Context) {
log.Trace("Reaction for issue removed: %d/%d", ctx.Repo.Repository.ID, issue.ID)
default:
- ctx.NotFound(fmt.Sprintf("Unknown action %s", ctx.Params(":action")), nil)
+ ctx.NotFound(fmt.Sprintf("Unknown action %s", ctx.PathParam(":action")), nil)
return
}
@@ -3352,7 +3352,7 @@ func ChangeIssueReaction(ctx *context.Context) {
// ChangeCommentReaction create a reaction for comment
func ChangeCommentReaction(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.ReactionForm)
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err)
return
@@ -3396,7 +3396,7 @@ func ChangeCommentReaction(ctx *context.Context) {
return
}
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "react":
reaction, err := issue_service.CreateCommentReaction(ctx, ctx.Doer, comment, form.Content)
if err != nil {
@@ -3430,7 +3430,7 @@ func ChangeCommentReaction(ctx *context.Context) {
log.Trace("Reaction for comment removed: %d/%d/%d", ctx.Repo.Repository.ID, comment.Issue.ID, comment.ID)
default:
- ctx.NotFound(fmt.Sprintf("Unknown action %s", ctx.Params(":action")), nil)
+ ctx.NotFound(fmt.Sprintf("Unknown action %s", ctx.PathParam(":action")), nil)
return
}
@@ -3504,7 +3504,7 @@ func GetIssueAttachments(ctx *context.Context) {
// GetCommentAttachments returns attachments for the comment
func GetCommentAttachments(ctx *context.Context) {
- comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
+ comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err)
return
diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go
index e3b85ee638..f1d133edb0 100644
--- a/routers/web/repo/issue_dependency.go
+++ b/routers/web/repo/issue_dependency.go
@@ -14,7 +14,7 @@ import (
// AddDependency adds new dependencies
func AddDependency(ctx *context.Context) {
- issueIndex := ctx.ParamsInt64("index")
+ issueIndex := ctx.PathParamInt64("index")
issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, issueIndex)
if err != nil {
ctx.ServerError("GetIssueByIndex", err)
@@ -88,7 +88,7 @@ func AddDependency(ctx *context.Context) {
// RemoveDependency removes the dependency
func RemoveDependency(ctx *context.Context) {
- issueIndex := ctx.ParamsInt64("index")
+ issueIndex := ctx.PathParamInt64("index")
issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, issueIndex)
if err != nil {
ctx.ServerError("GetIssueByIndex", err)
diff --git a/routers/web/repo/issue_pin.go b/routers/web/repo/issue_pin.go
index 365c812681..0074e31f03 100644
--- a/routers/web/repo/issue_pin.go
+++ b/routers/web/repo/issue_pin.go
@@ -39,7 +39,7 @@ func IssuePinOrUnpin(ctx *context.Context) {
// IssueUnpin unpins a Issue
func IssueUnpin(ctx *context.Context) {
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
ctx.Status(http.StatusInternalServerError)
log.Error(err.Error())
diff --git a/routers/web/repo/issue_timetrack.go b/routers/web/repo/issue_timetrack.go
index 241e434049..099711c5e9 100644
--- a/routers/web/repo/issue_timetrack.go
+++ b/routers/web/repo/issue_timetrack.go
@@ -61,7 +61,7 @@ func DeleteTime(c *context.Context) {
return
}
- t, err := issues_model.GetTrackedTimeByID(c, c.ParamsInt64(":timeid"))
+ t, err := issues_model.GetTrackedTimeByID(c, c.PathParamInt64(":timeid"))
if err != nil {
if db.IsErrNotExist(err) {
c.NotFound("time not found", err)
diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go
index c6c8cb5cfb..e4ee025875 100644
--- a/routers/web/repo/milestone.go
+++ b/routers/web/repo/milestone.go
@@ -165,7 +165,7 @@ func EditMilestone(ctx *context.Context) {
ctx.Data["PageIsMilestones"] = true
ctx.Data["PageIsEditMilestone"] = true
- m, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
+ m, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrMilestoneNotExist(err) {
ctx.NotFound("", nil)
@@ -205,7 +205,7 @@ func EditMilestonePost(ctx *context.Context) {
}
deadline = time.Date(deadline.Year(), deadline.Month(), deadline.Day(), 23, 59, 59, 0, deadline.Location())
- m, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
+ m, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":id"))
if err != nil {
if issues_model.IsErrMilestoneNotExist(err) {
ctx.NotFound("", nil)
@@ -229,7 +229,7 @@ func EditMilestonePost(ctx *context.Context) {
// ChangeMilestoneStatus response for change a milestone's status
func ChangeMilestoneStatus(ctx *context.Context) {
var toClose bool
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "open":
toClose = false
case "close":
@@ -238,7 +238,7 @@ func ChangeMilestoneStatus(ctx *context.Context) {
ctx.JSONRedirect(ctx.Repo.RepoLink + "/milestones")
return
}
- id := ctx.ParamsInt64(":id")
+ id := ctx.PathParamInt64(":id")
if err := issues_model.ChangeMilestoneStatusByRepoIDAndID(ctx, ctx.Repo.Repository.ID, id, toClose); err != nil {
if issues_model.IsErrMilestoneNotExist(err) {
@@ -248,7 +248,7 @@ func ChangeMilestoneStatus(ctx *context.Context) {
}
return
}
- ctx.JSONRedirect(ctx.Repo.RepoLink + "/milestones?state=" + url.QueryEscape(ctx.Params(":action")))
+ ctx.JSONRedirect(ctx.Repo.RepoLink + "/milestones?state=" + url.QueryEscape(ctx.PathParam(":action")))
}
// DeleteMilestone delete a milestone
@@ -264,7 +264,7 @@ func DeleteMilestone(ctx *context.Context) {
// MilestoneIssuesAndPulls lists all the issues and pull requests of the milestone
func MilestoneIssuesAndPulls(ctx *context.Context) {
- milestoneID := ctx.ParamsInt64(":id")
+ milestoneID := ctx.PathParamInt64(":id")
projectID := ctx.FormInt64("project")
milestone, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, milestoneID)
if err != nil {
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index 2e32f478aa..fdeead5703 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -170,7 +170,7 @@ func NewProjectPost(ctx *context.Context) {
// ChangeProjectStatus updates the status of a project between "open" and "close"
func ChangeProjectStatus(ctx *context.Context) {
var toClose bool
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "open":
toClose = false
case "close":
@@ -179,7 +179,7 @@ func ChangeProjectStatus(ctx *context.Context) {
ctx.JSONRedirect(ctx.Repo.RepoLink + "/projects")
return
}
- id := ctx.ParamsInt64(":id")
+ id := ctx.PathParamInt64(":id")
if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx, ctx.Repo.Repository.ID, id, toClose); err != nil {
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
@@ -190,7 +190,7 @@ func ChangeProjectStatus(ctx *context.Context) {
// DeleteProject delete a project
func DeleteProject(ctx *context.Context) {
- p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ p, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if project_model.IsErrProjectNotExist(err) {
ctx.NotFound("", nil)
@@ -220,7 +220,7 @@ func RenderEditProject(ctx *context.Context) {
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["CardTypes"] = project_model.GetCardConfig()
- p, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ p, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if project_model.IsErrProjectNotExist(err) {
ctx.NotFound("", nil)
@@ -247,7 +247,7 @@ func RenderEditProject(ctx *context.Context) {
// EditProjectPost response for editing a project
func EditProjectPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.CreateProjectForm)
- projectID := ctx.ParamsInt64(":id")
+ projectID := ctx.PathParamInt64(":id")
ctx.Data["Title"] = ctx.Tr("repo.projects.edit")
ctx.Data["PageIsEditProjects"] = true
@@ -292,7 +292,7 @@ func EditProjectPost(ctx *context.Context) {
// ViewProject renders the project with board view
func ViewProject(ctx *context.Context) {
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if project_model.IsErrProjectNotExist(err) {
ctx.NotFound("", nil)
@@ -424,7 +424,7 @@ func DeleteProjectColumn(ctx *context.Context) {
return
}
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if project_model.IsErrProjectNotExist(err) {
ctx.NotFound("", nil)
@@ -434,12 +434,12 @@ func DeleteProjectColumn(ctx *context.Context) {
return
}
- pb, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
+ pb, err := project_model.GetColumn(ctx, ctx.PathParamInt64(":columnID"))
if err != nil {
ctx.ServerError("GetProjectColumn", err)
return
}
- if pb.ProjectID != ctx.ParamsInt64(":id") {
+ if pb.ProjectID != ctx.PathParamInt64(":id") {
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
"message": fmt.Sprintf("ProjectColumn[%d] is not in Project[%d] as expected", pb.ID, project.ID),
})
@@ -453,7 +453,7 @@ func DeleteProjectColumn(ctx *context.Context) {
return
}
- if err := project_model.DeleteColumnByID(ctx, ctx.ParamsInt64(":columnID")); err != nil {
+ if err := project_model.DeleteColumnByID(ctx, ctx.PathParamInt64(":columnID")); err != nil {
ctx.ServerError("DeleteProjectColumnByID", err)
return
}
@@ -471,7 +471,7 @@ func AddColumnToProjectPost(ctx *context.Context) {
return
}
- project, err := project_model.GetProjectForRepoByID(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectForRepoByID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":id"))
if err != nil {
if project_model.IsErrProjectNotExist(err) {
ctx.NotFound("", nil)
@@ -509,7 +509,7 @@ func checkProjectColumnChangePermissions(ctx *context.Context) (*project_model.P
return nil, nil
}
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if project_model.IsErrProjectNotExist(err) {
ctx.NotFound("", nil)
@@ -519,12 +519,12 @@ func checkProjectColumnChangePermissions(ctx *context.Context) (*project_model.P
return nil, nil
}
- column, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
+ column, err := project_model.GetColumn(ctx, ctx.PathParamInt64(":columnID"))
if err != nil {
ctx.ServerError("GetProjectColumn", err)
return nil, nil
}
- if column.ProjectID != ctx.ParamsInt64(":id") {
+ if column.ProjectID != ctx.PathParamInt64(":id") {
ctx.JSON(http.StatusUnprocessableEntity, map[string]string{
"message": fmt.Sprintf("ProjectColumn[%d] is not in Project[%d] as expected", column.ID, project.ID),
})
@@ -595,7 +595,7 @@ func MoveIssues(ctx *context.Context) {
return
}
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
if project_model.IsErrProjectNotExist(err) {
ctx.NotFound("ProjectNotExist", nil)
@@ -609,7 +609,7 @@ func MoveIssues(ctx *context.Context) {
return
}
- column, err := project_model.GetColumn(ctx, ctx.ParamsInt64(":columnID"))
+ column, err := project_model.GetColumn(ctx, ctx.PathParamInt64(":columnID"))
if err != nil {
if project_model.IsErrProjectColumnNotExist(err) {
ctx.NotFound("ProjectColumnNotExist", nil)
diff --git a/routers/web/repo/projects_test.go b/routers/web/repo/projects_test.go
index d61230a57e..1a42c615ab 100644
--- a/routers/web/repo/projects_test.go
+++ b/routers/web/repo/projects_test.go
@@ -17,8 +17,8 @@ func TestCheckProjectColumnChangePermissions(t *testing.T) {
ctx, _ := contexttest.MockContext(t, "user2/repo1/projects/1/2")
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadRepo(t, ctx, 1)
- ctx.SetParams(":id", "1")
- ctx.SetParams(":columnID", "2")
+ ctx.SetPathParam(":id", "1")
+ ctx.SetPathParam(":columnID", "2")
project, column := checkProjectColumnChangePermissions(ctx)
assert.NotNil(t, project)
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index 92e0a1674e..4522099460 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -108,7 +108,7 @@ func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository {
}
func getPullInfo(ctx *context.Context) (issue *issues_model.Issue, ok bool) {
- issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrIssueNotExist(err) {
ctx.NotFound("GetIssueByIndex", err)
@@ -886,15 +886,15 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
}
func ViewPullFilesForSingleCommit(ctx *context.Context) {
- viewPullFiles(ctx, "", ctx.Params("sha"), true, true)
+ viewPullFiles(ctx, "", ctx.PathParam("sha"), true, true)
}
func ViewPullFilesForRange(ctx *context.Context) {
- viewPullFiles(ctx, ctx.Params("shaFrom"), ctx.Params("shaTo"), true, false)
+ viewPullFiles(ctx, ctx.PathParam("shaFrom"), ctx.PathParam("shaTo"), true, false)
}
func ViewPullFilesStartingFromCommit(ctx *context.Context) {
- viewPullFiles(ctx, "", ctx.Params("sha"), true, false)
+ viewPullFiles(ctx, "", ctx.PathParam("sha"), true, false)
}
func ViewPullFilesForAllCommitsOfPr(ctx *context.Context) {
@@ -1493,7 +1493,7 @@ func DownloadPullPatch(ctx *context.Context) {
// DownloadPullDiffOrPatch render a pull's raw diff or patch
func DownloadPullDiffOrPatch(ctx *context.Context, patch bool) {
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound("GetPullRequestByIndex", err)
@@ -1586,7 +1586,7 @@ func UpdatePullRequestTarget(ctx *context.Context) {
func SetAllowEdits(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.UpdateAllowEditsForm)
- pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64(":index"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.NotFound("GetPullRequestByIndex", err)
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index 8ba2adf3f1..85c7828f2e 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -286,7 +286,7 @@ func SingleRelease(ctx *context.Context) {
releases, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{
ListOptions: db.ListOptions{Page: 1, PageSize: 1},
RepoID: ctx.Repo.Repository.ID,
- TagNames: []string{ctx.Params("*")},
+ TagNames: []string{ctx.PathParam("*")},
// only show draft releases for users who can write, read-only users shouldn't see draft releases.
IncludeDrafts: writeAccess,
IncludeTags: true,
@@ -528,7 +528,7 @@ func EditRelease(ctx *context.Context) {
ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled
upload.AddUploadContext(ctx, "release")
- tagName := ctx.Params("*")
+ tagName := ctx.PathParam("*")
rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tagName)
if err != nil {
if repo_model.IsErrReleaseNotExist(err) {
@@ -571,7 +571,7 @@ func EditReleasePost(ctx *context.Context) {
ctx.Data["PageIsReleaseList"] = true
ctx.Data["PageIsEditRelease"] = true
- tagName := ctx.Params("*")
+ tagName := ctx.PathParam("*")
rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tagName)
if err != nil {
if repo_model.IsErrReleaseNotExist(err) {
diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go
index e64db03e20..6aba9e0ac1 100644
--- a/routers/web/repo/render.go
+++ b/routers/web/repo/render.go
@@ -47,7 +47,7 @@ func RenderFile(ctx *context.Context) {
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'; sandbox allow-scripts")
- if markupType := markup.Type(blob.Name()); markupType == "" {
+ if markupType := markup.DetectMarkupTypeByFileName(blob.Name()); markupType == "" {
if isTextFile {
_, _ = io.Copy(ctx.Resp, rd)
} else {
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 5a74971827..70dcbae0e1 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -312,7 +312,7 @@ const (
// Action response for actions to a repository
func Action(ctx *context.Context) {
var err error
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "watch":
err = repo_model.WatchRepo(ctx, ctx.Doer, ctx.Repo.Repository, true)
case "unwatch":
@@ -340,29 +340,29 @@ func Action(ctx *context.Context) {
if errors.Is(err, user_model.ErrBlockedUser) {
ctx.Flash.Error(ctx.Tr("repo.action.blocked_user"))
} else {
- ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
+ ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.PathParam(":action")), err)
return
}
}
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "watch", "unwatch":
ctx.Data["IsWatchingRepo"] = repo_model.IsWatching(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID)
case "star", "unstar":
ctx.Data["IsStaringRepo"] = repo_model.IsStaring(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID)
}
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "watch", "unwatch", "star", "unstar":
// we have to reload the repository because NumStars or NumWatching (used in the templates) has just changed
ctx.Data["Repository"], err = repo_model.GetRepositoryByName(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.Name)
if err != nil {
- ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
+ ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.PathParam(":action")), err)
return
}
}
- switch ctx.Params(":action") {
+ switch ctx.PathParam(":action") {
case "watch", "unwatch":
ctx.HTML(http.StatusOK, tplWatchUnwatch)
return
@@ -412,14 +412,15 @@ func acceptOrRejectRepoTransfer(ctx *context.Context, accept bool) error {
// RedirectDownload return a file based on the following infos:
func RedirectDownload(ctx *context.Context) {
var (
- vTag = ctx.Params("vTag")
- fileName = ctx.Params("fileName")
+ vTag = ctx.PathParam("vTag")
+ fileName = ctx.PathParam("fileName")
)
tagNames := []string{vTag}
curRepo := ctx.Repo.Repository
releases, err := db.Find[repo_model.Release](ctx, repo_model.FindReleasesOptions{
- RepoID: curRepo.ID,
- TagNames: tagNames,
+ IncludeDrafts: ctx.Repo.CanWrite(unit.TypeReleases),
+ RepoID: curRepo.ID,
+ TagNames: tagNames,
})
if err != nil {
ctx.ServerError("RedirectDownload", err)
@@ -459,7 +460,7 @@ func RedirectDownload(ctx *context.Context) {
// Download an archive of a repository
func Download(ctx *context.Context) {
- uri := ctx.Params("*")
+ uri := ctx.PathParam("*")
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
if err != nil {
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
@@ -518,7 +519,7 @@ func download(ctx *context.Context, archiveName string, archiver *repo_model.Rep
// a request that's already in-progress, but the archiver service will just
// kind of drop it on the floor if this is the case.
func InitiateDownload(ctx *context.Context) {
- uri := ctx.Params("*")
+ uri := ctx.PathParam("*")
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
if err != nil {
ctx.ServerError("archiver_service.NewRequest", err)
@@ -615,7 +616,7 @@ func SearchRepo(ctx *context.Context) {
if len(sortOrder) == 0 {
sortOrder = "asc"
}
- if searchModeMap, ok := repo_model.SearchOrderByMap[sortOrder]; ok {
+ if searchModeMap, ok := repo_model.OrderByMap[sortOrder]; ok {
if orderBy, ok := searchModeMap[sortMode]; ok {
opts.OrderBy = orderBy
} else {
diff --git a/routers/web/repo/setting/git_hooks.go b/routers/web/repo/setting/git_hooks.go
index 217a01c90c..2e9caa4c86 100644
--- a/routers/web/repo/setting/git_hooks.go
+++ b/routers/web/repo/setting/git_hooks.go
@@ -30,7 +30,7 @@ func GitHooksEdit(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.settings.githooks")
ctx.Data["PageIsSettingsGitHooks"] = true
- name := ctx.Params(":name")
+ name := ctx.PathParam(":name")
hook, err := ctx.Repo.GitRepo.GetHook(name)
if err != nil {
if err == git.ErrNotValidHook {
@@ -46,7 +46,7 @@ func GitHooksEdit(ctx *context.Context) {
// GitHooksEditPost response for editing a git hook of a repository
func GitHooksEditPost(ctx *context.Context) {
- name := ctx.Params(":name")
+ name := ctx.PathParam(":name")
hook, err := ctx.Repo.GitRepo.GetHook(name)
if err != nil {
if err == git.ErrNotValidHook {
diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go
index 2891556d6f..3b96f93ff2 100644
--- a/routers/web/repo/setting/lfs.go
+++ b/routers/web/repo/setting/lfs.go
@@ -236,7 +236,7 @@ func LFSUnlock(ctx *context.Context) {
ctx.NotFound("LFSUnlock", nil)
return
}
- _, err := git_model.DeleteLFSLockByID(ctx, ctx.ParamsInt64("lid"), ctx.Repo.Repository, ctx.Doer, true)
+ _, err := git_model.DeleteLFSLockByID(ctx, ctx.PathParamInt64("lid"), ctx.Repo.Repository, ctx.Doer, true)
if err != nil {
ctx.ServerError("LFSUnlock", err)
return
@@ -251,7 +251,7 @@ func LFSFileGet(ctx *context.Context) {
return
}
ctx.Data["LFSFilesLink"] = ctx.Repo.RepoLink + "/settings/lfs"
- oid := ctx.Params("oid")
+ oid := ctx.PathParam("oid")
p := lfs.Pointer{Oid: oid}
if !p.IsValid() {
@@ -348,7 +348,7 @@ func LFSDelete(ctx *context.Context) {
ctx.NotFound("LFSDelete", nil)
return
}
- oid := ctx.Params("oid")
+ oid := ctx.PathParam("oid")
p := lfs.Pointer{Oid: oid}
if !p.IsValid() {
ctx.NotFound("LFSDelete", nil)
diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go
index 4bab3f897a..400186db67 100644
--- a/routers/web/repo/setting/protected_branch.go
+++ b/routers/web/repo/setting/protected_branch.go
@@ -266,7 +266,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
// DeleteProtectedBranchRulePost delete protected branch rule by id
func DeleteProtectedBranchRulePost(ctx *context.Context) {
- ruleID := ctx.ParamsInt64("id")
+ ruleID := ctx.PathParamInt64("id")
if ruleID <= 0 {
ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", fmt.Sprintf("%d", ruleID)))
ctx.JSONRedirect(fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink))
diff --git a/routers/web/repo/setting/protected_tag.go b/routers/web/repo/setting/protected_tag.go
index 2c25b650b9..fcfa77aa8c 100644
--- a/routers/web/repo/setting/protected_tag.go
+++ b/routers/web/repo/setting/protected_tag.go
@@ -169,7 +169,7 @@ func setTagsContext(ctx *context.Context) error {
func selectProtectedTagByContext(ctx *context.Context) *git_model.ProtectedTag {
id := ctx.FormInt64("id")
if id == 0 {
- id = ctx.ParamsInt64(":id")
+ id = ctx.PathParamInt64(":id")
}
tag, err := git_model.GetProtectedTagByID(ctx, id)
diff --git a/routers/web/repo/setting/runners.go b/routers/web/repo/setting/runners.go
index a47d3b45e2..93e6f518b0 100644
--- a/routers/web/repo/setting/runners.go
+++ b/routers/web/repo/setting/runners.go
@@ -147,7 +147,7 @@ func RunnersEdit(ctx *context.Context) {
}
actions_shared.RunnerDetails(ctx, page,
- ctx.ParamsInt64(":runnerid"), rCtx.OwnerID, rCtx.RepoID,
+ ctx.PathParamInt64(":runnerid"), rCtx.OwnerID, rCtx.RepoID,
)
ctx.HTML(http.StatusOK, rCtx.RunnerEditTemplate)
}
@@ -158,9 +158,9 @@ func RunnersEditPost(ctx *context.Context) {
ctx.ServerError("getRunnersCtx", err)
return
}
- actions_shared.RunnerDetailsEditPost(ctx, ctx.ParamsInt64(":runnerid"),
+ actions_shared.RunnerDetailsEditPost(ctx, ctx.PathParamInt64(":runnerid"),
rCtx.OwnerID, rCtx.RepoID,
- rCtx.RedirectLink+url.PathEscape(ctx.Params(":runnerid")))
+ rCtx.RedirectLink+url.PathEscape(ctx.PathParam(":runnerid")))
}
func ResetRunnerRegistrationToken(ctx *context.Context) {
@@ -179,7 +179,7 @@ func RunnerDeletePost(ctx *context.Context) {
ctx.ServerError("getRunnersCtx", err)
return
}
- actions_shared.RunnerDeletePost(ctx, ctx.ParamsInt64(":runnerid"), rCtx.RedirectLink, rCtx.RedirectLink+url.PathEscape(ctx.Params(":runnerid")))
+ actions_shared.RunnerDeletePost(ctx, ctx.PathParamInt64(":runnerid"), rCtx.RedirectLink, rCtx.RedirectLink+url.PathEscape(ctx.PathParam(":runnerid")))
}
func RedirectToDefaultSetting(ctx *context.Context) {
diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go
index 1a3549fea4..7661599729 100644
--- a/routers/web/repo/setting/webhook.go
+++ b/routers/web/repo/setting/webhook.go
@@ -99,9 +99,9 @@ func getOwnerRepoCtx(ctx *context.Context) (*ownerRepoCtx, error) {
if ctx.Data["PageIsAdmin"] == true {
return &ownerRepoCtx{
IsAdmin: true,
- IsSystemWebhook: ctx.Params(":configType") == "system-hooks",
+ IsSystemWebhook: ctx.PathParam(":configType") == "system-hooks",
Link: path.Join(setting.AppSubURL, "/admin/hooks"),
- LinkNew: path.Join(setting.AppSubURL, "/admin/", ctx.Params(":configType")),
+ LinkNew: path.Join(setting.AppSubURL, "/admin/", ctx.PathParam(":configType")),
NewTemplate: tplAdminHookNew,
}, nil
}
@@ -110,7 +110,7 @@ func getOwnerRepoCtx(ctx *context.Context) (*ownerRepoCtx, error) {
}
func checkHookType(ctx *context.Context) string {
- hookType := strings.ToLower(ctx.Params(":type"))
+ hookType := strings.ToLower(ctx.PathParam(":type"))
if !util.SliceContainsString(setting.Webhook.Types, hookType, true) {
ctx.NotFound("checkHookType", nil)
return ""
@@ -592,11 +592,11 @@ func checkWebhook(ctx *context.Context) (*ownerRepoCtx, *webhook.Webhook) {
var w *webhook.Webhook
if orCtx.RepoID > 0 {
- w, err = webhook.GetWebhookByRepoID(ctx, orCtx.RepoID, ctx.ParamsInt64(":id"))
+ w, err = webhook.GetWebhookByRepoID(ctx, orCtx.RepoID, ctx.PathParamInt64(":id"))
} else if orCtx.OwnerID > 0 {
- w, err = webhook.GetWebhookByOwnerID(ctx, orCtx.OwnerID, ctx.ParamsInt64(":id"))
+ w, err = webhook.GetWebhookByOwnerID(ctx, orCtx.OwnerID, ctx.PathParamInt64(":id"))
} else if orCtx.IsAdmin {
- w, err = webhook.GetSystemOrDefaultWebhook(ctx, ctx.ParamsInt64(":id"))
+ w, err = webhook.GetSystemOrDefaultWebhook(ctx, ctx.PathParamInt64(":id"))
}
if err != nil || w == nil {
if webhook.IsErrWebhookNotExist(err) {
@@ -645,7 +645,7 @@ func WebHooksEdit(ctx *context.Context) {
// TestWebhook test if web hook is work fine
func TestWebhook(ctx *context.Context) {
- hookID := ctx.ParamsInt64(":id")
+ hookID := ctx.PathParamInt64(":id")
w, err := webhook.GetWebhookByRepoID(ctx, ctx.Repo.Repository.ID, hookID)
if err != nil {
ctx.Flash.Error("GetWebhookByRepoID: " + err.Error())
@@ -706,7 +706,7 @@ func TestWebhook(ctx *context.Context) {
// ReplayWebhook replays a webhook
func ReplayWebhook(ctx *context.Context) {
- hookTaskUUID := ctx.Params(":uuid")
+ hookTaskUUID := ctx.PathParam(":uuid")
orCtx, w := checkWebhook(ctx)
if ctx.Written() {
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 0aa3fe1efd..203dac7439 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -307,7 +307,7 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr
rd := charset.ToUTF8WithFallbackReader(io.MultiReader(bytes.NewReader(buf), dataRc), charset.ConvertOpts{})
- if markupType := markup.Type(readmeFile.Name()); markupType != "" {
+ if markupType := markup.DetectMarkupTypeByFileName(readmeFile.Name()); markupType != "" {
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
@@ -499,7 +499,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
readmeExist := util.IsReadmeFileName(blob.Name())
ctx.Data["ReadmeExist"] = readmeExist
- markupType := markup.Type(blob.Name())
+ markupType := markup.DetectMarkupTypeByFileName(blob.Name())
// If the markup is detected by custom markup renderer it should not be reset later on
// to not pass it down to the render context.
detected := false
@@ -607,7 +607,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
// TODO: this logic duplicates with "isRepresentableAsText=true", it is not the same as "LFSFileGet" in "lfs.go"
// It is used by "external renders", markupRender will execute external programs to get rendered content.
- if markupType := markup.Type(blob.Name()); markupType != "" {
+ if markupType := markup.DetectMarkupTypeByFileName(blob.Name()); markupType != "" {
rd := io.MultiReader(bytes.NewReader(buf), dataRc)
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
@@ -772,7 +772,7 @@ func checkCitationFile(ctx *context.Context, entry *git.TreeEntry) {
// Home render repository home page
func Home(ctx *context.Context) {
if setting.Other.EnableFeed {
- isFeed, _, showFeedType := feed.GetFeedType(ctx.Params(":reponame"), ctx.Req)
+ isFeed, _, showFeedType := feed.GetFeedType(ctx.PathParam(":reponame"), ctx.Req)
if isFeed {
switch {
case ctx.Link == fmt.Sprintf("%s.%s", ctx.Repo.RepoLink, showFeedType):
diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go
index df15f61b17..ff6397cd2a 100644
--- a/routers/web/repo/wiki.go
+++ b/routers/web/repo/wiki.go
@@ -532,7 +532,7 @@ func Wiki(ctx *context.Context) {
}
wikiPath := entry.Name()
- if markup.Type(wikiPath) != markdown.MarkupName {
+ if markup.DetectMarkupTypeByFileName(wikiPath) != markdown.MarkupName {
ext := strings.ToUpper(filepath.Ext(wikiPath))
ctx.Data["FormatWarning"] = fmt.Sprintf("%s rendering is not supported at the moment. Rendered as Markdown.", ext)
}
diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go
index 4602dcfeb4..7de5899e21 100644
--- a/routers/web/repo/wiki_test.go
+++ b/routers/web/repo/wiki_test.go
@@ -81,7 +81,7 @@ func TestWiki(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki")
- ctx.SetParams("*", "Home")
+ ctx.SetPathParam("*", "Home")
contexttest.LoadRepo(t, ctx, 1)
Wiki(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
@@ -153,7 +153,7 @@ func TestEditWiki(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/Home?action=_edit")
- ctx.SetParams("*", "Home")
+ ctx.SetPathParam("*", "Home")
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadRepo(t, ctx, 1)
EditWiki(ctx)
@@ -169,7 +169,7 @@ func TestEditWikiPost(t *testing.T) {
} {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/Home?action=_new")
- ctx.SetParams("*", "Home")
+ ctx.SetPathParam("*", "Home")
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadRepo(t, ctx, 1)
web.SetForm(ctx, &forms.NewWikiForm{
@@ -211,7 +211,7 @@ func TestWikiRaw(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/raw/"+url.PathEscape(filepath))
- ctx.SetParams("*", filepath)
+ ctx.SetPathParam("*", filepath)
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadRepo(t, ctx, 1)
WikiRaw(ctx)
@@ -236,7 +236,7 @@ func TestDefaultWikiBranch(t *testing.T) {
assert.NoError(t, repo_model.UpdateRepositoryCols(db.DefaultContext, &repo_model.Repository{ID: 1, DefaultWikiBranch: "wrong-branch"}))
ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki")
- ctx.SetParams("*", "Home")
+ ctx.SetPathParam("*", "Home")
contexttest.LoadRepo(t, ctx, 1)
assert.Equal(t, "wrong-branch", ctx.Repo.Repository.DefaultWikiBranch)
Wiki(ctx) // after the visiting, the out-of-sync database record will update the branch name to "master"
diff --git a/routers/web/shared/actions/variables.go b/routers/web/shared/actions/variables.go
index 79c03e4e8c..5c5768243a 100644
--- a/routers/web/shared/actions/variables.go
+++ b/routers/web/shared/actions/variables.go
@@ -40,7 +40,7 @@ func CreateVariable(ctx *context.Context, ownerID, repoID int64, redirectURL str
}
func UpdateVariable(ctx *context.Context, redirectURL string) {
- id := ctx.ParamsInt64(":variable_id")
+ id := ctx.PathParamInt64(":variable_id")
form := web.GetForm(ctx).(*forms.EditVariableForm)
if ok, err := actions_service.UpdateVariable(ctx, id, form.Name, form.Data); err != nil || !ok {
@@ -53,7 +53,7 @@ func UpdateVariable(ctx *context.Context, redirectURL string) {
}
func DeleteVariable(ctx *context.Context, redirectURL string) {
- id := ctx.ParamsInt64(":variable_id")
+ id := ctx.PathParamInt64(":variable_id")
if err := actions_service.DeleteVariableByID(ctx, id); err != nil {
log.Error("Delete variable [%d] failed: %v", id, err)
diff --git a/routers/web/shared/packages/packages.go b/routers/web/shared/packages/packages.go
index 57671ad8f1..1d3cabf71b 100644
--- a/routers/web/shared/packages/packages.go
+++ b/routers/web/shared/packages/packages.go
@@ -204,7 +204,7 @@ func SetRulePreviewContext(ctx *context.Context, owner *user_model.User) {
func getCleanupRuleByContext(ctx *context.Context, owner *user_model.User) *packages_model.PackageCleanupRule {
id := ctx.FormInt64("id")
if id == 0 {
- id = ctx.ParamsInt64("id")
+ id = ctx.PathParamInt64("id")
}
pcr, err := packages_model.GetCleanupRuleByID(ctx, id)
diff --git a/routers/web/shared/project/column.go b/routers/web/shared/project/column.go
index 599842ea9e..ba1f527bea 100644
--- a/routers/web/shared/project/column.go
+++ b/routers/web/shared/project/column.go
@@ -11,7 +11,7 @@ import (
// MoveColumns moves or keeps columns in a project and sorts them inside that project
func MoveColumns(ctx *context.Context) {
- project, err := project_model.GetProjectByID(ctx, ctx.ParamsInt64(":id"))
+ project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id"))
if err != nil {
ctx.NotFoundOrServerError("GetProjectByID", project_model.IsErrProjectNotExist, err)
return
diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go
index 04f510161d..7000e25778 100644
--- a/routers/web/user/avatar.go
+++ b/routers/web/user/avatar.go
@@ -23,8 +23,8 @@ func cacheableRedirect(ctx *context.Context, location string) {
// AvatarByUserName redirect browser to user avatar of requested size
func AvatarByUserName(ctx *context.Context) {
- userName := ctx.Params(":username")
- size := int(ctx.ParamsInt64(":size"))
+ userName := ctx.PathParam(":username")
+ size := int(ctx.PathParamInt64(":size"))
var user *user_model.User
if strings.ToLower(userName) != user_model.GhostUserLowerName {
@@ -46,7 +46,7 @@ func AvatarByUserName(ctx *context.Context) {
// AvatarByEmailHash redirects the browser to the email avatar link
func AvatarByEmailHash(ctx *context.Context) {
- hash := ctx.Params(":hash")
+ hash := ctx.PathParam(":hash")
email, err := avatars.GetEmailForHash(ctx, hash)
if err != nil {
ctx.ServerError("invalid avatar hash: "+hash, err)
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index b03a514030..e94433b3c5 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -50,7 +50,7 @@ const (
// getDashboardContextUser finds out which context user dashboard is being viewed as .
func getDashboardContextUser(ctx *context.Context) *user_model.User {
ctxUser := ctx.Doer
- orgName := ctx.Params(":org")
+ orgName := ctx.PathParam(":org")
if len(orgName) > 0 {
ctxUser = ctx.Org.Organization.AsUser()
ctx.Data["Teams"] = ctx.Org.Teams
@@ -714,9 +714,9 @@ func ShowGPGKeys(ctx *context.Context) {
func UsernameSubRoute(ctx *context.Context) {
// WORKAROUND to support usernames with "." in it
// https://github.com/go-chi/chi/issues/781
- username := ctx.Params("username")
+ username := ctx.PathParam("username")
reloadParam := func(suffix string) (success bool) {
- ctx.SetParams("username", strings.TrimSuffix(username, suffix))
+ ctx.SetPathParam("username", strings.TrimSuffix(username, suffix))
context.UserAssignmentWeb()(ctx)
if ctx.Written() {
return false
diff --git a/routers/web/user/home_test.go b/routers/web/user/home_test.go
index 1cc9886308..51246551ea 100644
--- a/routers/web/user/home_test.go
+++ b/routers/web/user/home_test.go
@@ -83,7 +83,7 @@ func TestMilestones(t *testing.T) {
ctx, _ := contexttest.MockContext(t, "milestones")
contexttest.LoadUser(t, ctx, 2)
- ctx.SetParams("sort", "issues")
+ ctx.SetPathParam("sort", "issues")
ctx.Req.Form.Set("state", "closed")
ctx.Req.Form.Set("sort", "furthestduedate")
Milestones(ctx)
@@ -102,8 +102,8 @@ func TestMilestonesForSpecificRepo(t *testing.T) {
ctx, _ := contexttest.MockContext(t, "milestones")
contexttest.LoadUser(t, ctx, 2)
- ctx.SetParams("sort", "issues")
- ctx.SetParams("repo", "1")
+ ctx.SetPathParam("sort", "issues")
+ ctx.SetPathParam("repo", "1")
ctx.Req.Form.Set("state", "closed")
ctx.Req.Form.Set("sort", "furthestduedate")
Milestones(ctx)
diff --git a/routers/web/user/package.go b/routers/web/user/package.go
index dad4c8f602..4e39eabc0f 100644
--- a/routers/web/user/package.go
+++ b/routers/web/user/package.go
@@ -136,7 +136,7 @@ func ListPackages(ctx *context.Context) {
// RedirectToLastVersion redirects to the latest package version
func RedirectToLastVersion(ctx *context.Context) {
- p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.Params("type")), ctx.Params("name"))
+ p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.PathParam("type")), ctx.PathParam("name"))
if err != nil {
if err == packages_model.ErrPackageNotExist {
ctx.NotFound("GetPackageByName", err)
@@ -298,7 +298,7 @@ func ViewPackageVersion(ctx *context.Context) {
// ListPackageVersions lists all versions of a package
func ListPackageVersions(ctx *context.Context) {
shared_user.PrepareContextForProfileBigAvatar(ctx)
- p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.Params("type")), ctx.Params("name"))
+ p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.PathParam("type")), ctx.PathParam("name"))
if err != nil {
if err == packages_model.ErrPackageNotExist {
ctx.NotFound("GetPackageByName", err)
@@ -485,7 +485,7 @@ func PackageSettingsPost(ctx *context.Context) {
// DownloadPackageFile serves the content of a package file
func DownloadPackageFile(ctx *context.Context) {
- pf, err := packages_model.GetFileForVersionByID(ctx, ctx.Package.Descriptor.Version.ID, ctx.ParamsInt64(":fileid"))
+ pf, err := packages_model.GetFileForVersionByID(ctx, ctx.Package.Descriptor.Version.ID, ctx.PathParamInt64(":fileid"))
if err != nil {
if err == packages_model.ErrPackageFileNotExist {
ctx.NotFound("", err)
diff --git a/routers/web/user/setting/oauth2_common.go b/routers/web/user/setting/oauth2_common.go
index 85d1e820a5..4477dc570f 100644
--- a/routers/web/user/setting/oauth2_common.go
+++ b/routers/web/user/setting/oauth2_common.go
@@ -73,7 +73,7 @@ func (oa *OAuth2CommonHandlers) AddApp(ctx *context.Context) {
// EditShow displays the given application
func (oa *OAuth2CommonHandlers) EditShow(ctx *context.Context) {
- app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id"))
+ app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.PathParamInt64("id"))
if err != nil {
if auth.IsErrOAuthApplicationNotFound(err) {
ctx.NotFound("Application not found", err)
@@ -102,7 +102,7 @@ func (oa *OAuth2CommonHandlers) EditSave(ctx *context.Context) {
// TODO validate redirect URI
var err error
if ctx.Data["App"], err = auth.UpdateOAuth2Application(ctx, auth.UpdateOAuth2ApplicationOptions{
- ID: ctx.ParamsInt64("id"),
+ ID: ctx.PathParamInt64("id"),
Name: form.Name,
RedirectURIs: util.SplitTrimSpace(form.RedirectURIs, "\n"),
UserID: oa.OwnerID,
@@ -117,7 +117,7 @@ func (oa *OAuth2CommonHandlers) EditSave(ctx *context.Context) {
// RegenerateSecret regenerates the secret
func (oa *OAuth2CommonHandlers) RegenerateSecret(ctx *context.Context) {
- app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id"))
+ app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.PathParamInt64("id"))
if err != nil {
if auth.IsErrOAuthApplicationNotFound(err) {
ctx.NotFound("Application not found", err)
@@ -142,7 +142,7 @@ func (oa *OAuth2CommonHandlers) RegenerateSecret(ctx *context.Context) {
// DeleteApp deletes the given oauth2 application
func (oa *OAuth2CommonHandlers) DeleteApp(ctx *context.Context) {
- if err := auth.DeleteOAuth2Application(ctx, ctx.ParamsInt64("id"), oa.OwnerID); err != nil {
+ if err := auth.DeleteOAuth2Application(ctx, ctx.PathParamInt64("id"), oa.OwnerID); err != nil {
ctx.ServerError("DeleteOAuth2Application", err)
return
}
@@ -153,7 +153,7 @@ func (oa *OAuth2CommonHandlers) DeleteApp(ctx *context.Context) {
// RevokeGrant revokes the grant
func (oa *OAuth2CommonHandlers) RevokeGrant(ctx *context.Context) {
- if err := auth.RevokeOAuth2Grant(ctx, ctx.ParamsInt64("grantId"), oa.OwnerID); err != nil {
+ if err := auth.RevokeOAuth2Grant(ctx, ctx.PathParamInt64("grantId"), oa.OwnerID); err != nil {
ctx.ServerError("RevokeOAuth2Grant", err)
return
}
diff --git a/routers/web/user/setting/security/webauthn.go b/routers/web/user/setting/security/webauthn.go
index e382c8b9af..1b8d0171f5 100644
--- a/routers/web/user/setting/security/webauthn.go
+++ b/routers/web/user/setting/security/webauthn.go
@@ -45,7 +45,9 @@ func WebAuthnRegister(ctx *context.Context) {
return
}
- credentialOptions, sessionData, err := wa.WebAuthn.BeginRegistration((*wa.User)(ctx.Doer))
+ credentialOptions, sessionData, err := wa.WebAuthn.BeginRegistration((*wa.User)(ctx.Doer), webauthn.WithAuthenticatorSelection(protocol.AuthenticatorSelection{
+ ResidentKey: protocol.ResidentKeyRequirementRequired,
+ }))
if err != nil {
ctx.ServerError("Unable to BeginRegistration", err)
return
diff --git a/routers/web/user/task.go b/routers/web/user/task.go
index 8476767e9e..475ef16212 100644
--- a/routers/web/user/task.go
+++ b/routers/web/user/task.go
@@ -14,11 +14,11 @@ import (
// TaskStatus returns task's status
func TaskStatus(ctx *context.Context) {
- task, opts, err := admin_model.GetMigratingTaskByID(ctx, ctx.ParamsInt64("task"), ctx.Doer.ID)
+ task, opts, err := admin_model.GetMigratingTaskByID(ctx, ctx.PathParamInt64("task"), ctx.Doer.ID)
if err != nil {
if admin_model.IsErrTaskDoesNotExist(err) {
ctx.JSON(http.StatusNotFound, map[string]any{
- "error": "task `" + strconv.FormatInt(ctx.ParamsInt64("task"), 10) + "` does not exist",
+ "error": "task `" + strconv.FormatInt(ctx.PathParamInt64("task"), 10) + "` does not exist",
})
return
}
diff --git a/routers/web/web.go b/routers/web/web.go
index 5fb1ce0e80..d08e8da772 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -226,8 +226,8 @@ func ctxDataSet(args ...any) func(ctx *context.Context) {
}
// Routes returns all web routes
-func Routes() *web.Route {
- routes := web.NewRoute()
+func Routes() *web.Router {
+ routes := web.NewRouter()
routes.Head("/", misc.DummyOK) // for health check - doesn't need to be passed through gzip handler
routes.Methods("GET, HEAD, OPTIONS", "/assets/*", optionsCorsHandler(), public.FileHandlerFunc())
@@ -283,7 +283,7 @@ func Routes() *web.Route {
mid = append(mid, repo.GetActiveStopwatch)
mid = append(mid, goGet)
- others := web.NewRoute()
+ others := web.NewRouter()
others.Use(mid...)
registerRoutes(others)
routes.Mount("", others)
@@ -293,7 +293,7 @@ func Routes() *web.Route {
var ignSignInAndCsrf = verifyAuthWithOptions(&common.VerifyOptions{DisableCSRF: true})
// registerRoutes register routes
-func registerRoutes(m *web.Route) {
+func registerRoutes(m *web.Router) {
reqSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: true})
reqSignOut := verifyAuthWithOptions(&common.VerifyOptions{SignOutRequired: true})
// TODO: rename them to "optSignIn", which means that the "sign-in" could be optional, depends on the VerifyOptions (RequireSignInView)
@@ -384,18 +384,18 @@ func registerRoutes(m *web.Route) {
return func(ctx *context.Context) {
// only check global disabled units when ignoreGlobal is false
if !ignoreGlobal && unitType.UnitGlobalDisabled() {
- ctx.NotFound(unitType.String(), nil)
+ ctx.NotFound("Repo unit is is disabled: "+unitType.LogString(), nil)
return
}
if ctx.ContextUser == nil {
- ctx.NotFound(unitType.String(), nil)
+ ctx.NotFound("ContextUser is nil", nil)
return
}
if ctx.ContextUser.IsOrganization() {
if ctx.Org.Organization.UnitPermission(ctx, ctx.Doer, unitType) < accessMode {
- ctx.NotFound(unitType.String(), nil)
+ ctx.NotFound("ContextUser is org but doer has no access to unit", nil)
return
}
}
@@ -487,7 +487,7 @@ func registerRoutes(m *web.Route) {
m.Get("/organizations", explore.Organizations)
m.Get("/code", func(ctx *context.Context) {
if unit.TypeCode.UnitGlobalDisabled() {
- ctx.NotFound(unit.TypeCode.String(), nil)
+ ctx.NotFound("Repo unit code is disabled", nil)
return
}
}, explore.Code)
@@ -535,6 +535,8 @@ func registerRoutes(m *web.Route) {
})
m.Group("/webauthn", func() {
m.Get("", auth.WebAuthn)
+ m.Get("/passkey/assertion", auth.WebAuthnPasskeyAssertion)
+ m.Post("/passkey/login", auth.WebAuthnPasskeyLogin)
m.Get("/assertion", auth.WebAuthnLoginAssertion)
m.Post("/assertion", auth.WebAuthnLoginAssertionPost)
})
@@ -692,6 +694,7 @@ func registerRoutes(m *web.Route) {
m.Get("", admin.Config)
m.Post("", admin.ChangeConfig)
m.Post("/test_mail", admin.SendTestMail)
+ m.Post("/test_cache", admin.TestCache)
m.Get("/settings", admin.ConfigSettings)
})
diff --git a/services/context/api.go b/services/context/api.go
index c684add297..84da526e74 100644
--- a/services/context/api.go
+++ b/services/context/api.go
@@ -317,7 +317,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
}
ctx.Repo.Commit = commit
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
- ctx.Repo.TreePath = ctx.Params("*")
+ ctx.Repo.TreePath = ctx.PathParam("*")
next.ServeHTTP(w, req)
return
}
@@ -347,7 +347,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return
}
} else {
- ctx.NotFound(fmt.Errorf("not exist: '%s'", ctx.Params("*")))
+ ctx.NotFound(fmt.Errorf("not exist: '%s'", ctx.PathParam("*")))
return
}
diff --git a/services/context/base.go b/services/context/base.go
index 23f0bcfc33..68619bf067 100644
--- a/services/context/base.go
+++ b/services/context/base.go
@@ -18,6 +18,7 @@ import (
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/translation"
"code.gitea.io/gitea/modules/web/middleware"
@@ -142,24 +143,28 @@ func (b *Base) RemoteAddr() string {
return b.Req.RemoteAddr
}
-// Params returns the param on route
-func (b *Base) Params(p string) string {
- s, _ := url.PathUnescape(chi.URLParam(b.Req, strings.TrimPrefix(p, ":")))
+// PathParam returns the param in request path, eg: "/{var}" => "/a%2fb", then `var == "a/b"`
+func (b *Base) PathParam(name string) string {
+ s, err := url.PathUnescape(b.PathParamRaw(name))
+ if err != nil && !setting.IsProd {
+ panic("Failed to unescape path param: " + err.Error() + ", there seems to be a double-unescaping bug")
+ }
return s
}
-func (b *Base) PathParamRaw(p string) string {
- return chi.URLParam(b.Req, strings.TrimPrefix(p, ":"))
+// PathParamRaw returns the raw param in request path, eg: "/{var}" => "/a%2fb", then `var == "a%2fb"`
+func (b *Base) PathParamRaw(name string) string {
+ return chi.URLParam(b.Req, strings.TrimPrefix(name, ":"))
}
-// ParamsInt64 returns the param on route as int64
-func (b *Base) ParamsInt64(p string) int64 {
- v, _ := strconv.ParseInt(b.Params(p), 10, 64)
+// PathParamInt64 returns the param in request path as int64
+func (b *Base) PathParamInt64(p string) int64 {
+ v, _ := strconv.ParseInt(b.PathParam(p), 10, 64)
return v
}
-// SetParams set params into routes
-func (b *Base) SetParams(k, v string) {
+// SetPathParam set request path params into routes
+func (b *Base) SetPathParam(k, v string) {
chiCtx := chi.RouteContext(b)
chiCtx.URLParams.Add(strings.TrimPrefix(k, ":"), url.PathEscape(v))
}
diff --git a/services/context/context.go b/services/context/context.go
index aab0485f1a..69b65cbddb 100644
--- a/services/context/context.go
+++ b/services/context/context.go
@@ -210,16 +210,9 @@ func Contexter() func(next http.Handler) http.Handler {
// FIXME: do we really always need these setting? There should be someway to have to avoid having to always set these
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations
ctx.Data["DisableStars"] = setting.Repository.DisableStars
- ctx.Data["EnableActions"] = setting.Actions.Enabled
+ ctx.Data["EnableActions"] = setting.Actions.Enabled && !unit.TypeActions.UnitGlobalDisabled()
ctx.Data["ManifestData"] = setting.ManifestData
-
- ctx.Data["UnitWikiGlobalDisabled"] = unit.TypeWiki.UnitGlobalDisabled()
- ctx.Data["UnitIssuesGlobalDisabled"] = unit.TypeIssues.UnitGlobalDisabled()
- ctx.Data["UnitPullsGlobalDisabled"] = unit.TypePullRequests.UnitGlobalDisabled()
- ctx.Data["UnitProjectsGlobalDisabled"] = unit.TypeProjects.UnitGlobalDisabled()
- ctx.Data["UnitActionsGlobalDisabled"] = unit.TypeActions.UnitGlobalDisabled()
-
ctx.Data["AllLangs"] = translation.AllLangs()
next.ServeHTTP(ctx.Resp, ctx.Req)
diff --git a/services/context/org.go b/services/context/org.go
index 018b76de43..7eba80ff96 100644
--- a/services/context/org.go
+++ b/services/context/org.go
@@ -41,7 +41,7 @@ func (org *Organization) CanReadUnit(ctx *Context, unitType unit.Type) bool {
}
func GetOrganizationByParams(ctx *Context) {
- orgName := ctx.Params(":org")
+ orgName := ctx.PathParam(":org")
var err error
@@ -221,7 +221,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
ctx.Data["NumTeams"] = len(ctx.Org.Teams)
}
- teamName := ctx.Params(":team")
+ teamName := ctx.PathParam(":team")
if len(teamName) > 0 {
teamExists := false
for _, team := range ctx.Org.Teams {
diff --git a/services/context/package.go b/services/context/package.go
index c452c657e7..271b61e99c 100644
--- a/services/context/package.go
+++ b/services/context/package.go
@@ -68,9 +68,9 @@ func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, string, any))
return pkg
}
- packageType := ctx.Params("type")
- name := ctx.Params("name")
- version := ctx.Params("version")
+ packageType := ctx.PathParam("type")
+ name := ctx.PathParam("name")
+ version := ctx.PathParam("version")
if packageType != "" && name != "" && version != "" {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, pkg.Owner.ID, packages_model.Type(packageType), name, version)
if err != nil {
diff --git a/services/context/repo.go b/services/context/repo.go
index d9a3feaf27..e0d3a0bfd3 100644
--- a/services/context/repo.go
+++ b/services/context/repo.go
@@ -319,8 +319,8 @@ func ComposeGoGetImport(owner, repo string) string {
// This is particular a workaround for "go get" command which does not respect
// .netrc file.
func EarlyResponseForGoGetMeta(ctx *Context) {
- username := ctx.Params(":username")
- reponame := strings.TrimSuffix(ctx.Params(":reponame"), ".git")
+ username := ctx.PathParam(":username")
+ reponame := strings.TrimSuffix(ctx.PathParam(":reponame"), ".git")
if username == "" || reponame == "" {
ctx.PlainText(http.StatusBadRequest, "invalid repository path")
return
@@ -339,8 +339,8 @@ func EarlyResponseForGoGetMeta(ctx *Context) {
// RedirectToRepo redirect to a differently-named repository
func RedirectToRepo(ctx *Base, redirectRepoID int64) {
- ownerName := ctx.Params(":username")
- previousRepoName := ctx.Params(":reponame")
+ ownerName := ctx.PathParam(":username")
+ previousRepoName := ctx.PathParam(":reponame")
repo, err := repo_model.GetRepositoryByID(ctx, redirectRepoID)
if err != nil {
@@ -419,8 +419,8 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
err error
)
- userName := ctx.Params(":username")
- repoName := ctx.Params(":reponame")
+ userName := ctx.PathParam(":username")
+ repoName := ctx.PathParam(":reponame")
repoName = strings.TrimSuffix(repoName, ".git")
if setting.Other.EnableFeed {
repoName = strings.TrimSuffix(repoName, ".rss")
@@ -463,7 +463,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
if strings.HasSuffix(repoName, ".wiki") {
// ctx.Req.URL.Path does not have the preceding appSubURL - any redirect must have this added
// Now we happen to know that all of our paths are: /:username/:reponame/whatever_else
- originalRepoName := ctx.Params(":reponame")
+ originalRepoName := ctx.PathParam(":reponame")
redirectRepoName := strings.TrimSuffix(repoName, ".wiki")
redirectRepoName += originalRepoName[len(redirectRepoName)+5:]
redirectPath := strings.Replace(
@@ -801,7 +801,7 @@ func getRefNameFromPath(repo *Repository, path string, isExist func(string) bool
}
func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
- path := ctx.Params("*")
+ path := ctx.PathParam("*")
switch pathType {
case RepoRefLegacy, RepoRefAny:
if refName := getRefName(ctx, repo, RepoRefBranch); len(refName) > 0 {
@@ -917,7 +917,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
}
// Get default branch.
- if len(ctx.Params("*")) == 0 {
+ if len(ctx.PathParam("*")) == 0 {
refName = ctx.Repo.Repository.DefaultBranch
if !ctx.Repo.GitRepo.IsBranchExist(refName) {
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1)
@@ -1005,13 +1005,13 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
if refType == RepoRefLegacy {
// redirect from old URL scheme to new URL scheme
- prefix := strings.TrimPrefix(setting.AppSubURL+strings.ToLower(strings.TrimSuffix(ctx.Req.URL.Path, ctx.Params("*"))), strings.ToLower(ctx.Repo.RepoLink))
-
- ctx.Redirect(path.Join(
+ prefix := strings.TrimPrefix(setting.AppSubURL+strings.ToLower(strings.TrimSuffix(ctx.Req.URL.Path, ctx.PathParam("*"))), strings.ToLower(ctx.Repo.RepoLink))
+ redirect := path.Join(
ctx.Repo.RepoLink,
util.PathEscapeSegments(prefix),
ctx.Repo.BranchNameSubURL(),
- util.PathEscapeSegments(ctx.Repo.TreePath)))
+ util.PathEscapeSegments(ctx.Repo.TreePath))
+ ctx.Redirect(redirect)
return cancel
}
}
diff --git a/services/context/upload/upload.go b/services/context/upload/upload.go
index 77a7eb9377..7123420e99 100644
--- a/services/context/upload/upload.go
+++ b/services/context/upload/upload.go
@@ -86,8 +86,8 @@ func AddUploadContext(ctx *context.Context, uploadType string) {
} else if uploadType == "comment" {
ctx.Data["UploadUrl"] = ctx.Repo.RepoLink + "/issues/attachments"
ctx.Data["UploadRemoveUrl"] = ctx.Repo.RepoLink + "/issues/attachments/remove"
- if len(ctx.Params(":index")) > 0 {
- ctx.Data["UploadLinkUrl"] = ctx.Repo.RepoLink + "/issues/" + url.PathEscape(ctx.Params(":index")) + "/attachments"
+ if len(ctx.PathParam(":index")) > 0 {
+ ctx.Data["UploadLinkUrl"] = ctx.Repo.RepoLink + "/issues/" + url.PathEscape(ctx.PathParam(":index")) + "/attachments"
} else {
ctx.Data["UploadLinkUrl"] = ctx.Repo.RepoLink + "/issues/attachments"
}
diff --git a/services/context/user.go b/services/context/user.go
index 4c9cd2928b..b0e855e923 100644
--- a/services/context/user.go
+++ b/services/context/user.go
@@ -33,7 +33,7 @@ func UserAssignmentWeb() func(ctx *Context) {
// UserIDAssignmentAPI returns a middleware to handle context-user assignment for api routes
func UserIDAssignmentAPI() func(ctx *APIContext) {
return func(ctx *APIContext) {
- userID := ctx.ParamsInt64(":user-id")
+ userID := ctx.PathParamInt64(":user-id")
if ctx.IsSigned && ctx.Doer.ID == userID {
ctx.ContextUser = ctx.Doer
@@ -59,7 +59,7 @@ func UserAssignmentAPI() func(ctx *APIContext) {
}
func userAssignment(ctx *Base, doer *user_model.User, errCb func(int, string, any)) (contextUser *user_model.User) {
- username := ctx.Params(":username")
+ username := ctx.PathParam(":username")
if doer != nil && doer.LowerName == strings.ToLower(username) {
contextUser = doer
diff --git a/services/convert/convert.go b/services/convert/convert.go
index c44179632e..5db33ad85d 100644
--- a/services/convert/convert.go
+++ b/services/convert/convert.go
@@ -408,6 +408,32 @@ func ToAnnotatedTagObject(repo *repo_model.Repository, commit *git.Commit) *api.
}
}
+// ToTagProtection convert a git.ProtectedTag to an api.TagProtection
+func ToTagProtection(ctx context.Context, pt *git_model.ProtectedTag, repo *repo_model.Repository) *api.TagProtection {
+ readers, err := access_model.GetRepoReaders(ctx, repo)
+ if err != nil {
+ log.Error("GetRepoReaders: %v", err)
+ }
+
+ whitelistUsernames := getWhitelistEntities(readers, pt.AllowlistUserIDs)
+
+ teamReaders, err := organization.OrgFromUser(repo.Owner).TeamsWithAccessToRepo(ctx, repo.ID, perm.AccessModeRead)
+ if err != nil {
+ log.Error("Repo.Owner.TeamsWithAccessToRepo: %v", err)
+ }
+
+ whitelistTeams := getWhitelistEntities(teamReaders, pt.AllowlistTeamIDs)
+
+ return &api.TagProtection{
+ ID: pt.ID,
+ NamePattern: pt.NamePattern,
+ WhitelistUsernames: whitelistUsernames,
+ WhitelistTeams: whitelistTeams,
+ Created: pt.CreatedUnix.AsTime(),
+ Updated: pt.UpdatedUnix.AsTime(),
+ }
+}
+
// ToTopicResponse convert from models.Topic to api.TopicResponse
func ToTopicResponse(topic *repo_model.Topic) *api.TopicResponse {
return &api.TopicResponse{
diff --git a/services/externalaccount/user.go b/services/externalaccount/user.go
index e2de41da18..3cfd8c81f9 100644
--- a/services/externalaccount/user.go
+++ b/services/externalaccount/user.go
@@ -5,6 +5,7 @@ package externalaccount
import (
"context"
+ "strconv"
"strings"
"code.gitea.io/gitea/models/auth"
@@ -82,6 +83,11 @@ func UpdateExternalUser(ctx context.Context, user *user_model.User, gothUser got
// UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID
func UpdateMigrationsByType(ctx context.Context, tp structs.GitServiceType, externalUserID string, userID int64) error {
+ // Skip update if externalUserID is not a valid numeric ID or exceeds int64
+ if _, err := strconv.ParseInt(externalUserID, 10, 64); err != nil {
+ return nil
+ }
+
if err := issues_model.UpdateIssuesMigrationsByType(ctx, tp, externalUserID, userID); err != nil {
return err
}
diff --git a/services/lfs/locks.go b/services/lfs/locks.go
index 2a362b1c0d..4254c99383 100644
--- a/services/lfs/locks.go
+++ b/services/lfs/locks.go
@@ -136,8 +136,8 @@ func GetListLockHandler(ctx *context.Context) {
// PostLockHandler create lock
func PostLockHandler(ctx *context.Context) {
- userName := ctx.Params("username")
- repoName := strings.TrimSuffix(ctx.Params("reponame"), ".git")
+ userName := ctx.PathParam("username")
+ repoName := strings.TrimSuffix(ctx.PathParam("reponame"), ".git")
authorization := ctx.Req.Header.Get("Authorization")
repository, err := repo_model.GetRepositoryByOwnerAndName(ctx, userName, repoName)
@@ -208,8 +208,8 @@ func PostLockHandler(ctx *context.Context) {
// VerifyLockHandler list locks for verification
func VerifyLockHandler(ctx *context.Context) {
- userName := ctx.Params("username")
- repoName := strings.TrimSuffix(ctx.Params("reponame"), ".git")
+ userName := ctx.PathParam("username")
+ repoName := strings.TrimSuffix(ctx.PathParam("reponame"), ".git")
authorization := ctx.Req.Header.Get("Authorization")
repository, err := repo_model.GetRepositoryByOwnerAndName(ctx, userName, repoName)
@@ -279,8 +279,8 @@ func VerifyLockHandler(ctx *context.Context) {
// UnLockHandler delete locks
func UnLockHandler(ctx *context.Context) {
- userName := ctx.Params("username")
- repoName := strings.TrimSuffix(ctx.Params("reponame"), ".git")
+ userName := ctx.PathParam("username")
+ repoName := strings.TrimSuffix(ctx.PathParam("reponame"), ".git")
authorization := ctx.Req.Header.Get("Authorization")
repository, err := repo_model.GetRepositoryByOwnerAndName(ctx, userName, repoName)
@@ -321,7 +321,7 @@ func UnLockHandler(ctx *context.Context) {
return
}
- lock, err := git_model.DeleteLFSLockByID(ctx, ctx.ParamsInt64("lid"), repository, ctx.Doer, req.Force)
+ lock, err := git_model.DeleteLFSLockByID(ctx, ctx.PathParamInt64("lid"), repository, ctx.Doer, req.Force)
if err != nil {
if git_model.IsErrLFSUnauthorizedAction(err) {
ctx.Resp.Header().Set("WWW-Authenticate", "Basic realm=gitea-lfs")
@@ -330,7 +330,7 @@ func UnLockHandler(ctx *context.Context) {
})
return
}
- log.Error("Unable to DeleteLFSLockByID[%d] by user %-v with force %t: Error: %v", ctx.ParamsInt64("lid"), ctx.Doer, req.Force, err)
+ log.Error("Unable to DeleteLFSLockByID[%d] by user %-v with force %t: Error: %v", ctx.PathParamInt64("lid"), ctx.Doer, req.Force, err)
ctx.JSON(http.StatusInternalServerError, api.LFSLockError{
Message: "unable to delete lock : Internal Server Error",
})
diff --git a/services/lfs/server.go b/services/lfs/server.go
index ae3dffe0c2..751dac64a0 100644
--- a/services/lfs/server.go
+++ b/services/lfs/server.go
@@ -82,7 +82,7 @@ var rangeHeaderRegexp = regexp.MustCompile(`bytes=(\d+)\-(\d*).*`)
// DownloadHandler gets the content from the content store
func DownloadHandler(ctx *context.Context) {
rc := getRequestContext(ctx)
- p := lfs_module.Pointer{Oid: ctx.Params("oid")}
+ p := lfs_module.Pointer{Oid: ctx.PathParam("oid")}
meta := getAuthenticatedMeta(ctx, rc, p, false)
if meta == nil {
@@ -137,7 +137,7 @@ func DownloadHandler(ctx *context.Context) {
ctx.Resp.Header().Set("Content-Length", strconv.FormatInt(contentLength, 10))
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
- filename := ctx.Params("filename")
+ filename := ctx.PathParam("filename")
if len(filename) > 0 {
decodedFilename, err := base64.RawURLEncoding.DecodeString(filename)
if err == nil {
@@ -272,9 +272,9 @@ func BatchHandler(ctx *context.Context) {
func UploadHandler(ctx *context.Context) {
rc := getRequestContext(ctx)
- p := lfs_module.Pointer{Oid: ctx.Params("oid")}
+ p := lfs_module.Pointer{Oid: ctx.PathParam("oid")}
var err error
- if p.Size, err = strconv.ParseInt(ctx.Params("size"), 10, 64); err != nil {
+ if p.Size, err = strconv.ParseInt(ctx.PathParam("size"), 10, 64); err != nil {
writeStatusMessage(ctx, http.StatusUnprocessableEntity, err.Error())
}
@@ -384,8 +384,8 @@ func decodeJSON(req *http.Request, v any) error {
func getRequestContext(ctx *context.Context) *requestContext {
return &requestContext{
- User: ctx.Params("username"),
- Repo: strings.TrimSuffix(ctx.Params("reponame"), ".git"),
+ User: ctx.PathParam("username"),
+ Repo: strings.TrimSuffix(ctx.PathParam("reponame"), ".git"),
Authorization: ctx.Req.Header.Get("Authorization"),
}
}
diff --git a/services/pull/merge.go b/services/pull/merge.go
index 9ef3fb2e05..e19292c31c 100644
--- a/services/pull/merge.go
+++ b/services/pull/merge.go
@@ -23,6 +23,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/references"
repo_module "code.gitea.io/gitea/modules/repository"
@@ -56,7 +57,7 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
issueReference = "!"
}
- reviewedOn := fmt.Sprintf("Reviewed-on: %s/%s", setting.AppURL, pr.Issue.Link())
+ reviewedOn := fmt.Sprintf("Reviewed-on: %s", httplib.MakeAbsoluteURL(ctx, pr.Issue.Link()))
reviewedBy := pr.GetApprovers(ctx)
if mergeStyle != "" {
diff --git a/services/repository/adopt_test.go b/services/repository/adopt_test.go
index c1520e01c9..38949c7602 100644
--- a/services/repository/adopt_test.go
+++ b/services/repository/adopt_test.go
@@ -6,10 +6,13 @@ package repository
import (
"os"
"path"
+ "path/filepath"
"testing"
"code.gitea.io/gitea/models/db"
+ repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
@@ -83,3 +86,13 @@ func TestListUnadoptedRepositories_ListOptions(t *testing.T) {
assert.Equal(t, 2, count)
assert.Equal(t, unadoptedList[1], repoNames[0])
}
+
+func TestAdoptRepository(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+ assert.NoError(t, unittest.CopyDir(filepath.Join(setting.RepoRootPath, "user2", "repo1.git"), filepath.Join(setting.RepoRootPath, "user2", "test-adopt.git")))
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ _, err := AdoptRepository(db.DefaultContext, user2, user2, CreateRepoOptions{Name: "test-adopt"})
+ assert.NoError(t, err)
+ repoTestAdopt := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "test-adopt"})
+ assert.Equal(t, "sha1", repoTestAdopt.ObjectFormatName)
+}
diff --git a/services/repository/files/content_test.go b/services/repository/files/content_test.go
index 4811f9d327..a899be70e3 100644
--- a/services/repository/files/content_test.go
+++ b/services/repository/files/content_test.go
@@ -53,7 +53,7 @@ func getExpectedReadmeContentsResponse() *api.ContentsResponse {
func TestGetContents(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
@@ -81,7 +81,7 @@ func TestGetContents(t *testing.T) {
func TestGetContentsOrListForDir(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
@@ -116,7 +116,7 @@ func TestGetContentsOrListForDir(t *testing.T) {
func TestGetContentsOrListForFile(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
@@ -144,7 +144,7 @@ func TestGetContentsOrListForFile(t *testing.T) {
func TestGetContentsErrors(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
@@ -175,7 +175,7 @@ func TestGetContentsErrors(t *testing.T) {
func TestGetContentsOrListErrors(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
@@ -206,7 +206,7 @@ func TestGetContentsOrListErrors(t *testing.T) {
func TestGetContentsOrListOfEmptyRepos(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user30/empty")
- ctx.SetParams(":id", "52")
+ ctx.SetPathParam(":id", "52")
contexttest.LoadRepo(t, ctx, 52)
contexttest.LoadUser(t, ctx, 30)
contexttest.LoadGitRepo(t, ctx)
@@ -231,15 +231,15 @@ func TestGetBlobBySHA(t *testing.T) {
defer ctx.Repo.GitRepo.Close()
sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
- ctx.SetParams(":id", "1")
- ctx.SetParams(":sha", sha)
+ ctx.SetPathParam(":id", "1")
+ ctx.SetPathParam(":sha", sha)
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
if err != nil {
t.Fail()
}
- gbr, err := GetBlobBySHA(ctx, ctx.Repo.Repository, gitRepo, ctx.Params(":sha"))
+ gbr, err := GetBlobBySHA(ctx, ctx.Repo.Repository, gitRepo, ctx.PathParam(":sha"))
expectedGBR := &api.GitBlobResponse{
Content: "dHJlZSAyYTJmMWQ0NjcwNzI4YTJlMTAwNDllMzQ1YmQ3YTI3NjQ2OGJlYWI2CmF1dGhvciB1c2VyMSA8YWRkcmVzczFAZXhhbXBsZS5jb20+IDE0ODk5NTY0NzkgLTA0MDAKY29tbWl0dGVyIEV0aGFuIEtvZW5pZyA8ZXRoYW50a29lbmlnQGdtYWlsLmNvbT4gMTQ4OTk1NjQ3OSAtMDQwMAoKSW5pdGlhbCBjb21taXQK",
Encoding: "base64",
diff --git a/services/repository/files/diff_test.go b/services/repository/files/diff_test.go
index 63aff9b0e3..ea6ffe60c3 100644
--- a/services/repository/files/diff_test.go
+++ b/services/repository/files/diff_test.go
@@ -18,7 +18,7 @@ import (
func TestGetDiffPreview(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
@@ -140,7 +140,7 @@ func TestGetDiffPreview(t *testing.T) {
func TestGetDiffPreviewErrors(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
diff --git a/services/repository/files/file_test.go b/services/repository/files/file_test.go
index a5b3aad91e..b2f51e3c82 100644
--- a/services/repository/files/file_test.go
+++ b/services/repository/files/file_test.go
@@ -99,7 +99,7 @@ func getExpectedFileResponse() *api.FileResponse {
func TestGetFileResponseFromCommit(t *testing.T) {
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
+ ctx.SetPathParam(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
diff --git a/services/repository/files/tree_test.go b/services/repository/files/tree_test.go
index 508f20090d..786bc15857 100644
--- a/services/repository/files/tree_test.go
+++ b/services/repository/files/tree_test.go
@@ -25,10 +25,10 @@ func TestGetTreeBySHA(t *testing.T) {
sha := ctx.Repo.Repository.DefaultBranch
page := 1
perPage := 10
- ctx.SetParams(":id", "1")
- ctx.SetParams(":sha", sha)
+ ctx.SetPathParam(":id", "1")
+ ctx.SetPathParam(":sha", sha)
- tree, err := GetTreeBySHA(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.Params(":sha"), page, perPage, true)
+ tree, err := GetTreeBySHA(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.PathParam(":sha"), page, perPage, true)
assert.NoError(t, err)
expectedTree := &api.GitTreeResponse{
SHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
diff --git a/services/wiki/wiki_path.go b/services/wiki/wiki_path.go
index 74c7064043..212a35ea25 100644
--- a/services/wiki/wiki_path.go
+++ b/services/wiki/wiki_path.go
@@ -33,7 +33,7 @@ import (
// TODO: support subdirectory in the future
//
// Although this package now has the ability to support subdirectory, but the route package doesn't:
-// * Double-escaping problem: the URL "/wiki/abc%2Fdef" becomes "/wiki/abc/def" by ctx.Params, which is incorrect
+// * Double-escaping problem: the URL "/wiki/abc%2Fdef" becomes "/wiki/abc/def" by ctx.PathParam, which is incorrect
// * This problem should have been 99% fixed, but it needs more tests.
// * The old wiki code's behavior is always using %2F, instead of subdirectory, so there are a lot of legacy "%2F" files in user wikis.
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index 197a6c6add..87f18192a6 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -229,8 +229,8 @@
{{ctx.Locale.Tr "admin.config.mailer_user"}}
{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}
- {{ctx.Locale.Tr "admin.config.send_test_mail"}}
-
+ {{ctx.Locale.Tr "admin.config.send_test_mail"}}
+