diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 139cbf91091..4159f021889 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -10,6 +10,7 @@ parserOptions: plugins: - "@eslint-community/eslint-plugin-eslint-comments" + - "@stylistic/eslint-plugin-js" - eslint-plugin-array-func - eslint-plugin-i - eslint-plugin-jquery @@ -114,11 +115,74 @@ rules: "@eslint-community/eslint-comments/no-unused-enable": [2] "@eslint-community/eslint-comments/no-use": [0] "@eslint-community/eslint-comments/require-description": [0] + "@stylistic/js/array-bracket-newline": [0] + "@stylistic/js/array-bracket-spacing": [2, never] + "@stylistic/js/array-element-newline": [0] + "@stylistic/js/arrow-parens": [2, always] + "@stylistic/js/arrow-spacing": [2, {before: true, after: true}] + "@stylistic/js/block-spacing": [0] + "@stylistic/js/brace-style": [2, 1tbs, {allowSingleLine: true}] + "@stylistic/js/comma-dangle": [2, only-multiline] + "@stylistic/js/comma-spacing": [2, {before: false, after: true}] + "@stylistic/js/comma-style": [2, last] + "@stylistic/js/computed-property-spacing": [2, never] + "@stylistic/js/dot-location": [2, property] + "@stylistic/js/eol-last": [2] + "@stylistic/js/func-call-spacing": [2, never] + "@stylistic/js/function-call-argument-newline": [0] + "@stylistic/js/function-paren-newline": [0] + "@stylistic/js/generator-star-spacing": [0] + "@stylistic/js/implicit-arrow-linebreak": [0] + "@stylistic/js/indent": [2, 2, {ignoreComments: true, SwitchCase: 1}] + "@stylistic/js/key-spacing": [2] + "@stylistic/js/keyword-spacing": [2] + "@stylistic/js/linebreak-style": [2, unix] + "@stylistic/js/lines-around-comment": [0] + "@stylistic/js/lines-between-class-members": [0] + "@stylistic/js/max-len": [0] + "@stylistic/js/max-statements-per-line": [0] + "@stylistic/js/multiline-ternary": [0] + "@stylistic/js/new-parens": [2] + "@stylistic/js/newline-per-chained-call": [0] + "@stylistic/js/no-confusing-arrow": [0] + "@stylistic/js/no-extra-parens": [0] + "@stylistic/js/no-extra-semi": [2] + "@stylistic/js/no-floating-decimal": [0] + "@stylistic/js/no-mixed-operators": [0] + "@stylistic/js/no-mixed-spaces-and-tabs": [2] + "@stylistic/js/no-multi-spaces": [2, {ignoreEOLComments: true, exceptions: {Property: true}}] + "@stylistic/js/no-multiple-empty-lines": [2, {max: 1, maxEOF: 0, maxBOF: 0}] + "@stylistic/js/no-tabs": [2] + "@stylistic/js/no-trailing-spaces": [2] + "@stylistic/js/no-whitespace-before-property": [2] + "@stylistic/js/nonblock-statement-body-position": [2] + "@stylistic/js/object-curly-newline": [0] + "@stylistic/js/object-curly-spacing": [2, never] + "@stylistic/js/object-property-newline": [0] + "@stylistic/js/one-var-declaration-per-line": [0] + "@stylistic/js/operator-linebreak": [2, after] + "@stylistic/js/padded-blocks": [2, never] + "@stylistic/js/padding-line-between-statements": [0] + "@stylistic/js/quote-props": [0] + "@stylistic/js/quotes": [2, single, {avoidEscape: true, allowTemplateLiterals: true}] + "@stylistic/js/rest-spread-spacing": [2, never] + "@stylistic/js/semi": [2, always, {omitLastInOneLineBlock: true}] + "@stylistic/js/semi-spacing": [2, {before: false, after: true}] + "@stylistic/js/semi-style": [2, last] + "@stylistic/js/space-before-blocks": [2, always] + "@stylistic/js/space-before-function-paren": [0] + "@stylistic/js/space-in-parens": [2, never] + "@stylistic/js/space-infix-ops": [2] + "@stylistic/js/space-unary-ops": [2] + "@stylistic/js/spaced-comment": [2, always] + "@stylistic/js/switch-colon-spacing": [2] + "@stylistic/js/template-curly-spacing": [2, never] + "@stylistic/js/template-tag-spacing": [2, never] + "@stylistic/js/wrap-iife": [2, inside] + "@stylistic/js/wrap-regex": [0] + "@stylistic/js/yield-star-spacing": [2, after] accessor-pairs: [2] - array-bracket-newline: [0] - array-bracket-spacing: [2, never] array-callback-return: [2, {checkForEach: true}] - array-element-newline: [0] array-func/avoid-reverse: [2] array-func/from-map: [2] array-func/no-unnecessary-this-arg: [2] @@ -126,18 +190,11 @@ rules: array-func/prefer-flat-map: [0] # handled by unicorn/prefer-array-flat-map array-func/prefer-flat: [0] # handled by unicorn/prefer-array-flat arrow-body-style: [0] - arrow-parens: [2, always] - arrow-spacing: [2, {before: true, after: true}] block-scoped-var: [2] - brace-style: [2, 1tbs, {allowSingleLine: true}] camelcase: [0] capitalized-comments: [0] class-methods-use-this: [0] - comma-dangle: [2, only-multiline] - comma-spacing: [2, {before: false, after: true}] - comma-style: [2, last] complexity: [0] - computed-property-spacing: [2, never] consistent-return: [0] consistent-this: [0] constructor-super: [2] @@ -145,25 +202,18 @@ rules: default-case-last: [2] default-case: [0] default-param-last: [0] - dot-location: [2, property] dot-notation: [0] - eol-last: [2] eqeqeq: [2] for-direction: [2] - func-call-spacing: [2, never] func-name-matching: [2] func-names: [0] func-style: [0] - function-call-argument-newline: [0] - function-paren-newline: [0] - generator-star-spacing: [0] getter-return: [2] grouped-accessor-pairs: [2] guard-for-in: [0] id-blacklist: [0] id-length: [0] id-match: [0] - implicit-arrow-linebreak: [0] i/consistent-type-specifier-style: [0] i/default: [0] i/dynamic-import-chunkname: [0] @@ -207,7 +257,6 @@ rules: i/order: [0] i/prefer-default-export: [0] i/unambiguous: [0] - indent: [2, 2, {SwitchCase: 1}] init-declarations: [0] jquery/no-ajax-events: [2] jquery/no-ajax: [0] @@ -258,27 +307,17 @@ rules: jquery/no-val: [0] jquery/no-when: [2] jquery/no-wrap: [2] - key-spacing: [2] - keyword-spacing: [2] line-comment-position: [0] - linebreak-style: [2, unix] - lines-around-comment: [0] - lines-between-class-members: [0] logical-assignment-operators: [0] max-classes-per-file: [0] max-depth: [0] - max-len: [0] max-lines-per-function: [0] max-lines: [0] max-nested-callbacks: [0] max-params: [0] - max-statements-per-line: [0] max-statements: [0] multiline-comment-style: [2, separate-lines] - multiline-ternary: [0] new-cap: [0] - new-parens: [2] - newline-per-chained-call: [0] no-alert: [0] no-array-constructor: [2] no-async-promise-executor: [0] @@ -290,7 +329,6 @@ rules: no-class-assign: [2] no-compare-neg-zero: [2] no-cond-assign: [2, except-parens] - no-confusing-arrow: [0] no-console: [1, {allow: [debug, info, warn, error]}] no-const-assign: [2] no-constant-binary-expression: [2] @@ -320,10 +358,7 @@ rules: no-extra-bind: [2] no-extra-boolean-cast: [2] no-extra-label: [0] - no-extra-parens: [0] - no-extra-semi: [2] no-fallthrough: [2] - no-floating-decimal: [0] no-func-assign: [2] no-global-assign: [2] no-implicit-coercion: [2] @@ -437,10 +472,7 @@ rules: no-loss-of-precision: [2] no-magic-numbers: [0] no-misleading-character-class: [2] - no-mixed-operators: [0] - no-mixed-spaces-and-tabs: [2] no-multi-assign: [0] - no-multi-spaces: [2, {ignoreEOLComments: true, exceptions: {Property: true}}] no-multi-str: [2] no-negated-condition: [0] no-nested-ternary: [0] @@ -474,12 +506,10 @@ rules: no-shadow-restricted-names: [2] no-shadow: [0] no-sparse-arrays: [2] - no-tabs: [2] no-template-curly-in-string: [2] no-ternary: [0] no-this-before-super: [2] no-throw-literal: [2] - no-trailing-spaces: [2] no-undef-init: [2] no-undef: [2, {typeof: true}] no-undefined: [0] @@ -509,18 +539,12 @@ rules: no-var: [2] no-void: [2] no-warning-comments: [0] - no-whitespace-before-property: [2] no-with: [0] # handled by no-restricted-syntax - nonblock-statement-body-position: [2] - object-curly-newline: [0] - object-curly-spacing: [2, never] object-shorthand: [2, always] one-var-declaration-per-line: [0] one-var: [0] operator-assignment: [2, always] operator-linebreak: [2, after] - padded-blocks: [2, never] - padding-line-between-statements: [0] prefer-arrow-callback: [2, {allowNamedFunctions: true, allowUnboundThis: true}] prefer-const: [2, {destructuring: all, ignoreReadBeforeAssign: true}] prefer-destructuring: [0] @@ -534,7 +558,6 @@ rules: prefer-rest-params: [2] prefer-spread: [2] prefer-template: [2] - quote-props: [0] quotes: [2, single, {avoidEscape: true, allowTemplateLiterals: true}] radix: [2, as-needed] regexp/confusing-quantifier: [2] @@ -620,10 +643,6 @@ rules: require-await: [0] require-unicode-regexp: [0] require-yield: [2] - rest-spread-spacing: [2, never] - semi-spacing: [2, {before: false, after: true}] - semi-style: [2, last] - semi: [2, always, {omitLastInOneLineBlock: true}] sonarjs/cognitive-complexity: [0] sonarjs/elseif-without-else: [0] sonarjs/max-switch-cases: [0] @@ -659,16 +678,8 @@ rules: sort-imports: [0] sort-keys: [0] sort-vars: [0] - space-before-blocks: [2, always] - space-in-parens: [2, never] - space-infix-ops: [2] - space-unary-ops: [2] - spaced-comment: [2, always] strict: [0] - switch-colon-spacing: [2] symbol-description: [2] - template-curly-spacing: [2, never] - template-tag-spacing: [2, never] unicode-bom: [2, never] unicorn/better-regex: [0] unicorn/catch-error-name: [0] @@ -807,7 +818,4 @@ rules: wc/no-typos: [2] wc/require-listener-teardown: [2] wc/tag-name-matches-class: [2] - wrap-iife: [2, inside] - wrap-regex: [0] - yield-star-spacing: [2, after] yoda: [2, never] diff --git a/.github/workflows/cron-licenses.yml b/.github/workflows/cron-licenses.yml index 0fbcbf603d8..6ef5813a64f 100644 --- a/.github/workflows/cron-licenses.yml +++ b/.github/workflows/cron-licenses.yml @@ -18,7 +18,7 @@ jobs: - run: make generate-license generate-gitignore timeout-minutes: 40 - name: push translations to repo - uses: appleboy/git-push-action@v0.0.2 + uses: appleboy/git-push-action@v0.0.3 with: author_email: "teabot@gitea.io" author_name: GiteaBot diff --git a/.github/workflows/cron-translations.yml b/.github/workflows/cron-translations.yml index b0effdee9d6..390aae7c079 100644 --- a/.github/workflows/cron-translations.yml +++ b/.github/workflows/cron-translations.yml @@ -22,7 +22,7 @@ jobs: - name: update locales run: ./build/update-locales.sh - name: push translations to repo - uses: appleboy/git-push-action@v0.0.2 + uses: appleboy/git-push-action@v0.0.3 with: author_email: "teabot@gitea.io" author_name: GiteaBot diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml index bf9236b093f..6977dc32b29 100644 --- a/.github/workflows/pull-compliance.yml +++ b/.github/workflows/pull-compliance.yml @@ -58,7 +58,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend @@ -115,7 +115,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend @@ -162,7 +162,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend diff --git a/.github/workflows/pull-docker-dryrun.yml b/.github/workflows/pull-docker-dryrun.yml index 61f1fd5632e..f74277de671 100644 --- a/.github/workflows/pull-docker-dryrun.yml +++ b/.github/workflows/pull-docker-dryrun.yml @@ -16,8 +16,8 @@ jobs: needs: files-changed runs-on: ubuntu-latest steps: - - uses: docker/setup-buildx-action@v2 - - uses: docker/build-push-action@v4 + - uses: docker/setup-buildx-action@v3 + - uses: docker/build-push-action@v5 with: push: false tags: gitea/gitea:linux-amd64 @@ -27,8 +27,8 @@ jobs: needs: files-changed runs-on: ubuntu-latest steps: - - uses: docker/setup-buildx-action@v2 - - uses: docker/build-push-action@v4 + - uses: docker/setup-buildx-action@v3 + - uses: docker/build-push-action@v5 with: push: false file: Dockerfile.rootless diff --git a/.github/workflows/pull-e2e-tests.yml b/.github/workflows/pull-e2e-tests.yml index 357ccb48be7..540263788d4 100644 --- a/.github/workflows/pull-e2e-tests.yml +++ b/.github/workflows/pull-e2e-tests.yml @@ -21,7 +21,7 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend frontend deps-backend diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index b70a65c070e..ef1e63df2ff 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -2,7 +2,7 @@ name: release-nightly on: push: - branches: [ main, release/v* ] + branches: [main, release/v*] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -22,7 +22,7 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend deps-backend @@ -32,7 +32,7 @@ jobs: TAGS: bindata sqlite sqlite_unlock_notify - name: import gpg key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5 + uses: crazy-max/ghaction-import-gpg@v6 with: gpg_private_key: ${{ secrets.GPGSIGN_KEY }} passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }} @@ -68,8 +68,8 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Get cleaned branch name id: clean_name run: | @@ -81,14 +81,14 @@ jobs: REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//') echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT" - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: fetch go modules run: make vendor - name: build rootful docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 @@ -105,8 +105,8 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Get cleaned branch name id: clean_name run: | @@ -118,14 +118,14 @@ jobs: REF_NAME=$(echo "${{ github.ref }}" | sed -e 's/refs\/heads\///' -e 's/refs\/tags\///' -e 's/release\/v//') echo "branch=${REF_NAME}-nightly" >> "$GITHUB_OUTPUT" - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: fetch go modules run: make vendor - name: build rootless docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/release-tag-rc.yml b/.github/workflows/release-tag-rc.yml index 06b21db4db7..861179d9c86 100644 --- a/.github/workflows/release-tag-rc.yml +++ b/.github/workflows/release-tag-rc.yml @@ -3,7 +3,7 @@ name: release-tag-rc on: push: tags: - - 'v1*-rc*' + - "v1*-rc*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -21,7 +21,7 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend deps-backend @@ -31,7 +31,7 @@ jobs: TAGS: bindata sqlite sqlite_unlock_notify - name: import gpg key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5 + uses: crazy-max/ghaction-import-gpg@v6 with: gpg_private_key: ${{ secrets.GPGSIGN_KEY }} passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }} @@ -68,8 +68,8 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - uses: docker/metadata-action@v5 id: meta with: @@ -78,12 +78,12 @@ jobs: tags: | type=semver,pattern={{version}} - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: build rootful docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 @@ -97,8 +97,8 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - uses: docker/metadata-action@v5 id: meta with: @@ -110,12 +110,12 @@ jobs: tags: | type=semver,pattern={{version}} - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: build rootless docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/release-tag-version.yml b/.github/workflows/release-tag-version.yml index f85f0028941..c3fce7e2a7c 100644 --- a/.github/workflows/release-tag-version.yml +++ b/.github/workflows/release-tag-version.yml @@ -3,9 +3,9 @@ name: release-tag-version on: push: tags: - - 'v1.*' - - '!v1*-rc*' - - '!v1*-dev' + - "v1.*" + - "!v1*-rc*" + - "!v1*-dev" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -23,7 +23,7 @@ jobs: with: go-version-file: go.mod check-latest: true - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 20 - run: make deps-frontend deps-backend @@ -33,7 +33,7 @@ jobs: TAGS: bindata sqlite sqlite_unlock_notify - name: import gpg key id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5 + uses: crazy-max/ghaction-import-gpg@v6 with: gpg_private_key: ${{ secrets.GPGSIGN_KEY }} passphrase: ${{ secrets.GPGSIGN_PASSPHRASE }} @@ -70,8 +70,8 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - uses: docker/metadata-action@v5 id: meta with: @@ -87,12 +87,12 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{version}} - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: build rootful docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 @@ -106,8 +106,8 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: docker/setup-qemu-action@v2 - - uses: docker/setup-buildx-action@v2 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - uses: docker/metadata-action@v5 id: meta with: @@ -126,12 +126,12 @@ jobs: type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{version}} - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: build rootless docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 diff --git a/.golangci.yml b/.golangci.yml index 069dc13c991..d6ce37f49af 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -29,7 +29,6 @@ linters: fast: false run: - go: "1.21" timeout: 10m skip-dirs: - node_modules @@ -75,7 +74,6 @@ linters-settings: - name: modifies-value-receiver gofumpt: extra-rules: true - lang-version: "1.21" depguard: rules: main: diff --git a/Dockerfile b/Dockerfile index b42b4daa5fa..5fe8df91268 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -#Build stage +# Build stage FROM docker.io/library/golang:1.21-alpine3.18 AS build-env ARG GOPROXY @@ -9,20 +9,38 @@ ARG TAGS="sqlite sqlite_unlock_notify" ENV TAGS "bindata timetzdata $TAGS" ARG CGO_EXTRA_CFLAGS -#Build deps -RUN apk --no-cache add build-base git nodejs npm +# Build deps +RUN apk --no-cache add \ + build-base \ + git \ + nodejs \ + npm \ + && rm -rf /var/cache/apk/* -#Setup repo +# Setup repo COPY . ${GOPATH}/src/code.gitea.io/gitea WORKDIR ${GOPATH}/src/code.gitea.io/gitea -#Checkout version if set +# Checkout version if set RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \ && make clean-all build # Begin env-to-ini build RUN go build contrib/environment-to-ini/environment-to-ini.go +# Copy local files +COPY docker/root /tmp/local + +# Set permissions +RUN chmod 755 /tmp/local/usr/bin/entrypoint \ + /tmp/local/usr/local/bin/gitea \ + /tmp/local/etc/s6/gitea/* \ + /tmp/local/etc/s6/openssh/* \ + /tmp/local/etc/s6/.s6-svscan/* \ + /go/src/code.gitea.io/gitea/gitea \ + /go/src/code.gitea.io/gitea/environment-to-ini +RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete + FROM docker.io/library/alpine:3.18 LABEL maintainer="maintainers@gitea.io" @@ -39,7 +57,8 @@ RUN apk --no-cache add \ s6 \ sqlite \ su-exec \ - gnupg + gnupg \ + && rm -rf /var/cache/apk/* RUN addgroup \ -S -g 1000 \ @@ -61,10 +80,7 @@ VOLUME ["/data"] ENTRYPOINT ["/usr/bin/entrypoint"] CMD ["/bin/s6-svscan", "/etc/s6"] -COPY docker/root / +COPY --from=build-env /tmp/local / COPY --from=build-env /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea COPY --from=build-env /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh -RUN chmod 755 /usr/bin/entrypoint /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini -RUN chmod 755 /etc/s6/gitea/* /etc/s6/openssh/* /etc/s6/.s6-svscan/* -RUN chmod 644 /etc/profile.d/gitea_bash_autocomplete.sh diff --git a/Dockerfile.rootless b/Dockerfile.rootless index 449e630fadb..5ea4d2fc751 100644 --- a/Dockerfile.rootless +++ b/Dockerfile.rootless @@ -1,4 +1,4 @@ -#Build stage +# Build stage FROM docker.io/library/golang:1.21-alpine3.18 AS build-env ARG GOPROXY @@ -10,19 +10,35 @@ ENV TAGS "bindata timetzdata $TAGS" ARG CGO_EXTRA_CFLAGS #Build deps -RUN apk --no-cache add build-base git nodejs npm +RUN apk --no-cache add \ + build-base \ + git \ + nodejs \ + npm \ + && rm -rf /var/cache/apk/* -#Setup repo +# Setup repo COPY . ${GOPATH}/src/code.gitea.io/gitea WORKDIR ${GOPATH}/src/code.gitea.io/gitea -#Checkout version if set +# Checkout version if set RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \ && make clean-all build # Begin env-to-ini build RUN go build contrib/environment-to-ini/environment-to-ini.go +# Copy local files +COPY docker/rootless /tmp/local + +# Set permissions +RUN chmod 755 /tmp/local/usr/local/bin/docker-entrypoint.sh \ + /tmp/local/usr/local/bin/docker-setup.sh \ + /tmp/local/usr/local/bin/gitea \ + /go/src/code.gitea.io/gitea/gitea \ + /go/src/code.gitea.io/gitea/environment-to-ini +RUN chmod 644 /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete + FROM docker.io/library/alpine:3.18 LABEL maintainer="maintainers@gitea.io" @@ -35,7 +51,8 @@ RUN apk --no-cache add \ gettext \ git \ curl \ - gnupg + gnupg \ + && rm -rf /var/cache/apk/* RUN addgroup \ -S -g 1000 \ @@ -51,21 +68,19 @@ RUN addgroup \ RUN mkdir -p /var/lib/gitea /etc/gitea RUN chown git:git /var/lib/gitea /etc/gitea -COPY docker/rootless / +COPY --from=build-env /tmp/local / COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/gitea /app/gitea/gitea COPY --from=build-env --chown=root:root /go/src/code.gitea.io/gitea/environment-to-ini /usr/local/bin/environment-to-ini COPY --from=build-env /go/src/code.gitea.io/gitea/contrib/autocompletion/bash_autocomplete /etc/profile.d/gitea_bash_autocomplete.sh -RUN chmod 755 /usr/local/bin/docker-entrypoint.sh /usr/local/bin/docker-setup.sh /app/gitea/gitea /usr/local/bin/gitea /usr/local/bin/environment-to-ini -RUN chmod 644 /etc/profile.d/gitea_bash_autocomplete.sh -#git:git +# 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 -#TODO add to docs the ability to define the ini to load (useful to test and revert a config) +# 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" VOLUME ["/var/lib/gitea", "/etc/gitea"] @@ -73,4 +88,3 @@ WORKDIR /var/lib/gitea ENTRYPOINT ["/usr/bin/dumb-init", "--", "/usr/local/bin/docker-entrypoint.sh"] CMD [] - diff --git a/Makefile b/Makefile index c38e88a8e0a..068dda5f52b 100644 --- a/Makefile +++ b/Makefile @@ -875,7 +875,7 @@ node_modules: package-lock.json @touch node_modules .venv: poetry.lock - poetry install + poetry install --no-root @touch .venv .PHONY: update @@ -892,7 +892,7 @@ update-js: node-check | node_modules update-py: node-check | node_modules npx updates -u -f pyproject.toml rm -rf .venv poetry.lock - poetry install + poetry install --no-root @touch .venv .PHONY: fomantic diff --git a/cmd/admin_auth.go b/cmd/admin_auth.go index 3b308d77f79..014ddf329f9 100644 --- a/cmd/admin_auth.go +++ b/cmd/admin_auth.go @@ -62,7 +62,7 @@ func runListAuth(c *cli.Context) error { return err } - authSources, err := auth_model.Sources(ctx) + authSources, err := auth_model.FindSources(ctx, auth_model.FindSourcesOptions{}) if err != nil { return err } diff --git a/contrib/environment-to-ini/environment-to-ini.go b/contrib/environment-to-ini/environment-to-ini.go index 7758045fd32..a7d7a6d293d 100644 --- a/contrib/environment-to-ini/environment-to-ini.go +++ b/contrib/environment-to-ini/environment-to-ini.go @@ -47,24 +47,28 @@ func main() { on the configuration cheat sheet.` app.Flags = []cli.Flag{ &cli.StringFlag{ - Name: "custom-path, C", - Value: setting.CustomPath, - Usage: "Custom path file path", + Name: "custom-path", + Aliases: []string{"C"}, + Value: setting.CustomPath, + Usage: "Custom path file path", }, &cli.StringFlag{ - Name: "config, c", - Value: setting.CustomConf, - Usage: "Custom configuration file path", + Name: "config", + Aliases: []string{"c"}, + Value: setting.CustomConf, + Usage: "Custom configuration file path", }, &cli.StringFlag{ - Name: "work-path, w", - Value: setting.AppWorkPath, - Usage: "Set the gitea working path", + Name: "work-path", + Aliases: []string{"w"}, + Value: setting.AppWorkPath, + Usage: "Set the gitea working path", }, &cli.StringFlag{ - Name: "out, o", - Value: "", - Usage: "Destination file to write to", + Name: "out", + Aliases: []string{"o"}, + Value: "", + Usage: "Destination file to write to", }, } app.Action = runEnvironmentToIni diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 901298898b3..0e8123526c1 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1230,6 +1230,9 @@ LEVEL = Info ;; For custom reactions, add a tightly cropped square image to public/assets/img/emoji/reaction_name.png ;REACTIONS = +1, -1, laugh, hooray, confused, heart, rocket, eyes ;; +;; Change the number of users that are displayed in reactions tooltip (triggered by mouse hover). +;REACTION_MAX_USER_NUM = 10 +;; ;; Additional Emojis not defined in the utf8 standard ;; By default we support gitea (:gitea:), to add more copy them to public/assets/img/emoji/emoji_name.png and add it to this config. ;; Dont mistake it for Reactions. diff --git a/docker/root/usr/bin/entrypoint b/docker/root/usr/bin/entrypoint index 0acfec4dbe4..d9dbb3ebe0b 100755 --- a/docker/root/usr/bin/entrypoint +++ b/docker/root/usr/bin/entrypoint @@ -7,7 +7,7 @@ if [ ! -x /bin/sh ]; then fi if [ "${USER}" != "git" ]; then - # rename user + # Rename user sed -i -e "s/^git\:/${USER}\:/g" /etc/passwd fi @@ -19,13 +19,13 @@ if [ -z "${USER_UID}" ]; then USER_UID="`id -u ${USER}`" fi -## Change GID for USER? +# Change GID for USER? if [ -n "${USER_GID}" ] && [ "${USER_GID}" != "`id -g ${USER}`" ]; then sed -i -e "s/^${USER}:\([^:]*\):[0-9]*/${USER}:\1:${USER_GID}/" /etc/group sed -i -e "s/^${USER}:\([^:]*\):\([0-9]*\):[0-9]*/${USER}:\1:\2:${USER_GID}/" /etc/passwd fi -## Change UID for USER? +# Change UID for USER? if [ -n "${USER_UID}" ] && [ "${USER_UID}" != "`id -u ${USER}`" ]; then sed -i -e "s/^${USER}:\([^:]*\):[0-9]*:\([0-9]*\)/${USER}:\1:${USER_UID}:\2/" /etc/passwd fi diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 7bdaf55e9b7..6f9a472052c 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -226,6 +226,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `REACTIONS`: All available reactions users can choose on issues/prs and comments Values can be emoji alias (:smile:) or a unicode emoji. For custom reactions, add a tightly cropped square image to public/assets/img/emoji/reaction_name.png +- `REACTION_MAX_USER_NUM`: **10**: Change the number of users that are displayed in reactions tooltip (triggered by mouse hover). - `CUSTOM_EMOJIS`: **gitea, codeberg, gitlab, git, github, gogs**: Additional Emojis not defined in the utf8 standard. By default, we support Gitea (:gitea:), to add more copy them to public/assets/img/emoji/emoji_name.png and add it to this config. @@ -427,7 +428,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a ## Database (`database`) - `DB_TYPE`: **mysql**: The database type in use \[mysql, postgres, mssql, sqlite3\]. -- `HOST`: **127.0.0.1:3306**: Database host address and port or absolute path for unix socket \[mysql, postgres\] (ex: /var/run/mysqld/mysqld.sock). +- `HOST`: **127.0.0.1:3306**: Database host address and port or absolute path for unix socket \[mysql, postgres[^1]\] (ex: /var/run/mysqld/mysqld.sock). - `NAME`: **gitea**: Database name. - `USER`: **root**: Database username. - `PASSWD`: **_empty_**: Database user password. Use \`your password\` or """your password""" for quoting if you use special characters in the password. @@ -458,6 +459,8 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `CONN_MAX_LIFETIME` **0 or 3s**: Sets the maximum amount of time a DB connection may be reused - default is 0, meaning there is no limit (except on MySQL where it is 3s - see #6804 & #7071). - `AUTO_MIGRATION` **true**: Whether execute database models migrations automatically. +[^1]: It may be necessary to specify a hostport even when listening on a unix socket, as the port is part of the socket name. see [#24552](https://github.com/go-gitea/gitea/issues/24552#issuecomment-1681649367) for additional details. + Please see #8540 & #8273 for further discussion of the appropriate values for `MAX_OPEN_CONNS`, `MAX_IDLE_CONNS` & `CONN_MAX_LIFETIME` and their relation to port exhaustion. diff --git a/docs/content/usage/actions/act-runner.en-us.md b/docs/content/usage/actions/act-runner.en-us.md index e2915be3651..6e99beb870a 100644 --- a/docs/content/usage/actions/act-runner.en-us.md +++ b/docs/content/usage/actions/act-runner.en-us.md @@ -114,6 +114,12 @@ If you cannot see the settings page, please make sure that you have the right pe The format of the registration token is a random string `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`. +A registration token can also be obtained from the gitea [command-line interface](../../administration/command-line.en-us.md#actions-generate-runner-token): + +``` +gitea --config /etc/gitea/app.ini actions generate-runner-token +``` + ### Register the runner The act runner can be registered by running the following command: @@ -262,6 +268,40 @@ The runner will fetch jobs from the Gitea instance and run them automatically. Since act runner is still in development, it is recommended to check the latest version and upgrade it regularly. +## Systemd service + +It is also possible to run act-runner as a [systemd](https://en.wikipedia.org/wiki/Systemd) service. Create an unprivileged `act_runner` user on your system, and the following file in `/etc/systemd/system/act_runner.service`. The paths in `ExecStart` and `WorkingDirectory` may need to be adjusted depending on where you installed the `act_runner` binary, its configuration file, and the home directory of the `act_runner` user. + +```ini +[Unit] +Description=Gitea Actions runner +Documentation=https://gitea.com/gitea/act_runner +After=docker.service + +[Service] +ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml +ExecReload=/bin/kill -s HUP $MAINPID +WorkingDirectory=/var/lib/act_runner +TimeoutSec=0 +RestartSec=10 +Restart=always +User=act_runner + +[Install] +WantedBy=multi-user.target +``` + +Then: + +```bash +# load the new systemd unit file +sudo systemctl daemon-reload +# start the service and enable it at boot +sudo systemctl enable act_runner --now +``` + +If using Docker, the `act_runner` user should also be added to the `docker` group before starting the service. Keep in mind that this effectively gives `act_runner` root access to the system [[1]](https://docs.docker.com/engine/security/#docker-daemon-attack-surface). + ## Configuration variable You can create configuration variables on the user, organization and repository level. diff --git a/docs/content/usage/actions/act-runner.zh-cn.md b/docs/content/usage/actions/act-runner.zh-cn.md index 11b69960f78..39d5c238c79 100644 --- a/docs/content/usage/actions/act-runner.zh-cn.md +++ b/docs/content/usage/actions/act-runner.zh-cn.md @@ -113,6 +113,8 @@ Runner级别决定了从哪里获取注册令牌。 注册令牌的格式是一个随机字符串 `D0gvfu2iHfUjNqCYVljVyRV14fISpJxxxxxxxxxx`。 +注册令牌也可以通过 Gitea 的 [命令行](../../administration/command-line.en-us.md#actions-generate-runner-token) 获得: + ### 注册Runner 可以通过运行以下命令来注册Act Runner: diff --git a/docs/content/usage/actions/comparison.en-us.md b/docs/content/usage/actions/comparison.en-us.md index caec9d3dea3..56874c2a9fd 100644 --- a/docs/content/usage/actions/comparison.en-us.md +++ b/docs/content/usage/actions/comparison.en-us.md @@ -130,34 +130,3 @@ More details about the `[actions].DEFAULT_ACTIONS_URL` configuration can be foun Context availability is not checked, so you can use the env context on more places. See [Context availability](https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability). - -## Known issues - -### `docker/build-push-action@v4` - -See [act_runner#119](https://gitea.com/gitea/act_runner/issues/119#issuecomment-738294). - -`ACTIONS_RUNTIME_TOKEN` is a random string in Gitea Actions, not a JWT. -But the `docker/build-push-action@v4` tries to parse the token as JWT and doesn't handle the error, so the job fails. - -There are two workarounds: - -Set the `ACTIONS_RUNTIME_TOKEN` to empty manually, like: - -``` yml -- name: Build and push - uses: docker/build-push-action@v4 - env: - ACTIONS_RUNTIME_TOKEN: '' - with: -... -``` - -The bug has been fixed in a newer [commit](https://gitea.com/docker/build-push-action/commit/d8823bfaed2a82c6f5d4799a2f8e86173c461aba?style=split&whitespace=show-all#diff-1af9a5bdf96ddff3a2f3427ed520b7005e9564ad), but it has not been released. So you could use the latest version by specifying the branch name, like: - -``` yml -- name: Build and push - uses: docker/build-push-action@master - with: -... -``` diff --git a/docs/content/usage/actions/comparison.zh-cn.md b/docs/content/usage/actions/comparison.zh-cn.md index 5dae75a44ba..1ef7d3ca989 100644 --- a/docs/content/usage/actions/comparison.zh-cn.md +++ b/docs/content/usage/actions/comparison.zh-cn.md @@ -132,34 +132,3 @@ Gitea Actions目前不支持此功能。 不检查上下文可用性,因此您可以在更多地方使用env上下文。 请参阅[上下文可用性](https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability)。 - -## 已知问题 - -### `docker/build-push-action@v4` - -请参阅[act_runner#119](https://gitea.com/gitea/act_runner/issues/119#issuecomment-738294)。 - -`ACTIONS_RUNTIME_TOKEN`在Gitea Actions中是一个随机字符串,而不是JWT。 -但是`DOCKER/BUILD-PUSH-ACTION@V4尝试将令牌解析为JWT,并且不处理错误,因此Job失败。 - -有两种解决方法: - -手动将`ACTIONS_RUNTIME_TOKEN`设置为空字符串,例如: - -``` yml -- name: Build and push - uses: docker/build-push-action@v4 - env: - ACTIONS_RUNTIME_TOKEN: '' - with: -... -``` - -该问题已在较新的[提交](https://gitea.com/docker/build-push-action/commit/d8823bfaed2a82c6f5d4799a2f8e86173c461aba?style=split&whitespace=show-all#diff-1af9a5bdf96ddff3a2f3427ed520b7005e9564ad)中修复,但尚未发布。因此,您可以通过指定分支名称来使用最新版本,例如: - -``` yml -- name: Build and push - uses: docker/build-push-action@master - with: -... -``` diff --git a/go.mod b/go.mod index 84f42969d50..97997cad6d5 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 github.com/NYTimes/gziphandler v1.1.1 github.com/PuerkitoBio/goquery v1.8.1 - github.com/alecthomas/chroma/v2 v2.9.1 + github.com/alecthomas/chroma/v2 v2.10.0 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb github.com/blevesearch/bleve/v2 v2.3.10 github.com/bufbuild/connect-go v1.10.0 @@ -36,7 +36,7 @@ require ( github.com/ethantkoenig/rupture v1.0.1 github.com/felixge/fgprof v0.9.3 github.com/fsnotify/fsnotify v1.6.0 - github.com/gliderlabs/ssh v0.3.5 + github.com/gliderlabs/ssh v0.3.6-0.20230927171611-ece6c7995e46 github.com/go-ap/activitypub v0.0.0-20231003111253-1fba3772399b github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 github.com/go-chi/chi/v5 v5.0.10 @@ -121,7 +121,7 @@ require ( mvdan.cc/xurls/v2 v2.5.0 strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 xorm.io/builder v0.3.13 - xorm.io/xorm v1.3.4-0.20231017094142-dbe499091a7e + xorm.io/xorm v1.3.4 ) require ( diff --git a/go.sum b/go.sum index 379533b08ce..fbe4fe06e56 100644 --- a/go.sum +++ b/go.sum @@ -118,8 +118,8 @@ github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink= github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs= -github.com/alecthomas/chroma/v2 v2.9.1 h1:0O3lTQh9FxazJ4BYE/MOi/vDGuHn7B+6Bu902N2UZvU= -github.com/alecthomas/chroma/v2 v2.9.1/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw= +github.com/alecthomas/chroma/v2 v2.10.0 h1:T2iQOCCt4pRmRMfL55gTodMtc7cU0y7lc1Jb8/mK/64= +github.com/alecthomas/chroma/v2 v2.10.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= @@ -329,8 +329,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= -github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= -github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= +github.com/gliderlabs/ssh v0.3.6-0.20230927171611-ece6c7995e46 h1:fYiA820jw7wmAvdXrHwMItxjJkra7dT9y8yiXhtzb94= +github.com/gliderlabs/ssh v0.3.6-0.20230927171611-ece6c7995e46/go.mod h1:i/TCLcdiX9Up/vs+Rp8c3yMbqp2Y4Y7Nh9uzGFCa5pM= 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-20231003111253-1fba3772399b h1:VLD6IPBDkqEsOZ+EfLO6MayuHycZ0cv4BStTlRoZduo= @@ -1237,7 +1237,6 @@ golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -1337,9 +1336,7 @@ golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1353,7 +1350,6 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= @@ -1648,5 +1644,5 @@ strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1: xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo= xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= -xorm.io/xorm v1.3.4-0.20231017094142-dbe499091a7e h1:oL+ktEW+iSrCXU6IauJ9csZFATEmawkhsq/MAoHTdwo= -xorm.io/xorm v1.3.4-0.20231017094142-dbe499091a7e/go.mod h1:qFJGFoVYbbIdnz2vaL5OxSQ2raleMpyRRalnq3n9OJo= +xorm.io/xorm v1.3.4 h1:vWFKzR3DhGUDl5b4srhUjhDwjxkZAc4C7BFszpu0swI= +xorm.io/xorm v1.3.4/go.mod h1:qFJGFoVYbbIdnz2vaL5OxSQ2raleMpyRRalnq3n9OJo= diff --git a/models/actions/runner.go b/models/actions/runner.go index ec6b49cf167..2c092c2b4a3 100644 --- a/models/actions/runner.go +++ b/models/actions/runner.go @@ -266,3 +266,27 @@ func CreateRunner(ctx context.Context, t *ActionRunner) error { _, err := db.GetEngine(ctx).Insert(t) return err } + +func CountRunnersWithoutBelongingOwner(ctx context.Context) (int64, error) { + // Only affect action runners were a owner ID is set, as actions runners + // could also be created on a repository. + return db.GetEngine(ctx).Table("action_runner"). + Join("LEFT", "user", "`action_runner`.owner_id = `user`.id"). + Where("`action_runner`.owner_id != ?", 0). + And(builder.IsNull{"`user`.id"}). + Count(new(ActionRunner)) +} + +func FixRunnersWithoutBelongingOwner(ctx context.Context) (int64, error) { + subQuery := builder.Select("`action_runner`.id"). + From("`action_runner`"). + Join("LEFT", "user", "`action_runner`.owner_id = `user`.id"). + Where(builder.Neq{"`action_runner`.owner_id": 0}). + And(builder.IsNull{"`user`.id"}) + b := builder.Delete(builder.In("id", subQuery)).From("`action_runner`") + res, err := db.GetEngine(ctx).Exec(b) + if err != nil { + return 0, err + } + return res.RowsAffected() +} diff --git a/models/activities/statistic.go b/models/activities/statistic.go index 009c8c5ab47..e9dab6fc10b 100644 --- a/models/activities/statistic.go +++ b/models/activities/statistic.go @@ -102,7 +102,7 @@ func GetStatistic(ctx context.Context) (stats Statistic) { stats.Counter.Follow, _ = e.Count(new(user_model.Follow)) stats.Counter.Mirror, _ = e.Count(new(repo_model.Mirror)) stats.Counter.Release, _ = e.Count(new(repo_model.Release)) - stats.Counter.AuthSource = auth.CountSources(ctx) + stats.Counter.AuthSource = auth.CountSources(ctx, auth.FindSourcesOptions{}) stats.Counter.Webhook, _ = e.Count(new(webhook.Webhook)) stats.Counter.Milestone, _ = e.Count(new(issues_model.Milestone)) stats.Counter.Label, _ = e.Count(new(issues_model.Label)) diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go index d73ad6965d2..76a4e9d835b 100644 --- a/models/auth/oauth2.go +++ b/models/auth/oauth2.go @@ -631,15 +631,6 @@ func (err ErrOAuthApplicationNotFound) Unwrap() error { return util.ErrNotExist } -// GetActiveOAuth2ProviderSources returns all actived LoginOAuth2 sources -func GetActiveOAuth2ProviderSources(ctx context.Context) ([]*Source, error) { - sources := make([]*Source, 0, 1) - if err := db.GetEngine(ctx).Where("is_active = ? and type = ?", true, OAuth2).Find(&sources); err != nil { - return nil, err - } - return sources, nil -} - // GetActiveOAuth2SourceByName returns a OAuth2 AuthSource based on the given name func GetActiveOAuth2SourceByName(ctx context.Context, name string) (*Source, error) { authSource := new(Source) diff --git a/models/auth/source.go b/models/auth/source.go index 0f57d1702a7..b3f3262cc20 100644 --- a/models/auth/source.go +++ b/models/auth/source.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" + "xorm.io/builder" "xorm.io/xorm" "xorm.io/xorm/convert" ) @@ -240,37 +241,26 @@ func CreateSource(ctx context.Context, source *Source) error { return err } -// Sources returns a slice of all login sources found in DB. -func Sources(ctx context.Context) ([]*Source, error) { +type FindSourcesOptions struct { + IsActive util.OptionalBool + LoginType Type +} + +func (opts FindSourcesOptions) ToConds() builder.Cond { + conds := builder.NewCond() + if !opts.IsActive.IsNone() { + conds = conds.And(builder.Eq{"is_active": opts.IsActive.IsTrue()}) + } + if opts.LoginType != NoType { + conds = conds.And(builder.Eq{"`type`": opts.LoginType}) + } + return conds +} + +// FindSources returns a slice of login sources found in DB according to given conditions. +func FindSources(ctx context.Context, opts FindSourcesOptions) ([]*Source, error) { auths := make([]*Source, 0, 6) - return auths, db.GetEngine(ctx).Find(&auths) -} - -// SourcesByType returns all sources of the specified type -func SourcesByType(ctx context.Context, loginType Type) ([]*Source, error) { - sources := make([]*Source, 0, 1) - if err := db.GetEngine(ctx).Where("type = ?", loginType).Find(&sources); err != nil { - return nil, err - } - return sources, nil -} - -// AllActiveSources returns all active sources -func AllActiveSources(ctx context.Context) ([]*Source, error) { - sources := make([]*Source, 0, 5) - if err := db.GetEngine(ctx).Where("is_active = ?", true).Find(&sources); err != nil { - return nil, err - } - return sources, nil -} - -// ActiveSources returns all active sources of the specified type -func ActiveSources(ctx context.Context, tp Type) ([]*Source, error) { - sources := make([]*Source, 0, 1) - if err := db.GetEngine(ctx).Where("is_active = ? and type = ?", true, tp).Find(&sources); err != nil { - return nil, err - } - return sources, nil + return auths, db.GetEngine(ctx).Where(opts.ToConds()).Find(&auths) } // IsSSPIEnabled returns true if there is at least one activated login @@ -279,7 +269,10 @@ func IsSSPIEnabled(ctx context.Context) bool { if !db.HasEngine { return false } - sources, err := ActiveSources(ctx, SSPI) + sources, err := FindSources(ctx, FindSourcesOptions{ + IsActive: util.OptionalBoolTrue, + LoginType: SSPI, + }) if err != nil { log.Error("ActiveSources: %v", err) return false @@ -354,8 +347,8 @@ func UpdateSource(ctx context.Context, source *Source) error { } // CountSources returns number of login sources. -func CountSources(ctx context.Context) int64 { - count, _ := db.GetEngine(ctx).Count(new(Source)) +func CountSources(ctx context.Context, opts FindSourcesOptions) int64 { + count, _ := db.GetEngine(ctx).Where(opts.ToConds()).Count(new(Source)) return count } diff --git a/models/git/commit_status.go b/models/git/commit_status.go index c6a52bcd9f5..acb01102005 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -235,7 +235,7 @@ func GetCommitStatuses(ctx context.Context, repo *repo_model.Repository, sha str countSession := listCommitStatusesStatement(ctx, repo, sha, opts) countSession = db.SetSessionPagination(countSession, opts) - maxResults, err := countSession.OrderBy("1").Count(new(CommitStatus)) + maxResults, err := countSession.Count(new(CommitStatus)) if err != nil { log.Error("Count PRs: %v", err) return nil, maxResults, err diff --git a/models/issues/issue.go b/models/issues/issue.go index 8655b9de3fe..b0ff0adddda 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -142,22 +142,14 @@ type Issue struct { } var ( - issueTasksPat *regexp.Regexp - issueTasksDonePat *regexp.Regexp -) - -const ( - issueTasksRegexpStr = `(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)` - issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)` + issueTasksPat = regexp.MustCompile(`(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)`) + issueTasksDonePat = regexp.MustCompile(`(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`) ) // IssueIndex represents the issue index table type IssueIndex db.ResourceIndex func init() { - issueTasksPat = regexp.MustCompile(issueTasksRegexpStr) - issueTasksDonePat = regexp.MustCompile(issueTasksDoneRegexpStr) - db.RegisterModel(new(Issue)) db.RegisterModel(new(IssueIndex)) } diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index 9b6bf117b1f..0bea1fed143 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -186,7 +186,7 @@ func applyProjectBoardCondition(sess *xorm.Session, opts *IssuesOptions) *xorm.S if opts.ProjectBoardID > 0 { sess.In("issue.id", builder.Select("issue_id").From("project_issue").Where(builder.Eq{"project_board_id": opts.ProjectBoardID})) } else if opts.ProjectBoardID == db.NoConditionID { - sess.In("issue.id", builder.Select("issue_id").From("project_issue").Where(builder.Neq{"project_board_id": 0})) + sess.In("issue.id", builder.Select("issue_id").From("project_issue").Where(builder.Eq{"project_board_id": 0})) } return sess } diff --git a/models/issues/review.go b/models/issues/review.go index 1cb5379b2f6..3db73a09ebc 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -897,6 +897,16 @@ func DeleteReview(ctx context.Context, r *Review) error { return err } + opts = FindCommentsOptions{ + Type: CommentTypeDismissReview, + IssueID: r.IssueID, + ReviewID: r.ID, + } + + if _, err := sess.Where(opts.ToConds()).Delete(new(Comment)); err != nil { + return err + } + if _, err := sess.ID(r.ID).Delete(new(Review)); err != nil { return err } diff --git a/models/issues/review_test.go b/models/issues/review_test.go index 63e2aef2cce..1868cb1bfab 100644 --- a/models/issues/review_test.go +++ b/models/issues/review_test.go @@ -8,6 +8,7 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -258,3 +259,32 @@ func TestDeleteReview(t *testing.T) { assert.NoError(t, err) assert.True(t, review1.Official) } + +func TestDeleteDismissedReview(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) + review, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{ + Content: "reject", + Type: issues_model.ReviewTypeReject, + Official: false, + Issue: issue, + Reviewer: user, + }) + assert.NoError(t, err) + assert.NoError(t, issues_model.DismissReview(db.DefaultContext, review, true)) + comment, err := issues_model.CreateComment(db.DefaultContext, &issues_model.CreateCommentOptions{ + Type: issues_model.CommentTypeDismissReview, + Doer: user, + Repo: repo, + Issue: issue, + ReviewID: review.ID, + Content: "dismiss", + }) + assert.NoError(t, err) + unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID}) + assert.NoError(t, issues_model.DeleteReview(db.DefaultContext, review)) + unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID}) +} diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 178adc35215..43a84e4525f 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -548,6 +548,8 @@ var migrations = []Migration{ NewMigration("Rename user themes", v1_22.RenameUserThemes), // v281 -> v282 NewMigration("Add auth_token table", v1_22.CreateAuthTokenTable), + // v282 -> v283 + NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID), // to modify later NewMigration("Add size limit on repository", v1_22.AddSizeLimitOnRepo), } diff --git a/models/migrations/v1_22/v282.go b/models/migrations/v1_22/v282.go new file mode 100644 index 00000000000..baad9e09168 --- /dev/null +++ b/models/migrations/v1_22/v282.go @@ -0,0 +1,16 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_22 //nolint + +import ( + "xorm.io/xorm" +) + +func AddIndexToPullAutoMergeDoerID(x *xorm.Engine) error { + type PullAutoMerge struct { + DoerID int64 `xorm:"INDEX NOT NULL"` + } + + return x.Sync(&PullAutoMerge{}) +} diff --git a/models/org.go b/models/org.go index 119465b9623..5e0deeb8de7 100644 --- a/models/org.go +++ b/models/org.go @@ -14,12 +14,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" ) -func removeOrgUser(ctx context.Context, orgID, userID int64) error { +// RemoveOrgUser removes user from given organization. +func RemoveOrgUser(ctx context.Context, orgID, userID int64) error { ou := new(organization.OrgUser) - sess := db.GetEngine(ctx) - - has, err := sess. + has, err := db.GetEngine(ctx). Where("uid=?", userID). And("org_id=?", orgID). Get(ou) @@ -52,7 +51,13 @@ func removeOrgUser(ctx context.Context, orgID, userID int64) error { } } - if _, err := sess.ID(ou.ID).Delete(ou); err != nil { + ctx, committer, err := db.TxContext(ctx) + if err != nil { + return err + } + defer committer.Close() + + if _, err := db.GetEngine(ctx).ID(ou.ID).Delete(ou); err != nil { return err } else if _, err = db.Exec(ctx, "UPDATE `user` SET num_members=num_members-1 WHERE id=?", orgID); err != nil { return err @@ -74,7 +79,7 @@ func removeOrgUser(ctx context.Context, orgID, userID int64) error { } if len(repoIDs) > 0 { - if _, err = sess. + if _, err = db.GetEngine(ctx). Where("user_id = ?", userID). In("repo_id", repoIDs). Delete(new(access_model.Access)); err != nil { @@ -93,18 +98,5 @@ func removeOrgUser(ctx context.Context, orgID, userID int64) error { } } - return nil -} - -// RemoveOrgUser removes user from given organization. -func RemoveOrgUser(ctx context.Context, orgID, userID int64) error { - ctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - if err := removeOrgUser(ctx, orgID, userID); err != nil { - return err - } return committer.Commit() } diff --git a/models/org_team.go b/models/org_team.go index acbab560892..03a4f6e98d8 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -502,7 +502,7 @@ func removeInvalidOrgUser(ctx context.Context, userID, orgID int64) error { }); err != nil { return err } else if count == 0 { - return removeOrgUser(ctx, orgID, userID) + return RemoveOrgUser(ctx, orgID, userID) } return nil } diff --git a/models/packages/container/search.go b/models/packages/container/search.go index 9a16b3ae44b..5df35117ce5 100644 --- a/models/packages/container/search.go +++ b/models/packages/container/search.go @@ -207,6 +207,9 @@ func (opts *ImageTagsSearchOptions) configureOrderBy(e db.Engine) { default: e.Desc("package_version.created_unix") } + + // Sort by id for stable order with duplicates in the other field + e.Asc("package_version.id") } // SearchImageTags gets a sorted list of the tags of an image diff --git a/models/packages/debian/search.go b/models/packages/debian/search.go index c63a3193046..77c4a184623 100644 --- a/models/packages/debian/search.go +++ b/models/packages/debian/search.go @@ -21,8 +21,7 @@ type PackageSearchOptions struct { Architecture string } -// SearchLatestPackages gets the latest packages matching the search options -func SearchLatestPackages(ctx context.Context, opts *PackageSearchOptions) ([]*packages.PackageFileDescriptor, error) { +func (opts *PackageSearchOptions) toCond() builder.Cond { var cond builder.Cond = builder.Eq{ "package_file.is_lead": true, "package.type": packages.TypeDebian, @@ -62,28 +61,40 @@ func SearchLatestPackages(ctx context.Context, opts *PackageSearchOptions) ([]*p }) } - cond = cond. - And(builder.Expr("pv2.id IS NULL")) + return cond +} - joinCond := builder. - Expr("package_version.package_id = pv2.package_id AND (package_version.created_unix < pv2.created_unix OR (package_version.created_unix = pv2.created_unix AND package_version.id < pv2.id))"). - And(builder.Eq{"pv2.is_internal": false}) +// ExistPackages tests if there are packages matching the search options +func ExistPackages(ctx context.Context, opts *PackageSearchOptions) (bool, error) { + return db.GetEngine(ctx). + Table("package_file"). + Join("INNER", "package_version", "package_version.id = package_file.version_id"). + Join("INNER", "package", "package.id = package_version.package_id"). + Where(opts.toCond()). + Exist(new(packages.PackageFile)) +} - pfs := make([]*packages.PackageFile, 0, 10) - err := db.GetEngine(ctx). +// SearchPackages gets the packages matching the search options +func SearchPackages(ctx context.Context, opts *PackageSearchOptions, iter func(*packages.PackageFileDescriptor)) error { + return db.GetEngine(ctx). Table("package_file"). Select("package_file.*"). Join("INNER", "package_version", "package_version.id = package_file.version_id"). - Join("LEFT", "package_version pv2", joinCond). Join("INNER", "package", "package.id = package_version.package_id"). - Where(cond). - Desc("package_version.created_unix"). - Find(&pfs) - if err != nil { - return nil, err - } + Where(opts.toCond()). + Asc("package.lower_name", "package_version.created_unix"). + Iterate(new(packages.PackageFile), func(_ int, bean any) error { + pf := bean.(*packages.PackageFile) - return packages.GetPackageFileDescriptors(ctx, pfs) + pfd, err := packages.GetPackageFileDescriptor(ctx, pf) + if err != nil { + return err + } + + iter(pfd) + + return nil + }) } // GetDistributions gets all available distributions diff --git a/models/packages/package_version.go b/models/packages/package_version.go index 4392c70f79b..9999fc4dab7 100644 --- a/models/packages/package_version.go +++ b/models/packages/package_version.go @@ -278,6 +278,9 @@ func (opts *PackageSearchOptions) configureOrderBy(e db.Engine) { default: e.Desc("package_version.created_unix") } + + // Sort by id for stable order with duplicates in the other field + e.Asc("package_version.id") } // SearchVersions gets all versions of packages matching the search options diff --git a/models/pull/automerge.go b/models/pull/automerge.go index f68fb7c681e..f69fcb60d16 100644 --- a/models/pull/automerge.go +++ b/models/pull/automerge.go @@ -17,7 +17,7 @@ import ( type AutoMerge struct { ID int64 `xorm:"pk autoincr"` PullID int64 `xorm:"UNIQUE"` - DoerID int64 `xorm:"NOT NULL"` + DoerID int64 `xorm:"INDEX NOT NULL"` Doer *user_model.User `xorm:"-"` MergeStyle repo_model.MergeStyle `xorm:"varchar(30)"` Message string `xorm:"LONGTEXT"` diff --git a/modules/context/api.go b/modules/context/api.go index a46af6ed782..ba35adf8310 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -11,7 +11,6 @@ import ( "net/url" "strings" - "code.gitea.io/gitea/models/auth" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -211,32 +210,6 @@ func (ctx *APIContext) SetLinkHeader(total, pageSize int) { } } -// CheckForOTP validates OTP -func (ctx *APIContext) CheckForOTP() { - if skip, ok := ctx.Data["SkipLocalTwoFA"]; ok && skip.(bool) { - return // Skip 2FA - } - - otpHeader := ctx.Req.Header.Get("X-Gitea-OTP") - twofa, err := auth.GetTwoFactorByUID(ctx, ctx.Doer.ID) - if err != nil { - if auth.IsErrTwoFactorNotEnrolled(err) { - return // No 2FA enrollment for this user - } - ctx.Error(http.StatusInternalServerError, "GetTwoFactorByUID", err) - return - } - ok, err := twofa.ValidateTOTP(otpHeader) - if err != nil { - ctx.Error(http.StatusInternalServerError, "ValidateTOTP", err) - return - } - if !ok { - ctx.Error(http.StatusUnauthorized, "", nil) - return - } -} - // APIContexter returns apicontext as middleware func APIContexter() func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { diff --git a/modules/context/context.go b/modules/context/context.go index 47ad310b095..8a94e958b51 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -157,7 +157,6 @@ func Contexter() func(next http.Handler) http.Handler { ctx.Data["Context"] = ctx // TODO: use "ctx" in template and remove this ctx.Data["CurrentURL"] = setting.AppSubURL + req.URL.RequestURI() ctx.Data["Link"] = ctx.Link - ctx.Data["locale"] = ctx.Locale // PageData is passed by reference, and it will be rendered to `window.config.pageData` in `head.tmpl` for JavaScript modules ctx.PageData = map[string]any{} diff --git a/modules/doctor/dbconsistency.go b/modules/doctor/dbconsistency.go index e5fc5785e82..ac983f91615 100644 --- a/modules/doctor/dbconsistency.go +++ b/modules/doctor/dbconsistency.go @@ -6,6 +6,7 @@ package doctor import ( "context" + actions_model "code.gitea.io/gitea/models/actions" activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" @@ -151,6 +152,12 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er Fixer: activities_model.FixActionCreatedUnixString, FixedMessage: "Set to zero", }, + { + Name: "Action Runners without existing owner", + Counter: actions_model.CountRunnersWithoutBelongingOwner, + Fixer: actions_model.FixRunnersWithoutBelongingOwner, + FixedMessage: "Removed", + }, } // TODO: function to recalc all counters diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 0ec23164c28..da4fc9b8789 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -382,6 +382,12 @@ func searchIssueInProject(t *testing.T) { }, []int64{1}, }, + { + SearchOptions{ + ProjectBoardID: int64Pointer(0), // issue with in default board + }, + []int64{2}, + }, } for _, test := range tests { issueIDs, _, err := SearchIssues(context.TODO(), &test.opts) diff --git a/modules/packages/hashed_buffer.go b/modules/packages/hashed_buffer.go index 017ddf1c8f5..4ab45edceca 100644 --- a/modules/packages/hashed_buffer.go +++ b/modules/packages/hashed_buffer.go @@ -32,7 +32,7 @@ func NewHashedBuffer() (*HashedBuffer, error) { return NewHashedBufferWithSize(DefaultMemorySize) } -// NewHashedBuffer creates a hashed buffer with a specific memory size +// NewHashedBufferWithSize creates a hashed buffer with a specific memory size func NewHashedBufferWithSize(maxMemorySize int) (*HashedBuffer, error) { b, err := filebuffer.New(maxMemorySize) if err != nil { diff --git a/modules/setting/database.go b/modules/setting/database.go index 709655368c6..aa42f506bc5 100644 --- a/modules/setting/database.go +++ b/modules/setting/database.go @@ -6,6 +6,7 @@ package setting import ( "errors" "fmt" + "net" "net/url" "os" "path" @@ -135,15 +136,18 @@ func DBConnStr() (string, error) { // parsePostgreSQLHostPort parses given input in various forms defined in // https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING // and returns proper host and port number. -func parsePostgreSQLHostPort(info string) (string, string) { - host, port := "127.0.0.1", "5432" - if strings.Contains(info, ":") && !strings.HasSuffix(info, "]") { - idx := strings.LastIndex(info, ":") - host = info[:idx] - port = info[idx+1:] - } else if len(info) > 0 { +func parsePostgreSQLHostPort(info string) (host, port string) { + if h, p, err := net.SplitHostPort(info); err == nil { + host, port = h, p + } else { + // treat the "info" as "host", if it's an IPv6 address, remove the wrapper host = info + if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") { + host = host[1 : len(host)-1] + } } + + // set fallback values if host == "" { host = "127.0.0.1" } @@ -155,14 +159,22 @@ func parsePostgreSQLHostPort(info string) (string, string) { func getPostgreSQLConnectionString(dbHost, dbUser, dbPasswd, dbName, dbParam, dbsslMode string) (connStr string) { host, port := parsePostgreSQLHostPort(dbHost) - if host[0] == '/' { // looks like a unix socket - connStr = fmt.Sprintf("postgres://%s:%s@:%s/%s%ssslmode=%s&host=%s", - url.PathEscape(dbUser), url.PathEscape(dbPasswd), port, dbName, dbParam, dbsslMode, host) - } else { - connStr = fmt.Sprintf("postgres://%s:%s@%s:%s/%s%ssslmode=%s", - url.PathEscape(dbUser), url.PathEscape(dbPasswd), host, port, dbName, dbParam, dbsslMode) + connURL := url.URL{ + Scheme: "postgres", + User: url.UserPassword(dbUser, dbPasswd), + Host: net.JoinHostPort(host, port), + Path: dbName, + OmitHost: false, + RawQuery: dbParam, } - return connStr + query := connURL.Query() + if dbHost[0] == '/' { // looks like a unix socket + query.Add("host", dbHost) + connURL.Host = ":" + port + } + query.Set("sslmode", dbsslMode) + connURL.RawQuery = query.Encode() + return connURL.String() } // ParseMSSQLHostPort splits the host into host and port diff --git a/modules/setting/database_test.go b/modules/setting/database_test.go index 481ca969b1f..85271c36cb3 100644 --- a/modules/setting/database_test.go +++ b/modules/setting/database_test.go @@ -10,46 +10,49 @@ import ( ) func Test_parsePostgreSQLHostPort(t *testing.T) { - tests := []struct { + tests := map[string]struct { HostPort string Host string Port string }{ - { + "host-port": { HostPort: "127.0.0.1:1234", Host: "127.0.0.1", Port: "1234", }, - { + "no-port": { HostPort: "127.0.0.1", Host: "127.0.0.1", Port: "5432", }, - { + "ipv6-port": { HostPort: "[::1]:1234", - Host: "[::1]", + Host: "::1", Port: "1234", }, - { + "ipv6-no-port": { HostPort: "[::1]", - Host: "[::1]", + Host: "::1", Port: "5432", }, - { + "unix-socket": { HostPort: "/tmp/pg.sock:1234", Host: "/tmp/pg.sock", Port: "1234", }, - { + "unix-socket-no-port": { HostPort: "/tmp/pg.sock", Host: "/tmp/pg.sock", Port: "5432", }, } - for _, test := range tests { - host, port := parsePostgreSQLHostPort(test.HostPort) - assert.Equal(t, test.Host, host) - assert.Equal(t, test.Port, port) + for k, test := range tests { + t.Run(k, func(t *testing.T) { + t.Log(test.HostPort) + host, port := parsePostgreSQLHostPort(test.HostPort) + assert.Equal(t, test.Host, host) + assert.Equal(t, test.Port, port) + }) } } @@ -72,7 +75,7 @@ func Test_getPostgreSQLConnectionString(t *testing.T) { Name: "gitea", Param: "", SSLMode: "false", - Output: "postgres://testuser:space%20space%20%21%23$%25%5E%5E%25%5E%60%60%60-=%3F=@:5432/giteasslmode=false&host=/tmp/pg.sock", + Output: "postgres://testuser:space%20space%20%21%23$%25%5E%5E%25%5E%60%60%60-=%3F=@:5432/gitea?host=%2Ftmp%2Fpg.sock&sslmode=false", }, { Host: "localhost", @@ -82,7 +85,7 @@ func Test_getPostgreSQLConnectionString(t *testing.T) { Name: "gitea", Param: "", SSLMode: "true", - Output: "postgres://pgsqlusername:I%20love%20Gitea%21@localhost:5432/giteasslmode=true", + Output: "postgres://pgsqlusername:I%20love%20Gitea%21@localhost:5432/gitea?sslmode=true", }, } diff --git a/modules/setting/storage.go b/modules/setting/storage.go index cc3a2899d76..f937c7cff39 100644 --- a/modules/setting/storage.go +++ b/modules/setting/storage.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "path/filepath" + "strings" ) // StorageType is a type of Storage @@ -249,14 +250,24 @@ func getStorageForMinio(targetSec, overrideSec ConfigSection, tp targetSecType, return nil, fmt.Errorf("map minio config failed: %v", err) } - if storage.MinioConfig.BasePath == "" { - storage.MinioConfig.BasePath = name + "/" + var defaultPath string + if storage.MinioConfig.BasePath != "" { + if tp == targetSecIsStorage || tp == targetSecIsDefault { + defaultPath = strings.TrimSuffix(storage.MinioConfig.BasePath, "/") + "/" + name + "/" + } else { + defaultPath = storage.MinioConfig.BasePath + } + } + if defaultPath == "" { + defaultPath = name + "/" } if overrideSec != nil { storage.MinioConfig.ServeDirect = ConfigSectionKeyBool(overrideSec, "SERVE_DIRECT", storage.MinioConfig.ServeDirect) - storage.MinioConfig.BasePath = ConfigSectionKeyString(overrideSec, "MINIO_BASE_PATH", storage.MinioConfig.BasePath) + storage.MinioConfig.BasePath = ConfigSectionKeyString(overrideSec, "MINIO_BASE_PATH", defaultPath) storage.MinioConfig.Bucket = ConfigSectionKeyString(overrideSec, "MINIO_BUCKET", storage.MinioConfig.Bucket) + } else { + storage.MinioConfig.BasePath = defaultPath } return &storage, nil } diff --git a/modules/setting/storage_test.go b/modules/setting/storage_test.go index 20886d4c4e9..6f38bf1d557 100644 --- a/modules/setting/storage_test.go +++ b/modules/setting/storage_test.go @@ -412,3 +412,56 @@ MINIO_USE_SSL = true assert.EqualValues(t, true, RepoArchive.Storage.MinioConfig.UseSSL) assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) } + +func Test_getStorageConfiguration28(t *testing.T) { + cfg, err := NewConfigProviderFromData(` +[storage] +STORAGE_TYPE = minio +MINIO_ACCESS_KEY_ID = my_access_key +MINIO_SECRET_ACCESS_KEY = my_secret_key +MINIO_USE_SSL = true +MINIO_BASE_PATH = /prefix +`) + assert.NoError(t, err) + assert.NoError(t, loadRepoArchiveFrom(cfg)) + assert.EqualValues(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID) + assert.EqualValues(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey) + assert.EqualValues(t, true, RepoArchive.Storage.MinioConfig.UseSSL) + assert.EqualValues(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) + + cfg, err = NewConfigProviderFromData(` +[storage] +STORAGE_TYPE = minio +MINIO_ACCESS_KEY_ID = my_access_key +MINIO_SECRET_ACCESS_KEY = my_secret_key +MINIO_USE_SSL = true +MINIO_BASE_PATH = /prefix + +[lfs] +MINIO_BASE_PATH = /lfs +`) + assert.NoError(t, err) + assert.NoError(t, loadLFSFrom(cfg)) + assert.EqualValues(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID) + assert.EqualValues(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey) + assert.EqualValues(t, true, LFS.Storage.MinioConfig.UseSSL) + assert.EqualValues(t, "/lfs", LFS.Storage.MinioConfig.BasePath) + + cfg, err = NewConfigProviderFromData(` +[storage] +STORAGE_TYPE = minio +MINIO_ACCESS_KEY_ID = my_access_key +MINIO_SECRET_ACCESS_KEY = my_secret_key +MINIO_USE_SSL = true +MINIO_BASE_PATH = /prefix + +[storage.lfs] +MINIO_BASE_PATH = /lfs +`) + assert.NoError(t, err) + assert.NoError(t, loadLFSFrom(cfg)) + assert.EqualValues(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID) + assert.EqualValues(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey) + assert.EqualValues(t, true, LFS.Storage.MinioConfig.UseSSL) + assert.EqualValues(t, "/lfs", LFS.Storage.MinioConfig.BasePath) +} diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go index 37624ab679c..f8e4f569b87 100644 --- a/modules/ssh/ssh.go +++ b/modules/ssh/ssh.go @@ -17,7 +17,6 @@ import ( "os" "os/exec" "path/filepath" - "reflect" "strconv" "strings" "sync" @@ -165,10 +164,6 @@ func sessionHandler(session ssh.Session) { } func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { - // FIXME: the "ssh.Context" is not thread-safe, so db operations should use the immutable parent "Context" - // TODO: Remove after https://github.com/gliderlabs/ssh/pull/211 - parentCtx := reflect.ValueOf(ctx).Elem().FieldByName("Context").Interface().(context.Context) - if log.IsDebug() { // <- FingerprintSHA256 is kinda expensive so only calculate it if necessary log.Debug("Handle Public Key: Fingerprint: %s from %s", gossh.FingerprintSHA256(key), ctx.RemoteAddr()) } @@ -200,7 +195,7 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { // look for the exact principal principalLoop: for _, principal := range cert.ValidPrincipals { - pkey, err := asymkey_model.SearchPublicKeyByContentExact(parentCtx, principal) + pkey, err := asymkey_model.SearchPublicKeyByContentExact(ctx, principal) if err != nil { if asymkey_model.IsErrKeyNotExist(err) { log.Debug("Principal Rejected: %s Unknown Principal: %s", ctx.RemoteAddr(), principal) @@ -257,7 +252,7 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { log.Debug("Handle Public Key: %s Fingerprint: %s is not a certificate", ctx.RemoteAddr(), gossh.FingerprintSHA256(key)) } - pkey, err := asymkey_model.SearchPublicKeyByContent(parentCtx, strings.TrimSpace(string(gossh.MarshalAuthorizedKey(key)))) + pkey, err := asymkey_model.SearchPublicKeyByContent(ctx, strings.TrimSpace(string(gossh.MarshalAuthorizedKey(key)))) if err != nil { if asymkey_model.IsErrKeyNotExist(err) { log.Warn("Unknown public key: %s from %s", gossh.FingerprintSHA256(key), ctx.RemoteAddr()) diff --git a/modules/structs/package.go b/modules/structs/package.go index 0059535bea8..a9a9429de2d 100644 --- a/modules/structs/package.go +++ b/modules/structs/package.go @@ -16,6 +16,7 @@ type Package struct { Type string `json:"type"` Name string `json:"name"` Version string `json:"version"` + HTMLURL string `json:"html_url"` // swagger:strfmt date-time CreatedAt time.Time `json:"created_at"` } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index a023d8fee3e..c64c97859bc 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -110,9 +110,6 @@ write = Write preview = Preview loading = Loading… -step1 = Step 1: -step2 = Step 2: - error = Error error404 = The page you are trying to reach either does not exist or you are not authorized to view it. go_back = Go Back @@ -729,7 +726,7 @@ add_email_success = The new email address has been added. email_preference_set_success = Email preference has been set successfully. add_openid_success = The new OpenID address has been added. keep_email_private = Hide Email Address -keep_email_private_popup = This will hide your email address from your profile, as well as when you make a pull request or edit a file using the web interface. Pushed commits will not be modified. +keep_email_private_popup = This will hide your email address from your profile, as well as when you make a pull request or edit a file using the web interface. Pushed commits will not be modified. Use %s in commits to associate them with your account. openid_desc = OpenID lets you delegate authentication to an external provider. manage_ssh_keys = Manage SSH Keys @@ -1792,6 +1789,8 @@ pulls.status_checks_failure = Some checks failed pulls.status_checks_error = Some checks reported errors pulls.status_checks_requested = Required pulls.status_checks_details = Details +pulls.status_checks_hide_all = Hide all checks +pulls.status_checks_show_all = Show all checks pulls.update_branch = Update branch by merge pulls.update_branch_rebase = Update branch by rebase pulls.update_branch_success = Branch update was successful @@ -1800,9 +1799,11 @@ pulls.outdated_with_base_branch = This branch is out-of-date with the base branc pulls.close = Close Pull Request pulls.closed_at = `closed this pull request %[2]s` pulls.reopened_at = `reopened this pull request %[2]s` -pulls.merge_instruction_hint = `You can also view command line instructions.` -pulls.merge_instruction_step1_desc = From your project repository, check out a new branch and test the changes. -pulls.merge_instruction_step2_desc = Merge the changes and update on Gitea. +pulls.cmd_instruction_hint = `View command line instructions.` +pulls.cmd_instruction_checkout_title = Checkout +pulls.cmd_instruction_checkout_desc = From your project repository, check out a new branch and test the changes. +pulls.cmd_instruction_merge_title = Merge +pulls.cmd_instruction_merge_desc = Merge the changes and update on Gitea. pulls.clear_merge_message = Clear merge message pulls.clear_merge_message_hint = Clearing the merge message will only remove the commit message content and keep generated git trailers such as "Co-Authored-By …". @@ -2860,7 +2861,7 @@ emails.updated = Email updated emails.not_updated = Failed to update the requested email address: %v emails.duplicate_active = This email address is already active for a different user. emails.change_email_header = Update Email Properties -emails.change_email_text = Are your sure you want to update this email address? +emails.change_email_text = Are you sure you want to update this email address? orgs.org_manage_panel = Organization Management orgs.name = Name @@ -3351,8 +3352,6 @@ alpine.repository.repositories = Repositories alpine.repository.architectures = Architectures cargo.registry = Setup this registry in the Cargo configuration file (for example ~/.cargo/config.toml): cargo.install = To install the package using Cargo, run the following command: -cargo.details.repository_site = Repository Site -cargo.details.documentation_site = Documentation Site chef.registry = Setup this registry in your ~/.chef/config.rb file: chef.install = To install the package, run the following command: composer.registry = Setup this registry in your ~/.composer/config.json file: @@ -3364,8 +3363,6 @@ conan.registry = Setup this registry from the command line: conan.install = To install the package using Conan, run the following command: conda.registry = Setup this registry as a Conda repository in your .condarc file: conda.install = To install the package using Conda, run the following command: -conda.details.repository_site = Repository Site -conda.details.documentation_site = Documentation Site container.details.type = Image Type container.details.platform = Platform container.pull = Pull the image from the command line: diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 8b63b3665aa..ebde7e5baeb 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -456,7 +456,7 @@ issue_assigned.pull=@%[1]s vous a assigné à la demande d’ajout %[2]s dans le issue_assigned.issue=@%[1]s vous a assigné le ticket %[2]s dans le dépôt %[3]s. issue.x_mentioned_you=@%s vous a mentionné: -issue.action.force_push=%[1]s a forcé la mise à jour de %[2]s depuis %[3]s vers %[4]s. +issue.action.force_push=%[1]s a forcé %[2]s de %[3]s vers %[4]s. issue.action.push_1=@%[1]s a soumis %[3]d révision sur %[2]s issue.action.push_n=@%[1]s a soumis %[3]d révisions sur %[2]s issue.action.close=@%[1]s a fermé #%[2]d. @@ -856,7 +856,7 @@ oauth2_client_secret_hint=Le secret ne sera plus affiché après avoir quitté o oauth2_application_edit=Éditer oauth2_application_create_description=Les applications OAuth2 permettent à votre application tierce d'accéder aux comptes d'utilisateurs de cette instance. oauth2_application_remove_description=La suppression d'une application OAuth2 l'empêchera d'accéder aux comptes d'utilisateurs autorisés sur cette instance. Poursuivre ? -oauth2_application_locked=Gitea préinstalle des applications OAuth2 au démarrage si elles sont activées dans la configuration. Pour éviter des comportements inattendus, celles-ci ne peuvent ni être éditées ni supprimées. Veuillez vous référer à la documentation OAuth2 pour plus d'informations. +oauth2_application_locked=Gitea préinstalle des applications OAuth2 au démarrage si elles sont activées dans la configuration. Pour éviter des comportements inattendus, celles-ci ne peuvent être éditées ni supprimées. Veuillez vous référer à la documentation OAuth2 pour plus d'informations. authorized_oauth2_applications=Applications OAuth2 autorisées authorized_oauth2_applications_description=Vous avez autorisé l'accès à votre compte personnel Gitea à ces applications tierces. Veuillez révoquer l'accès aux applications dont vous n'avez plus besoin. @@ -937,7 +937,7 @@ template_description=Les référentiels de modèles permettent aux utilisateurs visibility=Visibilité visibility_description=Seuls le propriétaire ou les membres de l'organisation, s'ils ont des droits, seront en mesure de le voir. visibility_helper=Rendre le dépôt privé -visibility_helper_forced=L'administrateur de votre serveur impose que les nouveaux dépôts soient privés. +visibility_helper_forced=L’administrateur requière que les nouveaux dépôts soient privés. visibility_fork_helper=(Changer ceci affectera toutes les bifurcations.) clone_helper=Besoin d'aide pour dupliquer ? Visitez l'aide. fork_repo=Bifurquer le dépôt @@ -1595,7 +1595,7 @@ issues.error_modifying_due_date=Impossible de modifier l'échéance. issues.error_removing_due_date=Impossible de supprimer l'échéance. issues.push_commit_1=a ajouté %d révision %s issues.push_commits_n=a ajouté %d révisions %s -issues.force_push_codes=`a forcé la soumission de %[1]s depuis %[2]s à %[4]s %[6]s.` +issues.force_push_codes=`a forcé %[1]s de %[2]s à %[4]s %[6]s.` issues.force_push_compare=Comparer issues.due_date_form=aaaa-mm-jj issues.due_date_form_add=Ajouter une échéance @@ -1725,7 +1725,7 @@ pulls.manually_merged=Fusionné manuellement pulls.merged_info_text=La branche %s peut maintenant être supprimée. pulls.is_closed=La demande d’ajout a été fermée. pulls.title_wip_desc=`Préfixer le titre par %s pour empêcher cette demande d'ajout d'être fusionnée par erreur.` -pulls.cannot_merge_work_in_progress=Cette demande d'ajout est marquée comme en cours de chantier. +pulls.cannot_merge_work_in_progress=Cette demande d’ajout est en chantier. pulls.still_in_progress=Toujours en cours ? pulls.add_prefix=Ajouter le préfixe %s pulls.remove_prefix=Enlever le préfixe %s @@ -1758,7 +1758,7 @@ pulls.wrong_commit_id=l'ID de la révision doit être un ID de révision sur la pulls.no_merge_desc=Cette demande d’ajout ne peut être fusionnée car toutes les options de fusion du dépôt sont désactivées. pulls.no_merge_helper=Activez des options de fusion dans les paramètres du dépôt ou fusionnez la demande manuellement. -pulls.no_merge_wip=Cette demande d'ajout ne peut pas être fusionnée car elle est marquée comme en cours de chantier. +pulls.no_merge_wip=Cette demande d’ajout ne peut pas être fusionnée car elle est marquée en chantier. pulls.no_merge_not_ready=Cette demande d’ajout n’est pas prête à être fusionnée, vérifiez les évaluations en cours et le contrôle qualité. pulls.no_merge_access=Vous n'êtes pas autorisé⋅e à fusionner cette demande d'ajout. pulls.merge_pull_request=Créer une révision de fusion @@ -2278,11 +2278,11 @@ settings.protect_this_branch_desc=Empêche les suppressions et limite les pouss settings.protect_disable_push=Désactiver la soumission settings.protect_disable_push_desc=Aucune soumission ne sera possible sur cette branche. settings.protect_enable_push=Activer la soumission -settings.protect_enable_push_desc=Toute personne ayant un accès en écriture sera autorisée à soumettre sur cette branche (mais pas de soumission de force). +settings.protect_enable_push_desc=Toute personne ayant un accès en écriture sera autorisée à soumettre sur cette branche (sans forcer). settings.protect_enable_merge=Activer la fusion settings.protect_enable_merge_desc=Toute personne ayant un accès en écriture sera autorisée à fusionner les demandes d'ajout dans cette branche. settings.protect_whitelist_committers=Liste blanche des soumissions -settings.protect_whitelist_committers_desc=Seuls les utilisateurs ou les équipes autorisés pourront soumettre sur cette branche (mais pas de soumission de force). +settings.protect_whitelist_committers_desc=Seuls les utilisateurs ou les équipes autorisés pourront soumettre sur cette branche (sans forcer). settings.protect_whitelist_deploy_keys=Mettez les clés de déploiement sur liste blanche avec accès en écriture pour soumettre. settings.protect_whitelist_users=Utilisateurs sur liste blanche : settings.protect_whitelist_search_users=Rechercher des utilisateurs… @@ -3404,8 +3404,8 @@ rubygems.install=Pour installer le paquet en utilisant gem, exécutez la command rubygems.install2=ou ajoutez-le au Gemfile : rubygems.dependencies.runtime=Dépendances d'exécution rubygems.dependencies.development=Dépendances de développement -rubygems.required.ruby=Nécessite la version de Ruby -rubygems.required.rubygems=Nécessite la version de RubyGem +rubygems.required.ruby=Nécessite Ruby en version +rubygems.required.rubygems=Nécessite RubyGem en version swift.registry=Configurez ce registre à partir d'un terminal : swift.install=Ajoutez le paquet dans votre fichier Package.swift: swift.install2=et exécutez la commande suivante : @@ -3460,7 +3460,7 @@ description=Les secrets seront transmis à certaines actions et ne pourront pas none=Il n'y a pas encore de secrets. creation=Ajouter un secret creation.name_placeholder=Caractères alphanumériques ou tirets bas uniquement, insensibles à la casse, ne peut commencer par GITEA_ ou GITHUB_. -creation.value_placeholder=Entrez n'importe quoi. Les blancs cernant seront taillés. +creation.value_placeholder=Entrez n’importe quoi. Les blancs cernant seront taillés. creation.success=Le secret "%s" a été ajouté. creation.failed=Impossible d'ajouter le secret. deletion=Supprimer le secret diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index db9014f4b00..302ff934667 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -4,6 +4,7 @@ explore=Explorar help=Ajuda logo=Logotipo sign_in=Acessar +sign_in_with_provider=Entrar com %s sign_in_or=ou sign_out=Sair sign_up=Cadastrar @@ -79,6 +80,7 @@ milestones=Marcos ok=Ok cancel=Cancelar +retry=Tentar novamente rerun=Reexecutar rerun_all=Reexecutar todas as tarefas save=Salvar @@ -91,6 +93,7 @@ edit=Editar enabled=Habilitado disabled=Desabilitado +locked=Bloqueado copy=Copiar copy_url=Copiar URL @@ -130,7 +133,9 @@ concept_user_organization=Organização show_timestamps=Mostrar data/hora show_log_seconds=Mostrar segundos show_full_screen=Mostrar tela cheia +download_logs=Baixar logs +confirm_delete_selected=Confirma a exclusão de todos os itens selecionados? name=Nome value=Valor @@ -169,6 +174,7 @@ string.desc=Z - A [error] occurred=Ocorreu um erro +report_message=Se você acredita que esse é um falha do Gitea, pesquise por issues no GitHub ou abra uma nova issue, se necessário. missing_csrf=Pedido inválido: não tem token CSRF presente invalid_csrf=Requisição Inválida: token CSRF inválido not_found=Não foi possível encontrar o destino. @@ -221,6 +227,7 @@ repo_path_helper=Todos os repositórios remotos do Git serão salvos neste diret lfs_path=Caminho raiz do Git LFS lfs_path_helper=Os arquivos armazenados com o Git LFS serão armazenados neste diretório. Deixe em branco para desabilitar. run_user=Executar como nome de usuário +run_user_helper=O nome de usuário do sistema operacional com o qual o Gitea é executado. Observe que este usuário deve ter acesso ao caminho da raiz do repositório. domain=Domínio do servidor domain_helper=Domínio ou endereço de host para o servidor. ssh_port=Porta do servidor SSH @@ -292,6 +299,8 @@ invalid_password_algorithm=Algoritmo de hash de senha inválido password_algorithm_helper=Escolha o algoritmo de hash para as senhas. Diferentes algoritmos têm requerimentos e forças diversos. O algoritmo argon2 é bastante seguro, mas usa muita memória e pode ser inapropriado para sistemas com menos recursos. enable_update_checker=Habilitar Verificador de Atualizações enable_update_checker_helper=Procura por novas versões periodicamente conectando-se ao gitea.io. +env_config_keys=Configuração do ambiente +env_config_keys_prompt=As seguintes variáveis de ambiente também serão aplicadas ao seu arquivo de configuração: [home] uname_holder=Usuário ou e-mail @@ -354,6 +363,7 @@ remember_me=Lembrar deste Dispositivo forgot_password_title=Esqueci minha senha forgot_password=Esqueceu sua senha? sign_up_now=Precisa de uma conta? Cadastre-se agora. +sign_up_successful=A conta foi criada com sucesso. Bem-vindo! confirmation_mail_sent_prompt=Um novo e-mail de confirmação foi enviado para %s. Por favor, verifique sua caixa de e-mail nas próximas %s horas para finalizar o processo de cadastro. must_change_password=Redefina sua senha allow_password_change=Exigir que o usuário redefina a senha (recomendado) @@ -361,6 +371,7 @@ reset_password_mail_sent_prompt=Um e-mail de confirmação foi enviado para % active_your_account=Ativar sua conta account_activated=Conta foi ativada prohibit_login=Acesso proibido +prohibit_login_desc=Sua conta está proibida de fazer login, entre em contato com o administrador do site. resent_limit_prompt=Você já solicitou recentemente um e-mail de ativação. Por favor, aguarde 3 minutos e tente novamente. has_unconfirmed_mail=Oi %s, você possui um endereço de e-mail não confirmado (%s). Se você não recebeu um e-mail de confirmação ou precisa reenviar um novo, clique no botão abaixo. resend_mail=Clique aqui para reenviar seu e-mail de ativação @@ -368,8 +379,10 @@ email_not_associate=O endereço de e-mail não está associado à nenhuma conta. send_reset_mail=Enviar e-mail de recuperação de conta reset_password=Recuperação de conta invalid_code=Seu código de confirmação é inválido ou expirou. +invalid_code_forgot_password=Seu código de confirmação expirou ou está inválido. Clique aqui para iniciar uma nova sessão. invalid_password=Sua senha não coincide com a senha que foi usada para criar a conta. reset_password_helper=Recuperar conta +reset_password_wrong_user=Você está conectado como %s, mas o link de recuperação de conta é destinado a %s password_too_short=A senha deve ter %d ou mais caracteres. non_local_account=Usuários não-locais não podem atualizar sua senha através da interface web do Gitea. verify=Verificar @@ -394,6 +407,7 @@ openid_connect_title=Conectar à uma conta existente openid_connect_desc=O URI do OpenID escolhido é desconhecido. Associe-o com uma nova conta aqui. openid_register_title=Criar uma nova conta openid_register_desc=O URI do OpenID escolhido é desconhecido. Associe-o com uma nova conta aqui. +openid_signin_desc=Digite o URI do seu OpenID. Por exemplo: alice.openid.example.org ou https://openid.example.org/alice. disable_forgot_password_mail=A recuperação de conta está desativada porque nenhum e-mail está configurado. Por favor, contate o administrador do site. disable_forgot_password_mail_admin=A recuperação de conta só está disponível quando o e-mail está configurado. Por favor, configure o e-mail para permitir a recuperação de conta. email_domain_blacklisted=Você não pode se cadastrar com seu endereço de e-mail. @@ -403,7 +417,9 @@ authorize_application_created_by=Este aplicativo foi criado por %s. authorize_application_description=Se você conceder o acesso, ele será capaz de acessar e escrever em todas as informações da sua conta, incluindo repositórios privados e organizações. authorize_title=Autorizar "%s" para acessar sua conta? authorization_failed=Autorização falhou +authorization_failed_desc=A autorização falhou porque detectamos uma solicitação inválida. Entre em contato com o responsável do aplicativo que você tentou autorizar. sspi_auth_failed=Falha de autenticação SSPI +password_pwned=A senha que você escolheu faz parte de uma lista de senhas roubadas expostas anteriormente em violações de dados. Tente novamente com uma senha diferente e considere alterar essa senha em outro lugar também. password_pwned_err=Não foi possível concluir a requisição ao HaveIBeenPwned [mail] @@ -418,6 +434,7 @@ activate_account.text_1=Olá %[1]s, obrigado por se registrar em %[2]s! activate_account.text_2=Por favor clique no link a seguir para ativar sua conta em %s: activate_email=Verifique seu endereço de e-mail +activate_email.title=%s, por favor verifique o seu endereço de e-mail activate_email.text=Por favor clique no link a seguir para verificar o seu endereço de e-mail em %s: register_notify=Bem-vindo ao Gitea @@ -587,6 +604,8 @@ user_bio=Biografia disabled_public_activity=Este usuário desativou a visibilidade pública da atividade. email_visibility.limited=Seu endereço de e-mail está visível para todos os usuários autenticados email_visibility.private=Seu endereço de e-mail é visível apenas para você e administradores +show_on_map=Mostrar este lugar em um mapa +settings=Configurações do usuário form.name_reserved=O nome de usuário "%s" está reservado. form.name_pattern_not_allowed=O padrão de "%s" não é permitido em um nome de usuário. @@ -608,9 +627,13 @@ delete=Excluir conta twofa=Autenticação de dois fatores account_link=Contas vinculadas organization=Organizações +uid=UID webauthn=Chaves de segurança public_profile=Perfil público +biography_placeholder=Conte-nos um pouco sobre você! (Você pode usar Markdown) +location_placeholder=Compartilhe sua localização aproximada com outras pessoas +profile_desc=Controle como o seu perfil é exibido para outros usuários. Seu endereço de e-mail principal será usado para notificações, recuperação de senha e operações do Git baseadas na Web. password_username_disabled=Usuários não-locais não podem alterar seus nomes de usuário. Por favor contate o administrador do site para mais informações. full_name=Nome completo website=Site @@ -622,6 +645,8 @@ update_language_not_found=Idioma "%s" não está disponível. update_language_success=O idioma foi atualizado. update_profile_success=Seu perfil foi atualizado. change_username=Seu nome de usuário foi alterado. +change_username_prompt=Observação: a alteração do seu nome de usuário também altera o URL da sua conta. +change_username_redirect_prompt=O nome de usuário antigo irá redirecionar até que alguém comece a usá-lo. continue=Continuar cancel=Cancelar language=Idioma @@ -646,6 +671,7 @@ comment_type_group_project=Projeto comment_type_group_issue_ref=Referência do issue saved_successfully=Suas configurações foram salvas com sucesso. privacy=Privacidade +keep_activity_private=Ocultar atividade da página de perfil keep_activity_private_popup=Torna a atividade visível somente para você e os administradores lookup_avatar_by_mail=Procurar o avatar do endereço de e-mail @@ -655,12 +681,14 @@ choose_new_avatar=Escolha um novo avatar update_avatar=Atualizar o avatar delete_current_avatar=Excluir o avatar atual uploaded_avatar_not_a_image=O arquivo enviado não é uma imagem. +uploaded_avatar_is_too_big=O tamanho do arquivo enviado (%d KiB) excede o tamanho máximo permitido (%d KiB). update_avatar_success=Seu avatar foi atualizado. update_user_avatar_success=O avatar do usuário foi atualizado. change_password=Atualizar senha old_password=Senha atual new_password=Nova senha +retype_new_password=Confirmar nova senha password_incorrect=A senha atual está incorreta. change_password_success=Sua senha foi atualizada. Acesse usando sua nova senha de agora em diante. password_change_disabled=Contas não-locais não podem alterar sua senha através da interface web do Gitea. @@ -669,6 +697,7 @@ emails=Endereços de e-mail manage_emails=Gerenciar endereços de e-mail manage_themes=Selecione o tema padrão manage_openid=Gerencia endereços OpenID +email_desc=Seu endereço de e-mail principal será usado para notificações, recuperação de senha e, desde que não esteja oculto, para operações do Git baseadas na Web. theme_desc=Este será o seu tema padrão em todo o site. primary=Principal activated=Ativado @@ -676,6 +705,7 @@ requires_activation=Requer ativação primary_email=Tornar Principal activate_email=Enviar Ativação activations_pending=Ativações pendentes +can_not_add_email_activations_pending=Há uma ativação pendente, tente novamente em alguns minutos se quiser adicionar um novo e-mail. delete_email=Remover email_deletion=Remover endereço de e-mail email_deletion_desc=O endereço de e-mail e informações relacionadas serão removidos de sua conta. Commits aplicados por este endereço de e-mail permanecerão inalterados. Continuar? @@ -694,6 +724,7 @@ add_email_success=O novo endereço de e-mail foi adicionado. email_preference_set_success=Preferência de e-mail definida com sucesso. add_openid_success=O novo endereço de OpenID foi adicionado. keep_email_private=Ocultar endereço de e-mail +keep_email_private_popup=Isso ocultará seu endereço de e-mail do seu perfil, bem como quando você fizer um pull request ou editar um arquivo usando a interface Web. Os commits enviados não serão modificados. openid_desc=OpenID permite delegar autenticação para um provedor externo. manage_ssh_keys=Gerenciar Chaves SSH @@ -772,7 +803,9 @@ ssh_disabled=SSH desabilitado ssh_signonly=O SSH está desativado no momento, portanto, essas chaves são usadas apenas para verificação de assinatura de confirmação. ssh_externally_managed=Esta chave SSH para este usuário é gerenciada externamente manage_social=Gerenciar contas sociais associadas +social_desc=Essas contas sociais podem ser usadas para fazer login em sua conta. Certifique-se de reconhecer todas elas. unbind=Desvincular +unbind_success=A conta social foi removida com sucesso. manage_access_token=Gerenciar tokens de acesso generate_new_token=Gerar novo token @@ -791,8 +824,9 @@ repo_and_org_access=Acesso ao Repositório e Organização permissions_public_only=Apenas público permissions_access_all=Todos (público, privado e limitado) select_permissions=Selecionar permissões -permission_no_access=Sem Acesso -permission_read=Lidas +permission_no_access=Sem acesso +permission_read=Ler +permission_write=Ler e escrever at_least_one_permission=Você deve selecionar pelo menos uma permissão para criar um token permissions_list=Permissões: @@ -804,6 +838,8 @@ remove_oauth2_application_desc=Remover um aplicativo OAuth2 irá revogar o acess remove_oauth2_application_success=O aplicativo foi excluído. create_oauth2_application=Criar um novo aplicativo OAuth2 create_oauth2_application_button=Criar aplicativo +create_oauth2_application_success=Você criou um aplicativo OAuth2 com sucesso. +update_oauth2_application_success=Você atualizou o aplicativo OAuth2 com sucesso. oauth2_application_name=Nome do aplicativo oauth2_confidential_client=Cliente Confidencial. Selecione para aplicativos que mantêm a confidencialidade do segredo, como aplicativos web. Não selecione para aplicativos nativos, incluindo aplicativos desktop e celulares. oauth2_redirect_uris=URIs de redirecionamento. Por favor use uma nova linha para cada URI. @@ -812,19 +848,25 @@ oauth2_client_id=Client ID oauth2_client_secret=Client Secret oauth2_regenerate_secret=Gerar novamente o Client Secret oauth2_regenerate_secret_hint=Perdeu seu Client Secret? +oauth2_client_secret_hint=O segredo não será exibido novamente depois que você sair ou atualizar esta página. Certifique-se de que você o salvou. oauth2_application_edit=Editar oauth2_application_create_description=Os aplicativos OAuth2 fornecem ao seus aplicativos de terceiros acesso a contas de usuário nesta instância. +oauth2_application_remove_description=A remoção de um aplicativo OAuth2 impedirá que ele acesse contas de usuários autorizados nesta instância. Continuar? +oauth2_application_locked=O Gitea pré-registra alguns aplicativos OAuth2 na inicialização, se habilitados na configuração. Para evitar um comportamento inesperado, eles não podem ser editados nem removidos. Consulte a documentação do OAuth2 para obter mais informações. authorized_oauth2_applications=Aplicações OAuth2 autorizadas +authorized_oauth2_applications_description=Você concedeu acesso à sua conta pessoal da Gitea para esses aplicativos de terceiros. Revogue o acesso aos aplicativos de que não precisa mais. revoke_key=Revogar revoke_oauth2_grant=Revogar acesso revoke_oauth2_grant_description=Revogando o acesso para este aplicativo de terceiros impedirá este aplicativo de acessar seus dados. Tem certeza? +revoke_oauth2_grant_success=Acesso revogado com sucesso. twofa_desc=Autenticação de dois fatores melhora a segurança de sua conta. twofa_is_enrolled=Sua conta está atualmente habilitada com autenticação de dois fatores. twofa_not_enrolled=Sua conta não está atualmente inscrita para a autenticação em duas etapas. twofa_disable=Desabilitar a autenticação de dois fatores twofa_scratch_token_regenerate=Gerar novamente o token de backup +twofa_scratch_token_regenerated=Seu token agora é %s. Guarde-a em um local seguro, pois ela nunca mais será exibido. twofa_enroll=Inscrever para a autenticação de dois fatores twofa_disable_note=Você pode desabilitar a autenticação de dois fatores se necessário. twofa_disable_desc=Desabilitar a autenticação de dois fatores tornará sua conta menos segura. Tem certeza que deseja continuar? @@ -851,8 +893,10 @@ remove_account_link=Remover conta vinculada remove_account_link_desc=A exclusão da chave SSH revogará o acesso à sua conta. Continuar? remove_account_link_success=A conta vinculada foi removida. +hooks.desc=Adicione webhooks que serão acionados para todos os repositórios que você possui. orgs_none=Você não é membro de nenhuma organização. +repos_none=Você não é proprietário de nenhum repositório. delete_account=Excluir sua conta delete_prompt=Esta operação irá apagar permanentemente a sua conta de usuário. Isto NÃO PODERÁ ser desfeito. @@ -871,9 +915,12 @@ visibility=Visibilidade do usuário visibility.public=Pública visibility.public_tooltip=Visível para todos visibility.limited=Limitada +visibility.limited_tooltip=Visível apenas para usuários autenticados visibility.private=Privada +visibility.private_tooltip=Visível apenas para membros das organizações às quais você se associou [repo] +new_repo_helper=Um repositório contém todos os arquivos do projeto, inclusive o histórico de revisões. Já está hospedando um em outro lugar? Migre o repositório. owner=Proprietário owner_helper=Algumas organizações podem não aparecer no menu devido a um limite de contagem dos repositórios. repo_name=Nome do repositório @@ -885,6 +932,7 @@ template_helper=Tornar repositório um modelo template_description=Os repositórios de modelo permitem que os usuários gerem novos repositórios com a mesma estrutura de diretório, arquivos e configurações opcionais. visibility=Visibilidade visibility_description=Somente o proprietário ou os membros da organização, se tiverem direitos, poderão vê-lo. +visibility_helper=Tornar o repositório privado visibility_helper_forced=O administrador do site força novos repositórios a serem privados. visibility_fork_helper=(Esta alteração irá afetar todos os forks.) clone_helper=Precisa de ajuda com o clone? Visite a Ajuda. @@ -893,6 +941,7 @@ fork_from=Fork de already_forked=Você já fez o fork de %s fork_to_different_account=Faça um fork para uma conta diferente fork_visibility_helper=A visibilidade do fork de um repositório não pode ser alterada. +fork_no_valid_owners=Não é possível fazer um fork desse repositório porque não há proprietários validos. use_template=Usar este modelo clone_in_vsc=Clonar no VS Code download_zip=Baixar ZIP @@ -921,6 +970,7 @@ trust_model_helper_collaborator_committer=Colaborador+Committer: Confiar em assi trust_model_helper_default=Padrão: Usar o modelo de confiança padrão para esta instalação create_repo=Criar repositório default_branch=Branch Padrão +default_branch_label=padrão default_branch_helper=O branch padrão é o branch base para pull requests e commits de código. mirror_prune=Varrer mirror_prune_desc=Remover referências obsoletas de controle remoto @@ -929,6 +979,8 @@ mirror_interval_invalid=O intervalo do espelhamento não é válido. mirror_sync_on_commit=Sincronizar quando commits forem enviados mirror_address=Clonar de URL mirror_address_desc=Coloque todas as credenciais necessárias na seção de autorização. +mirror_address_url_invalid=O URL fornecido é inválido. Você deve escapar todos os componentes do URL corretamente. +mirror_address_protocol_invalid=O URL fornecido é inválido. Somente locais http(s):// ou git:// podem ser usados para espelhamento. mirror_lfs=Armazenamento de Arquivo Grande (LFS) mirror_lfs_desc=Ativar espelhamento de dados LFS. mirror_lfs_endpoint=Destino LFS @@ -961,6 +1013,8 @@ transfer.accept=Aceitar transferência transfer.accept_desc=`Transferir para "%s"` transfer.reject=Rejeitar transferência transfer.reject_desc=`Cancelar a transferência para "%s"` +transfer.no_permission_to_accept=Você não tem permissão para aceitar essa transferência. +transfer.no_permission_to_reject=Você não tem permissão para rejeitar essa transferência. desc.private=Privado desc.public=Público @@ -981,6 +1035,8 @@ template.issue_labels=Etiquetas de issue template.one_item=Deve-se selecionar pelo menos um item de modelo template.invalid=Deve-se selecionar um repositório de modelo +archive.title=Este repositório está arquivado. Você pode visualizar arquivos e cloná-lo, mas não pode fazer push, abrir issues ou pull requests. +archive.title_date=Este repositório foi arquivado em %s. Você pode visualizar arquivos e cloná-lo, mas não pode fazer push, abrir issues ou pull requests. archive.issue.nocomment=Este repositório está arquivado. Você não pode comentar nas issues. archive.pull.nocomment=Este repositório está arquivado. Você não pode comentar nos pull requests. @@ -997,6 +1053,7 @@ migrate_options_lfs=Migrar arquivos LFS migrate_options_lfs_endpoint.label=Destino LFS migrate_options_lfs_endpoint.description=A migração tentará usar seu controle remoto Git para determinar o servidor LFS. Você também pode especificar um destino personalizado se os dados do repositório LFS forem armazenados em outro lugar. migrate_options_lfs_endpoint.description.local=Um caminho de servidor local também é suportado. +migrate_options_lfs_endpoint.placeholder=Se for deixado em branco, o endpoint será derivado do URL do clone migrate_items=Itens da migração migrate_items_wiki=Wiki migrate_items_milestones=Marcos @@ -1099,6 +1156,10 @@ file_view_rendered=Ver Renderizado file_view_raw=Ver original file_permalink=Link permanente file_too_large=O arquivo é muito grande para ser mostrado. +invisible_runes_header=`Este arquivo contém caracteres Unicode invisíveis` +invisible_runes_description=`Este arquivo contém caracteres Unicode invisíveis que são indistinguíveis para humanos, mas que podem ser processados de forma diferente por um computador. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los +ambiguous_runes_header=`Este arquivo contém caracteres Unicode ambíguos` +ambiguous_runes_description=`Este arquivo contém caracteres Unicode que podem ser confundidos com outros caracteres. Se você acha que isso é intencional, pode ignorar esse aviso com segurança. Use o botão Escapar para revelá-los invisible_runes_line=`Esta linha tem caracteres unicode invisíveis` ambiguous_runes_line=`Esta linha tem caracteres unicode ambíguos` ambiguous_character=`%[1]c [U+%04[1]X] é confundível com o %[2]c [U+%04[2]X]` @@ -1111,11 +1172,15 @@ video_not_supported_in_browser=Seu navegador não suporta a tag 'video' do HTML5 audio_not_supported_in_browser=Seu navegador não suporta a tag 'audio' do HTML5. stored_lfs=Armazenado com Git LFS symbolic_link=Link simbólico +executable_file=Arquivo executável commit_graph=Gráfico de commits commit_graph.select=Selecionar branches commit_graph.hide_pr_refs=Esconder Pull Requests commit_graph.monochrome=Monocromático commit_graph.color=Colorido +commit.contained_in=Esse commit está contido em: +commit.contained_in_default_branch=Esse commit faz parte do branch padrão +commit.load_referencing_branches_and_tags=Carregar branches e tags que fazem referência a este commit blame=Anotar download_file=Baixar arquivo normal_view=Visão normal @@ -1195,6 +1260,7 @@ commits.commits=Commits commits.no_commits=Nenhum commit em comum. "%s" e "%s" tem históricos completamente diferentes. commits.nothing_to_compare=Estes branches são iguais. commits.search=Pesquisar commits... +commits.search.tooltip=Você pode prefixar as palavras-chave com "author:" (autor da mudança), "committer:" (autor do commit), "after:" (depois) ou "before:" (antes). Por exemplo: "revert author:Ana before:2019-01-13".\ commits.find=Pesquisar commits.search_all=Todos os branches commits.author=Autor @@ -1251,8 +1317,10 @@ projects.column.edit_title=Nome projects.column.new_title=Nome projects.column.new_submit=Criar coluna projects.column.new=Nova Coluna -projects.column.set_default=Definir padrão +projects.column.set_default=Atribuir como padrão projects.column.set_default_desc=Definir esta coluna como padrão para pull e issues sem categoria +projects.column.unset_default=Desatribuir padrão +projects.column.unset_default_desc=Desatribuir esta coluna como padrão projects.column.delete=Excluir coluna projects.column.deletion_desc=Excluir uma coluna do projeto move todas as issues relacionadas para 'Sem categoria'. Continuar? projects.column.color=Cor @@ -1331,6 +1399,7 @@ issues.delete_branch_at=`excluiu branch %s %s` issues.filter_label=Etiqueta issues.filter_label_exclude=`Use alt + clique/enter para excluir etiquetas` issues.filter_label_no_select=Todas as etiquetas +issues.filter_label_select_no_label=Sem etiqueta issues.filter_milestone=Marco issues.filter_milestone_all=Todos os marcos issues.filter_milestone_none=Sem marcos @@ -1364,6 +1433,7 @@ issues.filter_sort.moststars=Mais estrelas issues.filter_sort.feweststars=Menos estrelas issues.filter_sort.mostforks=Mais forks issues.filter_sort.fewestforks=Menos forks +issues.keyword_search_unavailable=A pesquisa por palavra-chave não está disponível no momento. Entre em contato com o administrador do site. issues.action_open=Abrir issues.action_close=Fechar issues.action_label=Etiqueta @@ -1384,6 +1454,7 @@ issues.next=Próximo issues.open_title=Aberto issues.closed_title=Fechado issues.draft_title=Rascunho +issues.num_comments_1=%d comentário issues.num_comments=%d comentários issues.commented_at=`comentou %s` issues.delete_comment_confirm=Tem certeza que deseja excluir este comentário? @@ -1392,6 +1463,7 @@ issues.context.quote_reply=Citar resposta issues.context.reference_issue=Referência em uma nova issue issues.context.edit=Editar issues.context.delete=Excluir +issues.no_content=Nenhuma descrição fornecida. issues.close=Fechar issue issues.comment_pull_merged_at=aplicou o merge do commit %[1]s em %[2]s %[3]s issues.comment_manually_pull_merged_at=aplicou o merge manual do commit %[1]s em %[2]s %[3]s @@ -1410,7 +1482,9 @@ issues.ref_closed_from=`fechou esta issue %[4]s reabriu esta issue %[4]s %[2]s` issues.ref_from=`de %[1]s` issues.author=Autor +issues.author_helper=Este usuário é o autor. issues.role.owner=Proprietário +issues.role.owner_helper=Este usuário é o dono deste repositório. issues.role.member=Membro issues.re_request_review=Re-solicitar revisão issues.is_stale=Houve alterações nessa PR desde essa revisão @@ -1426,6 +1500,7 @@ issues.label_title=Nome da etiqueta issues.label_description=Descrição da etiqueta issues.label_color=Cor da etiqueta issues.label_exclusive=Exclusivo +issues.label_archive=Arquivar etiqueta issues.label_exclusive_desc=Nomeie o rótulo escopo/item para torná-lo mutuamente exclusivo com outros rótulos do escopo/. issues.label_exclusive_warning=Quaisquer rótulos com escopo conflitantes serão removidos ao editar os rótulos de uma issue ou pull request. issues.label_count=%d etiquetas @@ -1480,6 +1555,7 @@ issues.tracking_already_started=`Você já iniciou o cronômetro em %[2]s#%[3]d` @@ -1627,6 +1714,12 @@ pulls.is_empty=As alterações neste branch já estão na branch de destino. Est pulls.required_status_check_failed=Algumas verificações necessárias não foram bem sucedidas. pulls.required_status_check_missing=Estão faltando algumas verificações necessárias. pulls.required_status_check_administrator=Como administrador, você ainda pode aplicar o merge deste pull request. +pulls.blocked_by_approvals=Este pull request ainda não tem aprovações suficientes. %d de %d aprovações concedidas. +pulls.blocked_by_rejection=Este pull request tem alterações solicitadas por um revisor oficial. +pulls.blocked_by_official_review_requests=Este pull request tem solicitações de revisão oficiais. +pulls.blocked_by_outdated_branch=Este pull request está bloqueado porque está desatualizado. +pulls.blocked_by_changed_protected_files_1=Este pull request está bloqueado porque altera um arquivo protegido: +pulls.blocked_by_changed_protected_files_n=Este pull request está bloqueado porque altera arquivos protegidos: pulls.can_auto_merge_desc=O merge deste pull request pode ser aplicado automaticamente. pulls.cannot_auto_merge_desc=O merge deste pull request não pode ser aplicado automaticamente pois há conflitos. pulls.cannot_auto_merge_helper=Faça o merge manualmente para resolver os conflitos. @@ -1701,7 +1794,9 @@ pulls.auto_merge_canceled_schedule_comment=`cancelou o merge automático deste p pulls.delete.title=Excluir este pull request? pulls.delete.text=Você realmente deseja excluir este pull request? (Isto irá remover permanentemente todo o conteúdo. Considere fechá-la em vez disso, se você pretende mantê-la arquivado) +pulls.recently_pushed_new_branches=Você fez push no branch %[1]s %[2]s +pull.deleted_branch=(excluído):%s milestones.new=Novo marco milestones.closed=Fechado %s @@ -1709,6 +1804,7 @@ milestones.update_ago=Atualizado há %s milestones.no_due_date=Sem data limite milestones.open=Reabrir milestones.close=Fechar +milestones.new_subheader=Os marcos podem ajudá-lo a organizar os problemas e acompanhar seu progresso. milestones.completeness=%d%% concluído milestones.create=Criar marco milestones.title=Título @@ -1725,11 +1821,25 @@ milestones.edit_success=O marco "%s" foi atualizado. milestones.deletion=Excluir marco milestones.deletion_desc=A exclusão deste marco irá removê-lo de todas as issues. Tem certeza que deseja continuar? milestones.deletion_success=O marco foi excluído. +milestones.filter_sort.earliest_due_data=Data limite mais próxima +milestones.filter_sort.latest_due_date=Data limite mais distante milestones.filter_sort.least_complete=Menos completo milestones.filter_sort.most_complete=Mais completo milestones.filter_sort.most_issues=Com mais issues milestones.filter_sort.least_issues=Com menos issues +signing.will_sign=Esse commit será assinado com a chave "%s". +signing.wont_sign.error=Ocorreu um erro ao verificar se o commit poderia ser assinado. +signing.wont_sign.nokey=Não há nenhuma chave disponível para assinar esse commit. +signing.wont_sign.never=Commits nunca são assinados. +signing.wont_sign.always=Commits são sempre assinados. +signing.wont_sign.pubkey=O commit não será assinado porque você não tem uma chave pública associada à sua conta. +signing.wont_sign.twofa=Você deve ter a autenticação de dois fatores ativada para que os commits sejam assinados. +signing.wont_sign.parentsigned=O commit não será assinado, pois o commit pai não está assinado. +signing.wont_sign.basesigned=O merge não será assinado, pois o commit base não está assinado. +signing.wont_sign.commitssigned=O merge não será assinado, pois todos os commits associados não estão assinados. +signing.wont_sign.approved=O merge não será assinado porque o PR não foi aprovado. +signing.wont_sign.not_signed_in=Você não está conectado. ext_wiki=Acesso a Wiki Externo ext_wiki.desc=Link para uma wiki externa. @@ -1852,6 +1962,8 @@ settings.githooks=Hooks do Git settings.basic_settings=Configurações básicas settings.mirror_settings=Opções de espelhamento settings.mirror_settings.docs=Configure o seu repositório para sincronizar automaticamente commits, tags e branches de outro repositório. +settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=No momento, isso só pode ser feito no menu "Nova migração". Para obter mais informações, consulte: +settings.mirror_settings.docs.can_still_use=Embora não seja possível modificar os espelhos existentes ou criar novos espelhos, você ainda pode usar o espelho existente. settings.mirror_settings.docs.doc_link_title=Como posso espelhar repositórios? settings.mirror_settings.mirrored_repository=Repositório espelhado settings.mirror_settings.direction=Sentido @@ -1861,6 +1973,7 @@ settings.mirror_settings.last_update=Última atualização settings.mirror_settings.push_mirror.none=Nenhum espelhamento de push configurado settings.mirror_settings.push_mirror.remote_url=URL do repositório do Git remoto settings.mirror_settings.push_mirror.add=Adicionar Espelho de Push +settings.mirror_settings.push_mirror.edit_sync_time=Editar intervalo de sincronização de espelhos settings.sync_mirror=Sincronizar agora settings.site=Site @@ -2507,6 +2620,7 @@ users=Contas de usuário organizations=Organizações repositories=Repositórios hooks=Webhooks +integrations=Integrações authentication=Fontes de autenticação emails=E-mails do Usuário config=Configuração @@ -2600,6 +2714,7 @@ users.full_name=Nome Completo users.activated=Ativado users.admin=Administrador users.restricted=Restrito +users.remote=Remoto users.2fa=2FA users.repos=Repositórios users.created=Criado @@ -2646,6 +2761,7 @@ users.list_status_filter.is_prohibit_login=Proibir login users.list_status_filter.not_prohibit_login=Permitir login users.list_status_filter.is_2fa_enabled=2FA Ativado users.list_status_filter.not_2fa_enabled=2FA Desativado +users.details=Detalhes do usuário emails.email_manage_panel=Gerenciamento de E-mail de Usuário emails.primary=Principal @@ -2677,10 +2793,12 @@ repos.stars=Favoritos repos.forks=Forks repos.issues=Issues repos.size=Tamanho +repos.lfs_size=Tamanho do LFS packages.package_manage_panel=Gerenciamento de Pacotes packages.total_size=Tamanho Total: %s packages.unreferenced_size=Tamanho Não Referenciado: %s +packages.cleanup=Limpar dados expirados packages.owner=Proprietário packages.creator=Criador packages.name=Nome @@ -2754,7 +2872,7 @@ auths.pam_email_domain=Domínio de e-mail do PAM (opcional) auths.oauth2_provider=Provedor OAuth2 auths.oauth2_icon_url=URL do Ícone auths.oauth2_clientID=ID do cliente (chave) -auths.oauth2_clientSecret=Senha do cliente +auths.oauth2_clientSecret=Client Secret auths.openIdConnectAutoDiscoveryURL=URL do OpenID Connect Auto Discovery auths.oauth2_use_custom_url=Usar URLs personalizadas em vez de URLs padrão auths.oauth2_tokenURL=URL do Token @@ -2787,6 +2905,7 @@ auths.sspi_default_language=Idioma padrão do usuário auths.sspi_default_language_helper=Idioma padrão para usuários criados automaticamente pelo método de autenticação SSPI. Deixe em branco se você prefere que o idioma seja detectado automaticamente. auths.tips=Dicas auths.tips.oauth2.general=Autenticação OAuth2 +auths.tips.oauth2.general.tip=Ao registrar uma nova autenticação OAuth2, o URL de retorno de chamada/redirecionamento deve ser: auths.tip.oauth2_provider=Provedor OAuth2 auths.tip.bitbucket=Cadastrar um novo consumidor de OAuth em https://bitbucket.org/account/user/ e adicionar a permissão 'Account' - 'Read' auths.tip.nextcloud=`Registre um novo consumidor OAuth em sua instância usando o seguinte menu "Configurações -> Segurança -> Cliente OAuth 2.0"` @@ -2802,6 +2921,7 @@ auths.tip.yandex=`Crie um novo aplicativo em https://oauth.yandex.com/client/new auths.tip.mastodon=Insira a URL da instância personalizada do mastodon que você deseja usar para autenticar (ou use o padrão) auths.edit=Editar fonte de autenticação auths.activated=Esta fonte de autenticação está ativada +auths.new_success=A fonte de autenticação "%s" foi adicionada. auths.update_success=A fonte de autenticação foi atualizada. auths.update=Atualizar fonte de autenticação auths.delete=Excluir fonte de autenticação @@ -2809,6 +2929,7 @@ auths.delete_auth_title=Excluir a Fonte de Autenticação auths.delete_auth_desc=A exclusão de uma fonte de autenticação impede que os usuários a usem para acessar. Continuar? auths.still_in_used=A fonte de autenticação ainda está em uso. Converta ou exclua todos os usuários que usam essa fonte de autenticação primeiro. auths.deletion_success=A fonte de autenticação foi excluída. +auths.login_source_exist=A fonte de autenticação "%s" já existe. auths.login_source_of_type_exist=Uma fonte de autenticação deste tipo já existe. auths.unable_to_initialize_openid=Não é possível inicializar o Provedor OpenID Connect: %s auths.invalid_openIdConnectAutoDiscoveryURL=URL do Auto Discovery inválida (deve ser uma URL válida, começando com http:// ou https://) @@ -3185,6 +3306,8 @@ pub.install=Para instalar o pacote usando Dart, execute o seguinte comando: pypi.requires=Requer Python pypi.install=Para instalar o pacote usando pip, execute o seguinte comando: rpm.registry=Configure este registro pela linha de comando: +rpm.distros.redhat=em distribuições baseadas no RedHat +rpm.distros.suse=em distribuições baseadas no SUSE rpm.install=Para instalar o pacote, execute o seguinte comando: rubygems.install=Para instalar o pacote usando gem, execute o seguinte comando: rubygems.install2=ou adicione-o ao Gemfile: @@ -3261,6 +3384,7 @@ status.waiting=Em espera status.running=Rodando status.success=Sucesso status.failure=Falha +status.cancelled=Cancelado status.skipped=Ignorado status.blocked=Bloqueado @@ -3277,6 +3401,7 @@ runners.labels=Rótulos runners.last_online=Última Vez Online runners.runner_title=Runner runners.task_list=Tarefas recentes neste runner +runners.task_list.no_tasks=Ainda não há nenhuma tarefa. runners.task_list.run=Executar runners.task_list.status=Status runners.task_list.repository=Repositório @@ -3301,6 +3426,7 @@ runners.reset_registration_token_success=Token de registro de runner redefinido runs.all_workflows=Todos os Workflows runs.commit=Commit +runs.pushed_by=push feito por runs.invalid_workflow_helper=O arquivo de configuração do workflow é inválido. Por favor, verifique seu arquivo de configuração: %s runs.no_matching_runner_helper=Nenhum runner correspondente: %s runs.status=Status diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini index 6a1df50553a..d137a6d2bed 100644 --- a/options/locale/locale_sk-SK.ini +++ b/options/locale/locale_sk-SK.ini @@ -77,20 +77,24 @@ milestones=Míľniky ok=OK cancel=Zrušiť +retry=Opakovať save=Uložiť add=Pridať add_all=Pridať všetko remove=Odstrániť remove_all=Odstrániť všetko +remove_label_str=Odstrániť položku „%s“ edit=Upraviť enabled=Povolené copy=Kopírovať copy_url=Kopírovať URL +copy_content=Kopírovať obsah copy_branch=Kopírovať meno vetvy copy_success=Skopírované! copy_error=Kopírovanie zlyhalo +copy_type_unsupported=Tento typ súboru nie je možné skopírovať write=Zapísať preview=Náhľad diff --git a/package-lock.json b/package-lock.json index bb7be16a073..fa9c8a73280 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,8 +6,8 @@ "": { "dependencies": { "@citation-js/core": "0.7.1", - "@citation-js/plugin-bibtex": "0.7.1", - "@citation-js/plugin-csl": "0.7.1", + "@citation-js/plugin-bibtex": "0.7.2", + "@citation-js/plugin-csl": "0.7.2", "@citation-js/plugin-software-formats": "0.6.1", "@claviska/jquery-minicolors": "2.3.6", "@github/markdown-toolbar-element": "2.2.1", @@ -18,7 +18,7 @@ "@webcomponents/custom-elements": "1.6.0", "add-asset-webpack-plugin": "2.0.1", "ansi_up": "6.0.2", - "asciinema-player": "3.6.2", + "asciinema-player": "3.6.3", "clippie": "4.0.6", "css-loader": "6.8.1", "dropzone": "6.0.0-beta.2", @@ -30,7 +30,7 @@ "katex": "0.16.9", "license-checker-webpack-plugin": "0.2.1", "lightningcss-loader": "2.1.0", - "mermaid": "10.5.0", + "mermaid": "10.6.0", "mini-css-extract-plugin": "2.7.6", "minimatch": "9.0.3", "monaco-editor": "0.44.0", @@ -38,49 +38,50 @@ "pdfobject": "2.2.12", "pretty-ms": "8.0.0", "sortablejs": "1.15.0", - "swagger-ui-dist": "5.9.0", + "swagger-ui-dist": "5.9.1", "throttle-debounce": "5.0.0", "tinycolor2": "1.6.0", "tippy.js": "6.3.7", "toastify-js": "1.12.0", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", - "vue": "3.3.4", + "vue": "3.3.7", "vue-bar-graph": "2.0.0", - "vue-loader": "17.3.0", + "vue-loader": "17.3.1", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.88.2", + "webpack": "5.89.0", "webpack-cli": "5.1.4", - "wrap-ansi": "8.1.0" + "wrap-ansi": "9.0.0" }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "4.1.0", - "@playwright/test": "1.38.1", + "@playwright/test": "1.39.0", "@stoplight/spectral-cli": "6.11.0", + "@stylistic/eslint-plugin-js": "1.0.0", "@vitejs/plugin-vue": "4.4.0", - "eslint": "8.51.0", + "eslint": "8.53.0", "eslint-plugin-array-func": "4.0.0", - "eslint-plugin-i": "2.28.1", + "eslint-plugin-i": "2.29.0", "eslint-plugin-jquery": "1.5.1", "eslint-plugin-no-jquery": "2.7.0", "eslint-plugin-no-use-extend-native": "0.5.0", - "eslint-plugin-regexp": "2.0.0", - "eslint-plugin-sonarjs": "0.21.0", - "eslint-plugin-unicorn": "48.0.1", - "eslint-plugin-vitest": "0.3.2", + "eslint-plugin-regexp": "2.1.1", + "eslint-plugin-sonarjs": "0.23.0", + "eslint-plugin-unicorn": "49.0.0", + "eslint-plugin-vitest": "0.3.9", "eslint-plugin-vitest-globals": "1.4.0", - "eslint-plugin-vue": "9.17.0", + "eslint-plugin-vue": "9.18.1", "eslint-plugin-vue-scoped-css": "2.5.1", "eslint-plugin-wc": "2.0.4", "jsdom": "22.1.0", "markdownlint-cli": "0.37.0", "postcss-html": "1.5.0", - "stylelint": "15.10.3", + "stylelint": "15.11.0", "stylelint-declaration-block-no-ignored-properties": "2.7.0", "stylelint-declaration-strict-value": "1.9.2", "stylelint-stylistic": "0.4.3", "svgo": "3.0.2", - "updates": "15.0.2", + "updates": "15.0.4", "vite-string-plugin": "1.1.2", "vitest": "0.34.6" }, @@ -272,12 +273,6 @@ "node": ">=4" } }, - "node_modules/@babel/highlight/node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -302,9 +297,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.23.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz", - "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz", + "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -348,9 +343,9 @@ } }, "node_modules/@citation-js/plugin-bibtex": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.1.tgz", - "integrity": "sha512-dj/GzpceS/QNbU8+rVzJfXeli7XSTYVTltGv5w2RHM+CCOdtG3tiFP1Ohu3yWi+8VPMjQJG9u2W789grIqc/ng==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.2.tgz", + "integrity": "sha512-QkgPfYbs1dierenxKWzIlPV7450Jci8bvZbcpjO3HQTfTaj15SV2C2AaeKhUotXZmTjm49AJQWHZtrNh+7YWjg==", "dependencies": { "@citation-js/date": "^0.5.0", "@citation-js/name": "^0.4.2", @@ -376,9 +371,9 @@ } }, "node_modules/@citation-js/plugin-csl": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.1.tgz", - "integrity": "sha512-B5Yv1o04Ds8/PF3FYlfL7bL3LFpVUhCEOAEqLFN5qgk785dnU0gMhDYbpJuCbQ8P6lIQpoU7O5x+EcJvWQhqCA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.2.tgz", + "integrity": "sha512-ogNb/gdcZ/EXZq+We+/aw6RkiYxjF+h7myJypyR0PApGJq9GzwcfGHW9ded2JdQIxyz4fO46pCTR4nv6FPUvMA==", "dependencies": { "@citation-js/date": "^0.5.0", "citeproc": "^2.4.6" @@ -555,9 +550,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.4.tgz", - "integrity": "sha512-uBIbiYMeSsy2U0XQoOGVVcpIktjLMEKa7ryz2RLr7L/vTnANNEsPVAh4xOv7ondGz6ac1zVb0F8Jx20rQikffQ==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", + "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", "cpu": [ "arm" ], @@ -570,9 +565,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.4.tgz", - "integrity": "sha512-mRsi2vJsk4Bx/AFsNBqOH2fqedxn5L/moT58xgg51DjX1la64Z3Npicut2VbhvDFO26qjWtPMsVxCd80YTFVeg==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", + "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", "cpu": [ "arm64" ], @@ -585,9 +580,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.4.tgz", - "integrity": "sha512-4iPufZ1TMOD3oBlGFqHXBpa3KFT46aLl6Vy7gwed0ZSYgHaZ/mihbYb4t7Z9etjkC9Al3ZYIoOaHrU60gcMy7g==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", + "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", "cpu": [ "x64" ], @@ -600,9 +595,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.4.tgz", - "integrity": "sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", + "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", "cpu": [ "arm64" ], @@ -615,9 +610,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.4.tgz", - "integrity": "sha512-YHbSFlLgDwglFn0lAO3Zsdrife9jcQXQhgRp77YiTDja23FrC2uwnhXMNkAucthsf+Psr7sTwYEryxz6FPAVqw==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", + "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", "cpu": [ "x64" ], @@ -630,9 +625,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.4.tgz", - "integrity": "sha512-vz59ijyrTG22Hshaj620e5yhs2dU1WJy723ofc+KUgxVCM6zxQESmWdMuVmUzxtGqtj5heHyB44PjV/HKsEmuQ==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", + "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", "cpu": [ "arm64" ], @@ -645,9 +640,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.4.tgz", - "integrity": "sha512-3sRbQ6W5kAiVQRBWREGJNd1YE7OgzS0AmOGjDmX/qZZecq8NFlQsQH0IfXjjmD0XtUYqr64e0EKNFjMUlPL3Cw==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", + "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", "cpu": [ "x64" ], @@ -660,9 +655,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.4.tgz", - "integrity": "sha512-z/4ArqOo9EImzTi4b6Vq+pthLnepFzJ92BnofU1jgNlcVb+UqynVFdoXMCFreTK7FdhqAzH0vmdwW5373Hm9pg==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", + "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", "cpu": [ "arm" ], @@ -675,9 +670,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.4.tgz", - "integrity": "sha512-ZWmWORaPbsPwmyu7eIEATFlaqm0QGt+joRE9sKcnVUG3oBbr/KYdNE2TnkzdQwX6EDRdg/x8Q4EZQTXoClUqqA==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", + "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", "cpu": [ "arm64" ], @@ -690,9 +685,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.4.tgz", - "integrity": "sha512-EGc4vYM7i1GRUIMqRZNCTzJh25MHePYsnQfKDexD8uPTCm9mK56NIL04LUfX2aaJ+C9vyEp2fJ7jbqFEYgO9lQ==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", + "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", "cpu": [ "ia32" ], @@ -705,9 +700,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.4.tgz", - "integrity": "sha512-WVhIKO26kmm8lPmNrUikxSpXcgd6HDog0cx12BUfA2PkmURHSgx9G6vA19lrlQOMw+UjMZ+l3PpbtzffCxFDRg==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", + "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", "cpu": [ "loong64" ], @@ -720,9 +715,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.4.tgz", - "integrity": "sha512-keYY+Hlj5w86hNp5JJPuZNbvW4jql7c1eXdBUHIJGTeN/+0QFutU3GrS+c27L+NTmzi73yhtojHk+lr2+502Mw==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", + "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", "cpu": [ "mips64el" ], @@ -735,9 +730,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.4.tgz", - "integrity": "sha512-tQ92n0WMXyEsCH4m32S21fND8VxNiVazUbU4IUGVXQpWiaAxOBvtOtbEt3cXIV3GEBydYsY8pyeRMJx9kn3rvw==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", + "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", "cpu": [ "ppc64" ], @@ -750,9 +745,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.4.tgz", - "integrity": "sha512-tRRBey6fG9tqGH6V75xH3lFPpj9E8BH+N+zjSUCnFOX93kEzqS0WdyJHkta/mmJHn7MBaa++9P4ARiU4ykjhig==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", + "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", "cpu": [ "riscv64" ], @@ -765,9 +760,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.4.tgz", - "integrity": "sha512-152aLpQqKZYhThiJ+uAM4PcuLCAOxDsCekIbnGzPKVBRUDlgaaAfaUl5NYkB1hgY6WN4sPkejxKlANgVcGl9Qg==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", + "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", "cpu": [ "s390x" ], @@ -780,9 +775,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.4.tgz", - "integrity": "sha512-Mi4aNA3rz1BNFtB7aGadMD0MavmzuuXNTaYL6/uiYIs08U7YMPETpgNn5oue3ICr+inKwItOwSsJDYkrE9ekVg==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", + "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", "cpu": [ "x64" ], @@ -795,9 +790,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.4.tgz", - "integrity": "sha512-9+Wxx1i5N/CYo505CTT7T+ix4lVzEdz0uCoYGxM5JDVlP2YdDC1Bdz+Khv6IbqmisT0Si928eAxbmGkcbiuM/A==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", + "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", "cpu": [ "x64" ], @@ -810,9 +805,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.4.tgz", - "integrity": "sha512-MFsHleM5/rWRW9EivFssop+OulYVUoVcqkyOkjiynKBCGBj9Lihl7kh9IzrreDyXa4sNkquei5/DTP4uCk25xw==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", + "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", "cpu": [ "x64" ], @@ -825,9 +820,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.4.tgz", - "integrity": "sha512-6Xq8SpK46yLvrGxjp6HftkDwPP49puU4OF0hEL4dTxqCbfx09LyrbUj/D7tmIRMj5D5FCUPksBbxyQhp8tmHzw==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", + "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", "cpu": [ "x64" ], @@ -840,9 +835,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.4.tgz", - "integrity": "sha512-PkIl7Jq4mP6ke7QKwyg4fD4Xvn8PXisagV/+HntWoDEdmerB2LTukRZg728Yd1Fj+LuEX75t/hKXE2Ppk8Hh1w==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", + "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", "cpu": [ "arm64" ], @@ -855,9 +850,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.4.tgz", - "integrity": "sha512-ga676Hnvw7/ycdKB53qPusvsKdwrWzEyJ+AtItHGoARszIqvjffTwaaW3b2L6l90i7MO9i+dlAW415INuRhSGg==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", + "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", "cpu": [ "ia32" ], @@ -870,9 +865,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.4.tgz", - "integrity": "sha512-HP0GDNla1T3ZL8Ko/SHAS2GgtjOg+VmWnnYLhuTksr++EnduYB0f3Y2LzHsUwb2iQ13JGoY6G3R8h6Du/WG6uA==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", + "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", "cpu": [ "x64" ], @@ -916,18 +911,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -992,9 +987,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", - "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", + "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1024,12 +1019,12 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -1073,9 +1068,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@isaacs/cliui": { @@ -1107,6 +1102,18 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -1145,6 +1152,23 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -1201,9 +1225,9 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1234,9 +1258,9 @@ } }, "node_modules/@mcaptcha/core-glue": { - "version": "0.1.0-alpha-5", - "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-5.tgz", - "integrity": "sha512-16qWm5O5X0Y9LXULULaAks8Vf9FNlUUBcR5KDt49aWhFhG5++JzxNmCwQM9EJSHNU7y0U+FdyAWcGmjfKlkRLA==", + "version": "0.1.0-rc1", + "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-rc1.tgz", + "integrity": "sha512-P4SgUioJDR38QpnP9sPY72NyaYex8MXD6RbzrfKra+ngamT26XjqVZEHBiZU2RT7u0SsWhuko4N1ntNOghsgpg==", "funding": [ { "type": "individual", @@ -1325,12 +1349,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz", - "integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", "dev": true, "dependencies": { - "playwright": "1.38.1" + "playwright": "1.39.0" }, "bin": { "playwright": "cli.js" @@ -1857,6 +1881,21 @@ "integrity": "sha512-sV+51I7WYnLJnKPn2EMWgS4EUfoP4iWEbrWwbXsj0MZCB/xOK8j6+C9fntIdOM50kpx45ZLC3s6kwKivWuqvyg==", "dev": true }, + "node_modules/@stylistic/eslint-plugin-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.0.0.tgz", + "integrity": "sha512-xxvjyYnUEgjBTnXKYMk6JbU0LHkf269d6y4IgW69bK/VwHrqLfdgE6mYvft42U7KVpp6Tbf6Z64tLRYD/rYd/A==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "acorn": "^8.10.0", + "escape-string-regexp": "^4.0.0", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esutils": "^2.0.3", + "graphemer": "^1.4.0" + } + }, "node_modules/@swc/helpers": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.2.14.tgz", @@ -1881,76 +1920,76 @@ } }, "node_modules/@types/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==", + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.9.tgz", + "integrity": "sha512-69TtiDzu0bcmKQv3yg1Zx409/Kd7r0b5F1PfpYJfSHzLGtB53547V4u+9iqKYsTu/O2ai6KTb0TInNpvuQ3qmg==", "dev": true }, "node_modules/@types/chai-subset": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", - "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.4.tgz", + "integrity": "sha512-CCWNXrJYSUIojZ1149ksLl3AN9cmZ5djf+yUoVVV+NuYrtydItQVlL2ZDqyC6M6O9LWRnVf8yYDxbXHO2TfQZg==", "dev": true, "dependencies": { "@types/chai": "*" } }, "node_modules/@types/codemirror": { - "version": "5.60.10", - "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.10.tgz", - "integrity": "sha512-ZTA3teiCWKT8HUUofqlGPlShu5ojdIajizsS0HpH6GL0/iEdjRt7fXbCLHHqKYP5k7dC/HnnWIjZAiELUwBdjQ==", + "version": "5.60.12", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.12.tgz", + "integrity": "sha512-SFSj5Tb/mtQoVgaltsipdRGG1PkcFu/L0OXPNBGCXYUQtwsNoAGRNNHOTl1jYcQUcEI77EiUfk94bgETTbSo/A==", "dependencies": { "@types/tern": "*" } }, "node_modules/@types/d3-scale": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.5.tgz", - "integrity": "sha512-w/C++3W394MHzcLKO2kdsIn5KKNTOqeQVzyPSGPLzQbkPw/jpeaGtSRlakcKevGgGsjJxGsbqS0fPrVFDbHrDA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.6.tgz", + "integrity": "sha512-lo3oMLSiqsQUovv8j15X4BNEDOsnHuGjeVg7GRbAuB2PUa1prK5BNSOu6xixgNf3nqxPl4I1BqJWrPvFGlQoGQ==", "dependencies": { "@types/d3-time": "*" } }, "node_modules/@types/d3-scale-chromatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", - "integrity": "sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.1.tgz", + "integrity": "sha512-Ob7OrwiTeQXY/WBBbRHGZBOn6rH1h7y3jjpTSKYqDEeqFjktql6k2XSgNwLrLDmAsXhEn8P9NHDY4VTuo0ZY1w==" }, "node_modules/@types/d3-time": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.1.tgz", - "integrity": "sha512-5j/AnefKAhCw4HpITmLDTPlf4vhi8o/dES+zbegfPb7LaGfNyqkLxBR6E+4yvTAgnJLmhe80EXFMzUs38fw4oA==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.2.tgz", + "integrity": "sha512-kbdRXTmUgNfw5OTE3KZnFQn6XdIc4QGroN5UixgdrXATmYsdlPQS6pEut9tVlIojtzuFD4txs/L+Rq41AHtLpg==" }, "node_modules/@types/debug": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.9.tgz", - "integrity": "sha512-8Hz50m2eoS56ldRlepxSBa6PWEVCtzUo/92HgLc2qTMnotJNIm7xP+UZhyWoYsyOdd5dxZ+NZLb24rsKyFs2ow==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.10.tgz", + "integrity": "sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==", "dependencies": { "@types/ms": "*" } }, "node_modules/@types/es-aggregate-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.3.tgz", - "integrity": "sha512-GmY61WWXQemfJp+qmMu6RsrNev0eoEWeWtg46w9pdXje23jRJrf7yETbAkl7F+CfQJSKW7w3//sTYtQTt+R5Lg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.4.tgz", + "integrity": "sha512-95tL6tLR8P3Utx4SxXUEc0e+k2B9VhtBozhgxKGpv30ylIuxGxf080d7mYZ08sH5UjpDv/Nd6F80tH1p+KuPIg==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/eslint": { - "version": "8.44.3", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.3.tgz", - "integrity": "sha512-iM/WfkwAhwmPff3wZuPLYiHX18HI24jU8k1ZSH7P8FHwxTjZ2P6CoX2wnF43oprR+YXJM6UUxATkNvyv/JHd+g==", + "version": "8.44.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.6.tgz", + "integrity": "sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/eslint-scope": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.5.tgz", - "integrity": "sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA==", + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.6.tgz", + "integrity": "sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ==", "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -1962,9 +2001,9 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, "node_modules/@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==" + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==" }, "node_modules/@types/marked": { "version": "4.3.2", @@ -1972,39 +2011,42 @@ "integrity": "sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==" }, "node_modules/@types/mdast": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.13.tgz", - "integrity": "sha512-HjiGiWedR0DVFkeNljpa6Lv4/IZU1+30VY5d747K7lBudFc3R0Ibr6yJ9lN3BE28VnZyDfLF/VB1Ql1ZIbKrmg==", + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.14.tgz", + "integrity": "sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw==", "dependencies": { "@types/unist": "^2" } }, "node_modules/@types/minimist": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.3.tgz", - "integrity": "sha512-ZYFzrvyWUNhaPomn80dsMNgMeXxNWZBdkuG/hWlUvXvbdUH8ZERNBGXnU87McuGcWDsyzX2aChCv/SVN348k3A==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.4.tgz", + "integrity": "sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==", "dev": true }, "node_modules/@types/ms": { - "version": "0.7.32", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.32.tgz", - "integrity": "sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g==" + "version": "0.7.33", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz", + "integrity": "sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==" }, "node_modules/@types/node": { - "version": "20.8.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.3.tgz", - "integrity": "sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw==" + "version": "20.8.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", + "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/normalize-package-data": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz", - "integrity": "sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz", + "integrity": "sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==", "dev": true }, "node_modules/@types/sarif": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.5.tgz", - "integrity": "sha512-onJXseJAteCVczKQbO/Tx8zrvhZwZkAd+T7GGYXZvJJ7pzy7We5NJXcNk2oZoUbcnTP/AjkAH7XtPCkpfRBOnQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.6.tgz", + "integrity": "sha512-x+68l19JJnfXX9oq85k6KZwsPuOa2BKESkYqbRbA09zLSZXIDNyDo1illgDB/P0ZdpIa4EII3pHJ6DQq3xo3Qw==", "dev": true }, "node_modules/@types/semver": { @@ -2014,32 +2056,32 @@ "dev": true }, "node_modules/@types/tern": { - "version": "0.23.5", - "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.5.tgz", - "integrity": "sha512-POau56wDk3TQ0mQ0qG7XDzv96U5whSENZ9lC0htDvEH+9YUREo+J2U+apWcVRgR2UydEE70JXZo44goG+akTNQ==", + "version": "0.23.6", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.6.tgz", + "integrity": "sha512-ntalN+F2msUwz7/OCCADN4FwxtIGqF4Hqwxd15yAn0VOUozj1VaIrH4Prh95N8y69K3bQpHFVGwTJDZC4oRtvA==", "dependencies": { "@types/estree": "*" } }, "node_modules/@types/unist": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.8.tgz", - "integrity": "sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==" + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.9.tgz", + "integrity": "sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ==" }, "node_modules/@types/urijs": { - "version": "1.19.20", - "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.20.tgz", - "integrity": "sha512-77Mq/2BeHU894J364dUv9tSwxxyCLtcX228Pc8TwZpP5bvOoMns+gZoftp3LYl3FBH8vChpWbuagKGiMki2c1A==", + "version": "1.19.22", + "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.22.tgz", + "integrity": "sha512-qnYBwfN7O/+i6E1Kr8JaCKsrCLpRCiQ1XxkSxNIYuJ/5Aagt0+HlMX78DJMUrNzDULMz0eu2gcprlxJaDtACOw==", "dev": true }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.8.0.tgz", - "integrity": "sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", + "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0" + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2050,9 +2092,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.8.0.tgz", - "integrity": "sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", + "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2063,13 +2105,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.8.0.tgz", - "integrity": "sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", + "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/visitor-keys": "6.8.0", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2090,17 +2132,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.8.0.tgz", - "integrity": "sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", + "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.8.0", - "@typescript-eslint/types": "6.8.0", - "@typescript-eslint/typescript-estree": "6.8.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", "semver": "^7.5.4" }, "engines": { @@ -2115,12 +2157,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.8.0.tgz", - "integrity": "sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", + "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.8.0", + "@typescript-eslint/types": "6.9.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -2131,6 +2173,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@vitejs/plugin-vue": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.4.0.tgz", @@ -2214,9 +2262,9 @@ } }, "node_modules/@vitest/snapshot/node_modules/magic-string": { - "version": "0.30.4", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz", - "integrity": "sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -2252,46 +2300,46 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.7.tgz", + "integrity": "sha512-pACdY6YnTNVLXsB86YD8OF9ihwpolzhhtdLVHhBL6do/ykr6kKXNYABRtNMGrsQXpEXXyAdwvWWkuTbs4MFtPQ==", "dependencies": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", + "@babel/parser": "^7.23.0", + "@vue/shared": "3.3.7", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", - "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.7.tgz", + "integrity": "sha512-0LwkyJjnUPssXv/d1vNJ0PKfBlDoQs7n81CbO6Q0zdL7H1EzqYRrTVXDqdBVqro0aJjo/FOa1qBAPVI4PGSHBw==", "dependencies": { - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-core": "3.3.7", + "@vue/shared": "3.3.7" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", - "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.7.tgz", + "integrity": "sha512-7pfldWy/J75U/ZyYIXRVqvLRw3vmfxDo2YLMwVtWVNew8Sm8d6wodM+OYFq4ll/UxfqVr0XKiVwti32PCrruAw==", "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-ssr": "3.3.4", - "@vue/reactivity-transform": "3.3.4", - "@vue/shared": "3.3.4", + "@babel/parser": "^7.23.0", + "@vue/compiler-core": "3.3.7", + "@vue/compiler-dom": "3.3.7", + "@vue/compiler-ssr": "3.3.7", + "@vue/reactivity-transform": "3.3.7", + "@vue/shared": "3.3.7", "estree-walker": "^2.0.2", - "magic-string": "^0.30.0", - "postcss": "^8.1.10", + "magic-string": "^0.30.5", + "postcss": "^8.4.31", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-sfc/node_modules/magic-string": { - "version": "0.30.4", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz", - "integrity": "sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -2300,38 +2348,38 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", - "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.7.tgz", + "integrity": "sha512-TxOfNVVeH3zgBc82kcUv+emNHo+vKnlRrkv8YvQU5+Y5LJGJwSNzcmLUoxD/dNzv0bhQ/F0s+InlgV0NrApJZg==", "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-dom": "3.3.7", + "@vue/shared": "3.3.7" } }, "node_modules/@vue/reactivity": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz", - "integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.7.tgz", + "integrity": "sha512-cZNVjWiw00708WqT0zRpyAgduG79dScKEPYJXq2xj/aMtk3SKvL3FBt2QKUlh6EHBJ1m8RhBY+ikBUzwc7/khg==", "dependencies": { - "@vue/shared": "3.3.4" + "@vue/shared": "3.3.7" } }, "node_modules/@vue/reactivity-transform": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", - "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.7.tgz", + "integrity": "sha512-APhRmLVbgE1VPGtoLQoWBJEaQk4V8JUsqrQihImVqKT+8U6Qi3t5ATcg4Y9wGAPb3kIhetpufyZ1RhwbZCIdDA==", "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4", + "@babel/parser": "^7.23.0", + "@vue/compiler-core": "3.3.7", + "@vue/shared": "3.3.7", "estree-walker": "^2.0.2", - "magic-string": "^0.30.0" + "magic-string": "^0.30.5" } }, "node_modules/@vue/reactivity-transform/node_modules/magic-string": { - "version": "0.30.4", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz", - "integrity": "sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -2340,40 +2388,40 @@ } }, "node_modules/@vue/runtime-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz", - "integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.7.tgz", + "integrity": "sha512-LHq9du3ubLZFdK/BP0Ysy3zhHqRfBn80Uc+T5Hz3maFJBGhci1MafccnL3rpd5/3wVfRHAe6c+PnlO2PAavPTQ==", "dependencies": { - "@vue/reactivity": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/reactivity": "3.3.7", + "@vue/shared": "3.3.7" } }, "node_modules/@vue/runtime-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz", - "integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.7.tgz", + "integrity": "sha512-PFQU1oeJxikdDmrfoNQay5nD4tcPNYixUBruZzVX/l0eyZvFKElZUjW4KctCcs52nnpMGO6UDK+jF5oV4GT5Lw==", "dependencies": { - "@vue/runtime-core": "3.3.4", - "@vue/shared": "3.3.4", - "csstype": "^3.1.1" + "@vue/runtime-core": "3.3.7", + "@vue/shared": "3.3.7", + "csstype": "^3.1.2" } }, "node_modules/@vue/server-renderer": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz", - "integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.7.tgz", + "integrity": "sha512-UlpKDInd1hIZiNuVVVvLgxpfnSouxKQOSE2bOfQpBuGwxRV/JqqTCyyjXUWiwtVMyeRaZhOYYqntxElk8FhBhw==", "dependencies": { - "@vue/compiler-ssr": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-ssr": "3.3.7", + "@vue/shared": "3.3.7" }, "peerDependencies": { - "vue": "3.3.4" + "vue": "3.3.7" } }, "node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==" + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.7.tgz", + "integrity": "sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg==" }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", @@ -2581,9 +2629,9 @@ } }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "bin": { "acorn": "bin/acorn" }, @@ -2609,9 +2657,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz", + "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==", "dev": true, "engines": { "node": ">=0.4.0" @@ -2813,9 +2861,9 @@ } }, "node_modules/asciinema-player": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.6.2.tgz", - "integrity": "sha512-698O3/Vm2+V6uFlc6oYma67IZByQsiNpduhEGhuqrxBmKpIYpgouLNNJ3R8DrRPTNNMISHfnLgvAp1x8ChgrTw==", + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.6.3.tgz", + "integrity": "sha512-62aDgLpbuduhmpFfNgPOzf6fOluACLsftVnjpWJjUXX6dqhqTckFqWoJ+ayA0XjSlZ9l9wXTcJqRqvAAIpMblg==", "dependencies": { "@babel/runtime": "^7.21.0", "solid-js": "^1.3.0" @@ -3034,13 +3082,14 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3098,9 +3147,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001546", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz", - "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==", + "version": "1.0.30001561", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz", + "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==", "funding": [ { "type": "opencollective", @@ -3337,9 +3386,9 @@ } }, "node_modules/comment-parser": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.0.tgz", - "integrity": "sha512-QLyTNiZ2KDOibvFPlZ6ZngVsZ/0gYnE6uTXi5aoDg8ed3AkJAz4sEje3Y8a29hQ1s6A99MZXe47fLAXQ1rTqaw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true, "engines": { "node": ">= 12.0.0" @@ -3424,12 +3473,12 @@ } }, "node_modules/css-functions-list": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.0.tgz", - "integrity": "sha512-d/jBMPyYybkkLVypgtGv12R+pIFw4/f/IHtCTxWpZc8ofTYOPigIgmA6vu5rMHartZC+WuXhBUHfnyNUIQSYrg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz", + "integrity": "sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==", "dev": true, "engines": { - "node": ">=12.22" + "node": ">=12 || >=16" } }, "node_modules/css-loader": { @@ -3583,9 +3632,9 @@ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, "node_modules/cytoscape": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.26.0.tgz", - "integrity": "sha512-IV+crL+KBcrCnVVUCZW+zRRRFUZQcrtdOPXki+o4CFUWLdAEYvuZLcBSJC9EBK++suamERKzeY7roq2hdovV3w==", + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.27.0.tgz", + "integrity": "sha512-pPZJilfX9BxESwujODz5pydeGi+FBrXq1rcaB1mfhFXXFJ9GjE6CNndAk+8jPzoXGD+16LtSS4xlYEIUiW4Abg==", "dependencies": { "heap": "^0.2.6", "lodash": "^4.17.21" @@ -4193,9 +4242,9 @@ "dev": true }, "node_modules/define-data-property": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", - "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, "dependencies": { "get-intrinsic": "^1.2.1", @@ -4405,7 +4454,8 @@ "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true }, "node_modules/easymde": { "version": "2.18.0", @@ -4420,9 +4470,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.544", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.544.tgz", - "integrity": "sha512-54z7squS1FyFRSUqq/knOFSptjjogLZXbKcYk3B0qkE1KZzvqASwRZnY2KzZQJqIYLVD38XZeoiMRflYSwyO4w==" + "version": "1.4.576", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz", + "integrity": "sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA==" }, "node_modules/elkjs": { "version": "0.8.2", @@ -4476,9 +4526,9 @@ } }, "node_modules/envinfo": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", - "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz", + "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==", "bin": { "envinfo": "dist/cli.js" }, @@ -4496,26 +4546,26 @@ } }, "node_modules/es-abstract": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", - "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.2", "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.5", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.1", + "get-intrinsic": "^1.2.2", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", + "hasown": "^2.0.0", "internal-slot": "^1.0.5", "is-array-buffer": "^3.0.2", "is-callable": "^1.2.7", @@ -4525,7 +4575,7 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.12", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.5.1", @@ -4539,7 +4589,7 @@ "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -4576,14 +4626,14 @@ "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==" }, "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" }, "engines": { "node": ">= 0.4" @@ -4607,9 +4657,9 @@ } }, "node_modules/esbuild": { - "version": "0.19.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.4.tgz", - "integrity": "sha512-x7jL0tbRRpv4QUyuDMjONtWFciygUxWaUM1kMX2zWxI0X2YWOt7MSA0g4UdeSiHM8fcYVzpQhKYOycZwxTdZkA==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", + "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -4618,28 +4668,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.19.4", - "@esbuild/android-arm64": "0.19.4", - "@esbuild/android-x64": "0.19.4", - "@esbuild/darwin-arm64": "0.19.4", - "@esbuild/darwin-x64": "0.19.4", - "@esbuild/freebsd-arm64": "0.19.4", - "@esbuild/freebsd-x64": "0.19.4", - "@esbuild/linux-arm": "0.19.4", - "@esbuild/linux-arm64": "0.19.4", - "@esbuild/linux-ia32": "0.19.4", - "@esbuild/linux-loong64": "0.19.4", - "@esbuild/linux-mips64el": "0.19.4", - "@esbuild/linux-ppc64": "0.19.4", - "@esbuild/linux-riscv64": "0.19.4", - "@esbuild/linux-s390x": "0.19.4", - "@esbuild/linux-x64": "0.19.4", - "@esbuild/netbsd-x64": "0.19.4", - "@esbuild/openbsd-x64": "0.19.4", - "@esbuild/sunos-x64": "0.19.4", - "@esbuild/win32-arm64": "0.19.4", - "@esbuild/win32-ia32": "0.19.4", - "@esbuild/win32-x64": "0.19.4" + "@esbuild/android-arm": "0.19.5", + "@esbuild/android-arm64": "0.19.5", + "@esbuild/android-x64": "0.19.5", + "@esbuild/darwin-arm64": "0.19.5", + "@esbuild/darwin-x64": "0.19.5", + "@esbuild/freebsd-arm64": "0.19.5", + "@esbuild/freebsd-x64": "0.19.5", + "@esbuild/linux-arm": "0.19.5", + "@esbuild/linux-arm64": "0.19.5", + "@esbuild/linux-ia32": "0.19.5", + "@esbuild/linux-loong64": "0.19.5", + "@esbuild/linux-mips64el": "0.19.5", + "@esbuild/linux-ppc64": "0.19.5", + "@esbuild/linux-riscv64": "0.19.5", + "@esbuild/linux-s390x": "0.19.5", + "@esbuild/linux-x64": "0.19.5", + "@esbuild/netbsd-x64": "0.19.5", + "@esbuild/openbsd-x64": "0.19.5", + "@esbuild/sunos-x64": "0.19.5", + "@esbuild/win32-arm64": "0.19.5", + "@esbuild/win32-ia32": "0.19.5", + "@esbuild/win32-x64": "0.19.5" } }, "node_modules/esbuild-loader": { @@ -4691,18 +4741,19 @@ } }, "node_modules/eslint": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", - "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", + "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.51.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.53.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4803,14 +4854,14 @@ } }, "node_modules/eslint-plugin-i": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-i/-/eslint-plugin-i-2.28.1.tgz", - "integrity": "sha512-a4oVt0j3ixNhGhvV4XF6NS7OWRFK2rrJ0Q5C4S2dSRb8FxZi31J0uUd5WJLL58wnVJ/OiQ1BxiXnFA4dWQO1Cg==", + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-i/-/eslint-plugin-i-2.29.0.tgz", + "integrity": "sha512-slGeTS3GQzx9267wLJnNYNO8X9EHGsc75AKIAFvnvMYEcTJKotPKL1Ru5PIGVHIVet+2DsugePWp8Oxpx8G22w==", "dev": true, "dependencies": { "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", + "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.8.0", "get-tsconfig": "^4.6.2", "is-glob": "^4.0.3", @@ -4905,9 +4956,9 @@ } }, "node_modules/eslint-plugin-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.0.0.tgz", - "integrity": "sha512-VT3J6rOt3Lp+Mxw4jfvox5f31Do5UEsgRNXLy2Afl/gv5HiwMu7n+xt4J9bxePC1ds5uXTsPYMOKiCjfXsHapA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.1.1.tgz", + "integrity": "sha512-FGa/idrL5tzMCnGylyx8DCWTX3vDuEtE/CVqTx+yYwe5qY3JRppbNVkOVGIkQF0klVlrG+LxwAXRXTUr5yU5uA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", @@ -4926,9 +4977,9 @@ } }, "node_modules/eslint-plugin-sonarjs": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.21.0.tgz", - "integrity": "sha512-oezUDfFT5S6j3rQheZ4DLPrbetPmMS7zHIKWGHr0CM3g5JgyZroz1FpIKa4jV83NsGpmgIeagpokWDKIJzRQmw==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.23.0.tgz", + "integrity": "sha512-z44T3PBf9W7qQ/aR+NmofOTyg6HLhSEZOPD4zhStqBpLoMp8GYhFksuUBnCxbnf1nfISpKBVkQhiBLFI/F4Wlg==", "dev": true, "engines": { "node": ">=14" @@ -4938,12 +4989,12 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "48.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-48.0.1.tgz", - "integrity": "sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==", + "version": "49.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-49.0.0.tgz", + "integrity": "sha512-0fHEa/8Pih5cmzFW5L7xMEfUTvI9WKeQtjmKpTUmY+BiFCDxkxrTdnURJOHKykhtwIeyYsxnecbGvDCml++z4Q==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "@eslint-community/eslint-utils": "^4.4.0", "ci-info": "^3.8.0", "clean-regexp": "^1.0.0", @@ -4951,7 +5002,6 @@ "indent-string": "^4.0.0", "is-builtin-module": "^3.2.1", "jsesc": "^3.0.2", - "lodash": "^4.17.21", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.27", @@ -4966,16 +5016,16 @@ "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" }, "peerDependencies": { - "eslint": ">=8.44.0" + "eslint": ">=8.52.0" } }, "node_modules/eslint-plugin-vitest": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.2.tgz", - "integrity": "sha512-A1P0qJVkqHyfDolwm09h8/gu7SbGFOKbacJSeyZ9IRb8uyddgqLcqv4VrqgQfLA7QmGI9lwj1iV90NyZ1cHp8Q==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.3.9.tgz", + "integrity": "sha512-ZGrz8dWFlotM5dwrsMLP4VcY5MizwKNV4JTnY0VKdnuCZ+qeEUMHf1qd8kRGQA3tqLvXcV929wt2ANkduq2Pgw==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^6.6.0" + "@typescript-eslint/utils": "^6.9.1" }, "engines": { "node": "14.x || >= 16" @@ -4989,7 +5039,7 @@ "optional": true }, "vitest": { - "vitest": "*" + "optional": true } } }, @@ -5000,9 +5050,9 @@ "dev": true }, "node_modules/eslint-plugin-vue": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.17.0.tgz", - "integrity": "sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==", + "version": "9.18.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.18.1.tgz", + "integrity": "sha512-7hZFlrEgg9NIzuVik2I9xSnJA5RsmOfueYgsUGUokEDLJ1LHtxO0Pl4duje1BriZ/jDWb+44tcIlC3yi0tdlZg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", @@ -5391,6 +5441,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", @@ -5484,10 +5542,12 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.6", @@ -5525,6 +5585,17 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-func-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", @@ -5535,15 +5606,15 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5800,14 +5871,6 @@ "node": ">=6" } }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -5826,12 +5889,12 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "get-intrinsic": "^1.2.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5881,6 +5944,17 @@ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==" }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/heap": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", @@ -6128,13 +6202,13 @@ } }, "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -6233,11 +6307,11 @@ } }, "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6571,9 +6645,9 @@ "dev": true }, "node_modules/js-tokens": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.2.tgz", - "integrity": "sha512-Olnt+V7xYdvGze9YTbGFZIfQXuGV4R3nQwwl8BrtgaPE/wq8UFpUHWuTNc05saowhSr1ZO6tx+V6RjE9D5YQog==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "node_modules/js-types": { @@ -6758,18 +6832,18 @@ } }, "node_modules/keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/khroma": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.0.0.tgz", - "integrity": "sha512-2J8rDNlQWbtiNYThZRvmMv5yt44ZakX+Tz5ZIp/mN1pt4snn+m030Va5Z4v8xA0cQFDXBwO/8i42xL4QPsVk3g==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" }, "node_modules/kind-of": { "version": "6.0.3", @@ -6788,9 +6862,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz", - "integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==", + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", + "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", "dev": true }, "node_modules/layout-base": { @@ -7218,12 +7292,12 @@ "dev": true }, "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "dependencies": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "node_modules/lowercase-keys": { @@ -7547,9 +7621,9 @@ } }, "node_modules/mermaid": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.5.0.tgz", - "integrity": "sha512-9l0o1uUod78D3/FVYPGSsgV+Z0tSnzLBDiC9rVzvelPxuO80HbN1oDr9ofpPETQy9XpypPQa26fr09VzEPfvWA==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.6.0.tgz", + "integrity": "sha512-Hcti+Q2NiWnb2ZCijSX89Bn2i7TCUwosBdIn/d+u63Sz7y40XU6EKMctT4UX4qZuZGfKGZpfOeim2/KTrdR7aQ==", "dependencies": { "@braintree/sanitize-url": "^6.0.1", "@types/d3-scale": "^4.0.3", @@ -8329,9 +8403,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8668,12 +8742,12 @@ "dev": true }, "node_modules/playwright": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz", - "integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", "dev": true, "dependencies": { - "playwright-core": "1.38.1" + "playwright-core": "1.39.0" }, "bin": { "playwright": "cli.js" @@ -8686,9 +8760,9 @@ } }, "node_modules/playwright-core": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz", - "integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -8757,6 +8831,12 @@ "node": "^12 || >=14" } }, + "node_modules/postcss-html/node_modules/js-tokens": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.2.tgz", + "integrity": "sha512-Olnt+V7xYdvGze9YTbGFZIfQXuGV4R3nQwwl8BrtgaPE/wq8UFpUHWuTNc05saowhSr1ZO6tx+V6RjE9D5YQog==", + "dev": true + }, "node_modules/postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", @@ -8973,9 +9053,9 @@ "dev": true }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "engines": { "node": ">=6" } @@ -9297,9 +9377,9 @@ } }, "node_modules/resolve": { - "version": "1.22.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", - "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -9586,13 +9666,28 @@ } }, "node_modules/seroval": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/seroval/-/seroval-0.5.1.tgz", - "integrity": "sha512-ZfhQVB59hmIauJG5Ydynupy8KHyr5imGNtdDhbZG68Ufh1Ynkv9KOYOAABf71oVbQxJ8VkWnMHAjEHE7fWkH5g==", + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-0.12.3.tgz", + "integrity": "sha512-5WDeMpv7rmEylsypRj1iwRVHE/QLsMLiZ+9savlNNQEVdgGia1iRMb7qyaAagY0wu/7+QTe6d2wldk/lgaLb6g==", "engines": { "node": ">=10" } }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/set-function-name": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", @@ -9717,12 +9812,12 @@ } }, "node_modules/solid-js": { - "version": "1.7.12", - "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.7.12.tgz", - "integrity": "sha512-QoyoOUKu14iLoGxjxWFIU8+/1kLT4edQ7mZESFPonsEXZ//VJtPKD8Ud1aTKzotj+MNWmSs9YzK6TdY+fO9Eww==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.5.tgz", + "integrity": "sha512-xvtJvzJzWbsn35oKFhW9kNwaxG1Z/YLMsDp4tLVcYZTMPzvzQ8vEZuyDQ6nt7xDArVgZJ7TUFrJUwrui/oq53A==", "dependencies": { "csstype": "^3.1.0", - "seroval": "^0.5.0" + "seroval": "^0.12.0" } }, "node_modules/sortablejs": { @@ -10002,9 +10097,9 @@ "dev": true }, "node_modules/stylelint": { - "version": "15.10.3", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.10.3.tgz", - "integrity": "sha512-aBQMMxYvFzJJwkmg+BUUg3YfPyeuCuKo2f+LOw7yYbU8AZMblibwzp9OV4srHVeQldxvSFdz0/Xu8blq2AesiA==", + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.11.0.tgz", + "integrity": "sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==", "dev": true, "dependencies": { "@csstools/css-parser-algorithms": "^2.3.1", @@ -10014,12 +10109,12 @@ "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^8.2.0", - "css-functions-list": "^3.2.0", + "css-functions-list": "^3.2.1", "css-tree": "^2.3.1", "debug": "^4.3.4", "fast-glob": "^3.3.1", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^7.0.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -10028,13 +10123,13 @@ "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.28.0", + "known-css-properties": "^0.29.0", "mathml-tag-names": "^2.1.3", "meow": "^10.1.5", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.27", + "postcss": "^8.4.28", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", "postcss-selector-parser": "^6.0.13", @@ -10106,6 +10201,18 @@ "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-7.0.1.tgz", + "integrity": "sha512-uLfFktPmRetVCbHe5UPuekWrQ6hENufnA46qEGbfACkK5drjTTdQYUragRgMjHldcbYG+nslUerqMPjbBSHXjQ==", + "dev": true, + "dependencies": { + "flat-cache": "^3.1.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/stylelint/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -10229,9 +10336,9 @@ } }, "node_modules/swagger-ui-dist": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.9.0.tgz", - "integrity": "sha512-NUHSYoe5XRTk/Are8jPJ6phzBh3l9l33nEyXosM17QInoV95/jng8+PuSGtbD407QoPf93MH3Bkh773OgesJpA==" + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.9.1.tgz", + "integrity": "sha512-5zAx+hUwJb9T3EAntc7TqYkV716CMqG6sZpNlAAMOMWkNXRYxGkN8ADIvD55dQZ10LxN90ZM/TQmN7y1gpICnw==" }, "node_modules/symbol-tree": { "version": "3.2.4", @@ -10276,9 +10383,9 @@ } }, "node_modules/terser": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", - "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", + "version": "5.24.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.24.0.tgz", + "integrity": "sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -10623,7 +10730,7 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, + "devOptional": true, "peer": true, "bin": { "tsc": "bin/tsc", @@ -10670,6 +10777,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/unist-util-stringify-position": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", @@ -10683,9 +10795,9 @@ } }, "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -10721,9 +10833,9 @@ } }, "node_modules/updates": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/updates/-/updates-15.0.2.tgz", - "integrity": "sha512-bdVZgJ2lr4Ke3pWyq7bT9ynJ5L4J69xERSvMMlt96nWlzVhB5kG8tYzicqI3I5Bpyj7cAv9MLBxDWaj/mB+nfg==", + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/updates/-/updates-15.0.4.tgz", + "integrity": "sha512-eGbbyKcKK2JOkNkstkVFArT9xUk7CiHgBT56DF3Li3WY2xPvpbZZM2ieN9UNom8pUDyCT6K9C4Di+SuiLvyaVg==", "dev": true, "bin": { "updates": "bin/updates.js" @@ -10819,9 +10931,9 @@ } }, "node_modules/vite": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz", - "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", + "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", "dev": true, "dependencies": { "esbuild": "^0.18.10", @@ -11388,9 +11500,9 @@ } }, "node_modules/vitest/node_modules/magic-string": { - "version": "0.30.4", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz", - "integrity": "sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==", + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -11400,15 +11512,23 @@ } }, "node_modules/vue": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz", - "integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.7.tgz", + "integrity": "sha512-YEMDia1ZTv1TeBbnu6VybatmSteGOS3A3YgfINOfraCbf85wdKHzscD6HSS/vB4GAtI7sa1XPX7HcQaJ1l24zA==", "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-sfc": "3.3.4", - "@vue/runtime-dom": "3.3.4", - "@vue/server-renderer": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-dom": "3.3.7", + "@vue/compiler-sfc": "3.3.7", + "@vue/runtime-dom": "3.3.7", + "@vue/server-renderer": "3.3.7", + "@vue/shared": "3.3.7" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/vue-bar-graph": { @@ -11421,9 +11541,9 @@ } }, "node_modules/vue-eslint-parser": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz", - "integrity": "sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz", + "integrity": "sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==", "dev": true, "dependencies": { "debug": "^4.3.4", @@ -11445,9 +11565,9 @@ } }, "node_modules/vue-loader": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.3.0.tgz", - "integrity": "sha512-VUURABiN0TIUz0yvJJ/V/rZjGUh10JZtD+IDI5bXFslzFi9mV6ebKkPzoqiSi8e0vh8Ip7JHJx+I0AzAG0KsCA==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.3.1.tgz", + "integrity": "sha512-nmVu7KU8geOyzsStyyaxID/uBGDMS8BkPXb6Lu2SNkMawriIbb+hYrNtgftHMKxOSkjjjTF5OSSwPo3KP59egg==", "dependencies": { "chalk": "^4.1.0", "hash-sum": "^2.0.0", @@ -11516,9 +11636,9 @@ } }, "node_modules/webpack": { - "version": "5.88.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", - "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -11614,11 +11734,12 @@ } }, "node_modules/webpack-merge": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", - "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "dependencies": { "clone-deep": "^4.0.1", + "flat": "^5.0.2", "wildcard": "^2.0.0" }, "engines": { @@ -11635,9 +11756,9 @@ } }, "node_modules/webpack/node_modules/@types/estree": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz", - "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.4.tgz", + "integrity": "sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw==" }, "node_modules/webpack/node_modules/ajv": { "version": "6.12.6", @@ -11777,13 +11898,13 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.4", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.0" @@ -11817,16 +11938,16 @@ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" }, "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -11873,21 +11994,21 @@ } }, "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" }, "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", + "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/package.json b/package.json index c95ca6dbbc8..f536894e26f 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,8 @@ }, "dependencies": { "@citation-js/core": "0.7.1", - "@citation-js/plugin-bibtex": "0.7.1", - "@citation-js/plugin-csl": "0.7.1", + "@citation-js/plugin-bibtex": "0.7.2", + "@citation-js/plugin-csl": "0.7.2", "@citation-js/plugin-software-formats": "0.6.1", "@claviska/jquery-minicolors": "2.3.6", "@github/markdown-toolbar-element": "2.2.1", @@ -17,7 +17,7 @@ "@webcomponents/custom-elements": "1.6.0", "add-asset-webpack-plugin": "2.0.1", "ansi_up": "6.0.2", - "asciinema-player": "3.6.2", + "asciinema-player": "3.6.3", "clippie": "4.0.6", "css-loader": "6.8.1", "dropzone": "6.0.0-beta.2", @@ -29,7 +29,7 @@ "katex": "0.16.9", "license-checker-webpack-plugin": "0.2.1", "lightningcss-loader": "2.1.0", - "mermaid": "10.5.0", + "mermaid": "10.6.0", "mini-css-extract-plugin": "2.7.6", "minimatch": "9.0.3", "monaco-editor": "0.44.0", @@ -37,49 +37,50 @@ "pdfobject": "2.2.12", "pretty-ms": "8.0.0", "sortablejs": "1.15.0", - "swagger-ui-dist": "5.9.0", + "swagger-ui-dist": "5.9.1", "throttle-debounce": "5.0.0", "tinycolor2": "1.6.0", "tippy.js": "6.3.7", "toastify-js": "1.12.0", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", - "vue": "3.3.4", + "vue": "3.3.7", "vue-bar-graph": "2.0.0", - "vue-loader": "17.3.0", + "vue-loader": "17.3.1", "vue3-calendar-heatmap": "2.0.5", - "webpack": "5.88.2", + "webpack": "5.89.0", "webpack-cli": "5.1.4", - "wrap-ansi": "8.1.0" + "wrap-ansi": "9.0.0" }, "devDependencies": { "@eslint-community/eslint-plugin-eslint-comments": "4.1.0", - "@playwright/test": "1.38.1", + "@playwright/test": "1.39.0", "@stoplight/spectral-cli": "6.11.0", + "@stylistic/eslint-plugin-js": "1.0.0", "@vitejs/plugin-vue": "4.4.0", - "eslint": "8.51.0", + "eslint": "8.53.0", "eslint-plugin-array-func": "4.0.0", - "eslint-plugin-i": "2.28.1", + "eslint-plugin-i": "2.29.0", "eslint-plugin-jquery": "1.5.1", "eslint-plugin-no-jquery": "2.7.0", "eslint-plugin-no-use-extend-native": "0.5.0", - "eslint-plugin-regexp": "2.0.0", - "eslint-plugin-sonarjs": "0.21.0", - "eslint-plugin-unicorn": "48.0.1", - "eslint-plugin-vitest": "0.3.2", + "eslint-plugin-regexp": "2.1.1", + "eslint-plugin-sonarjs": "0.23.0", + "eslint-plugin-unicorn": "49.0.0", + "eslint-plugin-vitest": "0.3.9", "eslint-plugin-vitest-globals": "1.4.0", - "eslint-plugin-vue": "9.17.0", + "eslint-plugin-vue": "9.18.1", "eslint-plugin-vue-scoped-css": "2.5.1", "eslint-plugin-wc": "2.0.4", "jsdom": "22.1.0", "markdownlint-cli": "0.37.0", "postcss-html": "1.5.0", - "stylelint": "15.10.3", + "stylelint": "15.11.0", "stylelint-declaration-block-no-ignored-properties": "2.7.0", "stylelint-declaration-strict-value": "1.9.2", "stylelint-stylistic": "0.4.3", "svgo": "3.0.2", - "updates": "15.0.2", + "updates": "15.0.4", "vite-string-plugin": "1.1.2", "vitest": "0.34.6" }, diff --git a/poetry.lock b/poetry.lock index b6e04320581..15745cf5407 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. [[package]] name = "click" diff --git a/routers/api/actions/artifacts_utils.go b/routers/api/actions/artifacts_utils.go index 4c939348622..381e7eb16ee 100644 --- a/routers/api/actions/artifacts_utils.go +++ b/routers/api/actions/artifacts_utils.go @@ -58,7 +58,8 @@ func validateArtifactHash(ctx *ArtifactContext, artifactName string) bool { func parseArtifactItemPath(ctx *ArtifactContext) (string, string, bool) { // itemPath is generated from upload-artifact action // it's formatted as {artifact_name}/{artfict_path_in_runner} - itemPath := util.PathJoinRel(ctx.Req.URL.Query().Get("itemPath")) + // act_runner in host mode on Windows, itemPath is joined by Windows slash '\' + itemPath := util.PathJoinRelX(ctx.Req.URL.Query().Get("itemPath")) artifactName := strings.Split(itemPath, "/")[0] artifactPath := strings.TrimPrefix(itemPath, artifactName+"/") if !validateArtifactHash(ctx, artifactName) { diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 53ae8c4d016..cadddb44c39 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -316,10 +316,6 @@ func reqToken() func(ctx *context.APIContext) { return } - if ctx.IsBasicAuth { - ctx.CheckForOTP() - return - } if ctx.IsSigned { return } @@ -344,7 +340,6 @@ func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) { ctx.Error(http.StatusUnauthorized, "reqBasicAuth", "auth required") return } - ctx.CheckForOTP() } } @@ -701,12 +696,6 @@ func bind[T any](_ T) any { } } -// The OAuth2 plugin is expected to be executed first, as it must ignore the user id stored -// in the session (if there is a user id stored in session other plugins might return the user -// object for that id). -// -// The Session plugin is expected to be executed second, in order to skip authentication -// for users that have already signed in. func buildAuthGroup() *auth.Group { group := auth.NewGroup( &auth.OAuth2{}, @@ -786,31 +775,6 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.APIC }) return } - if ctx.IsSigned && ctx.IsBasicAuth { - if skip, ok := ctx.Data["SkipLocalTwoFA"]; ok && skip.(bool) { - return // Skip 2FA - } - twofa, err := auth_model.GetTwoFactorByUID(ctx, ctx.Doer.ID) - if err != nil { - if auth_model.IsErrTwoFactorNotEnrolled(err) { - return // No 2FA enrollment for this user - } - ctx.InternalServerError(err) - return - } - otpHeader := ctx.Req.Header.Get("X-Gitea-OTP") - ok, err := twofa.ValidateTOTP(otpHeader) - if err != nil { - ctx.InternalServerError(err) - return - } - if !ok { - ctx.JSON(http.StatusForbidden, map[string]string{ - "message": "Only signed in user is allowed to call APIs.", - }) - return - } - } } if options.AdminRequired { @@ -961,7 +925,7 @@ func Routes() *web.Route { m.Group("/actions/secrets", func() { m.Combo("/{secretname}"). Put(bind(api.CreateOrUpdateSecretOption{}), user.CreateOrUpdateSecret). - Delete(repo.DeleteSecret) + Delete(user.DeleteSecret) }) m.Get("/followers", user.ListMyFollowers) diff --git a/routers/common/errpage.go b/routers/common/errpage.go index 9c8ccc3388d..923421a29c8 100644 --- a/routers/common/errpage.go +++ b/routers/common/errpage.go @@ -9,6 +9,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -35,20 +36,18 @@ func RenderPanicErrorPage(w http.ResponseWriter, req *http.Request, err any) { httpcache.SetCacheControlInHeader(w.Header(), 0, "no-transform") w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions) - data := middleware.GetContextData(req.Context()) - if data["locale"] == nil { - data = middleware.CommonTemplateContextData() - data["locale"] = middleware.Locale(w, req) - } + tmplCtx := context.TemplateContext{} + tmplCtx["Locale"] = middleware.Locale(w, req) + ctxData := middleware.GetContextData(req.Context()) // This recovery handler could be called without Gitea's web context, so we shouldn't touch that context too much. // Otherwise, the 500-page may cause new panics, eg: cache.GetContextWithData, it makes the developer&users couldn't find the original panic. - user, _ := data[middleware.ContextDataKeySignedUser].(*user_model.User) + user, _ := ctxData[middleware.ContextDataKeySignedUser].(*user_model.User) if !setting.IsProd || (user != nil && user.IsAdmin) { - data["ErrorMsg"] = "PANIC: " + combinedErr + ctxData["ErrorMsg"] = "PANIC: " + combinedErr } - err = templates.HTMLRenderer().HTML(w, http.StatusInternalServerError, string(tplStatus500), data, nil) + err = templates.HTMLRenderer().HTML(w, http.StatusInternalServerError, string(tplStatus500), ctxData, tmplCtx) if err != nil { log.Error("Error occurs again when rendering error page: %v", err) w.WriteHeader(http.StatusInternalServerError) diff --git a/routers/common/errpage_test.go b/routers/common/errpage_test.go index 58a633b2a45..4fd63ba49e7 100644 --- a/routers/common/errpage_test.go +++ b/routers/common/errpage_test.go @@ -26,6 +26,7 @@ func TestRenderPanicErrorPage(t *testing.T) { respContent := w.Body.String() assert.Contains(t, respContent, `class="page-content status-page-500"`) assert.Contains(t, respContent, ``) + assert.Contains(t, respContent, `lang="en-US"`) // make sure the locale work // the 500 page doesn't have normal pages footer, it makes it easier to distinguish a normal page and a failed page. // especially when a sub-template causes page error, the HTTP response code is still 200, diff --git a/routers/web/admin/auths.go b/routers/web/admin/auths.go index da91e31efe1..23946d64afa 100644 --- a/routers/web/admin/auths.go +++ b/routers/web/admin/auths.go @@ -48,13 +48,13 @@ func Authentications(ctx *context.Context) { ctx.Data["PageIsAdminAuthentications"] = true var err error - ctx.Data["Sources"], err = auth.Sources(ctx) + ctx.Data["Sources"], err = auth.FindSources(ctx, auth.FindSourcesOptions{}) if err != nil { ctx.ServerError("auth.Sources", err) return } - ctx.Data["Total"] = auth.CountSources(ctx) + ctx.Data["Total"] = auth.CountSources(ctx, auth.FindSourcesOptions{}) ctx.HTML(http.StatusOK, tplAuths) } @@ -99,7 +99,7 @@ func NewAuthSource(ctx *context.Context) { ctx.Data["AuthSources"] = authSources ctx.Data["SecurityProtocols"] = securityProtocols ctx.Data["SMTPAuths"] = smtp.Authenticators - oauth2providers := oauth2.GetOAuth2Providers() + oauth2providers := oauth2.GetSupportedOAuth2Providers() ctx.Data["OAuth2Providers"] = oauth2providers ctx.Data["SSPIAutoCreateUsers"] = true @@ -242,7 +242,7 @@ func NewAuthSourcePost(ctx *context.Context) { ctx.Data["AuthSources"] = authSources ctx.Data["SecurityProtocols"] = securityProtocols ctx.Data["SMTPAuths"] = smtp.Authenticators - oauth2providers := oauth2.GetOAuth2Providers() + oauth2providers := oauth2.GetSupportedOAuth2Providers() ctx.Data["OAuth2Providers"] = oauth2providers ctx.Data["SSPIAutoCreateUsers"] = true @@ -284,7 +284,7 @@ func NewAuthSourcePost(ctx *context.Context) { ctx.RenderWithErr(err.Error(), tplAuthNew, form) return } - existing, err := auth.SourcesByType(ctx, auth.SSPI) + existing, err := auth.FindSources(ctx, auth.FindSourcesOptions{LoginType: auth.SSPI}) if err != nil || len(existing) > 0 { ctx.Data["Err_Type"] = true ctx.RenderWithErr(ctx.Tr("admin.auths.login_source_of_type_exist"), tplAuthNew, form) @@ -334,7 +334,7 @@ func EditAuthSource(ctx *context.Context) { ctx.Data["SecurityProtocols"] = securityProtocols ctx.Data["SMTPAuths"] = smtp.Authenticators - oauth2providers := oauth2.GetOAuth2Providers() + oauth2providers := oauth2.GetSupportedOAuth2Providers() ctx.Data["OAuth2Providers"] = oauth2providers source, err := auth.GetSourceByID(ctx, ctx.ParamsInt64(":authid")) @@ -368,7 +368,7 @@ func EditAuthSourcePost(ctx *context.Context) { ctx.Data["PageIsAdminAuthentications"] = true ctx.Data["SMTPAuths"] = smtp.Authenticators - oauth2providers := oauth2.GetOAuth2Providers() + oauth2providers := oauth2.GetSupportedOAuth2Providers() ctx.Data["OAuth2Providers"] = oauth2providers source, err := auth.GetSourceByID(ctx, ctx.ParamsInt64(":authid")) diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go index 91a578fb554..630d739836b 100644 --- a/routers/web/admin/users.go +++ b/routers/web/admin/users.go @@ -90,7 +90,9 @@ func NewUser(ctx *context.Context) { ctx.Data["login_type"] = "0-0" - sources, err := auth.Sources(ctx) + sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{ + IsActive: util.OptionalBoolTrue, + }) if err != nil { ctx.ServerError("auth.Sources", err) return @@ -109,7 +111,9 @@ func NewUserPost(ctx *context.Context) { ctx.Data["DefaultUserVisibilityMode"] = setting.Service.DefaultUserVisibilityMode ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice() - sources, err := auth.Sources(ctx) + sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{ + IsActive: util.OptionalBoolTrue, + }) if err != nil { ctx.ServerError("auth.Sources", err) return @@ -230,7 +234,7 @@ func prepareUserInfo(ctx *context.Context) *user_model.User { ctx.Data["LoginSource"] = &auth.Source{} } - sources, err := auth.Sources(ctx) + sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{}) if err != nil { ctx.ServerError("auth.Sources", err) return nil diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index e27307ef1af..0ea91fc759a 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -160,12 +160,11 @@ func SignIn(ctx *context.Context) { return } - orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx) + oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, util.OptionalBoolTrue) if err != nil { ctx.ServerError("UserSignIn", err) return } - ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names ctx.Data["OAuth2Providers"] = oauth2Providers ctx.Data["Title"] = ctx.Tr("sign_in") ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login" @@ -184,12 +183,11 @@ func SignIn(ctx *context.Context) { func SignInPost(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("sign_in") - orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx) + oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, util.OptionalBoolTrue) if err != nil { ctx.ServerError("UserSignIn", err) return } - ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names ctx.Data["OAuth2Providers"] = oauth2Providers ctx.Data["Title"] = ctx.Tr("sign_in") ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login" @@ -408,13 +406,12 @@ func SignUp(ctx *context.Context) { ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up" - orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx) + oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, util.OptionalBoolTrue) if err != nil { ctx.ServerError("UserSignUp", err) return } - ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names ctx.Data["OAuth2Providers"] = oauth2Providers context.SetCaptchaData(ctx) @@ -438,13 +435,12 @@ func SignUpPost(ctx *context.Context) { ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up" - orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx) + oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, util.OptionalBoolTrue) if err != nil { ctx.ServerError("UserSignUp", err) return } - ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names ctx.Data["OAuth2Providers"] = oauth2Providers context.SetCaptchaData(ctx) diff --git a/routers/web/githttp.go b/routers/web/githttp.go new file mode 100644 index 00000000000..b2fb5b472f7 --- /dev/null +++ b/routers/web/githttp.go @@ -0,0 +1,43 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package web + +import ( + "net/http" + + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/routers/web/repo" + context_service "code.gitea.io/gitea/services/context" +) + +func requireSignIn(ctx *context.Context) { + if !setting.Service.RequireSignInView { + return + } + + // rely on the results of Contexter + if !ctx.IsSigned { + // TODO: support digit auth - which would be Authorization header with digit + ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea"`) + ctx.Error(http.StatusUnauthorized) + } +} + +func gitHTTPRouters(m *web.Route) { + m.Group("", func() { + m.PostOptions("/git-upload-pack", repo.ServiceUploadPack) + m.PostOptions("/git-receive-pack", repo.ServiceReceivePack) + m.GetOptions("/info/refs", repo.GetInfoRefs) + m.GetOptions("/HEAD", repo.GetTextFile("HEAD")) + m.GetOptions("/objects/info/alternates", repo.GetTextFile("objects/info/alternates")) + m.GetOptions("/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates")) + m.GetOptions("/objects/info/packs", repo.GetInfoPacks) + m.GetOptions("/objects/info/{file:[^/]*}", repo.GetTextFile("")) + m.GetOptions("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject) + m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile) + m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile) + }, ignSignInAndCsrf, requireSignIn, repo.HTTPGitEnabledHandler, repo.CorsHandler(), context_service.UserAssignmentWeb()) +} diff --git a/routers/web/repo/http.go b/routers/web/repo/githttp.go similarity index 100% rename from routers/web/repo/http.go rename to routers/web/repo/githttp.go diff --git a/routers/web/repo/http_test.go b/routers/web/repo/githttp_test.go similarity index 100% rename from routers/web/repo/http_test.go rename to routers/web/repo/githttp_test.go diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 96fce488782..94300da8683 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1773,7 +1773,7 @@ func ViewIssue(ctx *context.Context) { pull := issue.PullRequest pull.Issue = issue canDelete := false - ctx.Data["AllowMerge"] = false + allowMerge := false if ctx.IsSigned { if err := pull.LoadHeadRepo(ctx); err != nil { @@ -1806,7 +1806,7 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("GetUserRepoPermission", err) return } - ctx.Data["AllowMerge"], err = pull_service.IsUserAllowedToMerge(ctx, pull, perm, ctx.Doer) + allowMerge, err = pull_service.IsUserAllowedToMerge(ctx, pull, perm, ctx.Doer) if err != nil { ctx.ServerError("IsUserAllowedToMerge", err) return @@ -1818,6 +1818,8 @@ func ViewIssue(ctx *context.Context) { } } + ctx.Data["AllowMerge"] = allowMerge + prUnit, err := repo.GetUnit(ctx, unit.TypePullRequests) if err != nil { ctx.ServerError("GetUnit", err) @@ -1927,7 +1929,7 @@ func ViewIssue(ctx *context.Context) { if pull.CanAutoMerge() || pull.IsWorkInProgress(ctx) || pull.IsChecking() { return false } - if (ctx.Doer.IsAdmin || ctx.Repo.IsAdmin()) && prConfig.AllowManualMerge { + if allowMerge && prConfig.AllowManualMerge { return true } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 4dfa01d8e2a..89bb1839e17 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -716,14 +716,11 @@ func checkCitationFile(ctx *context.Context, entry *git.TreeEntry) { return } defer dataRc.Close() - buf := make([]byte, 1024) - n, err := util.ReadAtMost(dataRc, buf) + ctx.PageData["citationFileContent"], err = blob.GetBlobContent(setting.UI.MaxDisplayFileSize) if err != nil { - ctx.ServerError("ReadAtMost", err) + ctx.ServerError("GetBlobContent", err) return } - buf = buf[:n] - ctx.PageData["citationFileContent"] = string(buf) break } } diff --git a/routers/web/user/setting/security/security.go b/routers/web/user/setting/security/security.go index c687f7314d4..ec269776e2b 100644 --- a/routers/web/user/setting/security/security.go +++ b/routers/web/user/setting/security/security.go @@ -6,12 +6,14 @@ package security import ( "net/http" + "sort" auth_model "code.gitea.io/gitea/models/auth" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/auth/source/oauth2" ) @@ -105,11 +107,31 @@ func loadSecurityData(ctx *context.Context) { } ctx.Data["AccountLinks"] = sources - orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx) + authSources, err := auth_model.FindSources(ctx, auth_model.FindSourcesOptions{ + IsActive: util.OptionalBoolNone, + LoginType: auth_model.OAuth2, + }) if err != nil { - ctx.ServerError("GetActiveOAuth2Providers", err) + ctx.ServerError("FindSources", err) return } + + var orderedOAuth2Names []string + oauth2Providers := make(map[string]oauth2.Provider) + for _, source := range authSources { + provider, err := oauth2.CreateProviderFromSource(source) + if err != nil { + ctx.ServerError("CreateProviderFromSource", err) + return + } + oauth2Providers[source.Name] = provider + if source.IsActive { + orderedOAuth2Names = append(orderedOAuth2Names, source.Name) + } + } + + sort.Strings(orderedOAuth2Names) + ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names ctx.Data["OAuth2Providers"] = oauth2Providers diff --git a/routers/web/web.go b/routers/web/web.go index 2fb4c155493..a485436da5b 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -276,6 +276,8 @@ func Routes() *web.Route { return routes } +var ignSignInAndCsrf = verifyAuthWithOptions(&common.VerifyOptions{DisableCSRF: true}) + // registerRoutes register routes func registerRoutes(m *web.Route) { reqSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: true}) @@ -283,7 +285,7 @@ func registerRoutes(m *web.Route) { // TODO: rename them to "optSignIn", which means that the "sign-in" could be optional, depends on the VerifyOptions (RequireSignInView) ignSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: setting.Service.RequireSignInView}) ignExploreSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView}) - ignSignInAndCsrf := verifyAuthWithOptions(&common.VerifyOptions{DisableCSRF: true}) + validation.AddBindingRules() linkAccountEnabled := func(ctx *context.Context) { @@ -1513,19 +1515,7 @@ func registerRoutes(m *web.Route) { }) }, ignSignInAndCsrf, lfsServerEnabled) - m.Group("", func() { - m.PostOptions("/git-upload-pack", repo.ServiceUploadPack) - m.PostOptions("/git-receive-pack", repo.ServiceReceivePack) - m.GetOptions("/info/refs", repo.GetInfoRefs) - m.GetOptions("/HEAD", repo.GetTextFile("HEAD")) - m.GetOptions("/objects/info/alternates", repo.GetTextFile("objects/info/alternates")) - m.GetOptions("/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates")) - m.GetOptions("/objects/info/packs", repo.GetInfoPacks) - m.GetOptions("/objects/info/{file:[^/]*}", repo.GetTextFile("")) - m.GetOptions("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject) - m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile) - m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile) - }, ignSignInAndCsrf, repo.HTTPGitEnabledHandler, repo.CorsHandler(), context_service.UserAssignmentWeb()) + gitHTTPRouters(m) }) }) // ***** END: Repository ***** diff --git a/services/auth/basic.go b/services/auth/basic.go index 6c3fbf595e4..1184d12d1c4 100644 --- a/services/auth/basic.go +++ b/services/auth/basic.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web/middleware" ) @@ -131,11 +132,30 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore return nil, err } - if skipper, ok := source.Cfg.(LocalTwoFASkipper); ok && skipper.IsSkipLocalTwoFA() { - store.GetData()["SkipLocalTwoFA"] = true + if skipper, ok := source.Cfg.(LocalTwoFASkipper); !ok || !skipper.IsSkipLocalTwoFA() { + if err := validateTOTP(req, u); err != nil { + return nil, err + } } log.Trace("Basic Authorization: Logged in user %-v", u) return u, nil } + +func validateTOTP(req *http.Request, u *user_model.User) error { + twofa, err := auth_model.GetTwoFactorByUID(req.Context(), u.ID) + if err != nil { + if auth_model.IsErrTwoFactorNotEnrolled(err) { + // No 2FA enrollment for this user + return nil + } + return err + } + if ok, err := twofa.ValidateTOTP(req.Header.Get("X-Gitea-OTP")); err != nil { + return err + } else if !ok { + return util.NewInvalidArgumentErrorf("invalid provided OTP") + } + return nil +} diff --git a/services/auth/signin.go b/services/auth/signin.go index 5fdf6d2bd7a..2e534536817 100644 --- a/services/auth/signin.go +++ b/services/auth/signin.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/auth/source/oauth2" "code.gitea.io/gitea/services/auth/source/smtp" @@ -85,7 +86,9 @@ func UserSignIn(ctx context.Context, username, password string) (*user_model.Use } } - sources, err := auth.AllActiveSources(ctx) + sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{ + IsActive: util.OptionalBoolTrue, + }) if err != nil { return nil, nil, err } diff --git a/services/auth/source/oauth2/init.go b/services/auth/source/oauth2/init.go index cfaddaa35d5..0ebbdaebd41 100644 --- a/services/auth/source/oauth2/init.go +++ b/services/auth/source/oauth2/init.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "github.com/google/uuid" "github.com/gorilla/sessions" @@ -63,7 +64,13 @@ func ResetOAuth2(ctx context.Context) error { // initOAuth2Sources is used to load and register all active OAuth2 providers func initOAuth2Sources(ctx context.Context) error { - authSources, _ := auth.GetActiveOAuth2ProviderSources(ctx) + authSources, err := auth.FindSources(ctx, auth.FindSourcesOptions{ + IsActive: util.OptionalBoolTrue, + LoginType: auth.OAuth2, + }) + if err != nil { + return err + } for _, source := range authSources { oauth2Source, ok := source.Cfg.(*Source) if !ok { diff --git a/services/auth/source/oauth2/providers.go b/services/auth/source/oauth2/providers.go index cd158614a2e..3b45b252f70 100644 --- a/services/auth/source/oauth2/providers.go +++ b/services/auth/source/oauth2/providers.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "github.com/markbates/goth" ) @@ -80,10 +81,10 @@ func RegisterGothProvider(provider GothProvider) { gothProviders[provider.Name()] = provider } -// GetOAuth2Providers returns the map of unconfigured OAuth2 providers +// GetSupportedOAuth2Providers returns the map of unconfigured OAuth2 providers // key is used as technical name (like in the callbackURL) // values to display -func GetOAuth2Providers() []Provider { +func GetSupportedOAuth2Providers() []Provider { providers := make([]Provider, 0, len(gothProviders)) for _, provider := range gothProviders { @@ -95,33 +96,39 @@ func GetOAuth2Providers() []Provider { return providers } -// GetActiveOAuth2Providers returns the map of configured active OAuth2 providers -// key is used as technical name (like in the callbackURL) -// values to display -func GetActiveOAuth2Providers(ctx context.Context) ([]string, map[string]Provider, error) { - // Maybe also separate used and unused providers so we can force the registration of only 1 active provider for each type +func CreateProviderFromSource(source *auth.Source) (Provider, error) { + oauth2Cfg, ok := source.Cfg.(*Source) + if !ok { + return nil, fmt.Errorf("invalid OAuth2 source config: %v", oauth2Cfg) + } + gothProv := gothProviders[oauth2Cfg.Provider] + return &AuthSourceProvider{GothProvider: gothProv, sourceName: source.Name, iconURL: oauth2Cfg.IconURL}, nil +} - authSources, err := auth.GetActiveOAuth2ProviderSources(ctx) +// GetOAuth2Providers returns the list of configured OAuth2 providers +func GetOAuth2Providers(ctx context.Context, isActive util.OptionalBool) ([]Provider, error) { + authSources, err := auth.FindSources(ctx, auth.FindSourcesOptions{ + IsActive: isActive, + LoginType: auth.OAuth2, + }) if err != nil { - return nil, nil, err + return nil, err } - var orderedKeys []string - providers := make(map[string]Provider) + providers := make([]Provider, 0, len(authSources)) for _, source := range authSources { - oauth2Cfg, ok := source.Cfg.(*Source) - if !ok { - log.Error("Invalid OAuth2 source config: %v", oauth2Cfg) - continue + provider, err := CreateProviderFromSource(source) + if err != nil { + return nil, err } - gothProv := gothProviders[oauth2Cfg.Provider] - providers[source.Name] = &AuthSourceProvider{GothProvider: gothProv, sourceName: source.Name, iconURL: oauth2Cfg.IconURL} - orderedKeys = append(orderedKeys, source.Name) + providers = append(providers, provider) } - sort.Strings(orderedKeys) + sort.Slice(providers, func(i, j int) bool { + return providers[i].Name() < providers[j].Name() + }) - return orderedKeys, providers, nil + return providers, nil } // RegisterProviderWithGothic register a OAuth2 provider in goth lib diff --git a/services/auth/sspi.go b/services/auth/sspi.go index 573d94b42c2..bc8ec948f29 100644 --- a/services/auth/sspi.go +++ b/services/auth/sspi.go @@ -130,7 +130,10 @@ func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, // getConfig retrieves the SSPI configuration from login sources func (s *SSPI) getConfig(ctx context.Context) (*sspi.Source, error) { - sources, err := auth.ActiveSources(ctx, auth.SSPI) + sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{ + IsActive: util.OptionalBoolTrue, + LoginType: auth.SSPI, + }) if err != nil { return nil, err } diff --git a/services/auth/sync.go b/services/auth/sync.go index 25b9460b992..11a59d41ae1 100644 --- a/services/auth/sync.go +++ b/services/auth/sync.go @@ -15,7 +15,7 @@ import ( func SyncExternalUsers(ctx context.Context, updateExisting bool) error { log.Trace("Doing: SyncExternalUsers") - ls, err := auth.Sources(ctx) + ls, err := auth.FindSources(ctx, auth.FindSourcesOptions{}) if err != nil { log.Error("SyncExternalUsers: %v", err) return err diff --git a/services/convert/package.go b/services/convert/package.go index 276856594bb..e90ce8a00f8 100644 --- a/services/convert/package.go +++ b/services/convert/package.go @@ -35,6 +35,7 @@ func ToPackage(ctx context.Context, pd *packages.PackageDescriptor, doer *user_m Name: pd.Package.Name, Version: pd.Version.Version, CreatedAt: pd.Version.CreatedUnix.AsTime(), + HTMLURL: pd.FullWebLink(), }, nil } diff --git a/services/mailer/mail.go b/services/mailer/mail.go index 0210128046e..1f139d233ff 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -26,7 +26,6 @@ import ( "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/translation" incoming_payload "code.gitea.io/gitea/services/mailer/incoming/payload" @@ -68,15 +67,12 @@ func SendTestMail(email string) error { func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, subject, info string) { locale := translation.NewLocale(language) data := map[string]any{ + "locale": locale, "DisplayName": u.DisplayName(), "ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale), "ResetPwdCodeLives": timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, locale), "Code": code, "Language": locale.Language(), - // helper - "locale": locale, - "Str2html": templates.Str2html, - "DotEscape": templates.DotEscape, } var content bytes.Buffer @@ -119,15 +115,12 @@ func SendActivateEmailMail(u *user_model.User, email *user_model.EmailAddress) { } locale := translation.NewLocale(u.Language) data := map[string]any{ + "locale": locale, "DisplayName": u.DisplayName(), "ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale), "Code": u.GenerateEmailActivateCode(email.Email), "Email": email.Email, "Language": locale.Language(), - // helper - "locale": locale, - "Str2html": templates.Str2html, - "DotEscape": templates.DotEscape, } var content bytes.Buffer @@ -152,13 +145,10 @@ func SendRegisterNotifyMail(u *user_model.User) { locale := translation.NewLocale(u.Language) data := map[string]any{ + "locale": locale, "DisplayName": u.DisplayName(), "Username": u.Name, "Language": locale.Language(), - // helper - "locale": locale, - "Str2html": templates.Str2html, - "DotEscape": templates.DotEscape, } var content bytes.Buffer @@ -185,14 +175,11 @@ func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository) subject := locale.Tr("mail.repo.collaborator.added.subject", doer.DisplayName(), repoName) data := map[string]any{ + "locale": locale, "Subject": subject, "RepoName": repoName, "Link": repo.HTMLURL(), "Language": locale.Language(), - // helper - "locale": locale, - "Str2html": templates.Str2html, - "DotEscape": templates.DotEscape, } var content bytes.Buffer @@ -259,6 +246,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient locale := translation.NewLocale(lang) mailMeta := map[string]any{ + "locale": locale, "FallbackSubject": fallback, "Body": body, "Link": link, @@ -275,10 +263,6 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient "ReviewComments": reviewComments, "Language": locale.Language(), "CanReply": setting.IncomingEmail.Enabled && commentType != issues_model.CommentTypePullRequestPush, - // helper - "locale": locale, - "Str2html": templates.Str2html, - "DotEscape": templates.DotEscape, } var mailSubject bytes.Buffer @@ -469,7 +453,7 @@ func SendIssueAssignedMail(ctx context.Context, issue *issues_model.Issue, doer if err != nil { return err } - SendAsyncs(msgs) + SendAsync(msgs...) } return nil } diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go index baa9f1d9abe..fab3315be21 100644 --- a/services/mailer/mail_issue.go +++ b/services/mailer/mail_issue.go @@ -162,7 +162,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi if err != nil { return err } - SendAsyncs(msgs) + SendAsync(msgs...) receivers = receivers[:i] } } diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go index 7bc3db3fe6c..88973a6be21 100644 --- a/services/mailer/mail_release.go +++ b/services/mailer/mail_release.go @@ -14,7 +14,6 @@ import ( "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/translation" ) @@ -69,13 +68,10 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo subject := locale.Tr("mail.release.new.subject", rel.TagName, rel.Repo.FullName()) mailMeta := map[string]any{ + "locale": locale, "Release": rel, "Subject": subject, "Language": locale.Language(), - // helper - "locale": locale, - "Str2html": templates.Str2html, - "DotEscape": templates.DotEscape, } var mailBody bytes.Buffer @@ -95,5 +91,5 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo msgs = append(msgs, msg) } - SendAsyncs(msgs) + SendAsync(msgs...) } diff --git a/services/mailer/mail_repo.go b/services/mailer/mail_repo.go index e9c1991b5b8..b89dcd43b55 100644 --- a/services/mailer/mail_repo.go +++ b/services/mailer/mail_repo.go @@ -12,7 +12,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/translation" ) @@ -65,6 +64,7 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U } data := map[string]any{ + "locale": locale, "Doer": doer, "User": repo.Owner, "Repo": repo.FullName(), @@ -72,10 +72,6 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U "Subject": subject, "Language": locale.Language(), "Destination": destination, - // helper - "locale": locale, - "Str2html": templates.Str2html, - "DotEscape": templates.DotEscape, } if err := bodyTemplates.ExecuteTemplate(&content, string(mailRepoTransferNotify), data); err != nil { diff --git a/services/mailer/mail_team_invite.go b/services/mailer/mail_team_invite.go index 88ad0c98365..ab32beeface 100644 --- a/services/mailer/mail_team_invite.go +++ b/services/mailer/mail_team_invite.go @@ -14,7 +14,6 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/translation" ) @@ -53,16 +52,13 @@ func MailTeamInvite(ctx context.Context, inviter *user_model.User, team *org_mod subject := locale.Tr("mail.team_invite.subject", inviter.DisplayName(), org.DisplayName()) mailMeta := map[string]any{ + "locale": locale, "Inviter": inviter, "Organization": org, "Team": team, "Invite": invite, "Subject": subject, "InviteURL": inviteURL, - // helper - "locale": locale, - "Str2html": templates.Str2html, - "DotEscape": templates.DotEscape, } var mailBody bytes.Buffer diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index 42d7d5ad5db..5e8e3dbb38c 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -425,15 +425,12 @@ func NewContext(ctx context.Context) { go graceful.GetManager().RunWithCancel(mailQueue) } -// SendAsync send mail asynchronously -func SendAsync(msg *Message) { - SendAsyncs([]*Message{msg}) -} +// SendAsync send emails asynchronously (make it mockable) +var SendAsync = sendAsync -// SendAsyncs send mails asynchronously -func SendAsyncs(msgs []*Message) { +func sendAsync(msgs ...*Message) { if setting.MailService == nil { - log.Error("Mailer: SendAsyncs is being invoked but mail service hasn't been initialized") + log.Error("Mailer: SendAsync is being invoked but mail service hasn't been initialized") return } diff --git a/services/migrations/gitea_downloader.go b/services/migrations/gitea_downloader.go index b9ba93325b9..d402a238f27 100644 --- a/services/migrations/gitea_downloader.go +++ b/services/migrations/gitea_downloader.go @@ -282,6 +282,8 @@ func (g *GiteaDownloader) convertGiteaRelease(rel *gitea_sdk.Release) *base.Rele httpClient := NewMigrationHTTPClient() for _, asset := range rel.Attachments { + assetID := asset.ID // Don't optimize this, for closure we need a local variable + assetDownloadURL := asset.DownloadURL size := int(asset.Size) dlCount := int(asset.DownloadCount) r.Assets = append(r.Assets, &base.ReleaseAsset{ @@ -292,18 +294,18 @@ func (g *GiteaDownloader) convertGiteaRelease(rel *gitea_sdk.Release) *base.Rele Created: asset.Created, DownloadURL: &asset.DownloadURL, DownloadFunc: func() (io.ReadCloser, error) { - asset, _, err := g.client.GetReleaseAttachment(g.repoOwner, g.repoName, rel.ID, asset.ID) + asset, _, err := g.client.GetReleaseAttachment(g.repoOwner, g.repoName, rel.ID, assetID) if err != nil { return nil, err } - if !hasBaseURL(asset.DownloadURL, g.baseURL) { - WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", asset.ID, g, asset.DownloadURL) + if !hasBaseURL(assetDownloadURL, g.baseURL) { + WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", assetID, g, assetDownloadURL) return io.NopCloser(strings.NewReader(asset.DownloadURL)), nil } // FIXME: for a private download? - req, err := http.NewRequest("GET", asset.DownloadURL, nil) + req, err := http.NewRequest("GET", assetDownloadURL, nil) if err != nil { return nil, err } diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go index f626036254e..22bc4cf8f39 100644 --- a/services/migrations/gitlab.go +++ b/services/migrations/gitlab.go @@ -310,6 +310,7 @@ func (g *GitlabDownloader) convertGitlabRelease(rel *gitlab.Release) *base.Relea httpClient := NewMigrationHTTPClient() for k, asset := range rel.Assets.Links { + assetID := asset.ID // Don't optimize this, for closure we need a local variable r.Assets = append(r.Assets, &base.ReleaseAsset{ ID: int64(asset.ID), Name: asset.Name, @@ -317,13 +318,13 @@ func (g *GitlabDownloader) convertGitlabRelease(rel *gitlab.Release) *base.Relea Size: &zero, DownloadCount: &zero, DownloadFunc: func() (io.ReadCloser, error) { - link, _, err := g.client.ReleaseLinks.GetReleaseLink(g.repoID, rel.TagName, asset.ID, gitlab.WithContext(g.ctx)) + link, _, err := g.client.ReleaseLinks.GetReleaseLink(g.repoID, rel.TagName, assetID, gitlab.WithContext(g.ctx)) if err != nil { return nil, err } if !hasBaseURL(link.URL, g.baseURL) { - WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", asset.ID, g, link.URL) + WarnAndNotice("Unexpected AssetURL for assetID[%d] in %s: %s", assetID, g, link.URL) return io.NopCloser(strings.NewReader(link.URL)), nil } @@ -528,11 +529,13 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque perPage = g.maxPerPage } + view := "simple" opt := &gitlab.ListProjectMergeRequestsOptions{ ListOptions: gitlab.ListOptions{ PerPage: perPage, Page: page, }, + View: &view, } allPRs := make([]*base.PullRequest, 0, perPage) @@ -541,7 +544,13 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque if err != nil { return nil, false, fmt.Errorf("error while listing merge requests: %w", err) } - for _, pr := range prs { + for _, simplePR := range prs { + // Load merge request again by itself, as not all fields are populated in the ListProjectMergeRequests endpoint. + // See https://gitlab.com/gitlab-org/gitlab/-/issues/29620 + pr, _, err := g.client.MergeRequests.GetMergeRequest(g.repoID, simplePR.IID, nil) + if err != nil { + return nil, false, fmt.Errorf("error while loading merge request: %w", err) + } labels := make([]*base.Label, 0, len(pr.Labels)) for _, l := range pr.Labels { @@ -566,6 +575,11 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque closeTime = pr.UpdatedAt } + mergeCommitSHA := pr.MergeCommitSHA + if mergeCommitSHA == "" { + mergeCommitSHA = pr.SquashCommitSHA + } + var locked bool if pr.State == "locked" { locked = true @@ -608,7 +622,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque Closed: closeTime, Labels: labels, Merged: merged, - MergeCommitSHA: pr.MergeCommitSHA, + MergeCommitSHA: mergeCommitSHA, MergedTime: mergeTime, IsLocked: locked, Reactions: g.awardsToReactions(reactions), diff --git a/services/packages/alpine/repository.go b/services/packages/alpine/repository.go index eeda0cca7bc..46093d5bdd2 100644 --- a/services/packages/alpine/repository.go +++ b/services/packages/alpine/repository.go @@ -238,6 +238,8 @@ func buildPackagesIndex(ctx context.Context, ownerID int64, repoVersion *package } unsignedIndexContent, _ := packages_module.NewHashedBuffer() + defer unsignedIndexContent.Close() + h := sha1.New() if err := writeGzipStream(io.MultiWriter(unsignedIndexContent, h), "APKINDEX", buf.Bytes(), true); err != nil { @@ -275,6 +277,7 @@ func buildPackagesIndex(ctx context.Context, ownerID int64, repoVersion *package } signedIndexContent, _ := packages_module.NewHashedBuffer() + defer signedIndexContent.Close() if err := writeGzipStream( signedIndexContent, diff --git a/services/packages/debian/repository.go b/services/packages/debian/repository.go index 25fa8073514..cbde53f9611 100644 --- a/services/packages/debian/repository.go +++ b/services/packages/debian/repository.go @@ -165,18 +165,17 @@ func buildRepositoryFiles(ctx context.Context, ownerID int64, repoVersion *packa // https://wiki.debian.org/DebianRepository/Format#A.22Packages.22_Indices func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packages_model.PackageVersion, distribution, component, architecture string) error { - pfds, err := debian_model.SearchLatestPackages(ctx, &debian_model.PackageSearchOptions{ + opts := &debian_model.PackageSearchOptions{ OwnerID: ownerID, Distribution: distribution, Component: component, Architecture: architecture, - }) - if err != nil { - return err } // Delete the package indices if there are no packages - if len(pfds) == 0 { + if has, err := debian_model.ExistPackages(ctx, opts); err != nil { + return err + } else if !has { key := fmt.Sprintf("%s|%s|%s", distribution, component, architecture) for _, filename := range []string{"Packages", "Packages.gz", "Packages.xz"} { pf, err := packages_model.GetFileForVersionByName(ctx, repoVersion.ID, filename, key) @@ -196,17 +195,22 @@ func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packa } packagesContent, _ := packages_module.NewHashedBuffer() + defer packagesContent.Close() packagesGzipContent, _ := packages_module.NewHashedBuffer() + defer packagesGzipContent.Close() + gzw := gzip.NewWriter(packagesGzipContent) packagesXzContent, _ := packages_module.NewHashedBuffer() + defer packagesXzContent.Close() + xzw, _ := xz.NewWriter(packagesXzContent) w := io.MultiWriter(packagesContent, gzw, xzw) addSeparator := false - for _, pfd := range pfds { + if err := debian_model.SearchPackages(ctx, opts, func(pfd *packages_model.PackageFileDescriptor) { if addSeparator { fmt.Fprintln(w) } @@ -220,6 +224,8 @@ func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packa fmt.Fprintf(w, "SHA1: %s\n", pfd.Blob.HashSHA1) fmt.Fprintf(w, "SHA256: %s\n", pfd.Blob.HashSHA256) fmt.Fprintf(w, "SHA512: %s\n", pfd.Blob.HashSHA512) + }); err != nil { + return err } gzw.Close() @@ -233,7 +239,7 @@ func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packa {"Packages.gz", packagesGzipContent}, {"Packages.xz", packagesXzContent}, } { - _, err = packages_service.AddFileToPackageVersionInternal( + _, err := packages_service.AddFileToPackageVersionInternal( ctx, repoVersion, &packages_service.PackageFileCreationInfo{ @@ -323,6 +329,8 @@ func buildReleaseFiles(ctx context.Context, ownerID int64, repoVersion *packages } inReleaseContent, _ := packages_module.NewHashedBuffer() + defer inReleaseContent.Close() + sw, err := clearsign.Encode(inReleaseContent, e.PrivateKey, nil) if err != nil { return err @@ -367,11 +375,14 @@ func buildReleaseFiles(ctx context.Context, ownerID int64, repoVersion *packages sw.Close() releaseGpgContent, _ := packages_module.NewHashedBuffer() + defer releaseGpgContent.Close() + if err := openpgp.ArmoredDetachSign(releaseGpgContent, e, bytes.NewReader(buf.Bytes()), nil); err != nil { return err } releaseContent, _ := packages_module.CreateHashedBufferFromReader(&buf) + defer releaseContent.Close() for _, file := range []struct { Name string diff --git a/services/packages/rpm/repository.go b/services/packages/rpm/repository.go index 93d9e41ca81..1d0dc83cae8 100644 --- a/services/packages/rpm/repository.go +++ b/services/packages/rpm/repository.go @@ -258,11 +258,14 @@ func buildRepomd(ctx context.Context, pv *packages_model.PackageVersion, ownerID } repomdAscContent, _ := packages_module.NewHashedBuffer() + defer repomdAscContent.Close() + if err := openpgp.ArmoredDetachSign(repomdAscContent, e, bytes.NewReader(buf.Bytes()), nil); err != nil { return err } repomdContent, _ := packages_module.CreateHashedBufferFromReader(&buf) + defer repomdContent.Close() for _, file := range []struct { Name string @@ -548,6 +551,8 @@ func (wc *writtenCounter) Written() int64 { func addDataAsFileToRepo(ctx context.Context, pv *packages_model.PackageVersion, filetype string, obj any) (*repoData, error) { content, _ := packages_module.NewHashedBuffer() + defer content.Close() + gzw := gzip.NewWriter(content) wc := &writtenCounter{} h := sha256.New() diff --git a/services/user/delete.go b/services/user/delete.go index 01e3c37b39f..c4617e064e7 100644 --- a/services/user/delete.go +++ b/services/user/delete.go @@ -10,6 +10,7 @@ import ( _ "image/jpeg" // Needed for jpeg support + actions_model "code.gitea.io/gitea/models/actions" activities_model "code.gitea.io/gitea/models/activities" asymkey_model "code.gitea.io/gitea/models/asymkey" auth_model "code.gitea.io/gitea/models/auth" @@ -90,6 +91,7 @@ func deleteUser(ctx context.Context, u *user_model.User, purge bool) (err error) &pull_model.AutoMerge{DoerID: u.ID}, &pull_model.ReviewState{UserID: u.ID}, &user_model.Redirect{RedirectUserID: u.ID}, + &actions_model.ActionRunner{OwnerID: u.ID}, ); err != nil { return fmt.Errorf("deleteBeans: %w", err) } diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go index c6fbe2f0765..d615e7254f8 100644 --- a/services/webhook/dingtalk.go +++ b/services/webhook/dingtalk.go @@ -173,6 +173,12 @@ func (d *DingtalkPayload) Release(p *api.ReleasePayload) (api.Payloader, error) return createDingtalkPayload(text, text, "view release", p.Release.HTMLURL), nil } +func (d *DingtalkPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, noneLinkFormatter, true) + + return createDingtalkPayload(text, text, "view package", p.Package.HTMLURL), nil +} + func createDingtalkPayload(title, text, singleTitle, singleURL string) *DingtalkPayload { return &DingtalkPayload{ MsgType: "actionCard", diff --git a/services/webhook/discord.go b/services/webhook/discord.go index b22bb4f9121..e2ac1410b8a 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -256,6 +256,12 @@ func (d *DiscordPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { return d.createPayload(p.Sender, text, p.Release.Note, p.Release.HTMLURL, color), nil } +func (d *DiscordPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, color := getPackagePayloadInfo(p, noneLinkFormatter, false) + + return d.createPayload(p.Sender, text, "", p.Package.HTMLURL, color), nil +} + // GetDiscordPayload converts a discord webhook into a DiscordPayload func GetDiscordPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) { s := new(DiscordPayload) diff --git a/services/webhook/feishu.go b/services/webhook/feishu.go index 089f51952fd..556443e70b7 100644 --- a/services/webhook/feishu.go +++ b/services/webhook/feishu.go @@ -16,7 +16,7 @@ import ( type ( // FeishuPayload represents FeishuPayload struct { - MsgType string `json:"msg_type"` // text / post / image / share_chat / interactive + MsgType string `json:"msg_type"` // text / post / image / share_chat / interactive / file /audio / media Content struct { Text string `json:"text"` } `json:"content"` @@ -175,6 +175,12 @@ func (f *FeishuPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { return newFeishuTextPayload(text), nil } +func (f *FeishuPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, noneLinkFormatter, true) + + return newFeishuTextPayload(text), nil +} + // GetFeishuPayload converts a ding talk webhook into a FeishuPayload func GetFeishuPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) { return convertPayloader(new(FeishuPayload), p, event) diff --git a/services/webhook/general.go b/services/webhook/general.go index 986467bc99d..69b944f4bd5 100644 --- a/services/webhook/general.go +++ b/services/webhook/general.go @@ -293,6 +293,24 @@ func getIssueCommentPayloadInfo(p *api.IssueCommentPayload, linkFormatter linkFo return text, issueTitle, color } +func getPackagePayloadInfo(p *api.PackagePayload, linkFormatter linkFormatter, withSender bool) (text string, color int) { + refLink := linkFormatter(p.Package.HTMLURL, p.Package.Name+":"+p.Package.Version) + + switch p.Action { + case api.HookPackageCreated: + text = fmt.Sprintf("Package created: %s", refLink) + color = greenColor + case api.HookPackageDeleted: + text = fmt.Sprintf("Package deleted: %s", refLink) + color = redColor + } + if withSender { + text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + } + + return text, color +} + // ToHook convert models.Webhook to api.Hook // This function is not part of the convert package to prevent an import cycle func ToHook(repoLink string, w *webhook_model.Webhook) (*api.Hook, error) { diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go index a7f57f97b6a..ab7e6b72c25 100644 --- a/services/webhook/matrix.go +++ b/services/webhook/matrix.go @@ -210,6 +210,21 @@ func (m *MatrixPayload) Repository(p *api.RepositoryPayload) (api.Payloader, err return getMatrixPayload(text, nil, m.MsgType), nil } +func (m *MatrixPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + senderLink := MatrixLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) + repoLink := MatrixLinkFormatter(p.Repository.HTMLURL, p.Repository.FullName) + var text string + + switch p.Action { + case api.HookPackageCreated: + text = fmt.Sprintf("[%s] Package published by %s", repoLink, senderLink) + case api.HookPackageDeleted: + text = fmt.Sprintf("[%s] Package deleted by %s", repoLink, senderLink) + } + + return getMatrixPayload(text, nil, m.MsgType), nil +} + // GetMatrixPayload converts a Matrix webhook into a MatrixPayload func GetMatrixPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) { s := new(MatrixPayload) diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go index dfc1c682895..f58da3fe1cd 100644 --- a/services/webhook/msteams.go +++ b/services/webhook/msteams.go @@ -296,6 +296,20 @@ func (m *MSTeamsPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { ), nil } +func (m *MSTeamsPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + title, color := getPackagePayloadInfo(p, noneLinkFormatter, false) + + return createMSTeamsPayload( + p.Repository, + p.Sender, + title, + "", + p.Package.HTMLURL, + color, + &MSTeamsFact{"Package:", p.Package.Name}, + ), nil +} + // GetMSTeamsPayload converts a MSTeams webhook into a MSTeamsPayload func GetMSTeamsPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) { return convertPayloader(new(MSTeamsPayload), p, event) diff --git a/services/webhook/packagist.go b/services/webhook/packagist.go index e47e7d32850..714a4c076ef 100644 --- a/services/webhook/packagist.go +++ b/services/webhook/packagist.go @@ -104,6 +104,10 @@ func (f *PackagistPayload) Release(_ *api.ReleasePayload) (api.Payloader, error) return nil, nil } +func (f *PackagistPayload) Package(_ *api.PackagePayload) (api.Payloader, error) { + return nil, nil +} + // GetPackagistPayload converts a packagist webhook into a PackagistPayload func GetPackagistPayload(p api.Payloader, event webhook_module.HookEventType, meta string) (api.Payloader, error) { s := new(PackagistPayload) diff --git a/services/webhook/payloader.go b/services/webhook/payloader.go index d53e65fa5ee..bd482c04ead 100644 --- a/services/webhook/payloader.go +++ b/services/webhook/payloader.go @@ -22,6 +22,7 @@ type PayloadConvertor interface { Repository(*api.RepositoryPayload) (api.Payloader, error) Release(*api.ReleasePayload) (api.Payloader, error) Wiki(*api.WikiPayload) (api.Payloader, error) + Package(*api.PackagePayload) (api.Payloader, error) } func convertPayloader(s PayloadConvertor, p api.Payloader, event webhook_module.HookEventType) (api.Payloader, error) { @@ -53,6 +54,8 @@ func convertPayloader(s PayloadConvertor, p api.Payloader, event webhook_module. return s.Release(p.(*api.ReleasePayload)) case webhook_module.HookEventWiki: return s.Wiki(p.(*api.WikiPayload)) + case webhook_module.HookEventPackage: + return s.Package(p.(*api.PackagePayload)) } return s, nil } diff --git a/services/webhook/slack.go b/services/webhook/slack.go index 75079d0fdf1..ac27b5bc71b 100644 --- a/services/webhook/slack.go +++ b/services/webhook/slack.go @@ -171,6 +171,12 @@ func (s *SlackPayload) Release(p *api.ReleasePayload) (api.Payloader, error) { return s.createPayload(text, nil), nil } +func (s *SlackPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, SlackLinkFormatter, true) + + return s.createPayload(text, nil), nil +} + // Push implements PayloadConvertor Push method func (s *SlackPayload) Push(p *api.PushPayload) (api.Payloader, error) { // n new commits diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go index ea7e8185def..1bdc74e183a 100644 --- a/services/webhook/telegram.go +++ b/services/webhook/telegram.go @@ -186,6 +186,12 @@ func (t *TelegramPayload) Release(p *api.ReleasePayload) (api.Payloader, error) return createTelegramPayload(text), nil } +func (t *TelegramPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, htmlLinkFormatter, true) + + return createTelegramPayload(text), nil +} + // GetTelegramPayload converts a telegram webhook into a TelegramPayload func GetTelegramPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) { return convertPayloader(new(TelegramPayload), p, event) diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go index a7680f1c671..80245c7e773 100644 --- a/services/webhook/wechatwork.go +++ b/services/webhook/wechatwork.go @@ -179,6 +179,12 @@ func (f *WechatworkPayload) Release(p *api.ReleasePayload) (api.Payloader, error return newWechatworkMarkdownPayload(text), nil } +func (f *WechatworkPayload) Package(p *api.PackagePayload) (api.Payloader, error) { + text, _ := getPackagePayloadInfo(p, noneLinkFormatter, true) + + return newWechatworkMarkdownPayload(text), nil +} + // GetWechatworkPayload GetWechatworkPayload converts a ding talk webhook into a WechatworkPayload func GetWechatworkPayload(p api.Payloader, event webhook_module.HookEventType, _ string) (api.Payloader, error) { return convertPayloader(new(WechatworkPayload), p, event) diff --git a/templates/org/header.tmpl b/templates/org/header.tmpl index 72adf6d9b5a..7b912c1c569 100644 --- a/templates/org/header.tmpl +++ b/templates/org/header.tmpl @@ -2,7 +2,7 @@
-
+
{{ctx.AvatarUtils.Avatar . 100}} {{.DisplayName}} diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl index ff4f3a8b1af..ee3237d45b0 100644 --- a/templates/org/home.tmpl +++ b/templates/org/home.tmpl @@ -3,7 +3,7 @@
{{ctx.AvatarUtils.Avatar .Org 140 "org-avatar"}}
-
+
{{.Org.DisplayName}} {{if .Org.Visibility.IsLimited}}{{ctx.Locale.Tr "org.settings.visibility.limited_shortname"}}{{end}} diff --git a/templates/org/team/teams.tmpl b/templates/org/team/teams.tmpl index 9723294fd6b..830fc8a33ea 100644 --- a/templates/org/team/teams.tmpl +++ b/templates/org/team/teams.tmpl @@ -37,7 +37,7 @@ {{end}}
-

{{.NumMembers}} {{ctx.Locale.Tr "org.lower_members"}} · {{.NumRepos}} {{ctx.Locale.Tr "org.lower_repositories"}}

+

{{.NumMembers}} {{ctx.Locale.Tr "org.lower_members"}} · {{.NumRepos}} {{ctx.Locale.Tr "org.lower_repositories"}}

{{end}} diff --git a/templates/package/metadata/cargo.tmpl b/templates/package/metadata/cargo.tmpl index 9cc0fde7308..c8471a71ef9 100644 --- a/templates/package/metadata/cargo.tmpl +++ b/templates/package/metadata/cargo.tmpl @@ -1,7 +1,7 @@ {{if eq .PackageDescriptor.Package.Type "cargo"}} {{range .PackageDescriptor.Metadata.Authors}}
{{svg "octicon-person" 16 "gt-mr-3"}} {{.}}
{{end}} {{if .PackageDescriptor.Metadata.ProjectURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.project_site"}}
{{end}} - {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.cargo.details.repository_site"}}
{{end}} - {{if .PackageDescriptor.Metadata.DocumentationURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.cargo.details.documentation_site"}}
{{end}} + {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.repository_site"}}
{{end}} + {{if .PackageDescriptor.Metadata.DocumentationURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.documentation_site"}}
{{end}} {{if .PackageDescriptor.Metadata.License}}
{{svg "octicon-law" 16 "gt-mr-3"}} {{.PackageDescriptor.Metadata.License}}
{{end}} {{end}} diff --git a/templates/package/metadata/conan.tmpl b/templates/package/metadata/conan.tmpl index 55892bb9197..40bda555bb6 100644 --- a/templates/package/metadata/conan.tmpl +++ b/templates/package/metadata/conan.tmpl @@ -2,5 +2,5 @@ {{if .PackageDescriptor.Metadata.Author}}
{{svg "octicon-person" 16 "gt-mr-3"}} {{.PackageDescriptor.Metadata.Author}}
{{end}} {{if .PackageDescriptor.Metadata.ProjectURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.project_site"}}
{{end}} {{if .PackageDescriptor.Metadata.License}}
{{svg "octicon-law" 16 "gt-mr-3"}} {{.PackageDescriptor.Metadata.License}}
{{end}} - {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.conan.details.repository"}}
{{end}} + {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.repository_site"}}
{{end}} {{end}} diff --git a/templates/package/metadata/conda.tmpl b/templates/package/metadata/conda.tmpl index fb7c2128630..f70e2b2a1cc 100644 --- a/templates/package/metadata/conda.tmpl +++ b/templates/package/metadata/conda.tmpl @@ -1,6 +1,6 @@ {{if eq .PackageDescriptor.Package.Type "conda"}} {{if .PackageDescriptor.Metadata.License}}
{{svg "octicon-law" 16 "gt-mr-3"}} {{.PackageDescriptor.Metadata.License}}
{{end}} {{if .PackageDescriptor.Metadata.ProjectURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.project_site"}}
{{end}} - {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.conda.details.repository_site"}}
{{end}} - {{if .PackageDescriptor.Metadata.DocumentationURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.conda.details.documentation_site"}}
{{end}} + {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.repository_site"}}
{{end}} + {{if .PackageDescriptor.Metadata.DocumentationURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.documentation_site"}}
{{end}} {{end}} diff --git a/templates/package/metadata/nuget.tmpl b/templates/package/metadata/nuget.tmpl index 48c8d602dd3..f25e1c3b63d 100644 --- a/templates/package/metadata/nuget.tmpl +++ b/templates/package/metadata/nuget.tmpl @@ -1,4 +1,5 @@ {{if eq .PackageDescriptor.Package.Type "nuget"}} {{if .PackageDescriptor.Metadata.Authors}}
{{svg "octicon-person" 16 "gt-mr-3"}} {{.PackageDescriptor.Metadata.Authors}}
{{end}} {{if .PackageDescriptor.Metadata.ProjectURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.project_site"}}
{{end}} + {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.repository_site"}}
{{end}} {{end}} diff --git a/templates/package/metadata/swift.tmpl b/templates/package/metadata/swift.tmpl index 3df38e32009..326ebe1a946 100644 --- a/templates/package/metadata/swift.tmpl +++ b/templates/package/metadata/swift.tmpl @@ -1,4 +1,4 @@ {{if eq .PackageDescriptor.Package.Type "swift"}} {{if .PackageDescriptor.Metadata.Author.String}}
{{svg "octicon-person" 16 "mr-3"}} {{.PackageDescriptor.Metadata.Author}}
{{end}} - {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "mr-3"}} {{ctx.Locale.Tr "packages.details.project_site"}}
{{end}} + {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.repository_site"}}
{{end}} {{end}} diff --git a/templates/package/metadata/vagrant.tmpl b/templates/package/metadata/vagrant.tmpl index 62c50a0dfd7..a92398a2759 100644 --- a/templates/package/metadata/vagrant.tmpl +++ b/templates/package/metadata/vagrant.tmpl @@ -1,5 +1,5 @@ {{if eq .PackageDescriptor.Package.Type "vagrant"}} {{if .PackageDescriptor.Metadata.Author}}
{{svg "octicon-person" 16 "gt-mr-3"}} {{.PackageDescriptor.Metadata.Author}}
{{end}} {{if .PackageDescriptor.Metadata.ProjectURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.project_site"}}
{{end}} - {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.conan.details.repository"}}
{{end}} + {{if .PackageDescriptor.Metadata.RepositoryURL}}
{{svg "octicon-link-external" 16 "gt-mr-3"}} {{ctx.Locale.Tr "packages.details.repository_site"}}
{{end}} {{end}} diff --git a/templates/package/shared/list.tmpl b/templates/package/shared/list.tmpl index af79490f4dd..a572d98bb62 100644 --- a/templates/package/shared/list.tmpl +++ b/templates/package/shared/list.tmpl @@ -38,7 +38,7 @@
{{else}} {{if not .HasPackages}} -
+
{{svg "octicon-package" 48}}

{{ctx.Locale.Tr "packages.empty"}}

{{if and .Repository .CanWritePackages}} diff --git a/templates/repo/actions/runs_list.tmpl b/templates/repo/actions/runs_list.tmpl index 37b19f0bdc3..b3469a2edc3 100644 --- a/templates/repo/actions/runs_list.tmpl +++ b/templates/repo/actions/runs_list.tmpl @@ -1,6 +1,6 @@
{{if eq (len .Runs) 0}} -
+
{{svg "octicon-no-entry" 48}}

{{if $.IsFiltered}}{{ctx.Locale.Tr "actions.runs.no_results"}}{{else}}{{ctx.Locale.Tr "actions.runs.no_runs"}}{{end}}

diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl index c0dfc6e0ad1..efdbb23e00a 100644 --- a/templates/repo/commit_page.tmpl +++ b/templates/repo/commit_page.tmpl @@ -19,7 +19,7 @@ {{end}}
-

{{RenderCommitMessage $.Context .Commit.Message $.RepoLink ($.Repository.ComposeMetas ctx)}}{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses "root" $}}

+

{{RenderCommitMessage $.Context .Commit.Message $.RepoLink ($.Repository.ComposeMetas ctx)}}{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses}}

{{if not $.PageIsWiki}}
diff --git a/templates/repo/commit_statuses.tmpl b/templates/repo/commit_statuses.tmpl index 0006dcb4a70..ec2be6c38d5 100644 --- a/templates/repo/commit_statuses.tmpl +++ b/templates/repo/commit_statuses.tmpl @@ -8,15 +8,7 @@ {{template "repo/commit_status" .Status}} {{end}} -
- {{range .Statuses}} - - {{end}} +
+ {{template "repo/pulls/status" (dict "CommitStatuses" .Statuses "CommitStatus" .Status)}}
{{end}} diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl index cdb893f51f2..77f16842451 100644 --- a/templates/repo/commits_list.tmpl +++ b/templates/repo/commits_list.tmpl @@ -66,7 +66,7 @@ {{if IsMultilineCommitMessage .Message}} {{end}} - {{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses "root" $}} + {{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}} {{if IsMultilineCommitMessage .Message}}
{{RenderCommitBody $.Context .Message $commitRepoLink ($.Repository.ComposeMetas ctx)}}
{{end}} diff --git a/templates/repo/commits_list_small.tmpl b/templates/repo/commits_list_small.tmpl index 5b715a71d4e..63eb5945bc2 100644 --- a/templates/repo/commits_list_small.tmpl +++ b/templates/repo/commits_list_small.tmpl @@ -14,7 +14,7 @@ {{$commitLink:= printf "%s/commit/%s" $.comment.Issue.PullRequest.BaseRepo.Link (PathEscape .ID.String)}} - {{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses "root" $.root}} + {{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}} {{$class := "ui sha label"}} {{if .Signature}} {{$class = (print $class " isSigned")}} diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index c037c3b3652..945c521a577 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -53,7 +53,7 @@ {{if not .DiffNotAvailable}} {{if and .IsShowingOnlySingleCommit .PageIsPullFiles}}
-
{{ctx.Locale.Tr "repo.pulls.showing_only_single_commit" (ShortSha .BeforeCommitID)}} - {{ctx.Locale.Tr "repo.pulls.show_all_commits"}}
+
{{ctx.Locale.Tr "repo.pulls.showing_only_single_commit" (ShortSha .AfterCommitID)}} - {{ctx.Locale.Tr "repo.pulls.show_all_commits"}}
{{else if and (not .IsShowingAllCommits) .PageIsPullFiles}}
@@ -238,8 +238,8 @@ "DropzoneParentContainer" ".ui.form" )}}
- - + +
diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index d3f0ead7299..d91dc4394e9 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -5,7 +5,7 @@ {{template "base/alert" .}} {{template "repo/code/recently_pushed_new_branches" .}} {{if and (not .HideRepoInfo) (not .IsBlame)}} -
+
{{$description := .Repository.DescriptionHTML $.Context}} {{if $description}}{{$description | RenderCodeBlock}}{{else if .IsRepositoryAdmin}}{{ctx.Locale.Tr "repo.no_desc"}}{{end}} @@ -35,9 +35,9 @@
{{end}} {{if and .Permission.IsAdmin (not .Repository.IsArchived)}} -
-
-