mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-27 00:25:56 +01:00
Merge branch 'main' into main
This commit is contained in:
335 files changed
+7929
-5144
No files matched your search
@@ -20,7 +20,6 @@
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {},
|
||||
// same extensions as Gitpod, should match /.gitpod.yml
|
||||
"extensions": [
|
||||
"editorconfig.editorconfig",
|
||||
"dbaeumer.vscode-eslint",
|
||||
|
||||
@@ -43,7 +43,6 @@ modifies/internal:
|
||||
- ".editorconfig"
|
||||
- ".eslintrc.cjs"
|
||||
- ".golangci.yml"
|
||||
- ".gitpod.yml"
|
||||
- ".markdownlint.yaml"
|
||||
- ".spectral.yaml"
|
||||
- "stylelint.config.*"
|
||||
|
||||
+1
-2
@@ -79,6 +79,7 @@ cpu.out
|
||||
/yarn-error.log
|
||||
/npm-debug.log*
|
||||
/.pnpm-store
|
||||
/public/assets/.vite
|
||||
/public/assets/js
|
||||
/public/assets/css
|
||||
/public/assets/fonts
|
||||
@@ -87,8 +88,6 @@ cpu.out
|
||||
/VERSION
|
||||
/.air
|
||||
|
||||
# Files and folders that were previously generated
|
||||
/public/assets/img/webpack
|
||||
|
||||
# Snapcraft
|
||||
/gitea_a*.txt
|
||||
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
tasks:
|
||||
- name: Setup
|
||||
init: |
|
||||
cp -r contrib/ide/vscode .vscode
|
||||
make deps
|
||||
make build
|
||||
command: |
|
||||
gp sync-done setup
|
||||
exit 0
|
||||
- name: Run backend
|
||||
command: |
|
||||
gp sync-await setup
|
||||
|
||||
# Get the URL and extract the domain
|
||||
url=$(gp url 3000)
|
||||
domain=$(echo $url | awk -F[/:] '{print $4}')
|
||||
|
||||
if [ -f custom/conf/app.ini ]; then
|
||||
sed -i "s|^ROOT_URL =.*|ROOT_URL = ${url}/|" custom/conf/app.ini
|
||||
sed -i "s|^DOMAIN =.*|DOMAIN = ${domain}|" custom/conf/app.ini
|
||||
sed -i "s|^SSH_DOMAIN =.*|SSH_DOMAIN = ${domain}|" custom/conf/app.ini
|
||||
sed -i "s|^NO_REPLY_ADDRESS =.*|SSH_DOMAIN = noreply.${domain}|" custom/conf/app.ini
|
||||
else
|
||||
mkdir -p custom/conf/
|
||||
echo -e "[server]\nROOT_URL = ${url}/" > custom/conf/app.ini
|
||||
echo -e "\n[database]\nDB_TYPE = sqlite3\nPATH = $GITPOD_REPO_ROOT/data/gitea.db" >> custom/conf/app.ini
|
||||
fi
|
||||
export TAGS="sqlite sqlite_unlock_notify"
|
||||
make watch-backend
|
||||
- name: Run frontend
|
||||
command: |
|
||||
gp sync-await setup
|
||||
make watch-frontend
|
||||
openMode: split-right
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
- editorconfig.editorconfig
|
||||
- dbaeumer.vscode-eslint
|
||||
- golang.go
|
||||
- stylelint.vscode-stylelint
|
||||
- DavidAnson.vscode-markdownlint
|
||||
- Vue.volar
|
||||
- ms-azuretools.vscode-docker
|
||||
- vitest.explorer
|
||||
- cweijan.vscode-database-client2
|
||||
- GitHub.vscode-pull-request-github
|
||||
|
||||
ports:
|
||||
- name: Gitea
|
||||
port: 3000
|
||||
@@ -4,5 +4,8 @@
|
||||
- Run `make tidy` after any `go.mod` changes
|
||||
- Add the current year into the copyright header of new `.go` files
|
||||
- Ensure no trailing whitespace in edited files
|
||||
- Never force-push to pull request branches
|
||||
- Always start issue and pull request comments with an authorship attribution
|
||||
- Never force-push, amend, or squash unless asked. Use new commits and normal push for pull request updates
|
||||
- Preserve existing code comments, do not remove or rewrite comments that are still relevant
|
||||
- In TypeScript, use `!` (non-null assertion) instead of `?.`/`??` when a value is known to always exist
|
||||
- Include authorship attribution in issue and pull request comments
|
||||
- Add `Co-Authored-By` lines to all commits, indicating name and model used
|
||||
+15
-12
@@ -70,16 +70,18 @@ For configuring IDEs for Gitea development, see the [contributed IDE configurati
|
||||
|
||||
## AI Contribution Policy
|
||||
|
||||
Contributions made with the assistance of AI tools are welcome, but contributors must use them responsibly.
|
||||
Contributions made with the assistance of AI tools are welcome, but contributors must use them responsibly and disclose that use clearly.
|
||||
|
||||
1. Include related issues or pull requests in the prompt so that the AI has ideal context.
|
||||
2. Review AI-generated code closely before submitting a pull request.
|
||||
3. Manually test the changes and add appropriate automated tests where feasible.
|
||||
4. Only use AI to assist in contributions that you understand well enough to respond to feedback without relying on AI.
|
||||
5. Indicate AI-generated content in issue and pull requests descriptions and comments. Specify which model was used.
|
||||
6. Do not use AI to reply to questions about your issue or pull request. The questions are for you, not an AI model.
|
||||
1. Review AI-generated code closely before marking a pull request ready for review.
|
||||
2. Manually test the changes and add appropriate automated tests where feasible.
|
||||
3. Only use AI to assist in contributions that you understand well enough to explain, defend, and revise yourself during review.
|
||||
4. Disclose AI-assisted content clearly.
|
||||
5. Do not use AI to reply to questions about your issue or pull request. The questions are for you, not an AI model.
|
||||
6. AI may be used to help draft issues and pull requests, but contributors remain responsible for the accuracy, completeness, and intent of what they submit.
|
||||
|
||||
Maintainers reserve the right to close pull requests and issues that appear to be low-quality AI-generated content. We welcome new contributors, but cannot sustain the effort of supporting contributors who primarily defer to AI rather than engaging substantively with the review process.
|
||||
Maintainers reserve the right to close pull requests and issues that do not disclose AI assistance, that appear to be low-quality AI-generated content, or where the contributor cannot explain or defend the proposed changes themselves.
|
||||
|
||||
We welcome new contributors, but cannot sustain the effort of supporting contributors who primarily defer to AI rather than engaging substantively with the review process.
|
||||
|
||||
## Issues
|
||||
|
||||
@@ -196,10 +198,11 @@ Here's how to run the test suite:
|
||||
|
||||
- E2E test environment variables
|
||||
|
||||
| Variable | Description |
|
||||
| :------------------------ | :---------------------------------------------------------------- |
|
||||
| ``GITEA_TEST_E2E_DEBUG`` | When set, show Gitea server output |
|
||||
| ``GITEA_TEST_E2E_FLAGS`` | Additional flags passed to Playwright, for example ``--ui`` |
|
||||
| Variable | Description |
|
||||
| :-------------------------------- | :---------------------------------------------------------- |
|
||||
| ``GITEA_TEST_E2E_DEBUG`` | When set, show Gitea server output |
|
||||
| ``GITEA_TEST_E2E_FLAGS`` | Additional flags passed to Playwright, for example ``--ui`` |
|
||||
| ``GITEA_TEST_E2E_TIMEOUT_FACTOR`` | Timeout multiplier (default: 3 on CI, 1 locally) |
|
||||
|
||||
## Translation
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
# Build frontend on the native platform to avoid QEMU-related issues with esbuild/webpack
|
||||
# Build frontend on the native platform to avoid QEMU-related issues with nodejs ecosystem
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
|
||||
RUN apk --no-cache add build-base git nodejs pnpm
|
||||
WORKDIR /src
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
# Build frontend on the native platform to avoid QEMU-related issues with esbuild/webpack
|
||||
# Build frontend on the native platform to avoid QEMU-related issues with nodejs ecosystem
|
||||
FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.26-alpine3.23 AS frontend-build
|
||||
RUN apk --no-cache add build-base git nodejs pnpm
|
||||
WORKDIR /src
|
||||
|
||||
@@ -15,7 +15,7 @@ XGO_VERSION := go-1.25.x
|
||||
AIR_PACKAGE ?= github.com/air-verse/air@v1
|
||||
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3
|
||||
GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.9.2
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.2
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.4
|
||||
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.15
|
||||
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/misspell@v0.8.0
|
||||
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.33.1
|
||||
@@ -81,15 +81,6 @@ STORED_VERSION_FILE := VERSION
|
||||
GITHUB_REF_TYPE ?= branch
|
||||
GITHUB_REF_NAME ?= $(shell git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
# Enable typescript support in Node.js before 22.18
|
||||
# TODO: Remove this once we can raise the minimum Node.js version to 22.18 (alpine >= 3.23)
|
||||
NODE_VERSION := $(shell printf "%03d%03d%03d" $(shell node -v 2>/dev/null | cut -c2- | sed 's/-.*//' | tr '.' ' '))
|
||||
ifeq ($(shell test "$(NODE_VERSION)" -lt "022018000"; echo $$?),0)
|
||||
NODE_VARS := NODE_OPTIONS="--experimental-strip-types"
|
||||
else
|
||||
NODE_VARS :=
|
||||
endif
|
||||
|
||||
ifneq ($(GITHUB_REF_TYPE),branch)
|
||||
VERSION ?= $(subst v,,$(GITHUB_REF_NAME))
|
||||
GITEA_VERSION ?= $(VERSION)
|
||||
@@ -120,10 +111,11 @@ LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64,linux/r
|
||||
GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration,$(shell $(GO) list ./... | grep -v /vendor/))
|
||||
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...)
|
||||
|
||||
WEBPACK_SOURCES := $(shell find web_src/js web_src/css -type f)
|
||||
WEBPACK_CONFIGS := webpack.config.ts tailwind.config.ts
|
||||
WEBPACK_DEST := public/assets/js/index.js public/assets/css/index.css
|
||||
WEBPACK_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts
|
||||
FRONTEND_SOURCES := $(shell find web_src/js web_src/css -type f)
|
||||
FRONTEND_CONFIGS := vite.config.ts tailwind.config.ts
|
||||
FRONTEND_DEST := public/assets/.vite/manifest.json
|
||||
FRONTEND_DEST_ENTRIES := public/assets/js public/assets/css public/assets/fonts public/assets/.vite
|
||||
FRONTEND_DEV_LOG_LEVEL ?= warn
|
||||
|
||||
BINDATA_DEST_WILDCARD := modules/migration/bindata.* modules/public/bindata.* modules/options/bindata.* modules/templates/bindata.*
|
||||
|
||||
@@ -199,7 +191,7 @@ git-check:
|
||||
|
||||
.PHONY: clean-all
|
||||
clean-all: clean ## delete backend, frontend and integration files
|
||||
rm -rf $(WEBPACK_DEST_ENTRIES) node_modules
|
||||
rm -rf $(FRONTEND_DEST_ENTRIES) node_modules
|
||||
|
||||
.PHONY: clean
|
||||
clean: ## delete backend and integration files
|
||||
@@ -293,33 +285,33 @@ lint-backend-fix: lint-go-fix lint-go-gitea-vet lint-editorconfig ## lint backen
|
||||
|
||||
.PHONY: lint-js
|
||||
lint-js: node_modules ## lint js and ts files
|
||||
$(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) $(ESLINT_FILES)
|
||||
$(NODE_VARS) pnpm exec vue-tsc
|
||||
pnpm exec eslint --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) $(ESLINT_FILES)
|
||||
pnpm exec vue-tsc
|
||||
|
||||
.PHONY: lint-js-fix
|
||||
lint-js-fix: node_modules ## lint js and ts files and fix issues
|
||||
$(NODE_VARS) pnpm exec eslint --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) $(ESLINT_FILES) --fix
|
||||
$(NODE_VARS) pnpm exec vue-tsc
|
||||
pnpm exec eslint --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) $(ESLINT_FILES) --fix
|
||||
pnpm exec vue-tsc
|
||||
|
||||
.PHONY: lint-css
|
||||
lint-css: node_modules ## lint css files
|
||||
$(NODE_VARS) pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES)
|
||||
pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES)
|
||||
|
||||
.PHONY: lint-css-fix
|
||||
lint-css-fix: node_modules ## lint css files and fix issues
|
||||
$(NODE_VARS) pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix
|
||||
pnpm exec stylelint --color --max-warnings=0 $(STYLELINT_FILES) --fix
|
||||
|
||||
.PHONY: lint-swagger
|
||||
lint-swagger: node_modules ## lint swagger files
|
||||
$(NODE_VARS) pnpm exec spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||
pnpm exec spectral lint -q -F hint $(SWAGGER_SPEC)
|
||||
|
||||
.PHONY: lint-md
|
||||
lint-md: node_modules ## lint markdown files
|
||||
$(NODE_VARS) pnpm exec markdownlint *.md
|
||||
pnpm exec markdownlint *.md
|
||||
|
||||
.PHONY: lint-md-fix
|
||||
lint-md-fix: node_modules ## lint markdown files and fix issues
|
||||
$(NODE_VARS) pnpm exec markdownlint --fix *.md
|
||||
pnpm exec markdownlint --fix *.md
|
||||
|
||||
.PHONY: lint-spell
|
||||
lint-spell: ## lint spelling
|
||||
@@ -369,20 +361,19 @@ lint-yaml: .venv ## lint yaml files
|
||||
|
||||
.PHONY: lint-json
|
||||
lint-json: node_modules ## lint json files
|
||||
$(NODE_VARS) pnpm exec eslint -c eslint.json.config.ts --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY)
|
||||
pnpm exec eslint -c eslint.json.config.ts --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY)
|
||||
|
||||
.PHONY: lint-json-fix
|
||||
lint-json-fix: node_modules ## lint and fix json files
|
||||
$(NODE_VARS) pnpm exec eslint -c eslint.json.config.ts --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) --fix
|
||||
pnpm exec eslint -c eslint.json.config.ts --color --max-warnings=0 --concurrency $(ESLINT_CONCURRENCY) --fix
|
||||
|
||||
.PHONY: watch
|
||||
watch: ## watch everything and continuously rebuild
|
||||
@bash tools/watch.sh
|
||||
|
||||
.PHONY: watch-frontend
|
||||
watch-frontend: node_modules ## watch frontend files and continuously rebuild
|
||||
@rm -rf $(WEBPACK_DEST_ENTRIES)
|
||||
NODE_ENV=development $(NODE_VARS) pnpm exec webpack --watch --progress
|
||||
watch-frontend: node_modules ## start vite dev server for frontend
|
||||
NODE_ENV=development pnpm exec vite --logLevel $(FRONTEND_DEV_LOG_LEVEL)
|
||||
|
||||
.PHONY: watch-backend
|
||||
watch-backend: ## watch backend files and continuously rebuild
|
||||
@@ -398,7 +389,7 @@ test-backend: ## test backend files
|
||||
|
||||
.PHONY: test-frontend
|
||||
test-frontend: node_modules ## test frontend files
|
||||
$(NODE_VARS) pnpm exec vitest
|
||||
pnpm exec vitest
|
||||
|
||||
.PHONY: test-check
|
||||
test-check:
|
||||
@@ -534,7 +525,7 @@ test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test
|
||||
.PHONY: playwright
|
||||
playwright: deps-frontend
|
||||
@# on GitHub Actions VMs, playwright's system deps are pre-installed
|
||||
@$(NODE_VARS) pnpm exec playwright install $(if $(GITHUB_ACTIONS),,--with-deps) chromium $(if $(CI),firefox) $(PLAYWRIGHT_FLAGS)
|
||||
@pnpm exec playwright install $(if $(GITHUB_ACTIONS),,--with-deps) chromium $(if $(CI),firefox) $(PLAYWRIGHT_FLAGS)
|
||||
|
||||
.PHONY: test-e2e
|
||||
test-e2e: playwright $(EXECUTABLE_E2E)
|
||||
@@ -645,7 +636,7 @@ install: $(wildcard *.go)
|
||||
build: frontend backend ## build everything
|
||||
|
||||
.PHONY: frontend
|
||||
frontend: $(WEBPACK_DEST) ## build frontend files
|
||||
frontend: $(FRONTEND_DEST) ## build frontend files
|
||||
|
||||
.PHONY: backend
|
||||
backend: generate-backend $(EXECUTABLE) ## build backend files
|
||||
@@ -672,7 +663,7 @@ ifneq ($(and $(STATIC),$(findstring pam,$(TAGS))),)
|
||||
endif
|
||||
CGO_ENABLED="$(CGO_ENABLED)" CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TAGS)' -ldflags '-s -w $(EXTLDFLAGS) $(LDFLAGS)' -o $@
|
||||
|
||||
$(EXECUTABLE_E2E): $(GO_SOURCES) $(WEBPACK_DEST)
|
||||
$(EXECUTABLE_E2E): $(GO_SOURCES) $(FRONTEND_DEST)
|
||||
CGO_ENABLED=1 $(GO) build $(GOFLAGS) $(EXTRA_GOFLAGS) -tags '$(TEST_TAGS)' -ldflags '-s -w $(EXTLDFLAGS) $(LDFLAGS)' -o $@
|
||||
|
||||
.PHONY: release
|
||||
@@ -750,7 +741,7 @@ deps-tools: ## install tool dependencies
|
||||
wait
|
||||
|
||||
node_modules: pnpm-lock.yaml
|
||||
$(NODE_VARS) pnpm install --frozen-lockfile
|
||||
pnpm install --frozen-lockfile
|
||||
@touch node_modules
|
||||
|
||||
.venv: uv.lock
|
||||
@@ -758,33 +749,38 @@ node_modules: pnpm-lock.yaml
|
||||
@touch .venv
|
||||
|
||||
.PHONY: update
|
||||
update: update-js update-py ## update js and py dependencies
|
||||
update: update-go update-js update-py ## update dependencies
|
||||
|
||||
.PHONY: update-go
|
||||
update-go: ## update go dependencies
|
||||
$(GO) get -u ./...
|
||||
$(MAKE) tidy
|
||||
|
||||
.PHONY: update-js
|
||||
update-js: node_modules ## update js dependencies
|
||||
$(NODE_VARS) pnpm exec updates -u -f package.json
|
||||
pnpm exec updates -u -f package.json
|
||||
rm -rf node_modules pnpm-lock.yaml
|
||||
$(NODE_VARS) pnpm install
|
||||
$(NODE_VARS) pnpm exec nolyfill install
|
||||
$(NODE_VARS) pnpm install
|
||||
pnpm install
|
||||
pnpm exec nolyfill install
|
||||
pnpm install
|
||||
@touch node_modules
|
||||
|
||||
.PHONY: update-py
|
||||
update-py: node_modules ## update py dependencies
|
||||
$(NODE_VARS) pnpm exec updates -u -f pyproject.toml
|
||||
pnpm exec updates -u -f pyproject.toml
|
||||
rm -rf .venv uv.lock
|
||||
uv sync
|
||||
@touch .venv
|
||||
|
||||
.PHONY: webpack
|
||||
webpack: $(WEBPACK_DEST) ## build webpack files
|
||||
.PHONY: vite
|
||||
vite: $(FRONTEND_DEST) ## build vite files
|
||||
|
||||
$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) pnpm-lock.yaml
|
||||
$(FRONTEND_DEST): $(FRONTEND_SOURCES) $(FRONTEND_CONFIGS) pnpm-lock.yaml
|
||||
@$(MAKE) -s node_modules
|
||||
@rm -rf $(WEBPACK_DEST_ENTRIES)
|
||||
@echo "Running webpack..."
|
||||
@BROWSERSLIST_IGNORE_OLD_DATA=true $(NODE_VARS) pnpm exec webpack
|
||||
@touch $(WEBPACK_DEST)
|
||||
@rm -rf $(FRONTEND_DEST_ENTRIES)
|
||||
@echo "Running vite build..."
|
||||
@pnpm exec vite build
|
||||
@touch $(FRONTEND_DEST)
|
||||
|
||||
.PHONY: svg
|
||||
svg: node_modules ## build svg files
|
||||
@@ -803,7 +799,7 @@ svg-check: svg
|
||||
|
||||
.PHONY: lockfile-check
|
||||
lockfile-check:
|
||||
$(NODE_VARS) pnpm install --frozen-lockfile
|
||||
pnpm install --frozen-lockfile
|
||||
@diff=$$(git diff --color=always pnpm-lock.yaml); \
|
||||
if [ -n "$$diff" ]; then \
|
||||
echo "pnpm-lock.yaml is inconsistent with package.json"; \
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
[](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
|
||||
[](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
|
||||
[](https://opensource.org/licenses/MIT "License: MIT")
|
||||
[](https://gitpod.io/#https://github.com/go-gitea/gitea)
|
||||
[](https://translate.gitea.com "Crowdin")
|
||||
|
||||
[繁體中文](./README.zh-tw.md) | [简体中文](./README.zh-cn.md)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
[](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
|
||||
[](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
|
||||
[](https://opensource.org/licenses/MIT "License: MIT")
|
||||
[](https://gitpod.io/#https://github.com/go-gitea/gitea)
|
||||
[](https://translate.gitea.com "Crowdin")
|
||||
|
||||
[English](./README.md) | [繁體中文](./README.zh-tw.md)
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
[](https://www.codetriage.com/go-gitea/gitea "Help Contribute to Open Source")
|
||||
[](https://opencollective.com/gitea "Become a backer/sponsor of gitea")
|
||||
[](https://opensource.org/licenses/MIT "License: MIT")
|
||||
[](https://gitpod.io/#https://github.com/go-gitea/gitea)
|
||||
[](https://translate.gitea.com "Crowdin")
|
||||
|
||||
[English](./README.md) | [简体中文](./README.zh-cn.md)
|
||||
|
||||
Generated
+49
-24
@@ -139,6 +139,11 @@
|
||||
"path": "github.com/andybalholm/brotli/LICENSE",
|
||||
"licenseText": "Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/andybalholm/brotli/flate",
|
||||
"path": "github.com/andybalholm/brotli/flate/LICENSE",
|
||||
"licenseText": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/andybalholm/cascadia",
|
||||
"path": "github.com/andybalholm/cascadia/LICENSE",
|
||||
@@ -369,6 +374,16 @@
|
||||
"path": "github.com/chi-middleware/proxy/LICENSE",
|
||||
"licenseText": "Copyright (c) 2020 Lauris BH\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/clipperhouse/displaywidth",
|
||||
"path": "github.com/clipperhouse/displaywidth/LICENSE",
|
||||
"licenseText": "MIT License\n\nCopyright (c) 2025 Matt Sherman\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/clipperhouse/uax29/v2",
|
||||
"path": "github.com/clipperhouse/uax29/v2/LICENSE",
|
||||
"licenseText": "MIT License\n\nCopyright (c) 2020 Matt Sherman\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/cloudflare/circl",
|
||||
"path": "github.com/cloudflare/circl/LICENSE",
|
||||
@@ -386,8 +401,8 @@
|
||||
},
|
||||
{
|
||||
"name": "github.com/couchbase/goutils",
|
||||
"path": "github.com/couchbase/goutils/LICENSE.md",
|
||||
"licenseText": "Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terLine truncated
|
||||
"path": "github.com/couchbase/goutils/LICENSE.txt",
|
||||
"licenseText": "Source code in this repository is licensed under various licenses. The\nBusiness Source License 1.1 (BSL) is one such license. Each file indicates in\na section at the beginning of the file the name of the license that applies to\nit. All licenses used in this repository can be found in the top-level\nlicenses directory.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/cpuguy83/go-md2man/v2",
|
||||
@@ -396,8 +411,8 @@
|
||||
},
|
||||
{
|
||||
"name": "github.com/cyphar/filepath-securejoin",
|
||||
"path": "github.com/cyphar/filepath-securejoin/LICENSE",
|
||||
"licenseText": "Copyright (C) 2014-2015 Docker Inc \u0026 Go Authors. All rights reserved.\nCopyright (C) 2017-2024 SUSE LLC. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||
"path": "github.com/cyphar/filepath-securejoin/COPYING.md",
|
||||
"licenseText": "## COPYING ##\n\n`SPDX-License-Identifier: BSD-3-Clause AND MPL-2.0`\n\nThis project is made up of code licensed under different licenses. Which code\nyou use will have an impact on whether only one or both licenses apply to your\nusage of this library.\n\nNote that **each file** in this project individually has a code comment at the\nstart describing the license of that particular file -- this is the most\naccurate license information of this project; in case there is any conflict\nbetween this document and the comment at the start of a file, the comment shall\ntake precedence. The only purpose of this document is to work around [a known\ntechnical limitation of pkg.go.dev's license checking tool when dealing with\nnon-trivial project licenses][go75067].\n\n[go75067]: https://go.dev/issue/75067\n\n### `BSD-3-Clause` ###\n\nAt time of writing, the following files and directories are licensed under the\nBSD-3-Clause license:\n\n * `doc.go`\n * `join*.go`\n * `vfs.go`\n * `internal/consts/*.go`\n * `pathrs-lite/internal/gocompat/*.go`\n * `pathrs-lite/internal/kernelversion/*.go`\n\nThe text of the BSD-3-Clause license used by this project is the following (the\ntext is also available from the [`LICENSE.BSD`](./LICENSE.BSD) file):\n\n```\nCopyright (C) 2014-2015 Docker Inc \u0026 Go Authors. All rights reserved.\nCopyright (C) 2017-2024 SUSE LLC. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n```\n\n### `MPL-2.0` ###\n\nAll other files (unless otherwise marked) are licensed under the Mozilla Public\nLicense (version 2.0).\n\nThe text of the Mozilla Public License (version 2.0) is the following (the text\nis also available from the [`LICENSE.MPL-2.0`](./LICENSE.MPL-2.0) file):\n\n```\nMozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n means each individual or legal entity that creates, contributes to\n the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n means the combination of the Contributions of others (if any) used\n by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n means Source Code Form to which the initial Contributor has attached\n the notice in Exhibit A, the Executable Form of such Source Code\n Form, and Modifications of such Source Code Form, in each case\n including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n means\n\n (a) that the initial Contributor has attached the notice described\n in Exhibit B to the Covered Software; or\n\n (b) that the Covered Software was made available under the terms of\n version 1.1 or earlier of the License, but not also under the\n terms of a Secondary License.\n\n1.6. \"Executable Form\"\n means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n means a work that combines Covered Software with other material, in\n a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n means this document.\n\n1.9. \"Licensable\"\n means having the right to grant, to the maximum extent possible,\n whether at the time of the initial grant or subsequently, any and\n all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n means any of the following:\n\n (a) any file in Source Code Form that results from an addition to,\n deletion from, or modification of the contentLine truncated
|
||||
},
|
||||
{
|
||||
"name": "github.com/davecgh/go-spew",
|
||||
@@ -500,8 +515,8 @@
|
||||
"licenseText": "Copyright (c) 2014 Olivier Poitrey \u003crs@dailymotion.com\u003e\nCopyright (c) 2016-Present https://github.com/go-chi authors\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/go-co-op/gocron",
|
||||
"path": "github.com/go-co-op/gocron/LICENSE",
|
||||
"name": "github.com/go-co-op/gocron/v2",
|
||||
"path": "github.com/go-co-op/gocron/v2/LICENSE",
|
||||
"licenseText": "MIT License\n\nCopyright (c) 2014, 辣椒面\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
@@ -549,10 +564,15 @@
|
||||
"path": "github.com/go-sql-driver/mysql/LICENSE",
|
||||
"licenseText": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n means each individual or legal entity that creates, contributes to\n the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n means the combination of the Contributions of others (if any) used\n by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n means Source Code Form to which the initial Contributor has attached\n the notice in Exhibit A, the Executable Form of such Source Code\n Form, and Modifications of such Source Code Form, in each case\n including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n means\n\n (a) that the initial Contributor has attached the notice described\n in Exhibit B to the Covered Software; or\n\n (b) that the Covered Software was made available under the terms of\n version 1.1 or earlier of the License, but not also under the\n terms of a Secondary License.\n\n1.6. \"Executable Form\"\n means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n means a work that combines Covered Software with other material, in \n a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n means this document.\n\n1.9. \"Licensable\"\n means having the right to grant, to the maximum extent possible,\n whether at the time of the initial grant or subsequently, any and\n all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n means any of the following:\n\n (a) any file in Source Code Form that results from an addition to,\n deletion from, or modification of the contents of Covered\n Software; or\n\n (b) any new file in Source Code Form that contains any Covered\n Software.\n\n1.11. \"Patent Claims\" of a Contributor\n means any patent claim(s), including without limitation, method,\n process, and apparatus claims, in any patent Licensable by such\n Contributor that would be infringed, but for the grant of the\n License, by the making, using, selling, offering for sale, having\n made, import, or transfer of either its Contributions or its\n Contributor Version.\n\n1.12. \"Secondary License\"\n means either the GNU General Public License, Version 2.0, the GNU\n Lesser General Public License, Version 2.1, the GNU Affero General\n Public License, Version 3.0, or any later versions of those\n licenses.\n\n1.13. \"Source Code Form\"\n means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n means an individual or a legal entity exercising rights under this\n License. For legal entities, \"You\" includes any entity that\n controls, is controlled by, or is under common control with You. For\n purposes of this definition, \"control\" means (a) the power, direct\n or indirect, to cause the direction or management of such entity,\n whether by contract or otherwise, or (b) ownership of more than\n fifty percent (50%) of the outstanding shares or beneficial\n ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n Licensable by such Contributor to use, reproduce, make available,\n modify, display, perform, distribute, and otherwise exploit its\n Contributions, either on an unmodified basis, with Modifications, or\n as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n for sale, have made, import, and otherwise transfer either its\n Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n or\n\n(b) for infringements caused by: (i) Your and any other third party's\n modifications of Covered Software, or (ii) the combination of its\n Contributions with other software (except as part of its Contributor\n Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n its Contributions.\n\nThis License does not grant any rights in the tLine truncated
|
||||
},
|
||||
{
|
||||
"name": "github.com/go-viper/mapstructure/v2",
|
||||
"path": "github.com/go-viper/mapstructure/v2/LICENSE",
|
||||
"licenseText": "The MIT License (MIT)\n\nCopyright (c) 2013 Mitchell Hashimoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/go-webauthn/webauthn",
|
||||
"path": "github.com/go-webauthn/webauthn/LICENSE",
|
||||
"licenseText": "Copyright (c) 2017 Duo Security, Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n3. Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\nCopyright (c) 2021-2022 github.com/go-webauthn/webauthn authors.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the\nfollowing conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following\n disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following\n disclaimer in the documentation and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products\n derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\nWHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
"licenseText": "Copyright (c) 2025 github.com/go-webauthn/webauthn authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n3. Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\nEXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\nPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
},
|
||||
{
|
||||
"name": "github.com/go-webauthn/x",
|
||||
@@ -615,8 +635,8 @@
|
||||
"licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under tLine truncated
|
||||
},
|
||||
{
|
||||
"name": "github.com/google/go-github/v74",
|
||||
"path": "github.com/google/go-github/v74/LICENSE",
|
||||
"name": "github.com/google/go-github/v84",
|
||||
"path": "github.com/google/go-github/v84/LICENSE",
|
||||
"licenseText": "Copyright (c) 2013 The go-github AUTHORS. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
||||
},
|
||||
{
|
||||
@@ -709,6 +729,11 @@
|
||||
"path": "github.com/huandu/xstrings/LICENSE",
|
||||
"licenseText": "The MIT License (MIT)\n\nCopyright (c) 2015 Huan Du\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/inbucket/html2text",
|
||||
"path": "github.com/inbucket/html2text/LICENSE",
|
||||
"licenseText": "The MIT License (MIT)\n\nCopyright (c) 2015 Jay Taylor\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/jaytaylor/html2text",
|
||||
"path": "github.com/jaytaylor/html2text/LICENSE",
|
||||
@@ -720,10 +745,15 @@
|
||||
"licenseText": "The MIT License (MIT)\n\nCopyright (c) 2014 Juan Batiz-Benet\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/jhillyerd/enmime",
|
||||
"path": "github.com/jhillyerd/enmime/LICENSE",
|
||||
"name": "github.com/jhillyerd/enmime/v2",
|
||||
"path": "github.com/jhillyerd/enmime/v2/LICENSE",
|
||||
"licenseText": "The MIT License (MIT)\n\nCopyright (c) 2012-2016 James Hillyerd, All Rights Reserved\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/jonboulle/clockwork",
|
||||
"path": "github.com/jonboulle/clockwork/LICENSE",
|
||||
"licenseText": "Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terLine truncated
|
||||
},
|
||||
{
|
||||
"name": "github.com/josharian/intern",
|
||||
"path": "github.com/josharian/intern/license.md",
|
||||
@@ -889,11 +919,6 @@
|
||||
"path": "github.com/minio/minlz/LICENSE",
|
||||
"licenseText": "\r\n Apache License\r\n Version 2.0, January 2004\r\n http://www.apache.org/licenses/\r\n\r\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r\n\r\n 1. Definitions.\r\n\r\n \"License\" shall mean the terms and conditions for use, reproduction,\r\n and distribution as defined by Sections 1 through 9 of this document.\r\n\r\n \"Licensor\" shall mean the copyright owner or entity authorized by\r\n the copyright owner that is granting the License.\r\n\r\n \"Legal Entity\" shall mean the union of the acting entity and all\r\n other entities that control, are controlled by, or are under common\r\n control with that entity. For the purposes of this definition,\r\n \"control\" means (i) the power, direct or indirect, to cause the\r\n direction or management of such entity, whether by contract or\r\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\r\n outstanding shares, or (iii) beneficial ownership of such entity.\r\n\r\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\r\n exercising permissions granted by this License.\r\n\r\n \"Source\" form shall mean the preferred form for making modifications,\r\n including but not limited to software source code, documentation\r\n source, and configuration files.\r\n\r\n \"Object\" form shall mean any form resulting from mechanical\r\n transformation or translation of a Source form, including but\r\n not limited to compiled object code, generated documentation,\r\n and conversions to other media types.\r\n\r\n \"Work\" shall mean the work of authorship, whether in Source or\r\n Object form, made available under the License, as indicated by a\r\n copyright notice that is included in or attached to the work\r\n (an example is provided in the Appendix below).\r\n\r\n \"Derivative Works\" shall mean any work, whether in Source or Object\r\n form, that is based on (or derived from) the Work and for which the\r\n editorial revisions, annotations, elaborations, or other modifications\r\n represent, as a whole, an original work of authorship. For the purposes\r\n of this License, Derivative Works shall not include works that remain\r\n separable from, or merely link (or bind by name) to the interfaces of,\r\n the Work and Derivative Works thereof.\r\n\r\n \"Contribution\" shall mean any work of authorship, including\r\n the original version of the Work and any modifications or additions\r\n to that Work or Derivative Works thereof, that is intentionally\r\n submitted to Licensor for inclusion in the Work by the copyright owner\r\n or by an individual or Legal Entity authorized to submit on behalf of\r\n the copyright owner. For the purposes of this definition, \"submitted\"\r\n means any form of electronic, verbal, or written communication sent\r\n to the Licensor or its representatives, including but not limited to\r\n communication on electronic mailing lists, source code control systems,\r\n and issue tracking systems that are managed by, or on behalf of, the\r\n Licensor for the purpose of discussing and improving the Work, but\r\n excluding communication that is conspicuously marked or otherwise\r\n designated in writing by the copyright owner as \"Not a Contribution.\"\r\n\r\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\r\n on behalf of whom a Contribution has been received by Licensor and\r\n subsequently incorporated within the Work.\r\n\r\n 2. Grant of Copyright License. Subject to the terms and conditions of\r\n this License, each Contributor hereby grants to You a perpetual,\r\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n copyright license to reproduce, prepare Derivative Works of,\r\n publicly display, publicly perform, sublicense, and distribute the\r\n Work and such Derivative Works in Source or Object form.\r\n\r\n 3. Grant of Patent License. Subject to the terms and conditions of\r\n this License, each Contributor hereby grants to You a perpetual,\r\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r\n (except as stated in this section) patent license to make, have made,\r\n use, offer to sell, sell, import, and otherwise transfer the Work,\r\n where such license applies only to those patent claims licensable\r\n by such Contributor that are necessarily infringed by their\r\n Contribution(s) alone or by combination of their Contribution(s)\r\n with the Work to which such Contribution(s) was submitted. If You\r\n institute patent litigation against any entity (including a\r\n cross-claim or counterclaim in a lawsuit) alleging that the Work\r\n Line truncated
|
||||
},
|
||||
{
|
||||
"name": "github.com/mitchellh/mapstructure",
|
||||
"path": "github.com/mitchellh/mapstructure/LICENSE",
|
||||
"licenseText": "The MIT License (MIT)\n\nCopyright (c) 2013 Mitchell Hashimoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/modern-go/concurrent",
|
||||
"path": "github.com/modern-go/concurrent/LICENSE",
|
||||
@@ -904,6 +929,11 @@
|
||||
"path": "github.com/modern-go/reflect2/LICENSE",
|
||||
"licenseText": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under thiLine truncated
|
||||
},
|
||||
{
|
||||
"name": "github.com/mschoch/smat",
|
||||
"path": "github.com/mschoch/smat/LICENSE",
|
||||
"licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under tLine truncated
|
||||
},
|
||||
{
|
||||
"name": "github.com/munnerz/goautoneg",
|
||||
"path": "github.com/munnerz/goautoneg/LICENSE",
|
||||
@@ -1029,11 +1059,6 @@
|
||||
"path": "github.com/rhysd/actionlint/LICENSE.txt",
|
||||
"licenseText": "the MIT License\n\nCopyright (c) 2021 rhysd\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\nPURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR\nTHE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/rivo/uniseg",
|
||||
"path": "github.com/rivo/uniseg/LICENSE.txt",
|
||||
"licenseText": "MIT License\n\nCopyright (c) 2019 Oliver Kuederle\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/robfig/cron/v3",
|
||||
"path": "github.com/robfig/cron/v3/LICENSE",
|
||||
@@ -1050,8 +1075,8 @@
|
||||
"licenseText": "Blackfriday is distributed under the Simplified BSD License:\n\n\u003e Copyright © 2011 Russ Ross\n\u003e All rights reserved.\n\u003e\n\u003e Redistribution and use in source and binary forms, with or without\n\u003e modification, are permitted provided that the following conditions\n\u003e are met:\n\u003e\n\u003e 1. Redistributions of source code must retain the above copyright\n\u003e notice, this list of conditions and the following disclaimer.\n\u003e\n\u003e 2. Redistributions in binary form must reproduce the above\n\u003e copyright notice, this list of conditions and the following\n\u003e disclaimer in the documentation and/or other materials provided with\n\u003e the distribution.\n\u003e\n\u003e THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\u003e \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n\u003e LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n\u003e FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n\u003e COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n\u003e INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n\u003e BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n\u003e LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n\u003e CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\u003e LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n\u003e ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n\u003e POSSIBILITY OF SUCH DAMAGE.\n"
|
||||
},
|
||||
{
|
||||
"name": "github.com/santhosh-tekuri/jsonschema/v5",
|
||||
"path": "github.com/santhosh-tekuri/jsonschema/v5/LICENSE",
|
||||
"name": "github.com/santhosh-tekuri/jsonschema/v6",
|
||||
"path": "github.com/santhosh-tekuri/jsonschema/v6/LICENSE",
|
||||
"licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under tLine truncated
|
||||
},
|
||||
{
|
||||
@@ -1227,7 +1252,7 @@
|
||||
{
|
||||
"name": "go.yaml.in/yaml/v4",
|
||||
"path": "go.yaml.in/yaml/v4/LICENSE",
|
||||
"licenseText": "\nThis project is covered by two different licenses: MIT and Apache.\n\n#### MIT License ####\n\nThe following files were ported to Go from C files of libyaml, and thus\nare still covered by their original MIT license, with the additional\ncopyright staring in 2011 when the project was ported over:\n\n apic.go emitterc.go parserc.go readerc.go scannerc.go\n writerc.go yamlh.go yamlprivateh.go\n\nCopyright (c) 2006-2010 Kirill Simonov\nCopyright (c) 2006-2011 Kirill Simonov\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n### Apache License ###\n\nAll the remaining project files are covered by the Apache license:\n\nCopyright (c) 2011-2019 Canonical Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
|
||||
"licenseText": "\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under tLine truncated
|
||||
},
|
||||
{
|
||||
"name": "go4.org",
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/v74/github"
|
||||
"github.com/google/go-github/v84/github"
|
||||
"github.com/urfave/cli/v3"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
+12
-4
@@ -329,7 +329,7 @@ export default defineConfig([
|
||||
'github/no-innerText': [2],
|
||||
'github/no-then': [2],
|
||||
'github/no-useless-passive': [2],
|
||||
'github/prefer-observers': [2],
|
||||
'github/prefer-observers': [0],
|
||||
'github/require-passive-events': [2],
|
||||
'github/unescaped-html-literal': [2],
|
||||
'grouped-accessor-pairs': [2],
|
||||
@@ -572,7 +572,11 @@ export default defineConfig([
|
||||
'no-restricted-exports': [0],
|
||||
'no-restricted-globals': [2, ...restrictedGlobals],
|
||||
'no-restricted-properties': [2, ...restrictedProperties],
|
||||
'no-restricted-imports': [0],
|
||||
'no-restricted-imports': [2, {paths: [
|
||||
{name: 'jquery', message: 'Use the global $ instead', allowTypeImports: true},
|
||||
{name: 'htmx.org', message: 'Use the global htmx instead', allowTypeImports: true},
|
||||
{name: 'idiomorph/htmx', message: 'Loaded in globals.ts', allowTypeImports: true},
|
||||
]}],
|
||||
'no-restricted-syntax': [2, 'WithStatement', 'ForInStatement', 'LabeledStatement', 'SequenceExpression'],
|
||||
'no-return-assign': [0],
|
||||
'no-script-url': [2],
|
||||
@@ -762,6 +766,7 @@ export default defineConfig([
|
||||
'unicorn/catch-error-name': [0],
|
||||
'unicorn/consistent-destructuring': [2],
|
||||
'unicorn/consistent-empty-array-spread': [2],
|
||||
'unicorn/consistent-template-literal-escape': [2],
|
||||
'unicorn/consistent-existence-index-check': [0],
|
||||
'unicorn/consistent-function-scoping': [0],
|
||||
'unicorn/custom-error-definition': [0],
|
||||
@@ -817,6 +822,7 @@ export default defineConfig([
|
||||
'unicorn/no-unused-properties': [2],
|
||||
'unicorn/no-useless-collection-argument': [2],
|
||||
'unicorn/no-useless-fallback-in-spread': [2],
|
||||
'unicorn/no-useless-iterator-to-array': [2],
|
||||
'unicorn/no-useless-length-check': [2],
|
||||
'unicorn/no-useless-promise-resolve-reject': [2],
|
||||
'unicorn/no-useless-spread': [2],
|
||||
@@ -866,6 +872,7 @@ export default defineConfig([
|
||||
'unicorn/prefer-response-static-json': [2],
|
||||
'unicorn/prefer-set-has': [0],
|
||||
'unicorn/prefer-set-size': [2],
|
||||
'unicorn/prefer-simple-condition-first': [0],
|
||||
'unicorn/prefer-spread': [0],
|
||||
'unicorn/prefer-string-raw': [0],
|
||||
'unicorn/prefer-string-replace-all': [0],
|
||||
@@ -884,6 +891,7 @@ export default defineConfig([
|
||||
'unicorn/require-post-message-target-origin': [0],
|
||||
'unicorn/string-content': [0],
|
||||
'unicorn/switch-case-braces': [0],
|
||||
'unicorn/switch-case-break-position': [2],
|
||||
'unicorn/template-indent': [2],
|
||||
'unicorn/text-encoding-identifier-case': [0],
|
||||
'unicorn/throw-new-error': [2],
|
||||
@@ -1009,11 +1017,11 @@ export default defineConfig([
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*', 'tools/**/*'],
|
||||
files: ['*', 'tools/**/*', 'tests/**/*'],
|
||||
languageOptions: {globals: globals.nodeBuiltin},
|
||||
},
|
||||
{
|
||||
files: ['web_src/**/*'],
|
||||
languageOptions: {globals: {...globals.browser, ...globals.webpack}},
|
||||
languageOptions: {globals: {...globals.browser, ...globals.jquery, htmx: false}},
|
||||
},
|
||||
]);
|
||||
Generated
+3
-3
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1773821835,
|
||||
"narHash": "sha256-TJ3lSQtW0E2JrznGVm8hOQGVpXjJyXY2guAxku2O9A4=",
|
||||
"lastModified": 1774386573,
|
||||
"narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b40629efe5d6ec48dd1efba650c797ddbd39ace0",
|
||||
"rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
inherit (pkgs) lib;
|
||||
|
||||
# only bump toolchain versions here
|
||||
go = pkgs.go_1_25;
|
||||
go = pkgs.go_1_26;
|
||||
nodejs = pkgs.nodejs_24;
|
||||
python3 = pkgs.python312;
|
||||
python3 = pkgs.python314;
|
||||
pnpm = pkgs.pnpm_10;
|
||||
|
||||
# Platform-specific dependencies
|
||||
|
||||
@@ -9,7 +9,7 @@ godebug x509negativeserial=1
|
||||
|
||||
require (
|
||||
code.gitea.io/actions-proto-go v0.4.1
|
||||
code.gitea.io/sdk/gitea v0.23.2
|
||||
code.gitea.io/sdk/gitea v0.24.1
|
||||
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
|
||||
connectrpc.com/connect v1.19.1
|
||||
gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed
|
||||
@@ -18,22 +18,22 @@ require (
|
||||
gitea.com/go-chi/session v0.0.0-20251124165456-68e0254e989e
|
||||
gitea.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
|
||||
gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4
|
||||
github.com/42wim/httpsig v1.2.3
|
||||
github.com/42wim/sshsig v0.0.0-20250502153856-5100632e8920
|
||||
github.com/42wim/httpsig v1.2.4
|
||||
github.com/42wim/sshsig v0.0.0-20260317195500-b9f38cf0d432
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.2
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358
|
||||
github.com/ProtonMail/go-crypto v1.3.0
|
||||
github.com/PuerkitoBio/goquery v1.11.0
|
||||
github.com/Azure/go-ntlmssp v0.1.0
|
||||
github.com/ProtonMail/go-crypto v1.4.1
|
||||
github.com/PuerkitoBio/goquery v1.12.0
|
||||
github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.8.0
|
||||
github.com/alecthomas/chroma/v2 v2.23.1
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.7
|
||||
github.com/aws/aws-sdk-go-v2/service/codecommit v1.33.8
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.13
|
||||
github.com/aws/aws-sdk-go-v2/service/codecommit v1.33.12
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
|
||||
github.com/blevesearch/bleve/v2 v2.5.7
|
||||
github.com/bohde/codel v0.2.0
|
||||
github.com/buildkite/terminal-to-html/v3 v3.16.8
|
||||
github.com/caddyserver/certmagic v0.25.1
|
||||
github.com/caddyserver/certmagic v0.25.2
|
||||
github.com/charmbracelet/git-lfs-transfer v0.1.1-0.20251013092601-6327009efd21
|
||||
github.com/chi-middleware/proxy v1.1.1
|
||||
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21
|
||||
@@ -49,42 +49,42 @@ require (
|
||||
github.com/gliderlabs/ssh v0.3.8
|
||||
github.com/go-chi/chi/v5 v5.2.5
|
||||
github.com/go-chi/cors v1.2.2
|
||||
github.com/go-co-op/gocron v1.37.0
|
||||
github.com/go-enry/go-enry/v2 v2.9.4
|
||||
github.com/go-git/go-billy/v5 v5.7.0
|
||||
github.com/go-git/go-git/v5 v5.16.5
|
||||
github.com/go-ldap/ldap/v3 v3.4.12
|
||||
github.com/go-redsync/redsync/v4 v4.15.0
|
||||
github.com/go-co-op/gocron/v2 v2.19.1
|
||||
github.com/go-enry/go-enry/v2 v2.9.5
|
||||
github.com/go-git/go-billy/v5 v5.8.0
|
||||
github.com/go-git/go-git/v5 v5.17.2
|
||||
github.com/go-ldap/ldap/v3 v3.4.13
|
||||
github.com/go-redsync/redsync/v4 v4.16.0
|
||||
github.com/go-sql-driver/mysql v1.9.3
|
||||
github.com/go-webauthn/webauthn v0.13.4
|
||||
github.com/goccy/go-json v0.10.5
|
||||
github.com/go-webauthn/webauthn v0.16.1
|
||||
github.com/goccy/go-json v0.10.6
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
|
||||
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1
|
||||
github.com/google/go-github/v74 v74.0.0
|
||||
github.com/google/go-github/v84 v84.0.0
|
||||
github.com/google/licenseclassifier/v2 v2.0.0
|
||||
github.com/google/pprof v0.0.0-20260202012954-cb029daf43ef
|
||||
github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gorilla/feeds v1.2.0
|
||||
github.com/gorilla/sessions v1.4.0
|
||||
github.com/hashicorp/go-version v1.8.0
|
||||
github.com/hashicorp/go-version v1.9.0
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
github.com/huandu/xstrings v1.5.0
|
||||
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056
|
||||
github.com/jhillyerd/enmime v1.3.0
|
||||
github.com/jhillyerd/enmime/v2 v2.3.0
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
github.com/klauspost/compress v1.18.3
|
||||
github.com/klauspost/compress v1.18.5
|
||||
github.com/klauspost/cpuid/v2 v2.3.0
|
||||
github.com/lib/pq v1.11.1
|
||||
github.com/lib/pq v1.12.1
|
||||
github.com/markbates/goth v1.82.0
|
||||
github.com/mattn/go-isatty v0.0.20
|
||||
github.com/mattn/go-sqlite3 v1.14.33
|
||||
github.com/meilisearch/meilisearch-go v0.36.0
|
||||
github.com/mattn/go-sqlite3 v1.14.38
|
||||
github.com/meilisearch/meilisearch-go v0.36.1
|
||||
github.com/mholt/archives v0.1.5
|
||||
github.com/microcosm-cc/bluemonday v1.0.27
|
||||
github.com/microsoft/go-mssqldb v1.9.6
|
||||
github.com/minio/minio-go/v7 v7.0.98
|
||||
github.com/msteinert/pam v1.2.0
|
||||
github.com/minio/minio-go/v7 v7.0.99
|
||||
github.com/msteinert/pam/v2 v2.1.0
|
||||
github.com/nektos/act v0.2.63
|
||||
github.com/niklasfasching/go-org v1.9.1
|
||||
github.com/olivere/elastic/v7 v7.0.32
|
||||
@@ -93,38 +93,38 @@ require (
|
||||
github.com/pquerna/otp v1.5.0
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
github.com/quasoft/websspi v1.1.2
|
||||
github.com/redis/go-redis/v9 v9.17.3
|
||||
github.com/redis/go-redis/v9 v9.18.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2
|
||||
github.com/sassoftware/go-rpmutils v0.4.0
|
||||
github.com/sergi/go-diff v1.4.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/tstranex/u2f v1.0.0
|
||||
github.com/ulikunitz/xz v0.5.15
|
||||
github.com/urfave/cli-docs/v3 v3.0.0-alpha6
|
||||
github.com/urfave/cli-docs/v3 v3.1.0
|
||||
github.com/urfave/cli/v3 v3.4.1
|
||||
github.com/wneessen/go-mail v0.7.2
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
github.com/yohcop/openid-go v1.0.1
|
||||
github.com/yuin/goldmark v1.7.16
|
||||
github.com/yuin/goldmark v1.8.2
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||
github.com/yuin/goldmark-meta v1.1.0
|
||||
gitlab.com/gitlab-org/api/client-go v0.142.4
|
||||
go.yaml.in/yaml/v4 v4.0.0-rc.2
|
||||
golang.org/x/crypto v0.47.0
|
||||
golang.org/x/image v0.35.0
|
||||
golang.org/x/net v0.49.0
|
||||
golang.org/x/oauth2 v0.34.0
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/sys v0.40.0
|
||||
golang.org/x/text v0.33.0
|
||||
google.golang.org/grpc v1.78.0
|
||||
gitlab.com/gitlab-org/api/client-go v1.46.0
|
||||
go.yaml.in/yaml/v4 v4.0.0-rc.3
|
||||
golang.org/x/crypto v0.49.0
|
||||
golang.org/x/image v0.38.0
|
||||
golang.org/x/net v0.52.0
|
||||
golang.org/x/oauth2 v0.36.0
|
||||
golang.org/x/sync v0.20.0
|
||||
golang.org/x/sys v0.42.0
|
||||
golang.org/x/text v0.35.0
|
||||
google.golang.org/grpc v1.79.3
|
||||
google.golang.org/protobuf v1.36.11
|
||||
gopkg.in/ini.v1 v1.67.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
mvdan.cc/xurls/v2 v2.6.0
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20260301104140-add494e31dab
|
||||
xorm.io/builder v0.3.13
|
||||
xorm.io/xorm v1.3.11
|
||||
)
|
||||
@@ -133,75 +133,78 @@ require (
|
||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||
code.gitea.io/gitea-vet v0.2.3 // indirect
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
filippo.io/edwards25519 v1.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
|
||||
github.com/DataDog/zstd v1.5.7 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/RoaringBitmap/roaring/v2 v2.10.0 // indirect
|
||||
github.com/RoaringBitmap/roaring/v2 v2.16.0 // indirect
|
||||
github.com/STARRY-S/zip v0.2.3 // indirect
|
||||
github.com/andybalholm/brotli v1.2.0 // indirect
|
||||
github.com/andybalholm/brotli v1.2.1 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.3 // indirect
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect
|
||||
github.com/aws/smithy-go v1.24.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect
|
||||
github.com/aws/smithy-go v1.24.2 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.24.0 // indirect
|
||||
github.com/blevesearch/bleve_index_api v1.2.11 // indirect
|
||||
github.com/blevesearch/geo v0.2.4 // indirect
|
||||
github.com/blevesearch/go-faiss v1.0.26 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.24.4 // indirect
|
||||
github.com/blevesearch/bleve_index_api v1.3.7 // indirect
|
||||
github.com/blevesearch/geo v0.2.5 // indirect
|
||||
github.com/blevesearch/go-faiss v1.0.30 // indirect
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
||||
github.com/blevesearch/gtreap v0.1.1 // indirect
|
||||
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.3.13 // indirect
|
||||
github.com/blevesearch/mmap-go v1.2.0 // indirect
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.4.5 // indirect
|
||||
github.com/blevesearch/segment v0.9.1 // indirect
|
||||
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
|
||||
github.com/blevesearch/vellum v1.1.0 // indirect
|
||||
github.com/blevesearch/zapx/v11 v11.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v12 v12.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v13 v13.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v14 v14.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v15 v15.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v16 v16.2.8 // indirect
|
||||
github.com/bmatcuk/doublestar/v4 v4.9.1 // indirect
|
||||
github.com/blevesearch/vellum v1.2.0 // indirect
|
||||
github.com/blevesearch/zapx/v11 v11.4.3 // indirect
|
||||
github.com/blevesearch/zapx/v12 v12.4.3 // indirect
|
||||
github.com/blevesearch/zapx/v13 v13.4.3 // indirect
|
||||
github.com/blevesearch/zapx/v14 v14.4.3 // indirect
|
||||
github.com/blevesearch/zapx/v15 v15.4.3 // indirect
|
||||
github.com/blevesearch/zapx/v16 v16.3.2 // indirect
|
||||
github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect
|
||||
github.com/bodgit/plumbing v1.3.0 // indirect
|
||||
github.com/bodgit/sevenzip v1.6.1 // indirect
|
||||
github.com/bodgit/windows v1.0.1 // indirect
|
||||
github.com/boombuler/barcode v1.1.0 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect
|
||||
github.com/caddyserver/zerossl v0.1.4 // indirect
|
||||
github.com/caddyserver/zerossl v0.1.5 // indirect
|
||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.11.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.3 // indirect
|
||||
github.com/couchbase/go-couchbase v0.1.1 // indirect
|
||||
github.com/couchbase/gomemcached v0.3.3 // indirect
|
||||
github.com/couchbase/goutils v0.1.2 // indirect
|
||||
github.com/couchbase/gomemcached v0.3.4 // indirect
|
||||
github.com/couchbase/goutils v0.3.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/davidmz/go-pageant v1.0.2 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/fatih/color v1.19.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.1 // indirect
|
||||
github.com/git-lfs/pktline v0.0.0-20230103162542-ca444d533ef1 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
|
||||
github.com/go-enry/go-oniguruma v1.2.1 // indirect
|
||||
github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-webauthn/x v0.1.24 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
||||
github.com/go-webauthn/x v0.2.2 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/flatbuffers v25.2.10+incompatible // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/go-tpm v0.9.5 // indirect
|
||||
github.com/google/flatbuffers v25.12.19+incompatible // indirect
|
||||
github.com/google/go-querystring v1.2.0 // indirect
|
||||
github.com/google/go-tpm v0.9.8 // indirect
|
||||
github.com/gorilla/css v1.0.1 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
@@ -209,55 +212,55 @@ require (
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||
github.com/inbucket/html2text v1.0.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jonboulle/clockwork v0.5.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kevinburke/ssh_config v1.4.0 // indirect
|
||||
github.com/kevinburke/ssh_config v1.6.0 // indirect
|
||||
github.com/klauspost/crc32 v1.3.0 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/libdns/libdns v1.1.1 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mailru/easyjson v0.9.2 // indirect
|
||||
github.com/markbates/going v1.0.3 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.21 // indirect
|
||||
github.com/mattn/go-shellwords v1.0.12 // indirect
|
||||
github.com/mholt/acmez/v3 v3.1.4 // indirect
|
||||
github.com/miekg/dns v1.1.69 // indirect
|
||||
github.com/mholt/acmez/v3 v3.1.6 // indirect
|
||||
github.com/miekg/dns v1.1.72 // indirect
|
||||
github.com/mikelolasagasti/xz v1.0.1 // indirect
|
||||
github.com/minio/crc64nvme v1.1.1 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minlz v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/minio/minlz v1.1.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect
|
||||
github.com/mschoch/smat v0.2.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/nwaples/rardecode/v2 v2.2.0 // indirect
|
||||
github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00 // indirect
|
||||
github.com/olekukonko/errors v1.1.0 // indirect
|
||||
github.com/olekukonko/ll v0.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v1.0.9 // indirect
|
||||
github.com/nwaples/rardecode/v2 v2.2.2 // indirect
|
||||
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
|
||||
github.com/olekukonko/errors v1.2.0 // indirect
|
||||
github.com/olekukonko/ll v0.1.8 // indirect
|
||||
github.com/olekukonko/tablewriter v1.1.4 // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/philhofer/fwd v1.2.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.22 // indirect
|
||||
github.com/pjbgf/sha1cd v0.4.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.26 // indirect
|
||||
github.com/pjbgf/sha1cd v0.5.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.66.1 // indirect
|
||||
github.com/prometheus/procfs v0.17.0 // indirect
|
||||
github.com/rhysd/actionlint v1.7.7 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/prometheus/common v0.67.5 // indirect
|
||||
github.com/prometheus/procfs v0.20.1 // indirect
|
||||
github.com/rhysd/actionlint v1.7.12 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.4 // indirect
|
||||
github.com/skeema/knownhosts v1.3.2 // indirect
|
||||
github.com/sorairolake/lzip-go v0.3.8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
||||
github.com/tinylib/msgp v1.6.1 // indirect
|
||||
github.com/tinylib/msgp v1.6.3 // indirect
|
||||
github.com/unknwon/com v1.0.1 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
@@ -271,14 +274,14 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.1 // indirect
|
||||
go.uber.org/zap/exp v0.3.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
go4.org v0.0.0-20260112195520-a5071408f32f // indirect
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b // indirect
|
||||
golang.org/x/mod v0.31.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.40.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
|
||||
golang.org/x/mod v0.34.0 // indirect
|
||||
golang.org/x/time v0.15.0 // indirect
|
||||
golang.org/x/tools v0.43.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260401020348-3a24fdc17823 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
@@ -288,16 +291,22 @@ ignore (
|
||||
./node_modules
|
||||
)
|
||||
|
||||
replace github.com/jaytaylor/html2text => github.com/Necoro/html2text v0.0.0-20250804200300-7bf1ce1c7347
|
||||
// When doing "go get -u ./...", Golang will try to update all dependencies
|
||||
// But not all latest versions of dependencies are compatible with other packages or our codebase, so we need to pin some dependencies to specific versions
|
||||
// Need to regularly maintain this list to try to update them to latest versions, especially the TODO ones
|
||||
|
||||
replace github.com/nektos/act => gitea.com/gitea/act v0.261.8
|
||||
replace github.com/jaytaylor/html2text => github.com/Necoro/html2text v0.0.0-20250804200300-7bf1ce1c7347 // jaytaylor/html2text is unmaintained
|
||||
|
||||
exclude github.com/gofrs/uuid v3.2.0+incompatible
|
||||
replace github.com/nektos/act => gitea.com/gitea/act v0.261.10 // gitea maintains its own package
|
||||
|
||||
exclude github.com/gofrs/uuid v4.0.0+incompatible
|
||||
replace github.com/urfave/cli/v3 => github.com/urfave/cli/v3 v3.4.1 // v3.6.2 breaks -c flag parsing in help commands
|
||||
|
||||
exclude github.com/goccy/go-json v0.4.11
|
||||
replace go.yaml.in/yaml/v4 => go.yaml.in/yaml/v4 v4.0.0-rc.3 // rc.4 changes block scalar serialization, wait for stable release
|
||||
|
||||
exclude github.com/satori/go.uuid v1.2.0
|
||||
replace github.com/Azure/azure-sdk-for-go/sdk/azcore => github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.0 // v1.21.0+ uses API version unsupported by Azurite in CI
|
||||
|
||||
replace github.com/Azure/azure-sdk-for-go/sdk/storage/azblob => github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.2 // v1.6.4+ uses API version unsupported by Azurite in CI
|
||||
|
||||
replace github.com/microsoft/go-mssqldb => github.com/microsoft/go-mssqldb v1.9.7 // downgraded with Azure SDK
|
||||
|
||||
tool code.gitea.io/gitea-vet
|
||||
@@ -139,7 +139,7 @@ func Test_CalcCommitStatus(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expected: &git_model.CommitStatus{
|
||||
State: commitstatus.CommitStatusPending,
|
||||
State: commitstatus.CommitStatusFailure,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -495,9 +495,9 @@ func updateUserWhitelist(ctx context.Context, repo *repo_model.Repository, curre
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUserByID [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err)
|
||||
}
|
||||
perm, err := access_model.GetUserRepoPermission(ctx, repo, user)
|
||||
perm, err := access_model.GetIndividualUserRepoPermission(ctx, repo, user)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUserRepoPermission [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err)
|
||||
return nil, fmt.Errorf("GetIndividualUserRepoPermission [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err)
|
||||
}
|
||||
|
||||
if !perm.CanWrite(unit.TypeCode) {
|
||||
|
||||
@@ -356,7 +356,7 @@ func ClearIssueLabels(ctx context.Context, issue *Issue, doer *user_model.User)
|
||||
return err
|
||||
}
|
||||
|
||||
perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer)
|
||||
perm, err := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -64,36 +64,6 @@ func LoadProjectIssueColumnMap(ctx context.Context, projectID, defaultColumnID i
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// LoadIssuesFromColumn load issues assigned to this column
|
||||
func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, opts *IssuesOptions) (IssueList, error) {
|
||||
issueList, err := Issues(ctx, opts.Copy(func(o *IssuesOptions) {
|
||||
o.ProjectColumnID = b.ID
|
||||
o.ProjectID = b.ProjectID
|
||||
o.SortType = "project-column-sorting"
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if b.Default {
|
||||
issues, err := Issues(ctx, opts.Copy(func(o *IssuesOptions) {
|
||||
o.ProjectColumnID = db.NoConditionID
|
||||
o.ProjectID = b.ProjectID
|
||||
o.SortType = "project-column-sorting"
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
issueList = append(issueList, issues...)
|
||||
}
|
||||
|
||||
if err := issueList.LoadComments(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return issueList, nil
|
||||
}
|
||||
|
||||
// IssueAssignOrRemoveProject changes the project associated with an issue
|
||||
// If newProjectID is 0, the issue is removed from the project
|
||||
func IssueAssignOrRemoveProject(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID, newColumnID int64) error {
|
||||
|
||||
@@ -665,9 +665,9 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
|
||||
continue
|
||||
}
|
||||
// Normal users must have read access to the referencing issue
|
||||
perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, user)
|
||||
perm, err := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, user)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetUserRepoPermission [%d]: %w", user.ID, err)
|
||||
return nil, fmt.Errorf("GetIndividualUserRepoPermission [%d]: %w", user.ID, err)
|
||||
}
|
||||
if !perm.CanReadIssuesOrPulls(issue.IsPull) {
|
||||
continue
|
||||
|
||||
@@ -207,7 +207,7 @@ func (issue *Issue) verifyReferencedIssue(stdCtx context.Context, ctx *crossRefe
|
||||
|
||||
// Check doer permissions; set action to None if the doer can't change the destination
|
||||
if refIssue.RepoID != ctx.OrigIssue.RepoID || ref.Action != references.XRefActionNone {
|
||||
perm, err := access_model.GetUserRepoPermission(stdCtx, refIssue.Repo, ctx.Doer)
|
||||
perm, err := access_model.GetDoerRepoPermission(stdCtx, refIssue.Repo, ctx.Doer)
|
||||
if err != nil {
|
||||
return nil, references.XRefActionNone, err
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ func CanMaintainerWriteToBranch(ctx context.Context, p access_model.Permission,
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
prPerm, err := access_model.GetUserRepoPermission(ctx, pr.BaseRepo, user)
|
||||
prPerm, err := access_model.GetIndividualUserRepoPermission(ctx, pr.BaseRepo, user)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -919,7 +919,7 @@ func CanMarkConversation(ctx context.Context, issue *Issue, doer *user_model.Use
|
||||
return false, nil
|
||||
}
|
||||
if doer.ID != issue.PosterID {
|
||||
p, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer)
|
||||
p, err := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -404,6 +404,7 @@ func prepareMigrationTasks() []*migration {
|
||||
newMigration(327, "Add disabled state to action runners", v1_26.AddDisabledToActionRunner),
|
||||
newMigration(328, "Add TokenPermissions column to ActionRunJob", v1_26.AddTokenPermissionsToActionRunJob),
|
||||
newMigration(329, "Add unique constraint for user badge", v1_26.AddUniqueIndexForUserBadge),
|
||||
newMigration(330, "Add name column to webhook", v1_26.AddNameToWebhook),
|
||||
}
|
||||
return preparedMigrations
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package v1_26
|
||||
|
||||
import (
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddNameToWebhook(x *xorm.Engine) error {
|
||||
type Webhook struct {
|
||||
Name string `xorm:"VARCHAR(255) NOT NULL DEFAULT ''"`
|
||||
}
|
||||
_, err := x.SyncWithOptions(xorm.SyncOptions{IgnoreDropIndices: true}, new(Webhook))
|
||||
return err
|
||||
}
|
||||
@@ -91,43 +91,80 @@ func updateUserAccess(accessMap map[int64]*userAccess, user *user_model.User, mo
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: do cross-comparison so reduce deletions and additions to the minimum?
|
||||
// refreshAccesses updates the repository's access records in the database by comparing the provided accessMap
|
||||
// with existing records. It minimizes DB operations by performing selective inserts, updates, and deletes
|
||||
// instead of removing all existing records and re-adding them.
|
||||
func refreshAccesses(ctx context.Context, repo *repo_model.Repository, accessMap map[int64]*userAccess) (err error) {
|
||||
minMode := perm.AccessModeRead
|
||||
minModeToKeep := perm.AccessModeRead
|
||||
if err := repo.LoadOwner(ctx); err != nil {
|
||||
return fmt.Errorf("LoadOwner: %w", err)
|
||||
}
|
||||
|
||||
// If the repo isn't private and isn't owned by a organization,
|
||||
// If the repo isn't private and isn't owned by an organization,
|
||||
// increase the minMode to Write.
|
||||
if !repo.IsPrivate && !repo.Owner.IsOrganization() {
|
||||
minMode = perm.AccessModeWrite
|
||||
minModeToKeep = perm.AccessModeWrite
|
||||
}
|
||||
|
||||
newAccesses := make([]Access, 0, len(accessMap))
|
||||
// Query existing accesses for cross-comparison
|
||||
var existingAccesses []Access
|
||||
if err := db.GetEngine(ctx).Where(builder.Eq{"repo_id": repo.ID}).Find(&existingAccesses); err != nil {
|
||||
return fmt.Errorf("find existing accesses: %w", err)
|
||||
}
|
||||
existingMap := make(map[int64]perm.AccessMode, len(existingAccesses))
|
||||
for _, a := range existingAccesses {
|
||||
existingMap[a.UserID] = a.Mode
|
||||
}
|
||||
|
||||
var toDelete []int64
|
||||
var toInsert, toUpdate []Access
|
||||
|
||||
// Determine changes
|
||||
for userID, ua := range accessMap {
|
||||
if ua.Mode < minMode && !ua.User.IsRestricted {
|
||||
continue
|
||||
if ua.Mode < minModeToKeep && !ua.User.IsRestricted {
|
||||
// No explicit access record needed (handled by default permissions, e.g., public repo access)
|
||||
if _, exists := existingMap[userID]; exists {
|
||||
toDelete = append(toDelete, userID)
|
||||
}
|
||||
} else {
|
||||
desiredMode := ua.Mode
|
||||
if existingMode, exists := existingMap[userID]; exists {
|
||||
if existingMode != desiredMode {
|
||||
toUpdate = append(toUpdate, Access{UserID: userID, RepoID: repo.ID, Mode: desiredMode})
|
||||
}
|
||||
} else {
|
||||
toInsert = append(toInsert, Access{UserID: userID, RepoID: repo.ID, Mode: desiredMode})
|
||||
}
|
||||
}
|
||||
|
||||
newAccesses = append(newAccesses, Access{
|
||||
UserID: userID,
|
||||
RepoID: repo.ID,
|
||||
Mode: ua.Mode,
|
||||
})
|
||||
delete(existingMap, userID)
|
||||
}
|
||||
|
||||
// Delete old accesses and insert new ones for repository.
|
||||
if _, err = db.DeleteByBean(ctx, &Access{RepoID: repo.ID}); err != nil {
|
||||
return fmt.Errorf("delete old accesses: %w", err)
|
||||
}
|
||||
if len(newAccesses) == 0 {
|
||||
return nil
|
||||
// Remaining in existingMap should be deleted
|
||||
for userID := range existingMap {
|
||||
toDelete = append(toDelete, userID)
|
||||
}
|
||||
|
||||
if err = db.Insert(ctx, newAccesses); err != nil {
|
||||
return fmt.Errorf("insert new accesses: %w", err)
|
||||
// Execute deletions
|
||||
if len(toDelete) > 0 {
|
||||
if _, err = db.GetEngine(ctx).In("user_id", toDelete).And("repo_id = ?", repo.ID).Delete(&Access{}); err != nil {
|
||||
return fmt.Errorf("delete accesses: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Execute updates
|
||||
for _, u := range toUpdate {
|
||||
if _, err = db.GetEngine(ctx).Where("user_id = ? AND repo_id = ?", u.UserID, repo.ID).Cols("mode").Update(&Access{Mode: u.Mode}); err != nil {
|
||||
return fmt.Errorf("update access for user %d: %w", u.UserID, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Execute insertions
|
||||
if len(toInsert) > 0 {
|
||||
if err = db.Insert(ctx, toInsert); err != nil {
|
||||
return fmt.Errorf("insert new accesses: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,20 @@ import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAccessLevel(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func TestAccess(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
t.Run("AccessLevel", testAccessLevel)
|
||||
t.Run("HasAccess", testHasAccess)
|
||||
t.Run("RecalculateAccesses", testRecalculateAccesses)
|
||||
t.Run("RecalculateAccesses2", testRecalculateAccesses2)
|
||||
t.Run("RecalculateAccessesUpdateMode", testRecalculateAccessesUpdateMode)
|
||||
t.Run("RecalculateAccessesRemoveAccess", testRecalculateAccessesRemoveAccess)
|
||||
}
|
||||
|
||||
func testAccessLevel(t *testing.T) {
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
|
||||
user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29})
|
||||
@@ -75,9 +84,7 @@ func TestAccessLevel(t *testing.T) {
|
||||
assert.Equal(t, perm_model.AccessModeRead, level)
|
||||
}
|
||||
|
||||
func TestHasAccess(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
func testHasAccess(t *testing.T) {
|
||||
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
|
||||
// A public repository owned by User 2
|
||||
@@ -101,9 +108,8 @@ func TestHasAccess(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRepository_RecalculateAccesses(t *testing.T) {
|
||||
func testRecalculateAccesses(t *testing.T) {
|
||||
// test with organization repo
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
|
||||
assert.NoError(t, repo1.LoadOwner(t.Context()))
|
||||
|
||||
@@ -118,9 +124,8 @@ func TestRepository_RecalculateAccesses(t *testing.T) {
|
||||
assert.Equal(t, perm_model.AccessModeOwner, access.Mode)
|
||||
}
|
||||
|
||||
func TestRepository_RecalculateAccesses2(t *testing.T) {
|
||||
func testRecalculateAccesses2(t *testing.T) {
|
||||
// test with non-organization repo
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
||||
assert.NoError(t, repo1.LoadOwner(t.Context()))
|
||||
|
||||
@@ -132,3 +137,67 @@ func TestRepository_RecalculateAccesses2(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, has)
|
||||
}
|
||||
|
||||
func testRecalculateAccessesUpdateMode(t *testing.T) {
|
||||
// Test the update path in refreshAccesses optimization
|
||||
// Scenario: User's access mode changes from Read to Write
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
||||
assert.NoError(t, repo.LoadOwner(t.Context()))
|
||||
|
||||
// Verify initial access mode
|
||||
_ = db.Insert(t.Context(), &repo_model.Collaboration{UserID: 4, RepoID: 4, Mode: perm_model.AccessModeWrite})
|
||||
_ = db.Insert(t.Context(), &access_model.Access{UserID: 4, RepoID: 4, Mode: perm_model.AccessModeWrite})
|
||||
initialAccess := &access_model.Access{UserID: 4, RepoID: 4}
|
||||
has, err := db.GetEngine(t.Context()).Get(initialAccess)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
initialMode := initialAccess.Mode
|
||||
|
||||
// Change collaboration mode to trigger update path
|
||||
newMode := perm_model.AccessModeAdmin
|
||||
assert.NotEqual(t, initialMode, newMode, "New mode should differ from initial mode")
|
||||
|
||||
_, err = db.GetEngine(t.Context()).
|
||||
Where("user_id = ? AND repo_id = ?", 4, 4).
|
||||
Cols("mode").
|
||||
Update(&repo_model.Collaboration{Mode: newMode})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Recalculate accesses - should UPDATE existing access, not delete+insert
|
||||
assert.NoError(t, access_model.RecalculateAccesses(t.Context(), repo))
|
||||
|
||||
// Verify access was updated, not deleted and re-inserted
|
||||
updatedAccess := &access_model.Access{UserID: 4, RepoID: 4}
|
||||
has, err = db.GetEngine(t.Context()).Get(updatedAccess)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has, "Access should still exist")
|
||||
assert.Equal(t, newMode, updatedAccess.Mode, "Access mode should be updated to new collaboration mode")
|
||||
}
|
||||
|
||||
func testRecalculateAccessesRemoveAccess(t *testing.T) {
|
||||
// Test the delete path in refreshAccesses optimization
|
||||
// Scenario: Remove a user's collaboration, access should be deleted
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
||||
assert.NoError(t, repo.LoadOwner(t.Context()))
|
||||
|
||||
// Verify initial access exists
|
||||
initialAccess := &access_model.Access{UserID: 4, RepoID: 4}
|
||||
has, err := db.GetEngine(t.Context()).Get(initialAccess)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has, "Access should exist initially")
|
||||
|
||||
// Remove the collaboration to trigger delete path
|
||||
_, err = db.GetEngine(t.Context()).
|
||||
Where("user_id = ? AND repo_id = ?", 4, 4).
|
||||
Delete(&repo_model.Collaboration{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Recalculate accesses - should DELETE the access record
|
||||
assert.NoError(t, access_model.RecalculateAccesses(t.Context(), repo))
|
||||
|
||||
// Verify access was deleted
|
||||
removedAccess := &access_model.Access{UserID: 4, RepoID: 4}
|
||||
has, err = db.GetEngine(t.Context()).Get(removedAccess)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, has, "Access should be deleted after removing collaboration")
|
||||
}
|
||||
@@ -331,7 +331,7 @@ func GetActionsUserRepoPermission(ctx context.Context, repo *repo_model.Reposito
|
||||
|
||||
// Check permission like simple user but limit to read-only (PR #36095)
|
||||
// Enhanced to also grant read-only access if isSameRepo is true and target repository is public
|
||||
botPerm, err := GetUserRepoPermission(ctx, repo, user_model.NewActionsUser())
|
||||
botPerm, err := GetIndividualUserRepoPermission(ctx, repo, user_model.NewActionsUser())
|
||||
if err != nil {
|
||||
return perm, err
|
||||
}
|
||||
@@ -379,8 +379,19 @@ func GetActionsUserRepoPermission(ctx context.Context, repo *repo_model.Reposito
|
||||
return perm, nil
|
||||
}
|
||||
|
||||
// GetUserRepoPermission returns the user permissions to the repository
|
||||
func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) {
|
||||
// GetDoerRepoPermission returns the repository permission for the current actor,
|
||||
// dispatching to GetActionsUserRepoPermission when the actor is an Actions token user.
|
||||
func GetDoerRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (Permission, error) {
|
||||
if taskID, ok := user_model.GetActionsUserTaskID(user); ok {
|
||||
return GetActionsUserRepoPermission(ctx, repo, user, taskID)
|
||||
}
|
||||
return GetIndividualUserRepoPermission(ctx, repo, user)
|
||||
}
|
||||
|
||||
// GetIndividualUserRepoPermission returns the permissions for an explicit user identity.
|
||||
// In most request paths, callers should use GetDoerRepoPermission instead.
|
||||
// Unlike GetDoerRepoPermission, this helper does not resolve Actions task users.
|
||||
func GetIndividualUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) {
|
||||
defer func() {
|
||||
if err == nil {
|
||||
finalProcessRepoUnitPermission(user, &perm)
|
||||
@@ -539,8 +550,9 @@ func AccessLevel(ctx context.Context, user *user_model.User, repo *repo_model.Re
|
||||
|
||||
// AccessLevelUnit returns the Access a user has to a repository's. Will return NoneAccess if the
|
||||
// user does not have access.
|
||||
// This helper only supports explicit user identities and does not resolve Actions task users.
|
||||
func AccessLevelUnit(ctx context.Context, user *user_model.User, repo *repo_model.Repository, unitType unit.Type) (perm_model.AccessMode, error) { //nolint:revive // export stutter
|
||||
perm, err := GetUserRepoPermission(ctx, repo, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo, user)
|
||||
if err != nil {
|
||||
return perm_model.AccessModeNone, err
|
||||
}
|
||||
@@ -559,7 +571,7 @@ func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.
|
||||
if user.IsOrganization() {
|
||||
return false, fmt.Errorf("organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID)
|
||||
}
|
||||
perm, err := GetUserRepoPermission(ctx, repo, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo, user)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -568,6 +580,7 @@ func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.
|
||||
}
|
||||
|
||||
// HasAnyUnitAccess see the comment of "perm.HasAnyUnitAccess"
|
||||
// This helper only supports explicit user identities and does not resolve Actions task users.
|
||||
func HasAnyUnitAccess(ctx context.Context, userID int64, repo *repo_model.Repository) (bool, error) {
|
||||
var user *user_model.User
|
||||
var err error
|
||||
@@ -577,7 +590,7 @@ func HasAnyUnitAccess(ctx context.Context, userID int64, repo *repo_model.Reposi
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
perm, err := GetUserRepoPermission(ctx, repo, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo, user)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -625,13 +638,14 @@ func GetUserIDsWithUnitAccess(ctx context.Context, repo *repo_model.Repository,
|
||||
}
|
||||
|
||||
// CheckRepoUnitUser check whether user could visit the unit of this repository
|
||||
// This helper only supports explicit user identities and does not resolve Actions task users.
|
||||
func CheckRepoUnitUser(ctx context.Context, repo *repo_model.Repository, user *user_model.User, unitType unit.Type) bool {
|
||||
if user != nil && user.IsAdmin {
|
||||
return true
|
||||
}
|
||||
perm, err := GetUserRepoPermission(ctx, repo, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo, user)
|
||||
if err != nil {
|
||||
log.Error("GetUserRepoPermission: %w", err)
|
||||
log.Error("GetIndividualUserRepoPermission: %w", err)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ package access
|
||||
import (
|
||||
"testing"
|
||||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
perm_model "code.gitea.io/gitea/models/perm"
|
||||
@@ -157,8 +158,13 @@ func TestUnitAccessMode(t *testing.T) {
|
||||
assert.Equal(t, perm_model.AccessModeRead, perm.UnitAccessMode(unit.TypeWiki), "has unit, and map, use map")
|
||||
}
|
||||
|
||||
func TestGetUserRepoPermission(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
func TestGetRepoPermission(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
t.Run("GetIndividualUserRepoPermission", testGetIndividualUserRepoPermission)
|
||||
t.Run("GetDoerRepoPermission", testGetDoerRepoPermission)
|
||||
}
|
||||
|
||||
func testGetIndividualUserRepoPermission(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
repo32 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}) // org public repo
|
||||
require.NoError(t, repo32.LoadOwner(ctx))
|
||||
@@ -172,7 +178,7 @@ func TestGetUserRepoPermission(t *testing.T) {
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamUser{OrgID: org.ID, TeamID: team.ID, UID: user.ID}))
|
||||
|
||||
t.Run("DoerInTeamWithNoRepo", func(t *testing.T) {
|
||||
perm, err := GetUserRepoPermission(ctx, repo32, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo32, user)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, perm_model.AccessModeRead, perm.AccessMode)
|
||||
assert.Nil(t, perm.unitsMode) // doer in the team, but has no access to the repo
|
||||
@@ -181,7 +187,7 @@ func TestGetUserRepoPermission(t *testing.T) {
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamRepo{OrgID: org.ID, TeamID: team.ID, RepoID: repo32.ID}))
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeCode, AccessMode: perm_model.AccessModeNone}))
|
||||
t.Run("DoerWithTeamUnitAccessNone", func(t *testing.T) {
|
||||
perm, err := GetUserRepoPermission(ctx, repo32, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo32, user)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, perm_model.AccessModeRead, perm.AccessMode)
|
||||
assert.Equal(t, perm_model.AccessModeRead, perm.unitsMode[unit.TypeCode])
|
||||
@@ -191,7 +197,7 @@ func TestGetUserRepoPermission(t *testing.T) {
|
||||
require.NoError(t, db.TruncateBeans(ctx, &organization.TeamUnit{}))
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeCode, AccessMode: perm_model.AccessModeWrite}))
|
||||
t.Run("DoerWithTeamUnitAccessWrite", func(t *testing.T) {
|
||||
perm, err := GetUserRepoPermission(ctx, repo32, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo32, user)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, perm_model.AccessModeRead, perm.AccessMode)
|
||||
assert.Equal(t, perm_model.AccessModeWrite, perm.unitsMode[unit.TypeCode])
|
||||
@@ -204,7 +210,7 @@ func TestGetUserRepoPermission(t *testing.T) {
|
||||
require.NoError(t, db.TruncateBeans(ctx, &organization.TeamUnit{}, &Access{})) // The user has access set of that repo, remove it, it is useless for our test
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamRepo{OrgID: org.ID, TeamID: team.ID, RepoID: repo3.ID}))
|
||||
t.Run("DoerWithNoopTeamOnPrivateRepo", func(t *testing.T) {
|
||||
perm, err := GetUserRepoPermission(ctx, repo3, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo3, user)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, perm_model.AccessModeNone, perm.AccessMode)
|
||||
assert.Equal(t, perm_model.AccessModeNone, perm.unitsMode[unit.TypeCode])
|
||||
@@ -214,7 +220,7 @@ func TestGetUserRepoPermission(t *testing.T) {
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeCode, AccessMode: perm_model.AccessModeNone}))
|
||||
require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeIssues, AccessMode: perm_model.AccessModeRead}))
|
||||
t.Run("DoerWithReadIssueTeamOnPrivateRepo", func(t *testing.T) {
|
||||
perm, err := GetUserRepoPermission(ctx, repo3, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo3, user)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, perm_model.AccessModeNone, perm.AccessMode)
|
||||
assert.Equal(t, perm_model.AccessModeNone, perm.unitsMode[unit.TypeCode])
|
||||
@@ -233,7 +239,7 @@ func TestGetUserRepoPermission(t *testing.T) {
|
||||
require.NoError(t, db.Insert(ctx, repo_model.Collaboration{RepoID: repo3.ID, UserID: user.ID, Mode: perm_model.AccessModeWrite}))
|
||||
require.NoError(t, db.Insert(ctx, Access{RepoID: repo3.ID, UserID: user.ID, Mode: perm_model.AccessModeWrite}))
|
||||
t.Run("DoerWithReadIssueTeamAndWriteCollaboratorOnPrivateRepo", func(t *testing.T) {
|
||||
perm, err := GetUserRepoPermission(ctx, repo3, user)
|
||||
perm, err := GetIndividualUserRepoPermission(ctx, repo3, user)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, perm_model.AccessModeWrite, perm.AccessMode)
|
||||
assert.Equal(t, perm_model.AccessModeWrite, perm.unitsMode[unit.TypeCode])
|
||||
@@ -245,3 +251,25 @@ func TestGetUserRepoPermission(t *testing.T) {
|
||||
assert.Equal(t, user.ID, users[0].ID)
|
||||
})
|
||||
}
|
||||
|
||||
func testGetDoerRepoPermission(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
|
||||
repo4 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
||||
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
task47 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionTask{ID: 47})
|
||||
actionsDoer := user_model.NewActionsUserWithTaskID(task47.ID)
|
||||
regularUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
|
||||
actionsPerm, err := GetDoerRepoPermission(ctx, repo4, actionsDoer)
|
||||
require.NoError(t, err)
|
||||
directPerm, err := GetActionsUserRepoPermission(ctx, repo4, actionsDoer, task47.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, directPerm, actionsPerm)
|
||||
|
||||
doerPerm, err := GetDoerRepoPermission(ctx, repo1, regularUser)
|
||||
require.NoError(t, err)
|
||||
individualPerm, err := GetIndividualUserRepoPermission(ctx, repo1, regularUser)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, individualPerm, doerPerm)
|
||||
}
|
||||
+24
-19
@@ -257,9 +257,12 @@ func (p *Project) GetColumns(ctx context.Context) (ColumnList, error) {
|
||||
return columns, nil
|
||||
}
|
||||
|
||||
// getDefaultColumn return default column and ensure only one exists
|
||||
func (p *Project) getDefaultColumn(ctx context.Context) (*Column, error) {
|
||||
// getDefaultColumnWithFallback return default column if one exists
|
||||
// otherwise return the first column by sorting and set it as default column
|
||||
func (p *Project) getDefaultColumnWithFallback(ctx context.Context) (*Column, error) {
|
||||
var column Column
|
||||
|
||||
// try to find a column "default=true"
|
||||
has, err := db.GetEngine(ctx).
|
||||
Where("project_id=? AND `default` = ?", p.ID, true).
|
||||
Desc("id").Get(&column)
|
||||
@@ -270,23 +273,9 @@ func (p *Project) getDefaultColumn(ctx context.Context) (*Column, error) {
|
||||
if has {
|
||||
return &column, nil
|
||||
}
|
||||
return nil, ErrProjectColumnNotExist{ColumnID: 0}
|
||||
}
|
||||
|
||||
// MustDefaultColumn returns the default column for a project.
|
||||
// If one exists, it is returned
|
||||
// If none exists, the first column will be elevated to the default column of this project
|
||||
func (p *Project) MustDefaultColumn(ctx context.Context) (*Column, error) {
|
||||
c, err := p.getDefaultColumn(ctx)
|
||||
if err != nil && !IsErrProjectColumnNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
if c != nil {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
var column Column
|
||||
has, err := db.GetEngine(ctx).Where("project_id=?", p.ID).OrderBy("sorting, id").Get(&column)
|
||||
// try to find the first column by sorting
|
||||
has, err = db.GetEngine(ctx).Where("project_id=?", p.ID).OrderBy("sorting, id").Get(&column)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -298,8 +287,24 @@ func (p *Project) MustDefaultColumn(ctx context.Context) (*Column, error) {
|
||||
return &column, nil
|
||||
}
|
||||
|
||||
return nil, ErrProjectColumnNotExist{ColumnID: 0}
|
||||
}
|
||||
|
||||
// MustDefaultColumn returns the default column for a project.
|
||||
// If one exists, it is returned
|
||||
// If none exists, the first column will be elevated to the default column of this project
|
||||
// If there is no column, it creates a default column and returns it
|
||||
func (p *Project) MustDefaultColumn(ctx context.Context) (*Column, error) {
|
||||
c, err := p.getDefaultColumnWithFallback(ctx)
|
||||
if err != nil && !IsErrProjectColumnNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
if c != nil {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// create a default column if none is found
|
||||
column = Column{
|
||||
column := Column{
|
||||
ProjectID: p.ID,
|
||||
Default: true,
|
||||
Title: "Uncategorized",
|
||||
|
||||
@@ -126,6 +126,7 @@ type Webhook struct {
|
||||
OwnerID int64 `xorm:"INDEX"`
|
||||
IsSystemWebhook bool
|
||||
URL string `xorm:"url TEXT"`
|
||||
Name string `xorm:"VARCHAR(255) NOT NULL DEFAULT ''"`
|
||||
HTTPMethod string `xorm:"http_method"`
|
||||
ContentType HookContentType
|
||||
Secret string `xorm:"TEXT"`
|
||||
|
||||
@@ -135,7 +135,7 @@ func rewriteSubExpression(in string, forceFormat bool) (string, error) {
|
||||
exprStart := -1
|
||||
strStart := -1
|
||||
var results []string
|
||||
formatOut := ""
|
||||
var formatOut strings.Builder
|
||||
for pos < len(in) {
|
||||
if strStart > -1 {
|
||||
matches := strPattern.FindStringIndex(in[pos:])
|
||||
@@ -158,7 +158,7 @@ func rewriteSubExpression(in string, forceFormat bool) (string, error) {
|
||||
}
|
||||
|
||||
if exprEnd > -1 {
|
||||
formatOut += fmt.Sprintf("{%d}", len(results))
|
||||
fmt.Fprintf(&formatOut, "{%d}", len(results))
|
||||
results = append(results, strings.TrimSpace(in[exprStart:pos+exprEnd]))
|
||||
pos += exprEnd + 2
|
||||
exprStart = -1
|
||||
@@ -170,20 +170,20 @@ func rewriteSubExpression(in string, forceFormat bool) (string, error) {
|
||||
} else {
|
||||
exprStart = strings.Index(in[pos:], "${{")
|
||||
if exprStart != -1 {
|
||||
formatOut += escapeFormatString(in[pos : pos+exprStart])
|
||||
formatOut.WriteString(escapeFormatString(in[pos : pos+exprStart]))
|
||||
exprStart = pos + exprStart + 3
|
||||
pos = exprStart
|
||||
} else {
|
||||
formatOut += escapeFormatString(in[pos:])
|
||||
formatOut.WriteString(escapeFormatString(in[pos:]))
|
||||
pos = len(in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(results) == 1 && formatOut == "{0}" && !forceFormat {
|
||||
if len(results) == 1 && formatOut.String() == "{0}" && !forceFormat {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
out := fmt.Sprintf("format('%s', %s)", strings.ReplaceAll(formatOut, "'", "''"), strings.Join(results, ", "))
|
||||
out := fmt.Sprintf("format('%s', %s)", strings.ReplaceAll(formatOut.String(), "'", "''"), strings.Join(results, ", "))
|
||||
return out, nil
|
||||
}
|
||||
@@ -9,7 +9,9 @@ import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
@@ -61,6 +63,8 @@ type LayeredFS struct {
|
||||
layers []*Layer
|
||||
}
|
||||
|
||||
var _ fs.ReadDirFS = (*LayeredFS)(nil)
|
||||
|
||||
// Layered returns a new LayeredFS with the given layers. The first layer is the top layer.
|
||||
func Layered(layers ...*Layer) *LayeredFS {
|
||||
return &LayeredFS{layers: layers}
|
||||
@@ -83,6 +87,27 @@ func (l *LayeredFS) ReadFile(elems ...string) ([]byte, error) {
|
||||
return bs, err
|
||||
}
|
||||
|
||||
func (l *LayeredFS) ReadDir(name string) (files []fs.DirEntry, _ error) {
|
||||
filesMap := map[string]fs.DirEntry{}
|
||||
for _, layer := range l.layers {
|
||||
entries, err := readDirOptional(layer, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, entry := range entries {
|
||||
entryName := entry.Name()
|
||||
if _, exist := filesMap[entryName]; !exist && shouldInclude(entry) {
|
||||
filesMap[entryName] = entry
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, file := range filesMap {
|
||||
files = append(files, file)
|
||||
}
|
||||
slices.SortFunc(files, func(a, b fs.DirEntry) int { return strings.Compare(a.Name(), b.Name()) })
|
||||
return files, nil
|
||||
}
|
||||
|
||||
// ReadLayeredFile reads the named file, and returns the layer name.
|
||||
func (l *LayeredFS) ReadLayeredFile(elems ...string) ([]byte, string, error) {
|
||||
name := util.PathJoinRel(elems...)
|
||||
|
||||
@@ -8,7 +8,7 @@ package pam
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/msteinert/pam"
|
||||
"github.com/msteinert/pam/v2"
|
||||
)
|
||||
|
||||
// Supported is true when built with PAM
|
||||
@@ -28,6 +28,7 @@ func Auth(serviceName, userName, passwd string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer t.End()
|
||||
|
||||
if err = t.Authenticate(0); err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -61,16 +61,17 @@ type CommitStatusStates []CommitStatusState //nolint:revive // export stutter
|
||||
// According to https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#get-the-combined-status-for-a-specific-reference
|
||||
// > Additionally, a combined state is returned. The state is one of:
|
||||
// > failure if any of the contexts report as error or failure
|
||||
// > failure if any of the contexts report as warning (Gitea specific behavior)
|
||||
// > pending if there are no statuses or a context is pending
|
||||
// > success if the latest status for all contexts is success
|
||||
func (css CommitStatusStates) Combine() CommitStatusState {
|
||||
successCnt := 0
|
||||
for _, state := range css {
|
||||
switch {
|
||||
case state.IsError() || state.IsFailure():
|
||||
case state.IsError() || state.IsFailure() || state.IsWarning():
|
||||
return CommitStatusFailure
|
||||
case state.IsPending():
|
||||
case state.IsSuccess() || state.IsWarning() || state.IsSkipped():
|
||||
case state.IsSuccess() || state.IsSkipped():
|
||||
successCnt++
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func TestCombine(t *testing.T) {
|
||||
{
|
||||
name: "warning",
|
||||
states: CommitStatusStates{CommitStatusWarning},
|
||||
expected: CommitStatusSuccess,
|
||||
expected: CommitStatusFailure,
|
||||
},
|
||||
// 2 states
|
||||
{
|
||||
@@ -62,7 +62,7 @@ func TestCombine(t *testing.T) {
|
||||
{
|
||||
name: "pending and warning",
|
||||
states: CommitStatusStates{CommitStatusPending, CommitStatusWarning},
|
||||
expected: CommitStatusPending,
|
||||
expected: CommitStatusFailure,
|
||||
},
|
||||
{
|
||||
name: "success and error",
|
||||
@@ -77,7 +77,7 @@ func TestCombine(t *testing.T) {
|
||||
{
|
||||
name: "success and warning",
|
||||
states: CommitStatusStates{CommitStatusSuccess, CommitStatusWarning},
|
||||
expected: CommitStatusSuccess,
|
||||
expected: CommitStatusFailure,
|
||||
},
|
||||
{
|
||||
name: "error and failure",
|
||||
@@ -98,7 +98,7 @@ func TestCombine(t *testing.T) {
|
||||
{
|
||||
name: "pending, success and warning",
|
||||
states: CommitStatusStates{CommitStatusPending, CommitStatusSuccess, CommitStatusWarning},
|
||||
expected: CommitStatusPending,
|
||||
expected: CommitStatusFailure,
|
||||
},
|
||||
{
|
||||
name: "pending, success and error",
|
||||
@@ -133,7 +133,7 @@ func TestCombine(t *testing.T) {
|
||||
{
|
||||
name: "success, warning and skipped",
|
||||
states: CommitStatusStates{CommitStatusSuccess, CommitStatusWarning, CommitStatusSkipped},
|
||||
expected: CommitStatusSuccess,
|
||||
expected: CommitStatusFailure,
|
||||
},
|
||||
// All success
|
||||
{
|
||||
@@ -181,12 +181,12 @@ func TestCombine(t *testing.T) {
|
||||
{
|
||||
name: "mixed states with all success",
|
||||
states: CommitStatusStates{CommitStatusSuccess, CommitStatusSuccess, CommitStatusPending, CommitStatusWarning},
|
||||
expected: CommitStatusPending,
|
||||
expected: CommitStatusFailure,
|
||||
},
|
||||
{
|
||||
name: "all success with warning",
|
||||
states: CommitStatusStates{CommitStatusSuccess, CommitStatusSuccess, CommitStatusSuccess, CommitStatusWarning},
|
||||
expected: CommitStatusSuccess,
|
||||
expected: CommitStatusFailure,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -22,16 +22,16 @@ import (
|
||||
var catFileBatchDebugWaitClose atomic.Int64
|
||||
|
||||
type catFileBatchCommunicator struct {
|
||||
cancel context.CancelFunc
|
||||
closeFunc func(err error)
|
||||
reqWriter io.Writer
|
||||
respReader *bufio.Reader
|
||||
debugGitCmd *gitcmd.Command
|
||||
}
|
||||
|
||||
func (b *catFileBatchCommunicator) Close() {
|
||||
if b.cancel != nil {
|
||||
b.cancel()
|
||||
b.cancel = nil
|
||||
if b.closeFunc != nil {
|
||||
b.closeFunc(nil)
|
||||
b.closeFunc = nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,10 +47,19 @@ func newCatFileBatch(ctx context.Context, repoPath string, cmdCatFile *gitcmd.Co
|
||||
}
|
||||
stdPipeClose()
|
||||
}
|
||||
closeFunc := func(err error) {
|
||||
ctxCancel(err)
|
||||
pipeClose()
|
||||
}
|
||||
return newCatFileBatchWithCloseFunc(ctx, repoPath, cmdCatFile, stdinWriter, stdoutReader, closeFunc)
|
||||
}
|
||||
|
||||
ret = &catFileBatchCommunicator{
|
||||
func newCatFileBatchWithCloseFunc(ctx context.Context, repoPath string, cmdCatFile *gitcmd.Command,
|
||||
stdinWriter gitcmd.PipeWriter, stdoutReader gitcmd.PipeReader, closeFunc func(err error),
|
||||
) *catFileBatchCommunicator {
|
||||
ret := &catFileBatchCommunicator{
|
||||
debugGitCmd: cmdCatFile,
|
||||
cancel: func() { ctxCancel(nil) },
|
||||
closeFunc: closeFunc,
|
||||
reqWriter: stdinWriter,
|
||||
respReader: bufio.NewReaderSize(stdoutReader, 32*1024), // use a buffered reader for rich operations
|
||||
}
|
||||
@@ -60,8 +69,7 @@ func newCatFileBatch(ctx context.Context, repoPath string, cmdCatFile *gitcmd.Co
|
||||
log.Error("Unable to start git command %v: %v", cmdCatFile.LogString(), err)
|
||||
// ideally here it should return the error, but it would require refactoring all callers
|
||||
// so just return a dummy communicator that does nothing, almost the same behavior as before, not bad
|
||||
ctxCancel(err)
|
||||
pipeClose()
|
||||
closeFunc(err)
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -70,8 +78,7 @@ func newCatFileBatch(ctx context.Context, repoPath string, cmdCatFile *gitcmd.Co
|
||||
if err != nil && !errors.Is(err, context.Canceled) {
|
||||
log.Error("cat-file --batch command failed in repo %s, error: %v", repoPath, err)
|
||||
}
|
||||
ctxCancel(err)
|
||||
pipeClose()
|
||||
closeFunc(err)
|
||||
}()
|
||||
|
||||
return ret
|
||||
|
||||
@@ -12,7 +12,12 @@ import (
|
||||
|
||||
func newHTTPServer(network, address, name string, handler http.Handler) (*Server, ServeFunction) {
|
||||
server := NewServer(network, address, name)
|
||||
protocols := http.Protocols{}
|
||||
protocols.SetHTTP1(true)
|
||||
protocols.SetHTTP2(true) // HTTP/2 can only be used when Gitea is configured to use TLS
|
||||
protocols.SetUnencryptedHTTP2(true) // Allow HTTP/2 without TLS, in case Gitea is behind a reverse proxy
|
||||
httpServer := http.Server{
|
||||
Protocols: &protocols,
|
||||
Handler: handler,
|
||||
BaseContext: func(net.Listener) context.Context { return GetManager().HammerContext() },
|
||||
}
|
||||
|
||||
Vendored
+5
-6
@@ -9,6 +9,7 @@ import (
|
||||
"io"
|
||||
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/public"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
@@ -61,19 +62,17 @@ func (p *openAPIRenderer) Render(ctx *markup.RenderContext, input io.Reader, out
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="%s/assets/css/swagger.css?v=%s">
|
||||
<link rel="stylesheet" href="%s">
|
||||
</head>
|
||||
<body>
|
||||
<div id="swagger-ui"><textarea class="swagger-spec-content" data-spec-filename="%s">%s</textarea></div>
|
||||
<script src="%s/assets/js/swagger.js?v=%s"></script>
|
||||
<script type="module" src="%s"></script>
|
||||
</body>
|
||||
</html>`,
|
||||
setting.StaticURLPrefix,
|
||||
setting.AssetVersion,
|
||||
public.AssetURI("css/swagger.css"),
|
||||
html.EscapeString(ctx.RenderOptions.RelativePath),
|
||||
html.EscapeString(util.UnsafeBytesToString(content)),
|
||||
setting.StaticURLPrefix,
|
||||
setting.AssetVersion,
|
||||
public.AssetURI("js/swagger.js"),
|
||||
))
|
||||
return err
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/modules/htmlutil"
|
||||
"code.gitea.io/gitea/modules/markup/internal"
|
||||
"code.gitea.io/gitea/modules/public"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/typesniffer"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
@@ -237,10 +238,10 @@ func RenderWithRenderer(ctx *RenderContext, renderer Renderer, input io.Reader,
|
||||
return renderIFrame(ctx, extOpts.ContentSandbox, output)
|
||||
}
|
||||
// else: this is a standalone page, fallthrough to the real rendering, and add extra JS/CSS
|
||||
extraStyleHref := setting.AppSubURL + "/assets/css/external-render-iframe.css"
|
||||
extraScriptSrc := setting.AppSubURL + "/assets/js/external-render-iframe.js"
|
||||
extraStyleHref := public.AssetURI("css/external-render-iframe.css")
|
||||
extraScriptSrc := public.AssetURI("js/external-render-iframe.js")
|
||||
// "<script>" must go before "<link>", to make Golang's http.DetectContentType() can still recognize the content as "text/html"
|
||||
extraHeadHTML = htmlutil.HTMLFormat(`<script src="%s"></script><link rel="stylesheet" href="%s">`, extraScriptSrc, extraStyleHref)
|
||||
extraHeadHTML = htmlutil.HTMLFormat(`<script type="module" src="%s"></script><link rel="stylesheet" href="%s">`, extraScriptSrc, extraStyleHref)
|
||||
}
|
||||
|
||||
ctx.usedByRender = true
|
||||
|
||||
@@ -12,10 +12,17 @@ import (
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"github.com/santhosh-tekuri/jsonschema/v5"
|
||||
"github.com/santhosh-tekuri/jsonschema/v6"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// schemaLoader implements jsonschema.URLLoader
|
||||
type schemaLoader struct{}
|
||||
|
||||
func (l *schemaLoader) Load(url string) (any, error) {
|
||||
return openSchema(url)
|
||||
}
|
||||
|
||||
// Load project data from file, with optional validation
|
||||
func Load(filename string, data any, validation bool) error {
|
||||
isJSON := strings.HasSuffix(filename, ".json")
|
||||
@@ -43,7 +50,7 @@ func unmarshal(bs []byte, data any, isJSON bool) error {
|
||||
|
||||
func getSchema(filename string) (*jsonschema.Schema, error) {
|
||||
c := jsonschema.NewCompiler()
|
||||
c.LoadURL = openSchema
|
||||
c.UseLoader(&schemaLoader{})
|
||||
return c.Compile(filename)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/santhosh-tekuri/jsonschema/v5"
|
||||
"github.com/santhosh-tekuri/jsonschema/v6"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
package migration
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/fs"
|
||||
"path"
|
||||
"sync"
|
||||
@@ -16,6 +15,8 @@ import (
|
||||
_ "embed"
|
||||
|
||||
"code.gitea.io/gitea/modules/assetfs"
|
||||
|
||||
"github.com/santhosh-tekuri/jsonschema/v6"
|
||||
)
|
||||
|
||||
//go:embed bindata.dat
|
||||
@@ -25,6 +26,11 @@ var BuiltinAssets = sync.OnceValue(func() fs.FS {
|
||||
return assetfs.NewEmbeddedFS(bindata)
|
||||
})
|
||||
|
||||
func openSchema(filename string) (io.ReadCloser, error) {
|
||||
return BuiltinAssets().Open(path.Base(filename))
|
||||
func openSchema(filename string) (any, error) {
|
||||
f, err := BuiltinAssets().Open(path.Base(filename))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return jsonschema.UnmarshalJSON(f)
|
||||
}
|
||||
@@ -6,14 +6,15 @@
|
||||
package migration
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/santhosh-tekuri/jsonschema/v6"
|
||||
)
|
||||
|
||||
func openSchema(s string) (io.ReadCloser, error) {
|
||||
func openSchema(s string) (any, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -34,5 +35,10 @@ func openSchema(s string) (io.ReadCloser, error) {
|
||||
filename = filepath.Join("modules/migration/schemas", basename)
|
||||
}
|
||||
}
|
||||
return os.Open(filename)
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return jsonschema.UnmarshalJSON(f)
|
||||
}
|
||||
@@ -140,7 +140,7 @@ type nuspecPackage struct {
|
||||
func ParsePackageMetaData(r io.ReaderAt, size int64) (*Package, error) {
|
||||
archive, err := zip.NewReader(r, size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, util.NewInvalidArgumentErrorf("unable to parse package meta: %v", err)
|
||||
}
|
||||
|
||||
for _, file := range archive.File {
|
||||
|
||||
@@ -42,7 +42,7 @@ func (l PortablePdbList) Close() {
|
||||
func ExtractPortablePdb(r io.ReaderAt, size int64) (PortablePdbList, error) {
|
||||
archive, err := zip.NewReader(r, size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, util.NewInvalidArgumentErrorf("unable to extract portable pdb: %v", err)
|
||||
}
|
||||
|
||||
var pdbs PortablePdbList
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package public
|
||||
|
||||
import (
|
||||
"io"
|
||||
"path"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
type manifestEntry struct {
|
||||
File string `json:"file"`
|
||||
Name string `json:"name"`
|
||||
IsEntry bool `json:"isEntry"`
|
||||
CSS []string `json:"css"`
|
||||
}
|
||||
|
||||
type manifestDataStruct struct {
|
||||
paths map[string]string // unhashed path -> hashed path
|
||||
names map[string]string // hashed path -> entry name
|
||||
modTime int64
|
||||
checkTime time.Time
|
||||
}
|
||||
|
||||
var (
|
||||
manifestData atomic.Pointer[manifestDataStruct]
|
||||
manifestFS = sync.OnceValue(AssetFS)
|
||||
)
|
||||
|
||||
const manifestPath = "assets/.vite/manifest.json"
|
||||
|
||||
func parseManifest(data []byte) (map[string]string, map[string]string) {
|
||||
var manifest map[string]manifestEntry
|
||||
if err := json.Unmarshal(data, &manifest); err != nil {
|
||||
log.Error("Failed to parse frontend manifest: %v", err)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
paths := make(map[string]string)
|
||||
names := make(map[string]string)
|
||||
for _, entry := range manifest {
|
||||
if !entry.IsEntry || entry.Name == "" {
|
||||
continue
|
||||
}
|
||||
// Build unhashed key from file path: "js/index.js", "css/theme-gitea-dark.css"
|
||||
dir := path.Dir(entry.File)
|
||||
ext := path.Ext(entry.File)
|
||||
key := dir + "/" + entry.Name + ext
|
||||
paths[key] = entry.File
|
||||
names[entry.File] = entry.Name
|
||||
// Map associated CSS files, e.g. "css/index.css" -> "css/index.B3zrQPqD.css"
|
||||
for _, css := range entry.CSS {
|
||||
cssKey := path.Dir(css) + "/" + entry.Name + path.Ext(css)
|
||||
paths[cssKey] = css
|
||||
names[css] = entry.Name
|
||||
}
|
||||
}
|
||||
return paths, names
|
||||
}
|
||||
|
||||
func reloadManifest(existingData *manifestDataStruct) *manifestDataStruct {
|
||||
now := time.Now()
|
||||
data := existingData
|
||||
if data != nil && now.Sub(data.checkTime) < time.Second {
|
||||
// a single request triggers multiple calls to getHashedPath
|
||||
// do not check the manifest file too frequently
|
||||
return data
|
||||
}
|
||||
|
||||
f, err := manifestFS().Open(manifestPath)
|
||||
if err != nil {
|
||||
log.Error("Failed to open frontend manifest: %v", err)
|
||||
return data
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
log.Error("Failed to stat frontend manifest: %v", err)
|
||||
return data
|
||||
}
|
||||
|
||||
needReload := data == nil || fi.ModTime().UnixNano() != data.modTime
|
||||
if !needReload {
|
||||
return data
|
||||
}
|
||||
manifestContent, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
log.Error("Failed to read frontend manifest: %v", err)
|
||||
return data
|
||||
}
|
||||
return storeManifestFromBytes(manifestContent, fi.ModTime().UnixNano(), now)
|
||||
}
|
||||
|
||||
func storeManifestFromBytes(manifestContent []byte, modTime int64, checkTime time.Time) *manifestDataStruct {
|
||||
paths, names := parseManifest(manifestContent)
|
||||
data := &manifestDataStruct{
|
||||
paths: paths,
|
||||
names: names,
|
||||
modTime: modTime,
|
||||
checkTime: checkTime,
|
||||
}
|
||||
manifestData.Store(data)
|
||||
return data
|
||||
}
|
||||
|
||||
func getManifestData() *manifestDataStruct {
|
||||
data := manifestData.Load()
|
||||
|
||||
// In production the manifest is immutable (embedded in the binary).
|
||||
// In dev mode, check if it changed on disk (for watch-frontend).
|
||||
if data == nil || !setting.IsProd {
|
||||
data = reloadManifest(data)
|
||||
}
|
||||
if data == nil {
|
||||
data = &manifestDataStruct{}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// getHashedPath resolves an unhashed asset path (origin path) to its content-hashed path from the frontend manifest.
|
||||
// Example: getHashedPath("js/index.js") returns "js/index.C6Z2MRVQ.js"
|
||||
// Falls back to returning the input path unchanged if the manifest is unavailable.
|
||||
func getHashedPath(originPath string) string {
|
||||
data := getManifestData()
|
||||
if p, ok := data.paths[originPath]; ok {
|
||||
return p
|
||||
}
|
||||
return originPath
|
||||
}
|
||||
|
||||
// AssetURI returns the URI for a frontend asset.
|
||||
// It may return a relative path or a full URL depending on the StaticURLPrefix setting.
|
||||
// In Vite dev mode, known entry points are mapped to their source paths
|
||||
// so the reverse proxy serves them from the Vite dev server.
|
||||
// In production, it resolves the content-hashed path from the manifest.
|
||||
func AssetURI(originPath string) string {
|
||||
if src := viteDevSourceURL(originPath); src != "" {
|
||||
return src
|
||||
}
|
||||
return setting.StaticURLPrefix + "/assets/" + getHashedPath(originPath)
|
||||
}
|
||||
|
||||
// AssetNameFromHashedPath returns the asset entry name for a given hashed asset path.
|
||||
// Example: returns "theme-gitea-dark" for "css/theme-gitea-dark.CyAaQnn5.css".
|
||||
// Returns empty string if the path is not found in the manifest.
|
||||
func AssetNameFromHashedPath(hashedPath string) string {
|
||||
return getManifestData().names[hashedPath]
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package public
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestViteManifest(t *testing.T) {
|
||||
defer test.MockVariableValue(&setting.IsProd, true)()
|
||||
|
||||
const testManifest = `{
|
||||
"web_src/js/index.ts": {
|
||||
"file": "js/index.C6Z2MRVQ.js",
|
||||
"name": "index",
|
||||
"src": "web_src/js/index.ts",
|
||||
"isEntry": true,
|
||||
"css": ["css/index.B3zrQPqD.css"]
|
||||
},
|
||||
"web_src/js/standalone/swagger.ts": {
|
||||
"file": "js/swagger.SujiEmYM.js",
|
||||
"name": "swagger",
|
||||
"src": "web_src/js/standalone/swagger.ts",
|
||||
"isEntry": true,
|
||||
"css": ["css/swagger._-APWT_3.css"]
|
||||
},
|
||||
"web_src/css/themes/theme-gitea-dark.css": {
|
||||
"file": "css/theme-gitea-dark.CyAaQnn5.css",
|
||||
"name": "theme-gitea-dark",
|
||||
"src": "web_src/css/themes/theme-gitea-dark.css",
|
||||
"isEntry": true
|
||||
},
|
||||
"web_src/js/features/eventsource.sharedworker.ts": {
|
||||
"file": "js/eventsource.sharedworker.Dug1twio.js",
|
||||
"name": "eventsource.sharedworker",
|
||||
"src": "web_src/js/features/eventsource.sharedworker.ts",
|
||||
"isEntry": true
|
||||
},
|
||||
"_chunk.js": {
|
||||
"file": "js/chunk.abc123.js",
|
||||
"name": "chunk"
|
||||
}
|
||||
}`
|
||||
|
||||
t.Run("EmptyManifest", func(t *testing.T) {
|
||||
storeManifestFromBytes([]byte(``), 0, time.Now())
|
||||
assert.Equal(t, "/assets/js/index.js", AssetURI("js/index.js"))
|
||||
assert.Equal(t, "/assets/css/theme-gitea-dark.css", AssetURI("css/theme-gitea-dark.css"))
|
||||
assert.Equal(t, "", AssetNameFromHashedPath("css/no-such-file.css"))
|
||||
})
|
||||
|
||||
t.Run("ParseManifest", func(t *testing.T) {
|
||||
storeManifestFromBytes([]byte(testManifest), 0, time.Now())
|
||||
paths, names := manifestData.Load().paths, manifestData.Load().names
|
||||
|
||||
// JS entries
|
||||
assert.Equal(t, "js/index.C6Z2MRVQ.js", paths["js/index.js"])
|
||||
assert.Equal(t, "js/swagger.SujiEmYM.js", paths["js/swagger.js"])
|
||||
assert.Equal(t, "js/eventsource.sharedworker.Dug1twio.js", paths["js/eventsource.sharedworker.js"])
|
||||
|
||||
// Associated CSS from JS entries
|
||||
assert.Equal(t, "css/index.B3zrQPqD.css", paths["css/index.css"])
|
||||
assert.Equal(t, "css/swagger._-APWT_3.css", paths["css/swagger.css"])
|
||||
|
||||
// CSS-only entries
|
||||
assert.Equal(t, "css/theme-gitea-dark.CyAaQnn5.css", paths["css/theme-gitea-dark.css"])
|
||||
|
||||
// Non-entry chunks should not be included
|
||||
assert.Empty(t, paths["js/chunk.js"])
|
||||
|
||||
// Names: hashed path -> entry name
|
||||
assert.Equal(t, "index", names["js/index.C6Z2MRVQ.js"])
|
||||
assert.Equal(t, "index", names["css/index.B3zrQPqD.css"])
|
||||
assert.Equal(t, "swagger", names["js/swagger.SujiEmYM.js"])
|
||||
assert.Equal(t, "swagger", names["css/swagger._-APWT_3.css"])
|
||||
assert.Equal(t, "theme-gitea-dark", names["css/theme-gitea-dark.CyAaQnn5.css"])
|
||||
assert.Equal(t, "eventsource.sharedworker", names["js/eventsource.sharedworker.Dug1twio.js"])
|
||||
|
||||
// Test Asset related functions
|
||||
assert.Equal(t, "/assets/js/index.C6Z2MRVQ.js", AssetURI("js/index.js"))
|
||||
assert.Equal(t, "/assets/css/theme-gitea-dark.CyAaQnn5.css", AssetURI("css/theme-gitea-dark.css"))
|
||||
assert.Equal(t, "theme-gitea-dark", AssetNameFromHashedPath("css/theme-gitea-dark.CyAaQnn5.css"))
|
||||
})
|
||||
}
|
||||
@@ -4,31 +4,36 @@
|
||||
package public
|
||||
|
||||
import (
|
||||
"mime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// wellKnownMimeTypesLower comes from Golang's builtin mime package: `builtinTypesLower`, see the comment of DetectWellKnownMimeType
|
||||
var wellKnownMimeTypesLower = map[string]string{
|
||||
".avif": "image/avif",
|
||||
".css": "text/css; charset=utf-8",
|
||||
".gif": "image/gif",
|
||||
".htm": "text/html; charset=utf-8",
|
||||
".html": "text/html; charset=utf-8",
|
||||
".jpeg": "image/jpeg",
|
||||
".jpg": "image/jpeg",
|
||||
".js": "text/javascript; charset=utf-8",
|
||||
".json": "application/json",
|
||||
".mjs": "text/javascript; charset=utf-8",
|
||||
".pdf": "application/pdf",
|
||||
".png": "image/png",
|
||||
".svg": "image/svg+xml",
|
||||
".wasm": "application/wasm",
|
||||
".webp": "image/webp",
|
||||
".xml": "text/xml; charset=utf-8",
|
||||
// wellKnownMimeTypesLower comes from Golang's builtin mime package: `builtinTypesLower`,
|
||||
// see the comment of DetectWellKnownMimeType
|
||||
var wellKnownMimeTypesLower = sync.OnceValue(func() map[string]string {
|
||||
return map[string]string{
|
||||
".avif": "image/avif",
|
||||
".css": "text/css; charset=utf-8",
|
||||
".gif": "image/gif",
|
||||
".htm": "text/html; charset=utf-8",
|
||||
".html": "text/html; charset=utf-8",
|
||||
".jpeg": "image/jpeg",
|
||||
".jpg": "image/jpeg",
|
||||
".js": "text/javascript; charset=utf-8",
|
||||
".json": "application/json",
|
||||
".mjs": "text/javascript; charset=utf-8",
|
||||
".pdf": "application/pdf",
|
||||
".png": "image/png",
|
||||
".svg": "image/svg+xml",
|
||||
".wasm": "application/wasm",
|
||||
".webp": "image/webp",
|
||||
".xml": "text/xml; charset=utf-8",
|
||||
|
||||
// well, there are some types missing from the builtin list
|
||||
".txt": "text/plain; charset=utf-8",
|
||||
}
|
||||
// well, there are some types missing from the builtin list
|
||||
".txt": "text/plain; charset=utf-8",
|
||||
}
|
||||
})
|
||||
|
||||
// DetectWellKnownMimeType will return the mime-type for a well-known file ext name
|
||||
// The purpose of this function is to bypass the unstable behavior of Golang's mime.TypeByExtension
|
||||
@@ -38,5 +43,8 @@ var wellKnownMimeTypesLower = map[string]string{
|
||||
// DetectWellKnownMimeType makes the Content-Type for well-known files stable.
|
||||
func DetectWellKnownMimeType(ext string) string {
|
||||
ext = strings.ToLower(ext)
|
||||
return wellKnownMimeTypesLower[ext]
|
||||
if s, ok := wellKnownMimeTypesLower()[ext]; ok {
|
||||
return s
|
||||
}
|
||||
return mime.TypeByExtension(ext)
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package public
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/httplib"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/web/routing"
|
||||
)
|
||||
|
||||
const viteDevPortFile = "public/assets/.vite/dev-port"
|
||||
|
||||
var viteDevProxy atomic.Pointer[httputil.ReverseProxy]
|
||||
|
||||
func getViteDevServerBaseURL() string {
|
||||
portFile := filepath.Join(setting.StaticRootPath, viteDevPortFile)
|
||||
portContent, _ := os.ReadFile(portFile)
|
||||
port := strings.TrimSpace(string(portContent))
|
||||
if port == "" {
|
||||
return ""
|
||||
}
|
||||
return "http://localhost:" + port
|
||||
}
|
||||
|
||||
func getViteDevProxy() *httputil.ReverseProxy {
|
||||
if proxy := viteDevProxy.Load(); proxy != nil {
|
||||
return proxy
|
||||
}
|
||||
|
||||
viteDevServerBaseURL := getViteDevServerBaseURL()
|
||||
if viteDevServerBaseURL == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
target, err := url.Parse(viteDevServerBaseURL)
|
||||
if err != nil {
|
||||
log.Error("Failed to parse Vite dev server base URL %s, err: %v", viteDevServerBaseURL, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// there is a strange error log (from Golang's HTTP package)
|
||||
// 2026/03/28 19:50:13 modules/log/misc.go:72:(*loggerToWriter).Write() [I] Unsolicited response received on idle HTTP channel starting with "HTTP/1.1 400 Bad Request\r\n\r\n"; err=<nil>
|
||||
// maybe it is caused by that the Vite dev server doesn't support keep-alive connections? or different keep-alive timeouts?
|
||||
transport := &http.Transport{
|
||||
IdleConnTimeout: 5 * time.Second,
|
||||
ResponseHeaderTimeout: 5 * time.Second,
|
||||
}
|
||||
log.Info("Proxying Vite dev server requests to %s", target)
|
||||
proxy := &httputil.ReverseProxy{
|
||||
Transport: transport,
|
||||
Rewrite: func(r *httputil.ProxyRequest) {
|
||||
r.SetURL(target)
|
||||
r.Out.Host = target.Host
|
||||
},
|
||||
ModifyResponse: func(resp *http.Response) error {
|
||||
// add a header to indicate the Vite dev server port,
|
||||
// make developers know that this request is proxied to Vite dev server and which port it is
|
||||
resp.Header.Add("X-Gitea-Vite-Dev-Server", viteDevServerBaseURL)
|
||||
return nil
|
||||
},
|
||||
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
|
||||
log.Error("Error proxying to Vite dev server: %v", err)
|
||||
http.Error(w, "Error proxying to Vite dev server: "+err.Error(), http.StatusBadGateway)
|
||||
},
|
||||
}
|
||||
viteDevProxy.Store(proxy)
|
||||
return proxy
|
||||
}
|
||||
|
||||
// ViteDevMiddleware proxies matching requests to the Vite dev server.
|
||||
// It is registered as middleware in non-production mode and lazily discovers
|
||||
// the Vite dev server port from the port file written by the viteDevServerPortPlugin.
|
||||
// It is needed because there are container-based development, only Gitea web server's port is exposed.
|
||||
func ViteDevMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
||||
if !isViteDevRequest(req) {
|
||||
next.ServeHTTP(resp, req)
|
||||
return
|
||||
}
|
||||
proxy := getViteDevProxy()
|
||||
if proxy == nil {
|
||||
next.ServeHTTP(resp, req)
|
||||
return
|
||||
}
|
||||
routing.MarkLongPolling(resp, req)
|
||||
proxy.ServeHTTP(resp, req)
|
||||
})
|
||||
}
|
||||
|
||||
var viteDevModeCheck atomic.Pointer[struct {
|
||||
isDev bool
|
||||
time time.Time
|
||||
}]
|
||||
|
||||
// IsViteDevMode returns true if the Vite dev server port file exists and the server is alive
|
||||
func IsViteDevMode() bool {
|
||||
if setting.IsProd {
|
||||
return false
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
lastCheck := viteDevModeCheck.Load()
|
||||
if lastCheck != nil && time.Now().Sub(lastCheck.time) < time.Second {
|
||||
return lastCheck.isDev
|
||||
}
|
||||
|
||||
viteDevServerBaseURL := getViteDevServerBaseURL()
|
||||
if viteDevServerBaseURL == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
req := httplib.NewRequest(viteDevServerBaseURL+"/web_src/js/__vite_dev_server_check", "GET")
|
||||
resp, _ := req.Response()
|
||||
if resp != nil {
|
||||
_ = resp.Body.Close()
|
||||
}
|
||||
isDev := resp != nil && resp.StatusCode == http.StatusOK
|
||||
viteDevModeCheck.Store(&struct {
|
||||
isDev bool
|
||||
time time.Time
|
||||
}{
|
||||
isDev: isDev,
|
||||
time: now,
|
||||
})
|
||||
return isDev
|
||||
}
|
||||
|
||||
func viteDevSourceURL(name string) string {
|
||||
if !IsViteDevMode() {
|
||||
return ""
|
||||
}
|
||||
if strings.HasPrefix(name, "css/theme-") {
|
||||
// Only redirect built-in themes to Vite source; custom themes are served from custom/public/assets/css/
|
||||
themeFile := strings.TrimPrefix(name, "css/")
|
||||
srcPath := filepath.Join(setting.StaticRootPath, "web_src/css/themes", themeFile)
|
||||
if _, err := os.Stat(srcPath); err == nil {
|
||||
return setting.AppSubURL + "/web_src/css/themes/" + themeFile
|
||||
}
|
||||
return ""
|
||||
}
|
||||
if strings.HasPrefix(name, "css/") {
|
||||
return setting.AppSubURL + "/web_src/" + name
|
||||
}
|
||||
if name == "js/eventsource.sharedworker.js" {
|
||||
return setting.AppSubURL + "/web_src/js/features/eventsource.sharedworker.ts"
|
||||
}
|
||||
if name == "js/iife.js" {
|
||||
return setting.AppSubURL + "/web_src/js/__vite_iife.js"
|
||||
}
|
||||
if name == "js/index.js" {
|
||||
return setting.AppSubURL + "/web_src/js/index.ts"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// isViteDevRequest returns true if the request should be proxied to the Vite dev server.
|
||||
// Ref: Vite source packages/vite/src/node/constants.ts and packages/vite/src/shared/constants.ts
|
||||
func isViteDevRequest(req *http.Request) bool {
|
||||
if req.Header.Get("Upgrade") == "websocket" {
|
||||
wsProtocol := req.Header.Get("Sec-WebSocket-Protocol")
|
||||
return wsProtocol == "vite-hmr" || wsProtocol == "vite-ping"
|
||||
}
|
||||
path := req.URL.Path
|
||||
|
||||
// vite internal requests
|
||||
if strings.HasPrefix(path, "/@vite/") /* HMR client */ ||
|
||||
strings.HasPrefix(path, "/@fs/") /* out-of-root file access, see vite.config.ts: fs.allow */ ||
|
||||
strings.HasPrefix(path, "/@id/") /* virtual modules */ {
|
||||
return true
|
||||
}
|
||||
|
||||
// local source requests (VITE-DEV-SERVER-SECURITY: don't serve sensitive files outside the allowed paths)
|
||||
if strings.HasPrefix(path, "/node_modules/") ||
|
||||
strings.HasPrefix(path, "/public/assets/") ||
|
||||
strings.HasPrefix(path, "/web_src/") {
|
||||
return true
|
||||
}
|
||||
|
||||
// Vite uses a path relative to project root and adds "?import" to non-JS/CSS asset imports:
|
||||
// - {WebSite}/public/assets/... (e.g. SVG icons from "{RepoRoot}/public/assets/img/svg/")
|
||||
// - {WebSite}/assets/emoji.json: it is an exception for the frontend assets, it is imported by JS code, but:
|
||||
// - KEEP IN MIND: all static frontend assets are served from "{AssetFS}/assets" to "{WebSite}/assets" by Gitea Web Server
|
||||
// - "{AssetFS}" is a layered filesystem from "{RepoRoot}/public" or embedded assets, and user's custom files in "{CustomPath}/public"
|
||||
// - "{RepoRoot}/assets/emoji.json" just happens to have the dir name "assets", it is not related to frontend assets
|
||||
// - BAD DESIGN: indeed it is a "conflicted and polluted name" sample
|
||||
if path == "/assets/emoji.json" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -72,9 +72,6 @@ var (
|
||||
// It maps to ini:"LOCAL_ROOT_URL" in [server]
|
||||
LocalURL string
|
||||
|
||||
// AssetVersion holds an opaque value that is used for cache-busting assets
|
||||
AssetVersion string
|
||||
|
||||
// appTempPathInternal is the temporary path for the app, it is only an internal variable
|
||||
// DO NOT use it directly, always use AppDataTempDir
|
||||
appTempPathInternal string
|
||||
@@ -317,8 +314,6 @@ func loadServerFrom(rootCfg ConfigProvider) {
|
||||
}
|
||||
|
||||
AbsoluteAssetURL = MakeAbsoluteAssetURL(appURL, StaticURLPrefix)
|
||||
AssetVersion = strings.ReplaceAll(AppVer, "+", "~") // make sure the version string is clear (no real escaping is needed)
|
||||
|
||||
manifestBytes := MakeManifestData(AppName, AppURL, AbsoluteAssetURL)
|
||||
ManifestData = `application/json;base64,` + base64.StdEncoding.EncodeToString(manifestBytes)
|
||||
|
||||
|
||||
@@ -28,8 +28,10 @@ var (
|
||||
CfgProvider ConfigProvider
|
||||
IsWindows bool
|
||||
|
||||
// IsInTesting indicates whether the testing is running. A lot of unreliable code causes a lot of nonsense error logs during testing
|
||||
// TODO: this is only a temporary solution, we should make the test code more reliable
|
||||
// IsInTesting indicates whether the testing is running (unit test or integration test). It can be used for:
|
||||
// * Skip nonsense error logs during testing caused by unreliable code (TODO: this is only a temporary solution, we should make the test code more reliable)
|
||||
// * Panic in dev or testing mode to make the problem more obvious and easier to debug
|
||||
// * Mock some functions or options to make testing easier (eg: session store, time, URL detection, etc.)
|
||||
IsInTesting = false
|
||||
)
|
||||
|
||||
@@ -57,6 +59,10 @@ func IsRunUserMatchCurrentUser(runUser string) (string, bool) {
|
||||
return currentUser, runUser == currentUser
|
||||
}
|
||||
|
||||
func IsInE2eTesting() bool {
|
||||
return os.Getenv("GITEA_TEST_E2E") == "true"
|
||||
}
|
||||
|
||||
// PrepareAppDataPath creates app data directory if necessary
|
||||
func PrepareAppDataPath() error {
|
||||
// FIXME: There are too many calls to MkdirAll in old code. It is incorrect.
|
||||
|
||||
@@ -12,7 +12,7 @@ type Activity struct {
|
||||
UserID int64 `json:"user_id"` // Receiver user
|
||||
// the type of action
|
||||
//
|
||||
// enum: create_repo,rename_repo,star_repo,watch_repo,commit_repo,create_issue,create_pull_request,transfer_repo,push_tag,comment_issue,merge_pull_request,close_issue,reopen_issue,close_pull_request,reopen_pull_request,delete_tag,delete_branch,mirror_sync_push,mirror_sync_create,mirror_sync_delete,approve_pull_request,reject_pull_request,comment_pull,publish_release,pull_review_dismissed,pull_request_ready_for_review,auto_merge_pull_request
|
||||
// enum: ["create_repo","rename_repo","star_repo","watch_repo","commit_repo","create_issue","create_pull_request","transfer_repo","push_tag","comment_issue","merge_pull_request","close_issue","reopen_issue","close_pull_request","reopen_pull_request","delete_tag","delete_branch","mirror_sync_push","mirror_sync_create","mirror_sync_delete","approve_pull_request","reject_pull_request","comment_pull","publish_release","pull_review_dismissed","pull_request_ready_for_review","auto_merge_pull_request"]
|
||||
OpType string `json:"op_type"`
|
||||
// The ID of the user who performed the action
|
||||
ActUserID int64 `json:"act_user_id"`
|
||||
|
||||
@@ -19,6 +19,8 @@ var ErrInvalidReceiveHook = errors.New("Invalid JSON payload received over webho
|
||||
type Hook struct {
|
||||
// The unique identifier of the webhook
|
||||
ID int64 `json:"id"`
|
||||
// Optional human-readable name for the webhook
|
||||
Name string `json:"name"`
|
||||
// The type of the webhook (e.g., gitea, slack, discord)
|
||||
Type string `json:"type"`
|
||||
// Branch filter pattern to determine which branches trigger the webhook
|
||||
@@ -51,7 +53,7 @@ type CreateHookOptionConfig map[string]string
|
||||
// CreateHookOption options when create a hook
|
||||
type CreateHookOption struct {
|
||||
// required: true
|
||||
// enum: dingtalk,discord,gitea,gogs,msteams,slack,telegram,feishu,wechatwork,packagist
|
||||
// enum: ["dingtalk","discord","gitea","gogs","msteams","slack","telegram","feishu","wechatwork","packagist"]
|
||||
// The type of the webhook to create
|
||||
Type string `json:"type" binding:"Required"`
|
||||
// required: true
|
||||
@@ -66,6 +68,8 @@ type CreateHookOption struct {
|
||||
// default: false
|
||||
// Whether the webhook should be active upon creation
|
||||
Active bool `json:"active"`
|
||||
// Optional human-readable name for the webhook
|
||||
Name string `json:"name" binding:"MaxSize(255)"`
|
||||
}
|
||||
|
||||
// EditHookOption options when modify one hook
|
||||
@@ -80,6 +84,8 @@ type EditHookOption struct {
|
||||
AuthorizationHeader string `json:"authorization_header"`
|
||||
// Whether the webhook is active and will be triggered
|
||||
Active *bool `json:"active"`
|
||||
// Optional human-readable name
|
||||
Name *string `json:"name,omitzero" binding:"MaxSize(255)"`
|
||||
}
|
||||
|
||||
// Payloader payload is some part of one hook
|
||||
|
||||
+18
-12
@@ -14,6 +14,8 @@ import (
|
||||
)
|
||||
|
||||
// StateType issue state type
|
||||
//
|
||||
// swagger:enum StateType
|
||||
type StateType string
|
||||
|
||||
const (
|
||||
@@ -21,10 +23,11 @@ const (
|
||||
StateOpen StateType = "open"
|
||||
// StateClosed pr is closed
|
||||
StateClosed StateType = "closed"
|
||||
// StateAll is all
|
||||
StateAll StateType = "all"
|
||||
)
|
||||
|
||||
// StateAll is a query parameter filter value, not a valid object state.
|
||||
const StateAll = "all"
|
||||
|
||||
// PullRequestMeta PR info if an issue is a PR
|
||||
type PullRequestMeta struct {
|
||||
HasMerged bool `json:"merged"`
|
||||
@@ -58,15 +61,11 @@ type Issue struct {
|
||||
Labels []*Label `json:"labels"`
|
||||
Milestone *Milestone `json:"milestone"`
|
||||
// deprecated
|
||||
Assignee *User `json:"assignee"`
|
||||
Assignees []*User `json:"assignees"`
|
||||
// Whether the issue is open or closed
|
||||
//
|
||||
// type: string
|
||||
// enum: open,closed
|
||||
State StateType `json:"state"`
|
||||
IsLocked bool `json:"is_locked"`
|
||||
Comments int `json:"comments"`
|
||||
Assignee *User `json:"assignee"`
|
||||
Assignees []*User `json:"assignees"`
|
||||
State StateType `json:"state"`
|
||||
IsLocked bool `json:"is_locked"`
|
||||
Comments int `json:"comments"`
|
||||
// swagger:strfmt date-time
|
||||
Created time.Time `json:"created_at"`
|
||||
// swagger:strfmt date-time
|
||||
@@ -82,6 +81,8 @@ type Issue struct {
|
||||
Repo *RepositoryMeta `json:"repository"`
|
||||
|
||||
PinOrder int `json:"pin_order"`
|
||||
// The version of the issue content for optimistic locking
|
||||
ContentVersion int `json:"content_version"`
|
||||
}
|
||||
|
||||
// CreateIssueOption options to create one issue
|
||||
@@ -115,6 +116,8 @@ type EditIssueOption struct {
|
||||
// swagger:strfmt date-time
|
||||
Deadline *time.Time `json:"due_date"`
|
||||
RemoveDeadline *bool `json:"unset_due_date"`
|
||||
// The current version of the issue content to detect conflicts during editing
|
||||
ContentVersion *int `json:"content_version"`
|
||||
}
|
||||
|
||||
// EditDeadlineOption options for creating a deadline
|
||||
@@ -132,6 +135,8 @@ type IssueDeadline struct {
|
||||
}
|
||||
|
||||
// IssueFormFieldType defines issue form field type, can be "markdown", "textarea", "input", "dropdown" or "checkboxes"
|
||||
//
|
||||
// swagger:enum IssueFormFieldType
|
||||
type IssueFormFieldType string
|
||||
|
||||
const (
|
||||
@@ -168,7 +173,8 @@ func (iff IssueFormField) VisibleInContent() bool {
|
||||
}
|
||||
|
||||
// IssueFormFieldVisible defines issue form field visible
|
||||
// swagger:model
|
||||
//
|
||||
// swagger:enum IssueFormFieldVisible
|
||||
type IssueFormFieldVisible string
|
||||
|
||||
const (
|
||||
|
||||
@@ -40,7 +40,7 @@ type CreateMilestoneOption struct {
|
||||
// swagger:strfmt date-time
|
||||
// Deadline is the due date for the milestone
|
||||
Deadline *time.Time `json:"due_on"`
|
||||
// enum: open,closed
|
||||
// enum: ["open","closed"]
|
||||
// State indicates the initial state of the milestone
|
||||
State string `json:"state"`
|
||||
}
|
||||
@@ -52,6 +52,7 @@ type EditMilestoneOption struct {
|
||||
// Description provides updated details about the milestone
|
||||
Description *string `json:"description"`
|
||||
// State indicates the updated state of the milestone
|
||||
// enum: ["open","closed"]
|
||||
State *string `json:"state"`
|
||||
// Deadline is the updated due date for the milestone
|
||||
Deadline *time.Time `json:"due_on"`
|
||||
|
||||
@@ -40,7 +40,7 @@ type NotificationSubject struct {
|
||||
// Type indicates the type of the notification subject
|
||||
Type NotifySubjectType `json:"type" binding:"In(Issue,Pull,Commit,Repository)"`
|
||||
// State indicates the current state of the notification subject
|
||||
State StateType `json:"state"`
|
||||
State NotifySubjectStateType `json:"state"`
|
||||
}
|
||||
|
||||
// NotificationCount number of unread notifications
|
||||
@@ -49,7 +49,22 @@ type NotificationCount struct {
|
||||
New int64 `json:"new"`
|
||||
}
|
||||
|
||||
// NotifySubjectStateType represents the state of a notification subject
|
||||
// swagger:enum NotifySubjectStateType
|
||||
type NotifySubjectStateType string
|
||||
|
||||
const (
|
||||
// NotifySubjectStateOpen is an open subject
|
||||
NotifySubjectStateOpen NotifySubjectStateType = "open"
|
||||
// NotifySubjectStateClosed is a closed subject
|
||||
NotifySubjectStateClosed NotifySubjectStateType = "closed"
|
||||
// NotifySubjectStateMerged is a merged pull request
|
||||
NotifySubjectStateMerged NotifySubjectStateType = "merged"
|
||||
)
|
||||
|
||||
// NotifySubjectType represent type of notification subject
|
||||
//
|
||||
// swagger:enum NotifySubjectType
|
||||
type NotifySubjectType string
|
||||
|
||||
const (
|
||||
|
||||
@@ -60,7 +60,7 @@ type CreateOrgOption struct {
|
||||
// The location of the organization
|
||||
Location string `json:"location" binding:"MaxSize(50)"`
|
||||
// possible values are `public` (default), `limited` or `private`
|
||||
// enum: public,limited,private
|
||||
// enum: ["public","limited","private"]
|
||||
Visibility string `json:"visibility" binding:"In(,public,limited,private)"`
|
||||
// Whether repository administrators can change team access
|
||||
RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"`
|
||||
@@ -79,7 +79,7 @@ type EditOrgOption struct {
|
||||
// The location of the organization
|
||||
Location *string `json:"location" binding:"MaxSize(50)"`
|
||||
// possible values are `public`, `limited` or `private`
|
||||
// enum: public,limited,private
|
||||
// enum: ["public","limited","private"]
|
||||
Visibility *string `json:"visibility" binding:"In(,public,limited,private)"`
|
||||
// Whether repository administrators can change team access
|
||||
RepoAdminChangeTeamAccess *bool `json:"repo_admin_change_team_access"`
|
||||
|
||||
@@ -16,7 +16,7 @@ type Team struct {
|
||||
Organization *Organization `json:"organization"`
|
||||
// Whether the team has access to all repositories in the organization
|
||||
IncludesAllRepositories bool `json:"includes_all_repositories"`
|
||||
// enum: none,read,write,admin,owner
|
||||
// enum: ["none","read","write","admin","owner"]
|
||||
Permission string `json:"permission"`
|
||||
// example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"]
|
||||
// Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions.
|
||||
@@ -35,7 +35,7 @@ type CreateTeamOption struct {
|
||||
Description string `json:"description" binding:"MaxSize(255)"`
|
||||
// Whether the team has access to all repositories in the organization
|
||||
IncludesAllRepositories bool `json:"includes_all_repositories"`
|
||||
// enum: read,write,admin
|
||||
// enum: ["read","write","admin"]
|
||||
Permission string `json:"permission"`
|
||||
// example: ["repo.actions","repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.ext_wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"]
|
||||
// Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions.
|
||||
@@ -54,7 +54,7 @@ type EditTeamOption struct {
|
||||
Description *string `json:"description" binding:"MaxSize(255)"`
|
||||
// Whether the team has access to all repositories in the organization
|
||||
IncludesAllRepositories *bool `json:"includes_all_repositories"`
|
||||
// enum: read,write,admin
|
||||
// enum: ["read","write","admin"]
|
||||
Permission string `json:"permission"`
|
||||
// example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"]
|
||||
// Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions.
|
||||
|
||||
@@ -91,6 +91,8 @@ type PullRequest struct {
|
||||
|
||||
// The pin order for the pull request
|
||||
PinOrder int `json:"pin_order"`
|
||||
// The version of the pull request content for optimistic locking
|
||||
ContentVersion int `json:"content_version"`
|
||||
}
|
||||
|
||||
// PRBranchInfo information about a branch
|
||||
@@ -168,6 +170,8 @@ type EditPullRequestOption struct {
|
||||
RemoveDeadline *bool `json:"unset_due_date"`
|
||||
// Whether to allow maintainer edits
|
||||
AllowMaintainerEdit *bool `json:"allow_maintainer_edit"`
|
||||
// The current version of the pull request content to detect conflicts during editing
|
||||
ContentVersion *int `json:"content_version"`
|
||||
}
|
||||
|
||||
// ChangedFile store information about files affected by the pull request
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
)
|
||||
|
||||
// ReviewStateType review state type
|
||||
//
|
||||
// swagger:enum ReviewStateType
|
||||
type ReviewStateType string
|
||||
|
||||
const (
|
||||
@@ -21,10 +23,11 @@ const (
|
||||
ReviewStateRequestChanges ReviewStateType = "REQUEST_CHANGES"
|
||||
// ReviewStateRequestReview review is requested from user
|
||||
ReviewStateRequestReview ReviewStateType = "REQUEST_REVIEW"
|
||||
// ReviewStateUnknown state of pr is unknown
|
||||
ReviewStateUnknown ReviewStateType = ""
|
||||
)
|
||||
|
||||
// ReviewStateUnknown is an internal sentinel for unknown review state, not a valid API value.
|
||||
const ReviewStateUnknown = ""
|
||||
|
||||
// PullReview represents a pull request review
|
||||
type PullReview struct {
|
||||
ID int64 `json:"id"`
|
||||
|
||||
@@ -114,7 +114,7 @@ type Repository struct {
|
||||
Internal bool `json:"internal"`
|
||||
MirrorInterval string `json:"mirror_interval"`
|
||||
// ObjectFormatName of the underlying git repository
|
||||
// enum: sha1,sha256
|
||||
// enum: ["sha1","sha256"]
|
||||
ObjectFormatName string `json:"object_format_name"`
|
||||
// swagger:strfmt date-time
|
||||
MirrorUpdated time.Time `json:"mirror_updated"`
|
||||
@@ -150,10 +150,10 @@ type CreateRepoOption struct {
|
||||
// DefaultBranch of the repository (used when initializes and in template)
|
||||
DefaultBranch string `json:"default_branch" binding:"GitRefName;MaxSize(100)"`
|
||||
// TrustModel of the repository
|
||||
// enum: default,collaborator,committer,collaboratorcommitter
|
||||
// enum: ["default","collaborator","committer","collaboratorcommitter"]
|
||||
TrustModel string `json:"trust_model"`
|
||||
// ObjectFormatName of the underlying git repository, empty string for default (sha1)
|
||||
// enum: sha1,sha256
|
||||
// enum: ["sha1","sha256"]
|
||||
ObjectFormatName string `json:"object_format_name" binding:"MaxSize(6)"`
|
||||
}
|
||||
|
||||
@@ -378,7 +378,7 @@ type MigrateRepoOptions struct {
|
||||
// required: true
|
||||
RepoName string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
|
||||
|
||||
// enum: git,github,gitea,gitlab,gogs,onedev,gitbucket,codebase,codecommit
|
||||
// enum: ["git","github","gitea","gitlab","gogs","onedev","gitbucket","codebase","codecommit"]
|
||||
Service string `json:"service"`
|
||||
AuthUsername string `json:"auth_username"`
|
||||
AuthPassword string `json:"auth_password"`
|
||||
|
||||
@@ -5,7 +5,7 @@ package structs
|
||||
|
||||
// AddCollaboratorOption options when adding a user as a collaborator of a repository
|
||||
type AddCollaboratorOption struct {
|
||||
// enum: read,write,admin
|
||||
// enum: ["read","write","admin"]
|
||||
// Permission level to grant the collaborator
|
||||
Permission *string `json:"permission"`
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ type ChangeFileOperation struct {
|
||||
// indicates what to do with the file: "create" for creating a new file, "update" for updating an existing file,
|
||||
// "upload" for creating or updating a file, "rename" for renaming a file, and "delete" for deleting an existing file.
|
||||
// required: true
|
||||
// enum: create,update,upload,rename,delete
|
||||
// enum: ["create","update","upload","rename","delete"]
|
||||
Operation string `json:"operation" binding:"Required"`
|
||||
// path to the existing or new file
|
||||
// required: true
|
||||
|
||||
@@ -6,15 +6,18 @@ package templates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/htmlutil"
|
||||
"code.gitea.io/gitea/modules/markup"
|
||||
"code.gitea.io/gitea/modules/public"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/svg"
|
||||
"code.gitea.io/gitea/modules/templates/eval"
|
||||
@@ -68,6 +71,8 @@ func NewFuncMap() template.FuncMap {
|
||||
return strconv.FormatInt(time.Since(startTime).Nanoseconds()/1e6, 10) + "ms"
|
||||
},
|
||||
|
||||
"AssetURI": public.AssetURI,
|
||||
"ScriptImport": scriptImport,
|
||||
// -----------------------------------------------------------------
|
||||
// setting
|
||||
"AppName": func() string {
|
||||
@@ -92,9 +97,6 @@ func NewFuncMap() template.FuncMap {
|
||||
"AppDomain": func() string { // documented in mail-templates.md
|
||||
return setting.Domain
|
||||
},
|
||||
"AssetVersion": func() string {
|
||||
return setting.AssetVersion
|
||||
},
|
||||
"ShowFooterTemplateLoadTime": func() bool {
|
||||
return setting.Other.ShowFooterTemplateLoadTime
|
||||
},
|
||||
@@ -303,3 +305,30 @@ func QueryBuild(a ...any) template.URL {
|
||||
}
|
||||
return template.URL(s)
|
||||
}
|
||||
|
||||
var globalVars = sync.OnceValue(func() (ret struct {
|
||||
scriptImportRemainingPart string
|
||||
},
|
||||
) {
|
||||
// add onerror handler to alert users when the script fails to load:
|
||||
// * for end users: there were many users reporting that "UI doesn't work", actually they made mistakes in their config
|
||||
// * for developers: help them to remember to run "make watch-frontend" to build frontend assets
|
||||
// the message will be directly put in the onerror JS code's string
|
||||
onScriptErrorPrompt := `Please make sure the asset files can be accessed.`
|
||||
if !setting.IsProd {
|
||||
onScriptErrorPrompt += `\n\nFor development, run: make watch-frontend.`
|
||||
}
|
||||
onScriptErrorJS := fmt.Sprintf(`alert('Failed to load asset file from ' + this.src + '. %s')`, onScriptErrorPrompt)
|
||||
ret.scriptImportRemainingPart = `onerror="` + html.EscapeString(onScriptErrorJS) + `"></script>`
|
||||
return ret
|
||||
})
|
||||
|
||||
func scriptImport(path string, typ ...string) template.HTML {
|
||||
if len(typ) > 0 {
|
||||
if typ[0] == "module" {
|
||||
return template.HTML(`<script type="module" src="` + html.EscapeString(public.AssetURI(path)) + `" ` + globalVars().scriptImportRemainingPart)
|
||||
}
|
||||
panic("unsupported script type: " + typ[0])
|
||||
}
|
||||
return template.HTML(`<script src="` + html.EscapeString(public.AssetURI(path)) + `" ` + globalVars().scriptImportRemainingPart)
|
||||
}
|
||||
@@ -53,11 +53,11 @@ func (lc *LogChecker) checkLogEvent(event *log.EventFormatted) {
|
||||
}
|
||||
}
|
||||
|
||||
var checkerIndex int64
|
||||
var checkerIndex atomic.Int64
|
||||
|
||||
func NewLogChecker(namePrefix string) (logChecker *LogChecker, cancel func()) {
|
||||
logger := log.GetManager().GetLogger(namePrefix)
|
||||
newCheckerIndex := atomic.AddInt64(&checkerIndex, 1)
|
||||
newCheckerIndex := checkerIndex.Add(1)
|
||||
writerName := namePrefix + "-" + strconv.FormatInt(newCheckerIndex, 10)
|
||||
|
||||
lc := &LogChecker{}
|
||||
|
||||
+12
-12
@@ -12,19 +12,19 @@ import (
|
||||
)
|
||||
|
||||
func TestDebounce(t *testing.T) {
|
||||
var c int64
|
||||
var c atomic.Int64
|
||||
d := Debounce(50 * time.Millisecond)
|
||||
d(func() { atomic.AddInt64(&c, 1) })
|
||||
assert.EqualValues(t, 0, atomic.LoadInt64(&c))
|
||||
d(func() { atomic.AddInt64(&c, 1) })
|
||||
d(func() { atomic.AddInt64(&c, 1) })
|
||||
d(func() { c.Add(1) })
|
||||
assert.EqualValues(t, 0, c.Load())
|
||||
d(func() { c.Add(1) })
|
||||
d(func() { c.Add(1) })
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
assert.EqualValues(t, 1, atomic.LoadInt64(&c))
|
||||
d(func() { atomic.AddInt64(&c, 1) })
|
||||
assert.EqualValues(t, 1, atomic.LoadInt64(&c))
|
||||
d(func() { atomic.AddInt64(&c, 1) })
|
||||
d(func() { atomic.AddInt64(&c, 1) })
|
||||
d(func() { atomic.AddInt64(&c, 1) })
|
||||
assert.EqualValues(t, 1, c.Load())
|
||||
d(func() { c.Add(1) })
|
||||
assert.EqualValues(t, 1, c.Load())
|
||||
d(func() { c.Add(1) })
|
||||
d(func() { c.Add(1) })
|
||||
d(func() { c.Add(1) })
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
assert.EqualValues(t, 2, atomic.LoadInt64(&c))
|
||||
assert.EqualValues(t, 2, c.Load())
|
||||
}
|
||||
@@ -4,7 +4,9 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
@@ -47,6 +49,13 @@ func (r *responseWriter) WriteHeader(statusCode int) {
|
||||
r.respWriter.WriteHeader(statusCode)
|
||||
}
|
||||
|
||||
func (r *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
if hj, ok := r.respWriter.(http.Hijacker); ok {
|
||||
return hj.Hijack()
|
||||
}
|
||||
return nil, nil, http.ErrNotSupported
|
||||
}
|
||||
|
||||
var (
|
||||
httpReqType = reflect.TypeFor[*http.Request]()
|
||||
respWriterType = reflect.TypeFor[http.ResponseWriter]()
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/public"
|
||||
"code.gitea.io/gitea/modules/reqctx"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
@@ -36,5 +37,6 @@ func CommonTemplateContextData() reqctx.ContextData {
|
||||
"PageStartTime": time.Now(),
|
||||
|
||||
"RunModeIsProd": setting.IsProd,
|
||||
"ViteModeIsDev": public.IsViteDevMode(),
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/gtprof"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/reqctx"
|
||||
)
|
||||
|
||||
@@ -40,6 +41,18 @@ func MarkLongPolling(resp http.ResponseWriter, req *http.Request) {
|
||||
|
||||
record.lock.Lock()
|
||||
record.isLongPolling = true
|
||||
record.logLevel = log.TRACE
|
||||
record.lock.Unlock()
|
||||
}
|
||||
|
||||
func MarkLogLevelTrace(resp http.ResponseWriter, req *http.Request) {
|
||||
record, ok := req.Context().Value(contextKey).(*requestRecord)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
record.lock.Lock()
|
||||
record.logLevel = log.TRACE
|
||||
record.lock.Unlock()
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ package routing
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@@ -36,17 +35,8 @@ var (
|
||||
|
||||
func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) {
|
||||
const callerName = "HTTPRequest"
|
||||
logTrace := func(fmt string, args ...any) {
|
||||
logger.Log(2, &log.Event{Level: log.TRACE, Caller: callerName}, fmt, args...)
|
||||
}
|
||||
logInfo := func(fmt string, args ...any) {
|
||||
logger.Log(2, &log.Event{Level: log.INFO, Caller: callerName}, fmt, args...)
|
||||
}
|
||||
logWarn := func(fmt string, args ...any) {
|
||||
logger.Log(2, &log.Event{Level: log.WARN, Caller: callerName}, fmt, args...)
|
||||
}
|
||||
logError := func(fmt string, args ...any) {
|
||||
logger.Log(2, &log.Event{Level: log.ERROR, Caller: callerName}, fmt, args...)
|
||||
logRequest := func(level log.Level, fmt string, args ...any) {
|
||||
logger.Log(2, &log.Event{Level: level, Caller: callerName}, fmt, args...)
|
||||
}
|
||||
return func(trigger Event, record *requestRecord) {
|
||||
if trigger == StartEvent {
|
||||
@@ -57,7 +47,7 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) {
|
||||
}
|
||||
// when a request starts, we have no information about the handler function information, we only have the request path
|
||||
req := record.request
|
||||
logTrace("router: %s %v %s for %s", startMessage, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr)
|
||||
logRequest(log.TRACE, "router: %s %v %s for %s", startMessage, log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -73,12 +63,12 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) {
|
||||
|
||||
if trigger == StillExecutingEvent {
|
||||
message := slowMessage
|
||||
logf := logWarn
|
||||
logLevel := log.WARN
|
||||
if isLongPolling {
|
||||
logf = logInfo
|
||||
logLevel = log.INFO
|
||||
message = pollingMessage
|
||||
}
|
||||
logf("router: %s %v %s for %s, elapsed %v @ %s",
|
||||
logRequest(logLevel, "router: %s %v %s for %s, elapsed %v @ %s",
|
||||
message,
|
||||
log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr,
|
||||
log.ColoredTime(time.Since(record.startTime)),
|
||||
@@ -88,7 +78,7 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) {
|
||||
}
|
||||
|
||||
if panicErr != nil {
|
||||
logWarn("router: %s %v %s for %s, panic in %v @ %s, err=%v",
|
||||
logRequest(log.WARN, "router: %s %v %s for %s, panic in %v @ %s, err=%v",
|
||||
failedMessage,
|
||||
log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr,
|
||||
log.ColoredTime(time.Since(record.startTime)),
|
||||
@@ -102,21 +92,22 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) {
|
||||
if v, ok := record.responseWriter.(types.ResponseStatusProvider); ok {
|
||||
status = v.WrittenStatus()
|
||||
}
|
||||
logf := logInfo
|
||||
logLevel := record.logLevel
|
||||
if logLevel == log.UNDEFINED {
|
||||
logLevel = log.INFO
|
||||
}
|
||||
// lower the log level for some specific requests, in most cases these logs are not useful
|
||||
if status > 0 && status < 400 &&
|
||||
strings.HasPrefix(req.RequestURI, "/assets/") /* static assets */ ||
|
||||
req.RequestURI == "/user/events" /* Server-Sent Events (SSE) handler */ ||
|
||||
req.RequestURI == "/api/actions/runner.v1.RunnerService/FetchTask" /* Actions Runner polling */ {
|
||||
logf = logTrace
|
||||
logLevel = log.TRACE
|
||||
}
|
||||
message := completedMessage
|
||||
if isUnknownHandler {
|
||||
logf = logError
|
||||
logLevel = log.ERROR
|
||||
message = unknownHandlerMessage
|
||||
}
|
||||
|
||||
logf("router: %s %v %s for %s, %v %v in %v @ %s",
|
||||
logRequest(logLevel, "router: %s %v %s for %s, %v %v in %v @ %s",
|
||||
message,
|
||||
log.ColoredMethod(req.Method), req.RequestURI, req.RemoteAddr,
|
||||
log.ColoredStatus(status), log.ColoredStatus(status, http.StatusText(status)), log.ColoredTime(time.Since(record.startTime)),
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
type requestRecord struct {
|
||||
@@ -23,6 +25,7 @@ type requestRecord struct {
|
||||
|
||||
// mutable fields
|
||||
isLongPolling bool
|
||||
logLevel log.Level
|
||||
funcInfo *FuncInfo
|
||||
panicError error
|
||||
}
|
||||
+116
-4
@@ -1155,6 +1155,11 @@
|
||||
"_dockerhub": "folder-docker",
|
||||
"-dockerhub": "folder-docker",
|
||||
"__dockerhub__": "folder-docker",
|
||||
"nginx": "folder-nginx",
|
||||
".nginx": "folder-nginx",
|
||||
"_nginx": "folder-nginx",
|
||||
"-nginx": "folder-nginx",
|
||||
"__nginx__": "folder-nginx",
|
||||
"astro": "folder-astro",
|
||||
".astro": "folder-astro",
|
||||
"_astro": "folder-astro",
|
||||
@@ -1785,6 +1790,11 @@
|
||||
"_pytest_cache": "folder-python",
|
||||
"-pytest_cache": "folder-python",
|
||||
"__pytest_cache__": "folder-python",
|
||||
"r": "folder-r",
|
||||
".r": "folder-r",
|
||||
"_r": "folder-r",
|
||||
"-r": "folder-r",
|
||||
"__r__": "folder-r",
|
||||
"sandbox": "folder-sandbox",
|
||||
".sandbox": "folder-sandbox",
|
||||
"_sandbox": "folder-sandbox",
|
||||
@@ -4517,7 +4527,37 @@
|
||||
".forms": "folder-form",
|
||||
"_forms": "folder-form",
|
||||
"-forms": "folder-form",
|
||||
"__forms__": "folder-form"
|
||||
"__forms__": "folder-form",
|
||||
"deprecated": "folder-deprecated",
|
||||
".deprecated": "folder-deprecated",
|
||||
"_deprecated": "folder-deprecated",
|
||||
"-deprecated": "folder-deprecated",
|
||||
"__deprecated__": "folder-deprecated",
|
||||
"scrap": "folder-scrap",
|
||||
".scrap": "folder-scrap",
|
||||
"_scrap": "folder-scrap",
|
||||
"-scrap": "folder-scrap",
|
||||
"__scrap__": "folder-scrap",
|
||||
"skill": "folder-skills",
|
||||
".skill": "folder-skills",
|
||||
"_skill": "folder-skills",
|
||||
"-skill": "folder-skills",
|
||||
"__skill__": "folder-skills",
|
||||
"skills": "folder-skills",
|
||||
".skills": "folder-skills",
|
||||
"_skills": "folder-skills",
|
||||
"-skills": "folder-skills",
|
||||
"__skills__": "folder-skills",
|
||||
"instruction": "folder-instructions",
|
||||
".instruction": "folder-instructions",
|
||||
"_instruction": "folder-instructions",
|
||||
"-instruction": "folder-instructions",
|
||||
"__instruction__": "folder-instructions",
|
||||
"instructions": "folder-instructions",
|
||||
".instructions": "folder-instructions",
|
||||
"_instructions": "folder-instructions",
|
||||
"-instructions": "folder-instructions",
|
||||
"__instructions__": "folder-instructions"
|
||||
},
|
||||
"folderNamesExpanded": {
|
||||
"rust": "folder-rust-open",
|
||||
@@ -5675,6 +5715,11 @@
|
||||
"_dockerhub": "folder-docker-open",
|
||||
"-dockerhub": "folder-docker-open",
|
||||
"__dockerhub__": "folder-docker-open",
|
||||
"nginx": "folder-nginx-open",
|
||||
".nginx": "folder-nginx-open",
|
||||
"_nginx": "folder-nginx-open",
|
||||
"-nginx": "folder-nginx-open",
|
||||
"__nginx__": "folder-nginx-open",
|
||||
"astro": "folder-astro-open",
|
||||
".astro": "folder-astro-open",
|
||||
"_astro": "folder-astro-open",
|
||||
@@ -6305,6 +6350,11 @@
|
||||
"_pytest_cache": "folder-python-open",
|
||||
"-pytest_cache": "folder-python-open",
|
||||
"__pytest_cache__": "folder-python-open",
|
||||
"r": "folder-r-open",
|
||||
".r": "folder-r-open",
|
||||
"_r": "folder-r-open",
|
||||
"-r": "folder-r-open",
|
||||
"__r__": "folder-r-open",
|
||||
"sandbox": "folder-sandbox-open",
|
||||
".sandbox": "folder-sandbox-open",
|
||||
"_sandbox": "folder-sandbox-open",
|
||||
@@ -9037,7 +9087,37 @@
|
||||
".forms": "folder-form-open",
|
||||
"_forms": "folder-form-open",
|
||||
"-forms": "folder-form-open",
|
||||
"__forms__": "folder-form-open"
|
||||
"__forms__": "folder-form-open",
|
||||
"deprecated": "folder-deprecated-open",
|
||||
".deprecated": "folder-deprecated-open",
|
||||
"_deprecated": "folder-deprecated-open",
|
||||
"-deprecated": "folder-deprecated-open",
|
||||
"__deprecated__": "folder-deprecated-open",
|
||||
"scrap": "folder-scrap-open",
|
||||
".scrap": "folder-scrap-open",
|
||||
"_scrap": "folder-scrap-open",
|
||||
"-scrap": "folder-scrap-open",
|
||||
"__scrap__": "folder-scrap-open",
|
||||
"skill": "folder-skills-open",
|
||||
".skill": "folder-skills-open",
|
||||
"_skill": "folder-skills-open",
|
||||
"-skill": "folder-skills-open",
|
||||
"__skill__": "folder-skills-open",
|
||||
"skills": "folder-skills-open",
|
||||
".skills": "folder-skills-open",
|
||||
"_skills": "folder-skills-open",
|
||||
"-skills": "folder-skills-open",
|
||||
"__skills__": "folder-skills-open",
|
||||
"instruction": "folder-instructions-open",
|
||||
".instruction": "folder-instructions-open",
|
||||
"_instruction": "folder-instructions-open",
|
||||
"-instruction": "folder-instructions-open",
|
||||
"__instruction__": "folder-instructions-open",
|
||||
"instructions": "folder-instructions-open",
|
||||
".instructions": "folder-instructions-open",
|
||||
"_instructions": "folder-instructions-open",
|
||||
"-instructions": "folder-instructions-open",
|
||||
"__instructions__": "folder-instructions-open"
|
||||
},
|
||||
"rootFolderNames": {},
|
||||
"rootFolderNamesExpanded": {},
|
||||
@@ -9063,6 +9143,7 @@
|
||||
"json5": "json",
|
||||
"jsonl": "json",
|
||||
"ndjson": "json",
|
||||
"schema.json": "json_schema",
|
||||
"hjson": "hjson",
|
||||
"jinja": "jinja",
|
||||
"jinja2": "jinja",
|
||||
@@ -9261,6 +9342,7 @@
|
||||
"vcxitems.filters": "visualstudio",
|
||||
"vcxproj": "visualstudio",
|
||||
"vcxproj.filters": "visualstudio",
|
||||
"wixproj": "visualstudio",
|
||||
"vcl": "varnish",
|
||||
"pdb": "database",
|
||||
"sql": "database",
|
||||
@@ -9984,6 +10066,7 @@
|
||||
"ast": "sas",
|
||||
"sast": "sas",
|
||||
"nupkg": "nuget",
|
||||
"nuspec": "nuget",
|
||||
"command": "command",
|
||||
"dsc": "denizenscript",
|
||||
"code-search": "search",
|
||||
@@ -10206,6 +10289,10 @@
|
||||
"lean": "lean",
|
||||
"sls": "salt",
|
||||
"m2": "macaulay2",
|
||||
"skill.md": "skill",
|
||||
"skills.md": "skill",
|
||||
"instructions.md": "instructions",
|
||||
"instruction.md": "instructions",
|
||||
"cljx": "clojure",
|
||||
"clojure": "clojure",
|
||||
"edn": "clojure",
|
||||
@@ -10363,7 +10450,6 @@
|
||||
"jmx": "xml",
|
||||
"launch": "xml",
|
||||
"menu": "xml",
|
||||
"nuspec": "xml",
|
||||
"opml": "xml",
|
||||
"owl": "xml",
|
||||
"proj": "xml",
|
||||
@@ -11094,7 +11180,18 @@
|
||||
"rstest.config.ts": "rstack",
|
||||
"rstest.config.mts": "rstack",
|
||||
"rstest.config.cts": "rstack",
|
||||
"rspress.config.js": "rstack",
|
||||
"rspress.config.mjs": "rstack",
|
||||
"rspress.config.cjs": "rstack",
|
||||
"rspress.config.ts": "rstack",
|
||||
"rspress.config.mts": "rstack",
|
||||
"rspress.config.cts": "rstack",
|
||||
"rslint.config.js": "rstack",
|
||||
"rslint.config.mjs": "rstack",
|
||||
"rslint.config.cjs": "rstack",
|
||||
"rslint.config.ts": "rstack",
|
||||
"rslint.config.mts": "rstack",
|
||||
"rslint.config.cts": "rstack",
|
||||
"rslint.json": "rstack",
|
||||
"rslint.jsonc": "rstack",
|
||||
"lynx.config.js": "lynx",
|
||||
@@ -11141,6 +11238,8 @@
|
||||
".env.dist": "tune",
|
||||
".env.prod": "tune",
|
||||
".env.production": "tune",
|
||||
".env.prod.example": "tune",
|
||||
".env.production.example": "tune",
|
||||
".env.stg": "tune",
|
||||
".env.stage": "tune",
|
||||
".env.staging": "tune",
|
||||
@@ -11850,6 +11949,12 @@
|
||||
"velite.config.ts": "velite",
|
||||
"velite.config.mts": "velite",
|
||||
"velite.config.cts": "velite",
|
||||
"rolldown.config.js": "rolldown",
|
||||
"rolldown.config.mjs": "rolldown",
|
||||
"rolldown.config.cjs": "rolldown",
|
||||
"rolldown.config.ts": "rolldown",
|
||||
"rolldown.config.mts": "rolldown",
|
||||
"rolldown.config.cts": "rolldown",
|
||||
"lerna.json": "lerna",
|
||||
"windi.config.js": "windicss",
|
||||
"windi.config.cjs": "windicss",
|
||||
@@ -12352,6 +12457,7 @@
|
||||
"lefthookrc": "lefthook",
|
||||
".github/labeler.yml": "label",
|
||||
".github/labeler.yaml": "label",
|
||||
"tags": "label",
|
||||
"zeabur.json": "zeabur",
|
||||
"zeabur.jsonc": "zeabur",
|
||||
"zeabur.json5": "zeabur",
|
||||
@@ -12427,6 +12533,7 @@
|
||||
".oxfmtrc.json": "oxc",
|
||||
".oxfmtrc.jsonc": "oxc",
|
||||
"oxlint.config.ts": "oxc",
|
||||
"oxfmt.config.ts": "oxc",
|
||||
"claude.md": "claude",
|
||||
"claude.local.md": "claude",
|
||||
".cursorignore": "cursor",
|
||||
@@ -12450,6 +12557,9 @@
|
||||
".shellcheckrc": "shellcheck",
|
||||
"shellcheckrc": "shellcheck",
|
||||
"warp.md": "warp",
|
||||
"skill.md": "skill",
|
||||
"instructions.md": "instructions",
|
||||
"instruction.md": "instructions",
|
||||
"language-configuration.json": "jsonc",
|
||||
"icon-theme.json": "jsonc",
|
||||
"color-theme.json": "jsonc",
|
||||
@@ -12653,7 +12763,9 @@
|
||||
"helm": "helm",
|
||||
"nginx": "nginx",
|
||||
"cue": "cue",
|
||||
"lean": "lean"
|
||||
"lean": "lean",
|
||||
"skill": "skill",
|
||||
"instructions": "instructions"
|
||||
},
|
||||
"light": {
|
||||
"fileExtensions": {
|
||||
|
||||
Generated
+16
@@ -319,6 +319,8 @@
|
||||
"folder-decorators": "<svg viewBox='0 0 32 32'><path fill='#ab47bc' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#e1bee7' d='M23.66 30a7.8 7.8 0 0 1-3.737-.929 7.06 7.06 0 0 1-2.81-2.784 9.2 9.2 0 0 1-1.07-4.655 18.3 18.3 0 0 1 .863-5.874 12.6 12.6 0 0 1 2.349-4.267 10.1 10.1 0 0 1 3.392-2.604A9.3 9.3 0 0 1 26.607 8a5.22 5.22 0 0 1 4.101 1.455A5.64 5.64 0 0 1 32 13.347a5.4 5.4 0 0 1-.069.832q-.07.443-.153.914l-1.611 7.97h-2.308l-.029-1.006h-.11c-.464.258-.96.665-1.488.96a3.96 3.96 0 0 1-1.96.444 3.03 3.03 0 0 1-2.098-.818 2.79 2.79 0 0 1-.904-2.175 4.34 4.34 0 0 1 1.877-3.781 13 13 0 0 1 5.907-1.76 6 6 0 0 0 .167-1.22 3.94 3.94 0 0 0-.611-2.258 2.71 2.71 0 0 0-2.39-.9 4.9 4.9 0 0 0-2.42.692 7.7 7.7 0 0 0-2.266 2.051 10.9 10.9 0 0 0-1.682 3.367 15.3 15.3 0 0 0-.638 4.641 7.05 7.05 0 0 0 .721 3.366 5 5 0 0 0 1.864 2.009 4.67 4.67 0 0 0 2.39.665 4.4 4.4 0 0 0 1.668-.29 6.2 6.2 0 0 0 1.418-.818l1.279 2.272a7.3 7.3 0 0 1-2.21 1.122A9 9 0 0 1 23.66 30m2.018-9.056a2.8 2.8 0 0 0 1.04-.21 4.8 4.8 0 0 0 1.04-.574l.56-2.742a6.8 6.8 0 0 0-2.99.951 1.87 1.87 0 0 0-.772 1.512 1 1 0 0 0 .31.783 1.16 1.16 0 0 0 .812.28'/></svg>",
|
||||
"folder-delta-open": "<svg viewBox='0 0 32 32'><path fill='#ec407a' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#f8bbd0' d='M23 17.699 28.337 26H17.663zM23 14l-9 14h18z'/></svg>",
|
||||
"folder-delta": "<svg viewBox='0 0 32 32'><path fill='#ec407a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#f8bbd0' d='M23 17.699 28.337 26H17.663zM23 14l-9 14h18z'/></svg>",
|
||||
"folder-deprecated-open.clone": "<svg viewBox='0 0 1024 1024'><path fill='#616161' d='M926.912 384H302.144a64 64 0 0 0-60.736 43.776L128 768V320h768a64 64 0 0 0-64-64H483.968a64 64 0 0 1-40.96-14.848l-41.216-34.304A64 64 0 0 0 360.832 192H128a64 64 0 0 0-64 64v512a64 64 0 0 0 64 64h704l153.792-358.784A64 64 0 0 0 926.912 384'/><path fill='#bdbdbd' d='M512 320c-35.456 0-64 28.544-64 64v64c0 35.456 28.544 64 64 64v320c0 35.456 28.544 64 64 64h320c35.456 0 64-28.544 64-64V512c35.456 0 64-28.544 64-64v-64c0-35.456-28.544-64-64-64zm0 64h448v64H512zm128 128h192v64H640z'/></svg>",
|
||||
"folder-deprecated.clone": "<svg viewBox='0 0 1024 1024'><path fill='#616161' d='m443.008 241.152-41.216-34.304A64 64 0 0 0 360.832 192H128a64 64 0 0 0-64 64v512a64 64 0 0 0 64 64h768a64 64 0 0 0 64-64V320a64 64 0 0 0-64-64H483.968a64 64 0 0 1-40.96-14.848'/><path fill='#bdbdbd' d='M512 320c-35.456 0-64 28.544-64 64v64c0 35.456 28.544 64 64 64v320c0 35.456 28.544 64 64 64h320c35.456 0 64-28.544 64-64V512c35.456 0 64-28.544 64-64v-64c0-35.456-28.544-64-64-64zm0 64h448v64H512zm128 128h192v64H640z'/></svg>",
|
||||
"folder-desktop-open": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#b3e5fc' d='M30 12H14a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h6v2h-2v2h8v-2h-2v-2h6a2 2 0 0 0 2-2V14a2 2 0 0 0-2-2m0 12H14V14h16Z'/></svg>",
|
||||
"folder-desktop": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b3e5fc' d='M30 12H14a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h6v2h-2v2h8v-2h-2v-2h6a2 2 0 0 0 2-2V14a2 2 0 0 0-2-2m0 12H14V14h16Z'/></svg>",
|
||||
"folder-development-open.clone": "<svg viewBox='0 0 32 32'><path fill='#0288d1' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#b3e5fc' d='M18.473 30a1 1 0 0 1-.238-.028 1.137 1.137 0 0 1-.828-1.323L20.5 12.905a1.13 1.13 0 0 1 .507-.744 1.06 1.06 0 0 1 .8-.134 1.14 1.14 0 0 1 .828 1.324l-3.101 15.744a1.12 1.12 0 0 1-.504.743 1.06 1.06 0 0 1-.557.162m6.2-2h-.077a1.08 1.08 0 0 1-.762-.412 1.164 1.164 0 0 1 .113-1.548l5.319-4.967-5.296-4.623a1.165 1.165 0 0 1-.162-1.544 1.08 1.08 0 0 1 .754-.437 1.06 1.06 0 0 1 .81.258l6.244 5.455a1.156 1.156 0 0 1 .003 1.723l-6.218 5.808a1.07 1.07 0 0 1-.729.289Zm-9.31 0a1.07 1.07 0 0 1-.728-.292l-6.226-5.811a1.16 1.16 0 0 1-.01-1.692l.02-.018 6.246-5.454a1.03 1.03 0 0 1 .8-.26 1.08 1.08 0 0 1 .76.436 1.165 1.165 0 0 1-.16 1.547l-5.294 4.62 5.32 4.964a1.156 1.156 0 0 1 .112 1.548 1.07 1.07 0 0 1-.762.412Z'/></svg>",
|
||||
@@ -427,6 +429,8 @@
|
||||
"folder-include": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b3e5fc' d='M25 14a7 7 0 1 0 7 7 7 7 0 0 0-7-7m1 8v4h-2v-4h-4v-2h4v-4h2v4h4v2Z'/></svg>",
|
||||
"folder-input-open": "<svg viewBox='0 0 32 32'><path fill='#00acc1' d='M28.965 12H9.441a2 2 0 0 0-1.898 1.368L4 24V10h23.998a2 2 0 0 0-2-2H15.122a2 2 0 0 1-1.28-.464l-1.287-1.072A2 2 0 0 0 11.275 6H3.999a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h21.998l4.805-11.212A2 2 0 0 0 28.964 12'/><path fill='#b2ebf2' d='M13.98 10c-1.098 0-1.98.994-1.98 2.229V16h2v-4h16v14H14v-4h-2v3.772c0 1.234.882 2.228 1.98 2.228h16.039c1.098 0 1.98-.994 1.98-2.228V12.229C32 10.994 31.118 10 30.02 10zM22 14v4H12v2h10v4l5.12-5z'/></svg>",
|
||||
"folder-input": "<svg viewBox='0 0 32 32'><path fill='#00acc1' d='m13.844 7.537-1.287-1.073A2 2 0 0 0 11.277 6H4.001A2 2 0 0 0 2 8v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.125a2 2 0 0 1-1.282-.463'/><path fill='#b2ebf2' d='M13.98 10c-1.098 0-1.98.994-1.98 2.229V16h2v-4h16v14H14v-4h-2v3.772c0 1.234.882 2.228 1.98 2.228h16.039c1.098 0 1.98-.994 1.98-2.228V12.229C32 10.994 31.118 10 30.02 10zM22 14v4H12v2h10v4l5.12-5z'/></svg>",
|
||||
"folder-instructions-open.clone": "<svg viewBox='0 0 32 32'><path fill='#00b8d4' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#b2ebf2' d='M16 16h-2v13a1 1 0 0 0 1 1h13v-2H16Z'/><path fill='#b2ebf2' d='M31 12H19a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V13a1 1 0 0 0-1-1m-5 12h-6v-2h6Zm4-4H20v-2h10Zm0-4H20v-2h10Z'/></svg>",
|
||||
"folder-instructions.clone": "<svg viewBox='0 0 32 32'><path fill='#00b8d4' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b2ebf2' d='M16 16h-2v13a1 1 0 0 0 1 1h13v-2H16Z'/><path fill='#b2ebf2' d='M31 12H19a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V13a1 1 0 0 0-1-1m-5 12h-6v-2h6Zm4-4H20v-2h10Zm0-4H20v-2h10Z'/></svg>",
|
||||
"folder-intellij-open": "<svg viewBox='0 0 32 32'><defs data-mit-no-recolor='true'><linearGradient id='a' x1='.445' x2='104.977' y1='3272.835' y2='3209.742' gradientTransform='translate(18.126 -331.024)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#fdd835'/><stop offset='1' stop-color='#f57c00'/></linearGradient><linearGradient id='b' x1='22.55' x2='117.962' y1='3121.343' y2='3204.873' gradientTransform='translate(18.126 -331.024)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#ef5350'/><stop offset='.57' stop-color='#ff6e40'/><stop offset='1' stop-color='#f57c00'/></linearGradient><linearGradient id='c' x1='28.608' x2='-27.937' y1='3197.064' y2='3161.75' gradientTransform='translate(18.126 -331.024)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#8e24aa'/><stop offset='.385' stop-color='#ab47bc'/><stop offset='.765' stop-color='#ec407a'/><stop offset='.957' stop-color='#ec407a'/></linearGradient><linearGradient id='d' x1='27.588' x2='-27.616' y1='3117.085' y2='3162.678' gradientTransform='translate(18.126 -331.024)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#ef5350'/><stop offset='.364' stop-color='#ec407a'/><stop offset='1' stop-color='#ec407a'/></linearGradient></defs><path fill='#546e7a' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='url(#a)' d='M30.93 22.519a.68.68 0 0 0 .22-.47.69.69 0 0 0-.647-.72.72.72 0 0 0-.485.161l-12.314 6.745a1.44 1.44 0 0 0-.69.602 1.48 1.48 0 0 0 .506 2.03l.022.013a1.51 1.51 0 0 0 1.573-.03c.03-.029.073-.043.103-.073l11.461-8.053a2 2 0 0 0 .25-.205Z'/><path fill='url(#b)' d='m30.959 21.534-9.376-9.199a1.133 1.133 0 1 0-1.66 1.543 2 2 0 0 0 .176.147l9.904 8.48a.76.76 0 0 0 .441.19.69.69 0 0 0 .72-.646.73.73 0 0 0-.205-.515'/><path fill='url(#c)' d='M21.892 20.711c-.015 0-5.79-4.555-5.907-4.628l-.265-.133a1.644 1.644 0 0 0-1.44 2.94 1.3 1.3 0 0 0 .294.131c.059.03 6.671 2.763 6.671 2.763a.63.63 0 0 0 .647-1.073'/><path fill='url(#d)' d='M20.746 11.968a1.2 1.2 0 0 0-.676.22l-5.849 3.939c-.014.014-.03.014-.03.029h-.014a1.638 1.638 0 0 0 .397 2.865 1.61 1.61 0 0 0 1.528-.205 1.4 1.4 0 0 0 .265-.235l5.084-4.585a1.132 1.132 0 0 0-.705-2.028'/></svg>",
|
||||
"folder-intellij-open_light": "<svg viewBox='0 0 32 32'><defs data-mit-no-recolor='true'><linearGradient id='a' x1='.445' x2='104.977' y1='3611.926' y2='3548.833' gradientTransform='translate(18.126 -368.395)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#fdd835'/><stop offset='1' stop-color='#f57c00'/></linearGradient><linearGradient id='b' x1='22.55' x2='117.962' y1='3460.434' y2='3543.963' gradientTransform='translate(18.126 -368.395)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#ef5350'/><stop offset='.57' stop-color='#ff6e40'/><stop offset='1' stop-color='#f57c00'/></linearGradient><linearGradient id='c' x1='28.608' x2='-27.937' y1='3536.154' y2='3500.841' gradientTransform='translate(18.126 -368.395)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#8e24aa'/><stop offset='.385' stop-color='#ab47bc'/><stop offset='.765' stop-color='#ec407a'/><stop offset='.957' stop-color='#ec407a'/></linearGradient><linearGradient id='d' x1='27.588' x2='-27.616' y1='3456.176' y2='3501.769' gradientTransform='translate(18.126 -368.395)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#ef5350'/><stop offset='.364' stop-color='#ec407a'/><stop offset='1' stop-color='#ec407a'/></linearGradient></defs><path fill='#b0bec5' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='url(#a)' d='M30.93 22.519a.68.68 0 0 0 .22-.47.69.69 0 0 0-.647-.72.72.72 0 0 0-.485.161l-12.314 6.745a1.44 1.44 0 0 0-.69.602 1.48 1.48 0 0 0 .506 2.03l.022.013a1.51 1.51 0 0 0 1.573-.03c.03-.029.073-.043.103-.073l11.461-8.053a2 2 0 0 0 .25-.205Z'/><path fill='url(#b)' d='m30.959 21.534-9.376-9.199a1.133 1.133 0 1 0-1.66 1.543 2 2 0 0 0 .176.147l9.904 8.48a.76.76 0 0 0 .441.19.69.69 0 0 0 .72-.646.73.73 0 0 0-.205-.515'/><path fill='url(#c)' d='M21.892 20.711c-.015 0-5.79-4.555-5.907-4.628l-.265-.133a1.644 1.644 0 0 0-1.44 2.94 1.3 1.3 0 0 0 .294.131c.059.03 6.671 2.763 6.671 2.763a.63.63 0 0 0 .647-1.073'/><path fill='url(#d)' d='M20.746 11.968a1.2 1.2 0 0 0-.676.22l-5.849 3.939c-.014.014-.03.014-.03.029h-.014a1.638 1.638 0 0 0 .397 2.865 1.61 1.61 0 0 0 1.528-.205 1.4 1.4 0 0 0 .265-.235l5.084-4.585a1.132 1.132 0 0 0-.705-2.028'/></svg>",
|
||||
"folder-intellij": "<svg viewBox='0 0 32 32'><defs data-mit-no-recolor='true'><linearGradient id='a' x1='-338.646' x2='-234.114' y1='3272.835' y2='3209.742' gradientTransform='translate(55.497 -331.024)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#fdd835'/><stop offset='1' stop-color='#f57c00'/></linearGradient><linearGradient id='b' x1='-316.541' x2='-221.129' y1='3121.343' y2='3204.873' gradientTransform='translate(55.497 -331.024)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#ef5350'/><stop offset='.57' stop-color='#ff6e40'/><stop offset='1' stop-color='#f57c00'/></linearGradient><linearGradient id='c' x1='-310.483' x2='-367.028' y1='3197.064' y2='3161.75' gradientTransform='translate(55.497 -331.024)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#8e24aa'/><stop offset='.385' stop-color='#ab47bc'/><stop offset='.765' stop-color='#ec407a'/><stop offset='.957' stop-color='#ec407a'/></linearGradient><linearGradient id='d' x1='-311.503' x2='-366.707' y1='3117.085' y2='3162.678' gradientTransform='translate(55.497 -331.024)scale(.11021)' gradientUnits='userSpaceOnUse'><stop offset='0' stop-color='#ef5350'/><stop offset='.364' stop-color='#ec407a'/><stop offset='1' stop-color='#ec407a'/></linearGradient></defs><path fill='#546e7a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='url(#a)' d='M30.93 22.519a.68.68 0 0 0 .22-.47.69.69 0 0 0-.647-.72.72.72 0 0 0-.485.161l-12.314 6.745a1.44 1.44 0 0 0-.69.602 1.48 1.48 0 0 0 .506 2.03l.022.013a1.51 1.51 0 0 0 1.573-.03c.03-.029.073-.043.103-.073l11.461-8.053a2 2 0 0 0 .25-.205Z'/><path fill='url(#b)' d='m30.959 21.534-9.376-9.199a1.133 1.133 0 1 0-1.66 1.543 2 2 0 0 0 .176.147l9.904 8.48a.76.76 0 0 0 .441.19.69.69 0 0 0 .72-.646.73.73 0 0 0-.205-.515'/><path fill='url(#c)' d='M21.892 20.711c-.015 0-5.79-4.555-5.907-4.628l-.265-.133a1.644 1.644 0 0 0-1.44 2.94 1.3 1.3 0 0 0 .294.131c.059.03 6.671 2.763 6.671 2.763a.63.63 0 0 0 .647-1.073'/><path fill='url(#d)' d='M20.746 11.968a1.2 1.2 0 0 0-.676.22l-5.849 3.939c-.014.014-.03.014-.03.029h-.014a1.638 1.638 0 0 0 .397 2.865 1.61 1.61 0 0 0 1.528-.205 1.4 1.4 0 0 0 .265-.235l5.084-4.585a1.132 1.132 0 0 0-.705-2.028'/></svg>",
|
||||
@@ -517,6 +521,8 @@
|
||||
"folder-netlify": "<svg viewBox='0 0 32 32'><path fill='#26a69a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#a7ffeb' d='M22 16h-4v6h2v-4h1.5a.5.5 0 0 1 .5.5V22h2v-4a2 2 0 0 0-2-2'/><rect width='6' height='2' x='26' y='18' fill='#a7ffeb' rx='.5'/><rect width='2' height='6' x='20' y='8' fill='#a7ffeb' rx='.5'/><rect width='6' height='2' x='10' y='18' fill='#a7ffeb' rx='.5'/><rect width='2' height='6' x='20' y='24' fill='#a7ffeb' rx='.5'/><path fill='#a7ffeb' d='m13 12.172 1.414-1.414 2.828 2.828L15.828 15zM15.828 23l1.414 1.414-2.828 2.828L13 25.828z'/></svg>",
|
||||
"folder-next-open": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#cfd8dc' d='M24 12a8 8 0 1 0 3.969 14.94L22 19v4.5a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-7a.5.5 0 0 1 .5-.5h1.232a.5.5 0 0 1 .416.223l6.736 10.103A7.993 7.993 0 0 0 24 12m4 8h-2v-3.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5Z'/></svg>",
|
||||
"folder-next": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#cfd8dc' d='M24 12a8 8 0 1 0 3.969 14.94L22 19v4.5a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-7a.5.5 0 0 1 .5-.5h1.232a.5.5 0 0 1 .416.223l6.736 10.103A7.993 7.993 0 0 0 24 12m4 8h-2v-3.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5Z'/></svg>",
|
||||
"folder-nginx-open": "<svg viewBox='0 0 32 32'><path fill='#388e3c' d='M28.966 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.806-11.212A2 2 0 0 0 28.966 12'/><path fill='#a5d6a7' d='m24 10.857-8 4.571v9.143l8 4.572 8-4.572v-9.143zM28 23.5v.5h-1.76a.5.5 0 0 1-.39-.187L22 19v5h-2v-8h1.76a.5.5 0 0 1 .39.188L26 21v-5h2z'/></svg>",
|
||||
"folder-nginx": "<svg viewBox='0 0 32 32'><path fill='#388e3c' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#a5d6a7' d='m24 10.857-8 4.571v9.143l8 4.572 8-4.572v-9.143zM28 24h-1.76a.5.5 0 0 1-.39-.187L22 19v5h-2v-8h1.76a.5.5 0 0 1 .39.188L26 21v-5h2z'/></svg>",
|
||||
"folder-ngrx-actions-open.clone": "<svg viewBox='0 0 32 32'><path fill='#ab47bc' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#e1bee7' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
|
||||
"folder-ngrx-actions.clone": "<svg viewBox='0 0 32 32'><path fill='#ab47bc' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#e1bee7' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
|
||||
"folder-ngrx-effects-open.clone": "<svg viewBox='0 0 32 32'><path fill='#00bcd4' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#b2ebf2' d='m23 9-9 3 1 12 8 4 8-4 1-12Zm-1.869 2.785a2.3 2.3 0 0 1 1.124.324 5.3 5.3 0 0 0 1.214.305 6.63 6.63 0 0 1 4.433 2.834c.448.875.356 1.348-.33 1.7-.59.303-1.799.157-3.554-.432l-1.481-.497-.527.199a3.53 3.53 0 0 0-1.84 1.73 2.9 2.9 0 0 0-.218 1.622 2.9 2.9 0 0 0 .41 1.645c.35.613 1.15 1.395 1.287 1.259.038-.038-.044-.287-.182-.553a1.1 1.1 0 0 1-.178-.595c.038-.061.4.165.802.504a5.6 5.6 0 0 0 2.898 1.333c.787.081.967-.064.377-.307a1.8 1.8 0 0 1-.547-.363c-.23-.252-.243-.244.738-.462a4.6 4.6 0 0 0 1.887-.996c.023-.073-.173-.102-.495-.077-.292.023-.53-.006-.53-.067a3 3 0 0 1 .53-.656 4.93 4.93 0 0 0 1.585-3.596l.08-1.114.258.53a3.2 3.2 0 0 1 .133 2.148c-.168.605-.056.672.253.152.382-.644.505-.543.438.364a3.95 3.95 0 0 1-1.183 2.561c-.627.68-.551.803.207.34.731-.449.83-.379.453.325a6.08 6.08 0 0 1-3.782 2.831 6.2 6.2 0 0 1-2.487.16 7.33 7.33 0 0 1-5.44-3.849 13 13 0 0 0-.836-1.437c-.403-.542-.436-.785-.166-1.197a.92.92 0 0 0 .111-.73c-.257-1.451-.248-1.496.337-2.088.512-.513.543-.581.543-1.182 0-.52.052-.69.29-.925a1 1 0 0 1 .561-.291 2.88 2.88 0 0 0 1.624-.865 1.67 1.67 0 0 1 1.203-.587'/></svg>",
|
||||
@@ -582,6 +588,8 @@
|
||||
"folder-quasar": "<svg viewBox='0 0 32 32'><path fill='#1976d2' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#bbdefb' d='M24.026 20A2.028 2.028 0 1 1 22 18.048 1.99 1.99 0 0 1 24.026 20m6.967-5.002a10 10 0 0 0-1.59-2.002L27.06 14.3a7.9 7.9 0 0 0-2.445-1.365 9.3 9.3 0 0 0-1.893 2.6 11.74 11.74 0 0 1 7.8 2.618l1.473-.819A9.8 9.8 0 0 0 30.993 15Zm0 10.002A9.8 9.8 0 0 0 32 22.67l-2.342-1.303a7.2 7.2 0 0 0 .005-2.72 10 10 0 0 0-3.285-.278 10.7 10.7 0 0 1 1.545 7.812l1.473.82A10 10 0 0 0 30.993 25m-8.992 5a10.8 10.8 0 0 0 2.597-.326v-2.603a7.9 7.9 0 0 0 2.451-1.357 9.1 9.1 0 0 0-1.392-2.88 11.36 11.36 0 0 1-6.255 5.196v1.64a10.8 10.8 0 0 0 2.599.33m-8.994-5a10 10 0 0 0 1.592 2.004L16.94 25.7a7.8 7.8 0 0 0 2.447 1.365 9.3 9.3 0 0 0 1.891-2.6 11.75 11.75 0 0 1-7.8-2.618l-1.471.819a9.8 9.8 0 0 0 1 2.333Zm0-10A9.8 9.8 0 0 0 12 17.33l2.343 1.303a7.2 7.2 0 0 0-.005 2.72 10 10 0 0 0 3.286.278 10.7 10.7 0 0 1-1.545-7.814l-1.475-.82a10 10 0 0 0-1.597 2.005Zm8.992-5a10.8 10.8 0 0 0-2.597.326v2.603a7.9 7.9 0 0 0-2.45 1.357 9.1 9.1 0 0 0 1.393 2.88A11.35 11.35 0 0 1 24.6 11.97v-1.64A10.8 10.8 0 0 0 22 10Z'/></svg>",
|
||||
"folder-queue-open": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#b3e5fc' d='M24 16v-2h-3a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3v-2h-2v-8Zm8-2v-2h-5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-2h-4V14Zm-16 2h2v8h-2z'/></svg>",
|
||||
"folder-queue": "<svg viewBox='0 0 32 32'><path fill='#039be5' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#b3e5fc' d='M24 16v-2h-3a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h3v-2h-2v-8Zm8-2v-2h-5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h5v-2h-4V14Zm-16 2h2v8h-2z'/></svg>",
|
||||
"folder-r-open": "<svg viewBox='0 0 32 32'><path fill='#1976d2' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#90caf9' fill-rule='evenodd' d='M16 22.405v2.786c-4.8-1.097-8.263-4.17-8.263-7.804 0-4.553 5.432-8.245 12.132-8.245S32 12.834 32 17.387a6.46 6.46 0 0 1-1.915 4.433l-.49-.855a4.65 4.65 0 0 0 .981-2.962c0-3.91-3.758-5.637-8.85-5.637-5.093 0-9.221 2.523-9.221 5.637 0 1.787 1.372 3.37 3.495 4.402m15.332 5.596V28h-.001Zm0-.001h-4.656l-2.177-4.208a5.4 5.4 0 0 0-.72-1.017c-.23-.19-.327-.258-.553-.258H22V28h-4V14h8.274S30 14.07 30 17.76a3.866 3.866 0 0 1-3.559 3.964 9 9 0 0 1 1.156.448 2.2 2.2 0 0 1 .586.431 1.6 1.6 0 0 1 .268.396ZM26 17.5a1.5 1.5 0 0 0-1.5-1.5H22v4h2.5a1.5 1.5 0 0 0 1.5-1.5Z'/></svg>",
|
||||
"folder-r": "<svg viewBox='0 0 32 32'><path fill='#1976d2' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#90caf9' fill-rule='evenodd' d='M16 22.405v2.786c-4.8-1.097-8.263-4.17-8.263-7.804 0-4.553 5.432-8.245 12.132-8.245S32 12.834 32 17.387a6.46 6.46 0 0 1-1.915 4.433l-.49-.855a4.65 4.65 0 0 0 .981-2.962c0-3.91-3.758-5.637-8.85-5.637-5.093 0-9.221 2.523-9.221 5.637 0 1.787 1.372 3.37 3.495 4.402m15.332 5.596V28h-.001Zm0-.001h-4.656l-2.177-4.208a5.4 5.4 0 0 0-.72-1.017c-.23-.19-.327-.258-.553-.258H22V28h-4V14h8.274S30 14.07 30 17.76a3.866 3.866 0 0 1-3.559 3.964 9 9 0 0 1 1.156.448 2.2 2.2 0 0 1 .586.431 1.6 1.6 0 0 1 .268.396ZM26 17.5a1.5 1.5 0 0 0-1.5-1.5H22v4h2.5a1.5 1.5 0 0 0 1.5-1.5Z'/></svg>",
|
||||
"folder-react-components-open": "<svg viewBox='0 0 16 16'><path fill='#00bcd4' d='M14.484 6H4.72a1 1 0 0 0-.949.684L2 12V5h13a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232l-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h11l2.403-5.606A1 1 0 0 0 14.483 6'/><g fill='#b2ebf2'><path d='M10.5 8.399c2.924 0 4.714 1.037 4.714 1.6s-1.79 1.602-4.714 1.602S5.785 10.564 5.785 10s1.79-1.601 4.715-1.601m0-.8c-3.038 0-5.5 1.075-5.5 2.4s2.462 2.402 5.5 2.402S16 11.326 16 10s-2.463-2.401-5.5-2.401'/><path d='M10.5 9.2a.786.8 0 1 0 .785.8.786.8 0 0 0-.785-.8'/><path d='M8.322 5.8c.793 0 2.333 1.272 3.538 3.4 1.463 2.58 1.476 4.677.997 4.959a.354.36 0 0 1-.18.04c-.792 0-2.333-1.271-3.538-3.399-1.463-2.58-1.476-4.677-.997-4.96a.354.36 0 0 1 .18-.04m0-.8a1.128 1.149 0 0 0-.572.147c-1.128.663-.81 3.374.708 6.054C9.748 13.478 11.491 15 12.678 15a1.128 1.149 0 0 0 .572-.148c1.127-.663.81-3.373-.71-6.053C11.25 6.522 9.509 5 8.323 5Z'/><path d='M12.677 5.8a.354.36 0 0 1 .18.04c.48.283.466 2.38-.997 4.96-1.206 2.128-2.746 3.4-3.538 3.4a.354.36 0 0 1-.18-.04c-.48-.284-.466-2.38.997-4.96 1.206-2.128 2.746-3.4 3.538-3.4m0-.8c-1.186 0-2.929 1.522-4.22 3.8-1.517 2.68-1.835 5.39-.707 6.052a1.128 1.149 0 0 0 .572.148c1.186 0 2.929-1.523 4.22-3.8 1.517-2.68 1.835-5.39.708-6.052A1.128 1.149 0 0 0 12.677 5'/></g></svg>",
|
||||
"folder-react-components": "<svg viewBox='0 0 16 16'><path fill='#00bcd4' d='m6.922 3.768-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232'/><g fill='#b2ebf2'><path d='M10.5 8.399c2.924 0 4.714 1.037 4.714 1.6s-1.79 1.602-4.714 1.602S5.785 10.564 5.785 10s1.79-1.601 4.715-1.601m0-.8c-3.038 0-5.5 1.075-5.5 2.4s2.462 2.402 5.5 2.402S16 11.326 16 10s-2.463-2.401-5.5-2.401'/><path d='M10.5 9.2a.786.8 0 1 0 .785.8.786.8 0 0 0-.785-.8'/><path d='M8.322 5.8c.793 0 2.333 1.272 3.538 3.4 1.463 2.58 1.476 4.677.997 4.959a.354.36 0 0 1-.18.04c-.792 0-2.333-1.271-3.538-3.399-1.463-2.58-1.476-4.677-.997-4.96a.354.36 0 0 1 .18-.04m0-.8a1.128 1.149 0 0 0-.572.147c-1.128.663-.81 3.374.708 6.054C9.748 13.478 11.491 15 12.678 15a1.128 1.149 0 0 0 .572-.148c1.127-.663.81-3.373-.71-6.053C11.25 6.522 9.509 5 8.323 5Z'/><path d='M12.677 5.8a.354.36 0 0 1 .18.04c.48.283.466 2.38-.997 4.96-1.206 2.128-2.746 3.4-3.538 3.4a.354.36 0 0 1-.18-.04c-.48-.284-.466-2.38.997-4.96 1.206-2.128 2.746-3.4 3.538-3.4m0-.8c-1.186 0-2.929 1.522-4.22 3.8-1.517 2.68-1.835 5.39-.707 6.052a1.128 1.149 0 0 0 .572.148c1.186 0 2.929-1.523 4.22-3.8 1.517-2.68 1.835-5.39.708-6.052A1.128 1.149 0 0 0 12.677 5'/></g></svg>",
|
||||
"folder-redux-actions-open.clone": "<svg viewBox='0 0 32 32'><path fill='#ab47bc' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#f3e5f5' stroke='#f3e5f5' stroke-linejoin='round' stroke-width='.293' d='M25.948 24.114a1.65 1.65 0 0 0 .97-.6 1.8 1.8 0 0 0 .381-1.274 1.72 1.72 0 0 0-1.69-1.596h-.06a1.724 1.724 0 0 0-1.61 1.814 1.85 1.85 0 0 0 .34.985 8.85 8.85 0 0 1-3.863 3.799 6.15 6.15 0 0 1-3.876.771 3.13 3.13 0 0 1-2.32-1.411 3.67 3.67 0 0 1-.18-3.738 5.8 5.8 0 0 1 1.605-1.986.3.3 0 0 0 .098-.313 14 14 0 0 1-.315-1.298.29.29 0 0 0-.172-.213.28.28 0 0 0-.272.036c-3.731 2.836-3.326 6.763-2.188 8.579a5.36 5.36 0 0 0 4.294 2.229q.125 0 .24-.005h.04a6 6 0 0 0 1.5-.188 9.88 9.88 0 0 0 7.078-5.591Z'/><path fill='#f3e5f5' stroke='#f3e5f5' stroke-linejoin='round' stroke-width='.293' d='M30.327 20.428a10.12 10.12 0 0 0-7.774-3.69q-.133 0-.265.003h-.234a1.61 1.61 0 0 0-1.377-.78h-.053a1.62 1.62 0 0 0-1.175.535 1.806 1.806 0 0 0 .039 2.466 1.67 1.67 0 0 0 1.19.494h.064a1.68 1.68 0 0 0 1.375-.886h.27a8.83 8.83 0 0 1 5.126 1.646 6.6 6.6 0 0 1 2.522 3.202 3.48 3.48 0 0 1-.046 2.831 3.39 3.39 0 0 1-3.137 1.97 5.8 5.8 0 0 1-2.32-.522.27.27 0 0 0-.304.054 14 14 0 0 1-1.088.912.294.294 0 0 0 .039.495 7.7 7.7 0 0 0 3.313.84l.192.002a5.66 5.66 0 0 0 4.886-2.948 6.39 6.39 0 0 0-1.243-6.624Z'/><path fill='#f3e5f5' stroke='#f3e5f5' stroke-linejoin='round' stroke-width='.293' d='m17.249 24.295.123-.01-.123.02a1.705 1.705 0 0 0 1.67 1.682h.053a1.715 1.715 0 0 0 1.64-1.778 1.78 1.78 0 0 0-.507-1.224 1.6 1.6 0 0 0-1.187-.493h-.076a9.6 9.6 0 0 1-1.154-5.448 6.83 6.83 0 0 1 1.39-3.853 3.97 3.97 0 0 1 2.842-1.363h.055c2.438 0 3.415 3.34 3.477 4.491a.29.29 0 0 0 .216.265c.299.073.822.246 1.213.384a.27.27 0 0 0 .266-.048.3.3 0 0 0 .105-.247C26.928 12.088 24.204 10 21.804 10a5.96 5.96 0 0 0-5.36 4.39 11.38 11.38 0 0 0 .936 9.155 1.5 1.5 0 0 0-.131.75Z'/></svg>",
|
||||
@@ -622,6 +630,8 @@
|
||||
"folder-scala": "<svg viewBox='0 0 32 32'><path fill='#f44336' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#ffcdd2' d='M18 26v4c2.281-.781 8.713-1.025 10-2v-4c-1.287.975-7.719 1.219-10 2m0-6v4c2.281-.781 8.713-1.025 10-2v-4c-1.287.975-7.719 1.219-10 2m0-6v4c2.281-.781 8.713-1.025 10-2v-4c-1.287.975-7.719 1.219-10 2'/></svg>",
|
||||
"folder-scons-open": "<svg viewBox='0 0 32 32'><path fill='#ef5350' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffcdd2' d='M12 24h8v4h-8Zm12 0h8v4h-8Zm-12-6h4v4h-4Zm16 0h4v4h-4Zm-10-8h8v4h-8Zm4 14-4-4h2v-4h4v4h2Z'/></svg>",
|
||||
"folder-scons": "<svg viewBox='0 0 32 32'><path fill='#ef5350' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124c-.468 0-.921-.164-1.28-.464'/><path fill='#ffcdd2' d='M12 24h8v4h-8Zm12 0h8v4h-8Zm-12-6h4v4h-4Zm16 0h4v4h-4Zm-10-8h8v4h-8Zm4 14-4-4h2v-4h4v4h2Z'/></svg>",
|
||||
"folder-scrap-open.clone": "<svg fill-rule='evenodd' clip-rule='evenodd' image-rendering='optimizeQuality' shape-rendering='geometricPrecision' text-rendering='geometricPrecision' viewBox='0 0 512 512'><path fill='#616161' d='M463.47 192H151.06c-13.77 0-26 8.82-30.35 21.89L64 384V160h384c0-17.67-14.33-32-32-32H241.98a32 32 0 0 1-20.48-7.42l-20.6-17.15c-5.75-4.8-13-7.43-20.48-7.43H64c-17.67 0-32 14.33-32 32v256c0 17.67 14.33 32 32 32h352l76.88-179.39c1.7-3.98 2.59-8.28 2.59-12.61 0-17.67-14.33-32-32-32'/><path fill='#bdbdbd' d='M320 160v32h-96v32h32v192c0 17.63 14.38 32 32 32h160c17.63 0 32-14.37 32-32V224h32v-32h-96v-32zm0 96v128h32V256zm64 0v128h32V256z'/></svg>",
|
||||
"folder-scrap.clone": "<svg fill-rule='evenodd' clip-rule='evenodd' image-rendering='optimizeQuality' shape-rendering='geometricPrecision' text-rendering='geometricPrecision' viewBox='0 0 512 512'><path fill='#616161' d='m221.5 120.58-20.6-17.16A32 32 0 0 0 180.42 96H64c-17.67 0-32 14.33-32 32v256c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32V160c0-17.67-14.33-32-32-32H241.98a32 32 0 0 1-20.48-7.42'/><path fill='#bdbdbd' d='M320 160v32h-96v32h32v192c0 17.63 14.38 32 32 32h160c17.63 0 32-14.37 32-32V224h32v-32h-96v-32zm0 96v128h32V256zm64 0v128h32V256z'/></svg>",
|
||||
"folder-scripts-open": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#cfd8dc' d='M28 12h-6a4 4 0 0 0-4 4v8h2v-8h8v9.893a2.074 2.074 0 0 1-1.664 2.08A2 2 0 0 1 24 26h-8a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4V16h2a4 4 0 0 0-4-4'/></svg>",
|
||||
"folder-scripts": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#cfd8dc' d='M28 12h-6a4 4 0 0 0-4 4v8h2v-8h8v9.893a2.074 2.074 0 0 1-1.664 2.08A2 2 0 0 1 24 26h-8a4 4 0 0 0 4 4h6a4 4 0 0 0 4-4V16h2a4 4 0 0 0-4-4'/></svg>",
|
||||
"folder-secure-open": "<svg viewBox='0 0 32 32'><path fill='#f9a825' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#fff9c4' d='M28 16v-3.828a4.116 4.116 0 0 0-3.607-4.153A4 4 0 0 0 20 12v4h-2a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2Zm-4 8a2 2 0 1 1 2-2 2 2 0 0 1-2 2m2-8h-4v-4a2 2 0 0 1 4 0Z'/></svg>",
|
||||
@@ -638,6 +648,8 @@
|
||||
"folder-shared": "<svg viewBox='0 0 32 32'><path fill='#ab47bc' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#e1bee7' d='M28 26a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2H18a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h-4v2h18v-2Zm-5-6v-2l4 2.798L23 24v-2a4.12 4.12 0 0 0-4 2c.448-2.003.888-3.595 4-4'/></svg>",
|
||||
"folder-simulations-open": "<svg viewBox='0 0 32 32'><path fill='#ab47bc' d='M28.965 12H9.441a2 2 0 0 0-1.898 1.368L4 24V10h23.998a2 2 0 0 0-2-2H15.122a2 2 0 0 1-1.28-.464l-1.287-1.072A2 2 0 0 0 11.275 6H3.999a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h21.998l4.805-11.212A2 2 0 0 0 28.964 12'/><path fill='#e1bee7' d='m24.029 28.172-1.474-3.447c1.417-.523 2.733-1.225 3.97-2.044zm-6.749-8.723-3.448-1.466 5.501-2.493a18.6 18.6 0 0 0-2.053 3.96m14.383-9.1s-4.458-1.907-9.55 3.187c-1.974 1.97-3.154 4.14-3.914 6.04a1.79 1.79 0 0 0 .409 1.916l1.916 1.908c.5.504 1.237.666 1.906.414a17.2 17.2 0 0 0 6.046-3.914c5.093-5.095 3.187-9.55 3.187-9.55m-6.374 6.363a1.82 1.82 0 0 1 0-2.547 1.81 1.81 0 0 1 2.552 0 1.81 1.81 0 0 1 0 2.547 1.81 1.81 0 0 1-2.552 0m-5.093 6.364-1.26-1.27zm-2.371 4.923 3.278-3.276a2.8 2.8 0 0 1-.873-.406l-3.675 3.682zm-3.811 0h1.259l4.299-4.284-1.282-1.27-4.276 4.285zm0-2.548 3.675-3.671a2.6 2.6 0 0 1-.408-.874l-3.267 3.277z'/></svg>",
|
||||
"folder-simulations": "<svg viewBox='0 0 32 32'><path fill='#ab47bc' d='m13.843 7.537-1.287-1.073A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h23.998A2 2 0 0 0 30 24V10a2 2 0 0 0-2-2.001H15.122a2 2 0 0 1-1.28-.463'/><path fill='#e1bee7' d='m24.029 28.172-1.474-3.447c1.417-.523 2.733-1.225 3.97-2.044zm-6.749-8.723-3.448-1.466 5.501-2.493a18.6 18.6 0 0 0-2.053 3.96m14.383-9.1s-4.458-1.907-9.55 3.187c-1.974 1.97-3.154 4.14-3.914 6.04a1.79 1.79 0 0 0 .409 1.916l1.916 1.908c.5.504 1.237.666 1.906.414a17.2 17.2 0 0 0 6.046-3.914c5.093-5.095 3.187-9.55 3.187-9.55m-6.374 6.363a1.82 1.82 0 0 1 0-2.547 1.81 1.81 0 0 1 2.552 0 1.81 1.81 0 0 1 0 2.547 1.81 1.81 0 0 1-2.552 0m-5.093 6.364-1.26-1.27zm-2.371 4.923 3.278-3.276a2.8 2.8 0 0 1-.873-.406l-3.675 3.682zm-3.811 0h1.259l4.299-4.284-1.282-1.27-4.276 4.285zm0-2.548 3.675-3.671a2.6 2.6 0 0 1-.408-.874l-3.267 3.277z'/></svg>",
|
||||
"folder-skills-open": "<svg viewBox='0 0 32 32'><path fill='#ff8f00' d='M28.967 12H9.442a2 2 0 0 0-1.898 1.368L4 24V10h24a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464l-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.805-11.212A2 2 0 0 0 28.967 12'/><path fill='#ffecb3' d='M24 26v2h4v-2zm0-16-4 4v4l2 2v2l2 2h4l2-2v-2l2-2v-4l-4-4-2 2v2l-2 2h-2v-2l2-2h2l2-2z'/></svg>",
|
||||
"folder-skills": "<svg viewBox='0 0 32 32'><path fill='#ff8f00' d='m13.844 7.536-1.288-1.072A2 2 0 0 0 11.276 6H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2H15.124a2 2 0 0 1-1.28-.464'/><path fill='#ffecb3' d='M24 26v2h4v-2zm0-16-4 4v4l2 2v2l2 2h4l2-2v-2l2-2v-4l-4-4-2 2v2l-2 2h-2v-2l2-2h2l2-2z'/></svg>",
|
||||
"folder-snapcraft-open": "<svg viewBox='0 0 16 16'><path fill='#66bb6a' d='M14.033 6H4.597a.97.97 0 0 0-.918.684L2 12V5h11.566c0-.552-.433-1-.967-1H7.343a.95.95 0 0 1-.619-.232l-.622-.536A.95.95 0 0 0 5.483 3H1.967C1.433 3 1 3.448 1 4v8c0 .552.433 1 .967 1h10.632l2.323-5.606c.273-.66-.195-1.394-.889-1.394'/><path fill='#dcedc8' d='m12.538 7.077 2.077 1.038-2.077 2.077zM8.385 14l3.807-3.462-1.73-1.73zM7 5l5.192 5.192V7.077zm8.654 2.077-3.116-.346L16 8.46z'/></svg>",
|
||||
"folder-snapcraft": "<svg viewBox='0 0 16 16'><path fill='#66bb6a' d='m6.922 3.768-.644-.536A1 1 0 0 0 5.638 3H2a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H7.562a1 1 0 0 1-.64-.232'/><path fill='#dcedc8' d='m12.538 7.077 2.077 1.038-2.077 2.077zM8.385 14l3.807-3.462-1.73-1.73zM7 5l5.192 5.192V7.077zm8.654 2.077-3.116-.346L16 8.46z'/></svg>",
|
||||
"folder-snippet-open": "<svg viewBox='0 0 32 32'><path fill='#ff9800' d='M29 12H9.4a2 2 0 0 0-1.9 1.4L4 24V10h24a2 2 0 0 0-2-2H15.1a2 2 0 0 1-1.3-.5l-1.2-1a2 2 0 0 0-1.3-.5H4a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h22l4.8-11.2A2 2 0 0 0 29 12'/><path fill='#ffe0b2' d='M20 10s-2 1.86-2 4 6 8 6 8l-.89.88a3 3 0 0 0-5.1 2A3.01 3.01 0 0 0 20.87 28a3.02 3.02 0 0 0 3.11-3.24L26 23.5l.25.31A3.02 3.02 0 0 0 28.88 28 3.01 3.01 0 0 0 32 25.12a3.01 3.01 0 0 0-4.38-2.78zm10 0-4 8 2 2s4-3.94 4-6-2-4-2-4m-9.06 14h.1c.51.02.9.4.95.89v.2a.98.98 0 0 1-1.03.91.99.99 0 0 1-.96-1.04.98.98 0 0 1 .94-.96m8 0h.1c.56.02.98.48.96 1.04a.98.98 0 0 1-1.04.96.98.98 0 0 1-.96-1.04.98.98 0 0 1 .94-.96' style='-inkscape-stroke:none'/></svg>",
|
||||
@@ -808,6 +820,7 @@
|
||||
"image": "<svg viewBox='0 0 16 16'><path fill='#26a69a' d='M8.5 6h4l-4-4zM3.875 1H9.5l4 4v8.6c0 .773-.616 1.4-1.375 1.4h-8.25c-.76 0-1.375-.627-1.375-1.4V2.4c0-.777.612-1.4 1.375-1.4M4 13.6h8V8l-2.625 2.8L8 9.4zm1.25-7.7c-.76 0-1.375.627-1.375 1.4s.616 1.4 1.375 1.4c.76 0 1.375-.627 1.375-1.4S6.009 5.9 5.25 5.9'/></svg>",
|
||||
"imba": "<svg stroke-linejoin='round' stroke-miterlimit='1.414' clip-rule='evenodd' viewBox='0 0 201 201'><path fill='#ffc400' d='M161.96 61.952c-3.043 13.905-32.633 79.576-36.431 94.457-2.698 10.575 11.229 23.851 13.555 15.159 6.84-25.548 37.32-86.251 39.023-98.893 1.468-10.897-14.66-17.516-16.147-10.723m-37.128 48.192a4.97 4.97 0 0 1 5.726 6.91c.023.012.021.015.021.016a19.04 19.04 0 0 1-13.667 10.676c-3.4.645-7.236 1.182-11.504 1.588-15.316 1.453-31.743-17.007-20.624-16.49 16.552.77 29.747-.447 40.047-2.7zm16.256-17.347a13.36 13.36 0 0 1-9.677 8.152c-20.232 4.242-49.32 2.59-63.662-.888-13.94-3.38-23.102-23.665-14.05-20.64 21.019 7.024 60.118 9.347 82.248 6.838a4.808 4.808 0 0 1 5.133 6.523c.011.004.011.004.008.015m8.398-23.8a11.39 11.39 0 0 1-9.973 8.037c-40.633 2.924-92.83-6.466-107.91-22.019C20.273 43.326 21 20.85 27.442 27.992c24.417 27.072 84.437 34.865 117.12 34.521a5.022 5.022 0 0 1 4.92 6.481q.003.002.001.003z'/></svg>",
|
||||
"installation": "<svg viewBox='0 0 16 16'><path fill='#ff5722' d='M12 7h-2V2H6v5H4l4 4zm-9 5.5V14h10v-1.5z'/></svg>",
|
||||
"instructions.clone": "<svg fill='none' viewBox='0 0 24 24'><path d='M0 0h24v24H0z'/><path fill='#00b8d4' d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2m0 14H8V4h12zM10 9h8v2h-8zm0 3h4v2h-4zm0-6h8v2h-8z'/></svg>",
|
||||
"ionic": "<svg viewBox='0 0 512 512'><g fill='#448aff'><path d='M423.59 132.8a31.86 31.86 0 0 0 5.408-17.804c0-17.675-14.33-32-32-32a31.85 31.85 0 0 0-17.805 5.409c-34.486-25.394-77.085-40.409-123.2-40.409-114.88 0-208 93.125-208 208 0 114.88 93.125 208 208 208 114.87 0 208-93.123 208-208 0-46.111-15.016-88.71-40.408-123.2zm-31.762 259.03c-17.646 17.646-38.191 31.499-61.064 41.174-23.672 10.012-48.826 15.089-74.766 15.089s-51.095-5.077-74.767-15.089c-22.873-9.675-43.417-23.527-61.064-41.174s-31.5-38.191-41.174-61.064c-10.013-23.672-15.09-48.828-15.09-74.768s5.077-51.095 15.089-74.767c9.674-22.873 23.527-43.417 41.174-61.064s38.191-31.5 61.064-41.174c23.673-10.013 48.828-15.09 74.768-15.09s51.094 5.077 74.766 15.089a191.2 191.2 0 0 1 37.802 21.327 31.85 31.85 0 0 0-3.568 14.679c0 17.675 14.327 32 32 32 5.293 0 10.28-1.293 14.678-3.568a191 191 0 0 1 21.327 37.801c10.013 23.672 15.09 48.827 15.09 74.767s-5.077 51.096-15.09 74.768c-9.675 22.873-23.527 43.418-41.175 61.064'/><circle cx='256' cy='256' r='96'/></g></svg>",
|
||||
"istanbul": "<svg viewBox='0 0 32 32'><path fill='#fdd835' d='M30 13v-3h-2v3h-1v.5a.5.5 0 0 0 .5.5h.5v10h-1v-2h-1v-8h-1v6h-2v-3h-1v1h-1v-1h1a6.35 6.35 0 0 0-6-4 6.35 6.35 0 0 0-6 4h1v1h-1v-1H9v3H7v-6H6v8H5v2H4V14h.5a.5.5 0 0 0 .5-.5V13H4v-3H2v3H1v.5a.5.5 0 0 0 .5.5H2v12h8v-6h2v6h8v-6h2v6h8V14h.5a.5.5 0 0 0 .5-.5V13ZM14 24h-1v-2h1Zm3 0h-2v-2a1 1 0 0 1 2 0Zm2 0h-1v-2h1Zm-1-7v1h-1v-1Zm-3 0v1h-1v-1Zm-3 0h1v1h-1Zm7 1v-1h1v1ZM3 6 2 9h2zm26 0-1 3h2z'/><path fill='#fdd835' d='m16 10-1 2h2zm9.5 1-.5 2h1zm-19 0L6 13h1z'/></svg>",
|
||||
"jar": "<svg viewBox='0 0 32 32'><path fill='#f44336' d='M22 10h2v4h-2z'/><path fill='#f44336' d='M28 2H4a2 2 0 0 0-2 2v24a2 2 0 0 0 2 2h24a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2m-2 12a2 2 0 0 1-2 2h-2v4a4 4 0 0 1-4 4h-8a4 4 0 0 1-4-4V8h18a2 2 0 0 1 2 2Z'/></svg>",
|
||||
@@ -821,6 +834,7 @@
|
||||
"jinja_light": "<svg viewBox='0 0 32 32'><path fill='#616161' d='M30 8V4a94.4 94.4 0 0 1-14 1A94.4 94.4 0 0 1 2 4v4s1.482.247 3.95.495L5.4 14H2v2h3.2L4 28h6V16h12v12h6l-1.2-12H30v-2h-3.4l-.55-5.505C28.517 8.247 30 8 30 8m-20 6V8.817c1.235.074 2.576.13 4 .16V14Zm12 0h-4V8.977a104 104 0 0 0 4-.16Z'/></svg>",
|
||||
"jsconfig": "<svg viewBox='0 0 32 32'><path fill='#757575' d='M15 2H6a2.006 2.006 0 0 0-2 2v22a2.006 2.006 0 0 0 2 2h6v-4H6v-2h6v-2H6v-2h6v-2H6v-2h6v-2h2V4l8 8h2v-1Z' data-mit-no-recolor='true'/><path fill='#ffca28' d='M12 12v18h18V12zm8 12a2.006 2.006 0 0 1-2 2h-2a2.006 2.006 0 0 1-2-2v-2h2v2h2v-8h2zm8-6h-4v2h2a2.006 2.006 0 0 1 2 2v2a2.006 2.006 0 0 1-2 2h-4v-2h4v-2h-2a2.006 2.006 0 0 1-2-2v-2a2.006 2.006 0 0 1 2-2h4z'/></svg>",
|
||||
"json": "<svg viewBox='0 -960 960 960'><path fill='#f9a825' d='M560-160v-80h120q17 0 28.5-11.5T720-280v-80q0-38 22-69t58-44v-14q-36-13-58-44t-22-69v-80q0-17-11.5-28.5T680-720H560v-80h120q50 0 85 35t35 85v80q0 17 11.5 28.5T840-560h40v160h-40q-17 0-28.5 11.5T800-360v80q0 50-35 85t-85 35zm-280 0q-50 0-85-35t-35-85v-80q0-17-11.5-28.5T120-400H80v-160h40q17 0 28.5-11.5T160-600v-80q0-50 35-85t85-35h120v80H280q-17 0-28.5 11.5T240-680v80q0 38-22 69t-58 44v14q36 13 58 44t22 69v80q0 17 11.5 28.5T280-240h120v80z'/></svg>",
|
||||
"json_schema": "<svg viewBox='0 -960 960 960'><path fill='#f9a825' d='M560-160v-80h120q17 0 28.5-11.5T720-280v-80q0-38 22-69t58-44v-14q-36-13-58-44t-22-69v-80q0-17-11.5-28.5T680-720H560v-80h120q50 0 85 35t35 85v80q0 17 11.5 28.5T840-560h40v160h-40q-17 0-28.5 11.5T800-360v80q0 50-35 85t-85 35zm-280 0q-50 0-85-35t-35-85v-80q0-17-11.5-28.5T120-400H80v-160h40q17 0 28.5-11.5T160-600v-80q0-50 35-85t85-35h120v80H280q-17 0-28.5 11.5T240-680v80q0 38-22 69t-58 44v14q36 13 58 44t22 69v80q0 17 11.5 28.5T280-240h120v80z'/><path fill='#f9a825' stroke='#f9a825' stroke-width='36.192' d='M581.79-570.48 446.07-434.76l-67.859-67.859-22.62 22.62 90.479 90.479 158.34-158.34z'/></svg>",
|
||||
"jsr": "<svg viewBox='0 0 16 16'><path fill='#fdd835' d='M2 7h1v2h1V5h1v5H2m4-5h4v1H7v1.5h3V11H6v-1h3V8.5H6M11 6h3v2.5h-1V7h-1v4h-1'/></svg>",
|
||||
"jsr_light": "<svg viewBox='0 0 16 16'><path fill='#37474f' d='M1 6h2V4h8v1h4v5h-2v2H5v-1H1'/><path fill='#fdd835' d='M2 7h1v2h1V5h1v5H2m4-5h4v1H7v1.5h3V11H6v-1h3V8.5H6M11 6h3v2.5h-1V7h-1v4h-1'/></svg>",
|
||||
"julia": "<svg viewBox='0 0 50 50'><g transform='translate(.21 -247.01)'><circle cx='13.497' cy='281.63' r='9.555' fill='#c62828'/><circle cx='36.081' cy='281.63' r='9.555' fill='#7e57c2'/><circle cx='24.722' cy='262.39' r='9.555' fill='#388e3c'/></g></svg>",
|
||||
@@ -1024,6 +1038,7 @@
|
||||
"robots": "<svg viewBox='0 0 32 32'><path fill='#ff5252' d='M28.586 18H28a8 8 0 0 0-8-8h-2V8.445a4 4 0 1 0-4 0V10h-2a8 8 0 0 0-8 8h-.586A1.414 1.414 0 0 0 2 19.414v3.172A1.414 1.414 0 0 0 3.414 24H4v1a3 3 0 0 0 3 3h18a3 3 0 0 0 3-3v-1h.586A1.414 1.414 0 0 0 30 22.586v-3.172A1.414 1.414 0 0 0 28.586 18M11 22a3 3 0 1 1 3-3 3 3 0 0 1-3 3m10 0a3 3 0 1 1 3-3 3 3 0 0 1-3 3'/></svg>",
|
||||
"rocket": "<svg viewBox='0 0 32 32'><path fill='#ef5350' d='M12 26c-1.71 1.905-7.64 2.149-7.93 1.937l-.004.003-.002-.005-.005-.002.004-.003C3.85 27.64 4.1 21.715 6 20ZM29.64 7.908c-.655 2.69-1.681 5.64-5.64 10.092l-.789 4.749a4 4 0 0 1-1.116 2.171l-4.863 4.868A.72.72 0 0 1 16 29.277v-6.23L9 16H2.723a.721.721 0 0 1-.511-1.232L7.08 9.905A4 4 0 0 1 9.25 8.79L14 8c4.453-3.959 7.402-4.985 10.092-5.64a11.1 11.1 0 0 1 3.642-.329 3.1 3.1 0 0 1 1.72.515 3.1 3.1 0 0 1 .515 1.72 11.1 11.1 0 0 1-.33 3.642ZM26 10a4 4 0 1 0-4 4 4 4 0 0 0 4-4'/></svg>",
|
||||
"rojo": "<svg fill='none' viewBox='0 0 24 24'><path fill='#e53935' d='M9.586 2h.077l-.077.135v.29c.598-.116.908-.27.908-.425l.425.058A36 36 0 0 1 12.869 2h.077c.927 0 2.009.502 3.284 1.526.27.444.424.83.502 1.197v.695c-.155.966-.425 1.7-.773 2.183q-.319.26-1.39 1.738h-.078v-.135l.194-.29h-.116a17.6 17.6 0 0 1-5.601 3.226 6.2 6.2 0 0 1-1.545.212c.656.772 1.873 1.796 3.63 3.07.174.097 1.295.812 3.361 2.183 1.719 1.062 3.766 2.221 6.161 3.496v.077h-.29c-.463-.174-.695-.309-.695-.367l-.135.077h-.135c-.058 0-.078-.019-.078-.077-.173.039-.309.213-.424.502.29.078.424.174.424.27-.115.097-.193.155-.27.155l-.348-.077v.077c0 .078.058.135.194.135v.213h-.058c-.097 0-1.16-.618-3.148-1.835-1.41-.715-3.149-1.815-5.176-3.283-.676-.31-1.912-1.217-3.728-2.723h-.193c-.27.405-.618 1.41-1.062 3.013-.097.367-.56.907-1.39 1.602h-.155l-.135-.212v-.077c0-.097.077-.31.212-.618v-.077h-.077c0 .135-.29.347-.83.637H3v-.135c1.642-4.867 2.781-8.035 3.438-9.522q1.68-3.852 1.68-4.403c-.251 0-.811.309-1.68.965h-.135l.058-.135v-.135c-.252 0-.831.406-1.739 1.255h-.077v-.077l.908-1.043.154-.212v-.077h-.154l-.83.695c-.097 0-.136-.039-.136-.116A11.1 11.1 0 0 1 7.693 3.12c1.178-.309 1.758-.656 1.758-1.062zm6.373 1.95v.078c0 .077.058.135.135.135v-.077c0-.077-.038-.135-.135-.135M7.77 10.673h.058c.85-.174 1.275-.31 1.275-.425-.058-.097-.077-.155-.077-.213C10.803 9.436 12 8.837 12.599 8.22c.058 0 .425-.386 1.12-1.198h.077V7.1c-.096.154-.154.27-.154.347h.077c.599-.463.908-.965.908-1.525v-.425c-.136 0-.213-.058-.213-.155q.348-.057.348-.347 0-.348-1.39-.696c-.754-.193-1.565-.27-2.453-.27-.445 0-.889.811-1.333 2.453-.193.193-.792 1.583-1.816 4.19m.83-5.949V4.8c.078 0 .136-.077.213-.212v-.077c-.058 0-.135.077-.212.212m.078 1.333h.077c.136-.058.213-.193.213-.425-.077 0-.174.135-.29.425m6.586.27v.155c.058 0 .135-.078.193-.213v-.077H15.4c-.096.02-.135.058-.135.135m-7.57 4.693v.078h.134a.5.5 0 0 1 .213-.078v.078c1.14-.213 1.815-.445 2.047-.696h-.077c-1.024.232-1.796.444-2.318.618m-.271.696h.058l1.274-.27-.077-.136c-.83.097-1.255.251-1.255.406m2.78 4.345v.135c.735.56 1.179.85 1.334.85-.174-.135-.27-.251-.27-.348zm2.048 1.545c.039.174.174.27.406.27h.077v-.077c-.116 0-.251-.058-.425-.193zm4.539 2.51q.55.495 1.68.986l.077-.135c-.58-.348-1.12-.638-1.603-.85zm3.862 1.121h.213c.077.02.135.058.135.135-.097 0-.135.078-.135.213h-.155l.078-.136v-.077h-.136z'/></svg>",
|
||||
"rolldown": "<svg fill='none' viewBox='0 0 16 16'><path fill='#f4511e' d='M13.628 1c.3 0 .465.35.272.582l-3.277 3.933c-.385.462-.229 1.485.374 1.485h3.644c.301 0 .465.35.273.582l-6.645 7.29a.355.355 0 0 1-.545 0l-6.64-7.29A.355.355 0 0 1 1.355 7h3.64c.602 0 .759-1.023.373-1.485L2.092 1.582A.355.355 0 0 1 2.364 1z'/></svg>",
|
||||
"rollup": "<svg viewBox='100 100 800 800'><path fill='#f44336' d='M733.79 394.71c0 77.407-42.308 144.79-104.67 180.51-3.76 3.134-5.954 8.148-3.76 12.849l106.87 211.22c2.82 6.581-1.568 14.103-8.776 14.103h-408.35l2.194-1.254c15.356-8.774 121.91-219.06 225.95-318.72 104.05-99.658 117.21-66.439 59.857-174.87 0 0 44.188 86.182 6.581 92.763-29.459 5.328-97.15-60.17-72.08-119.09 25.071-57.664 123.79-46.695 169.23.314 17.236 30.085 26.952 64.872 26.952 102.17m-385.47 140.71c-41.367 76.154-67.692 131.62-82.108 170.48v-509.57c0-5.328 4.388-9.715 9.715-9.715h252.91c73.333 1.253 137.58 40.114 173.62 98.718-26.325-32.906-67.692-51.71-108.43-51.71-77.407 0-96.837 28.206-245.7 301.79z'/></svg>",
|
||||
"rome": "<svg viewBox='0 0 32 32'><path fill='#546e7a' d='M9.875 5.409A14.02 14.02 0 0 0 2.01 17.48a.51.51 0 0 0 .508.519H5.52a.495.495 0 0 0 .491-.481 10.01 10.01 0 0 1 5.273-8.337.494.494 0 0 0 .243-.592l-.958-2.882a.505.505 0 0 0-.694-.3Zm11.556.299-.958 2.882a.494.494 0 0 0 .243.592 10.01 10.01 0 0 1 5.273 8.337.495.495 0 0 0 .49.481h3.004a.51.51 0 0 0 .508-.519A14.02 14.02 0 0 0 22.125 5.41a.505.505 0 0 0-.694.299ZM26 20.5v9a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-9a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5m-24 0v9a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-9a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 0-.5.5'/><path fill='#ffc400' d='M16.13 10h-.26A7.87 7.87 0 0 0 8 17.87V29.5a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5V17.87A3.88 3.88 0 0 1 15.87 14h.26A3.88 3.88 0 0 1 20 17.87V29.5a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5V17.87A7.87 7.87 0 0 0 16.13 10m1.51-2h-3.28a.5.5 0 0 1-.474-.342l-1.667-5A.5.5 0 0 1 12.694 2h6.612a.5.5 0 0 1 .475.658l-1.667 5A.5.5 0 0 1 17.64 8'/></svg>",
|
||||
"routing": "<svg viewBox='0 0 32 32'><path fill='#43a047' d='M18 14v-2h8l2-3-2-3h-8V4l-2-2-2 2v6H6l-2 3 2 3h8v10a4 4 0 0 0-4 4h12a4 4 0 0 0-4-4v-6h8l2-3-2-3Z'/></svg>",
|
||||
@@ -1060,6 +1075,7 @@
|
||||
"simulink": "<svg viewBox='0 0 4.233 4.233'><path fill='#9e9e9e' d='M.53 1.323v.264h2.38v.794h.265V1.323z'/><path fill='#ff6e40' d='M2.381 2.381h1.323v1.323H2.381z'/><path fill='#64b5f6' d='m2.381 1.455-1.587.926V.53z'/></svg>",
|
||||
"siyuan": "<svg viewBox='0 0 32 32'><path fill='#e53935' d='M2 11.976 10 4v16l-8 8Z'/><path fill='#455a64' d='M30 11.976 22 4v15.99L30 28ZM10 4l6 6v16l-6-6Z'/><path fill='#e53935' d='m22 4-6 6v16l6-6.01Z'/></svg>",
|
||||
"sketch": "<svg viewBox='0 0 24 24'><path fill='#ffc107' d='M15.705 9.221h2.779l-4.632 6.484m-3.705-6.484h3.705L12 16.631m-6.484-7.41h2.779l1.852 6.484M14.78 4.59h1.852l1.853 2.779h-2.78m-4.63-2.779h1.852l.926 2.779h-3.705M7.368 4.59h1.853l-.926 2.78h-2.78m.927-4.631L2.737 8.294 12 21.263l9.262-12.968-3.705-5.557z'/></svg>",
|
||||
"skill": "<svg viewBox='0 0 16 16'><path fill='#ff8f00' d='M6 12v1h4v-1zm1 2v1h2v-1zM7 1 5 2 4 4v2l1 2 1 1v1l1 1h2l1-1V9l1-1 1-2V4l-1-2-2-1v2L7 5H6V4l2-2h1v1-2z'/></svg>",
|
||||
"slim": "<svg viewBox='0 0 32 32'><path fill='#f57f17' d='M23 2H9a7 7 0 0 0-7 7v14a7 7 0 0 0 7 7h14a7 7 0 0 0 7-7V9a7 7 0 0 0-7-7m-5 14-4-6v6H6a10 10 0 0 1 20 0Z'/></svg>",
|
||||
"slint": "<svg viewBox='0 0 16 16'><path fill='#2979ff' d='M12 1 3 7l5 2-2-2Z'/><path fill='#2979ff' d='m4 15 9-6-5-2 2 2Z'/></svg>",
|
||||
"slug": "<svg viewBox='0 0 24 24'><path fill='#f9a825' d='m9.164 21.221-.983-.056c-3.402-.19-5.654-.714-6.125-1.427-.136-.205-.146-.515-.022-.681.115-.154.377-.28.744-.355l.313-.064.373.122c1.568.517 2.903.589 4.875.263.82-.135 1.26-.29 1.736-.613.183-.124.26-.152.413-.152.62-.002 1.581-.168 2.066-.357 1.392-.544 2.655-2.023 2.979-3.49.159-.717.072-1.83-.211-2.693l-.13-.397.028-.747c.023-.606.047-.818.126-1.123.29-1.108.991-1.878 1.957-2.145.374-.103 1.17-.093 1.589.02a3.34 3.34 0 0 1 1.595.941c.505.548.707 1.025.735 1.738.021.55-.034.809-.283 1.316-.211.43-.542.833-.909 1.107-.15.113-.302.23-.336.26-.052.046-.067.192-.087.837-.014.43-.053.986-.086 1.235-.458 3.354-2.234 5.421-5.307 6.174-1.023.25-1.37.283-3.183.292-.908.005-1.748.002-1.867-.005m-3.967-2.877-.45-.07-.3-.322c-1.514-1.613-2.085-4.002-1.43-5.98.646-1.953 2.32-3.39 4.496-3.86.557-.121 1.912-.133 2.437-.023a6.7 6.7 0 0 1 1.631.56c1.828.904 2.982 2.495 3.205 4.421.111.955-.13 1.793-.763 2.651-.712.966-1.618 1.525-2.681 1.654l-.233.028.267-.277c.475-.495.596-.93.596-2.15 0-.683-.011-.831-.087-1.134-.182-.721-.476-1.239-.967-1.705-.643-.611-1.44-.923-2.349-.92-1.295.005-2.196.828-2.196 2.006 0 .398.069.695.24 1.033.135.269.446.62.68.769.368.233.984.35 1.195.225a.387.387 0 0 0 .096-.61c-.09-.101-.15-.126-.364-.154-.337-.043-.437-.086-.642-.275-.26-.239-.395-.57-.397-.964-.002-.269.014-.348.11-.543.133-.27.396-.497.703-.603.327-.114.98-.096 1.386.038.854.281 1.456.918 1.699 1.797.054.196.07.401.07.903 0 .57-.011.683-.092.941-.103.327-.31.758-.488 1.019-.295.429-.853.927-1.283 1.144-.691.348-2.98.573-4.09.4zM19.199 6.578l-.244-.078.14-.4c.537-1.544 1.334-2.521 2.057-2.521.567 0 1.043.588.862 1.067-.045.12-.244.345-.37.419-.044.025-.31.054-.597.065-.497.019-.524.024-.688.139-.221.154-.503.575-.69 1.03-.081.2-.166.361-.188.36a3 3 0 0 1-.282-.081m-2.185-.06c-.068-.115-.127-.837-.126-1.545.001-.639.015-.863.07-1.08.194-.765.529-1.121 1.055-1.121.588 0 .932.42.782.957-.072.258-.183.365-.591.568-.312.155-.394.216-.496.369-.176.262-.228.59-.2 1.253l.023.538-.165.027c-.09.014-.202.035-.249.047s-.092.006-.103-.012z'/></svg>",
|
||||
|
||||
@@ -213,6 +213,9 @@
|
||||
"editor.buttons.switch_to_legacy.tooltip": "Use the legacy editor instead",
|
||||
"editor.buttons.enable_monospace_font": "Enable monospace font",
|
||||
"editor.buttons.disable_monospace_font": "Disable monospace font",
|
||||
"editor.code_editor.command_palette": "Command Palette",
|
||||
"editor.code_editor.find": "Find",
|
||||
"editor.code_editor.placeholder": "Enter file content here",
|
||||
"filter.string.asc": "A–Z",
|
||||
"filter.string.desc": "Z–A",
|
||||
"error.occurred": "An error occurred",
|
||||
@@ -2250,13 +2253,14 @@
|
||||
"repo.settings.webhook.delivery.success": "An event has been added to the delivery queue. It may take few seconds before it shows up in the delivery history.",
|
||||
"repo.settings.githooks_desc": "Git Hooks are powered by Git itself. You can edit hook files below to set up custom operations.",
|
||||
"repo.settings.githook_edit_desc": "If the hook is inactive, sample content will be presented. Leaving content to an empty value will disable this hook.",
|
||||
"repo.settings.githook_name": "Hook Name",
|
||||
"repo.settings.githook_content": "Hook Content",
|
||||
"repo.settings.update_githook": "Update Hook",
|
||||
"repo.settings.add_webhook_desc": "Gitea will send <code>POST</code> requests with a specified content type to the target URL. Read more in the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"%s\">webhooks guide</a>.",
|
||||
"repo.settings.payload_url": "Target URL",
|
||||
"repo.settings.http_method": "HTTP Method",
|
||||
"repo.settings.content_type": "POST Content Type",
|
||||
"repo.settings.webhook.name": "Webhook name",
|
||||
"repo.settings.webhook.name_helper": "Optionally give this webhook a friendly name",
|
||||
"repo.settings.webhook.name_empty": "Unnamed Webhook",
|
||||
"repo.settings.secret": "Secret",
|
||||
"repo.settings.webhook_secret_desc": "If the webhook server supports using secret, you can follow the webhook's manual and fill in a secret here.",
|
||||
"repo.settings.slack_username": "Username",
|
||||
@@ -2778,9 +2782,9 @@
|
||||
"org.settings.labels_desc": "Add labels which can be used on issues for <strong>all repositories</strong> under this organization.",
|
||||
"org.members.membership_visibility": "Membership Visibility:",
|
||||
"org.members.public": "Visible",
|
||||
"org.members.public_helper": "make hidden",
|
||||
"org.members.public_helper": "Make hidden",
|
||||
"org.members.private": "Hidden",
|
||||
"org.members.private_helper": "make visible",
|
||||
"org.members.private_helper": "Make visible",
|
||||
"org.members.member_role": "Member Role:",
|
||||
"org.members.owner": "Owner",
|
||||
"org.members.member": "Member",
|
||||
@@ -2808,7 +2812,10 @@
|
||||
"org.teams.no_desc": "This team has no description",
|
||||
"org.teams.settings": "Settings",
|
||||
"org.teams.owners_permission_desc": "Owners have full access to <strong>all repositories</strong> and have <strong>administrator access</strong> to the organization.",
|
||||
"org.teams.owners_permission_suggestion": "You can create new teams for members to get fine-grained access control.",
|
||||
"org.teams.members": "Team Members",
|
||||
"org.teams.manage_team_member": "Manage teams and members",
|
||||
"org.teams.manage_team_member_prompt": "Members are managed through teams. Add users to a team to invite them to this organization.",
|
||||
"org.teams.update_settings": "Update Settings",
|
||||
"org.teams.delete_team": "Delete Team",
|
||||
"org.teams.add_team_member": "Add Team Member",
|
||||
@@ -3715,6 +3722,8 @@
|
||||
"actions.runs.workflow_run_count_1": "%d workflow run",
|
||||
"actions.runs.workflow_run_count_n": "%d workflow runs",
|
||||
"actions.runs.commit": "Commit",
|
||||
"actions.runs.run_details": "Run Details",
|
||||
"actions.runs.workflow_file": "Workflow file",
|
||||
"actions.runs.scheduled": "Scheduled",
|
||||
"actions.runs.pushed_by": "pushed by",
|
||||
"actions.runs.invalid_workflow_helper": "Workflow config file is invalid. Please check your config file: %s",
|
||||
|
||||
+36
-26
@@ -2,7 +2,7 @@
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@10.33.0",
|
||||
"engines": {
|
||||
"node": ">= 22.6.0",
|
||||
"node": ">= 22.18.0",
|
||||
"pnpm": ">= 10.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -10,44 +10,56 @@
|
||||
"@citation-js/plugin-bibtex": "0.7.21",
|
||||
"@citation-js/plugin-csl": "0.7.22",
|
||||
"@citation-js/plugin-software-formats": "0.6.2",
|
||||
"@codemirror/autocomplete": "6.20.1",
|
||||
"@codemirror/commands": "6.10.3",
|
||||
"@codemirror/lang-json": "6.0.2",
|
||||
"@codemirror/lang-markdown": "6.5.0",
|
||||
"@codemirror/language": "6.12.3",
|
||||
"@codemirror/language-data": "6.5.2",
|
||||
"@codemirror/legacy-modes": "6.5.2",
|
||||
"@codemirror/lint": "6.9.5",
|
||||
"@codemirror/search": "6.6.0",
|
||||
"@codemirror/state": "6.6.0",
|
||||
"@codemirror/view": "6.41.0",
|
||||
"@github/markdown-toolbar-element": "2.2.3",
|
||||
"@github/paste-markdown": "1.5.3",
|
||||
"@github/text-expander-element": "2.9.4",
|
||||
"@lezer/highlight": "1.2.3",
|
||||
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
|
||||
"@mermaid-js/layout-elk": "0.2.1",
|
||||
"@primer/octicons": "19.23.1",
|
||||
"@replit/codemirror-indentation-markers": "6.5.3",
|
||||
"@replit/codemirror-lang-nix": "6.0.1",
|
||||
"@replit/codemirror-lang-svelte": "6.0.0",
|
||||
"@replit/codemirror-vscode-keymap": "6.0.2",
|
||||
"@resvg/resvg-wasm": "2.6.2",
|
||||
"@silverwind/vue3-calendar-heatmap": "2.1.1",
|
||||
"@techknowlogick/license-checker-webpack-plugin": "0.3.0",
|
||||
"add-asset-webpack-plugin": "3.1.1",
|
||||
"@vitejs/plugin-vue": "6.0.5",
|
||||
"ansi_up": "6.0.6",
|
||||
"asciinema-player": "3.15.1",
|
||||
"chart.js": "4.5.1",
|
||||
"chartjs-adapter-dayjs-4": "1.0.4",
|
||||
"chartjs-plugin-zoom": "2.2.0",
|
||||
"clippie": "4.1.10",
|
||||
"codemirror-lang-elixir": "4.0.1",
|
||||
"colord": "2.9.3",
|
||||
"compare-versions": "6.1.1",
|
||||
"cropperjs": "1.6.2",
|
||||
"css-loader": "7.1.4",
|
||||
"dayjs": "1.11.20",
|
||||
"dropzone": "6.0.0-beta.2",
|
||||
"easymde": "2.20.0",
|
||||
"esbuild-loader": "4.4.2",
|
||||
"esbuild": "0.27.4",
|
||||
"htmx.org": "2.0.8",
|
||||
"idiomorph": "0.7.4",
|
||||
"jquery": "4.0.0",
|
||||
"js-yaml": "4.1.1",
|
||||
"katex": "0.16.43",
|
||||
"mermaid": "11.13.0",
|
||||
"mini-css-extract-plugin": "2.10.2",
|
||||
"monaco-editor": "0.55.1",
|
||||
"monaco-editor-webpack-plugin": "7.1.1",
|
||||
"katex": "0.16.44",
|
||||
"mermaid": "11.14.0",
|
||||
"online-3d-viewer": "0.18.0",
|
||||
"pdfobject": "2.3.1",
|
||||
"perfect-debounce": "2.1.0",
|
||||
"postcss": "8.5.8",
|
||||
"postcss-loader": "8.2.1",
|
||||
"rollup-plugin-license": "3.7.0",
|
||||
"sortablejs": "1.15.7",
|
||||
"swagger-ui-dist": "5.32.1",
|
||||
"tailwindcss": "3.4.19",
|
||||
@@ -57,20 +69,19 @@
|
||||
"tributejs": "5.1.3",
|
||||
"uint8-to-base64": "0.2.1",
|
||||
"vanilla-colorful": "0.7.2",
|
||||
"vite": "8.0.3",
|
||||
"vite-string-plugin": "2.0.2",
|
||||
"vue": "3.5.31",
|
||||
"vue-bar-graph": "2.2.0",
|
||||
"vue-chartjs": "5.3.3",
|
||||
"vue-loader": "17.4.2",
|
||||
"webpack": "5.105.4",
|
||||
"webpack-cli": "7.0.2",
|
||||
"wrap-ansi": "10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "4.7.1",
|
||||
"@eslint/json": "1.2.0",
|
||||
"@playwright/test": "1.58.2",
|
||||
"@playwright/test": "1.59.0",
|
||||
"@stylistic/eslint-plugin": "5.10.0",
|
||||
"@stylistic/stylelint-plugin": "5.0.1",
|
||||
"@stylistic/stylelint-plugin": "5.1.0",
|
||||
"@types/codemirror": "5.60.17",
|
||||
"@types/dropzone": "5.7.9",
|
||||
"@types/jquery": "4.0.0",
|
||||
@@ -82,27 +93,27 @@
|
||||
"@types/swagger-ui-dist": "3.30.6",
|
||||
"@types/throttle-debounce": "5.0.2",
|
||||
"@types/toastify-js": "1.12.4",
|
||||
"@typescript-eslint/parser": "8.57.2",
|
||||
"@typescript-eslint/parser": "8.58.0",
|
||||
"@vitejs/plugin-vue": "6.0.5",
|
||||
"@vitest/eslint-plugin": "1.6.13",
|
||||
"@vitest/eslint-plugin": "1.6.14",
|
||||
"eslint": "10.1.0",
|
||||
"eslint-import-resolver-typescript": "4.4.4",
|
||||
"eslint-plugin-array-func": "5.1.1",
|
||||
"eslint-plugin-github": "6.0.0",
|
||||
"eslint-plugin-de-morgan": "2.1.1",
|
||||
"eslint-plugin-github": "6.0.0",
|
||||
"eslint-plugin-import-x": "4.16.2",
|
||||
"eslint-plugin-playwright": "2.10.1",
|
||||
"eslint-plugin-regexp": "3.1.0",
|
||||
"eslint-plugin-sonarjs": "4.0.2",
|
||||
"eslint-plugin-unicorn": "63.0.0",
|
||||
"eslint-plugin-unicorn": "64.0.0",
|
||||
"eslint-plugin-vue": "10.8.0",
|
||||
"eslint-plugin-vue-scoped-css": "3.0.0",
|
||||
"eslint-plugin-wc": "3.1.0",
|
||||
"globals": "17.4.0",
|
||||
"happy-dom": "20.8.8",
|
||||
"happy-dom": "20.8.9",
|
||||
"jiti": "2.6.1",
|
||||
"markdownlint-cli": "0.48.0",
|
||||
"material-icon-theme": "5.32.0",
|
||||
"material-icon-theme": "5.33.1",
|
||||
"nolyfill": "1.0.44",
|
||||
"postcss-html": "1.8.1",
|
||||
"spectral-cli-bundle": "1.0.7",
|
||||
@@ -112,10 +123,9 @@
|
||||
"stylelint-declaration-strict-value": "1.11.1",
|
||||
"stylelint-value-no-unknown-custom-properties": "6.1.1",
|
||||
"svgo": "4.0.1",
|
||||
"typescript": "5.9.3",
|
||||
"typescript-eslint": "8.57.2",
|
||||
"updates": "17.12.0",
|
||||
"vite-string-plugin": "2.0.2",
|
||||
"typescript": "6.0.2",
|
||||
"typescript-eslint": "8.58.0",
|
||||
"updates": "17.13.1",
|
||||
"vitest": "4.1.2",
|
||||
"vue-tsc": "3.2.6"
|
||||
},
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
import {env} from 'node:process';
|
||||
import {defineConfig, devices} from '@playwright/test';
|
||||
|
||||
const timeoutFactor = Number(env.GITEA_TEST_E2E_TIMEOUT_FACTOR) || 1;
|
||||
const timeout = 5000 * timeoutFactor;
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './tests/e2e/',
|
||||
outputDir: './tests/e2e-output/',
|
||||
testMatch: /.*\.test\.ts/,
|
||||
forbidOnly: Boolean(env.CI),
|
||||
reporter: 'list',
|
||||
timeout: env.CI ? 12000 : 6000,
|
||||
timeout: 2 * timeout,
|
||||
expect: {
|
||||
timeout: env.CI ? 6000 : 3000,
|
||||
timeout,
|
||||
},
|
||||
use: {
|
||||
baseURL: env.GITEA_TEST_E2E_URL?.replace?.(/\/$/g, ''),
|
||||
baseURL: env.GITEA_TEST_E2E_URL?.replace?.(/\/$/, ''),
|
||||
locale: 'en-US',
|
||||
actionTimeout: env.CI ? 6000 : 3000,
|
||||
navigationTimeout: env.CI ? 12000 : 6000,
|
||||
actionTimeout: timeout,
|
||||
navigationTimeout: 2 * timeout,
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
|
||||
Generated
+1361
-1276
File diff suppressed because it is too large.
Load diff
@@ -169,7 +169,7 @@ func UploadPackage(ctx *context.Context) {
|
||||
canWrite := repo.OwnerID == ctx.Doer.ID
|
||||
|
||||
if !canWrite {
|
||||
perms, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
perms, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
return
|
||||
|
||||
@@ -40,7 +40,7 @@ func ListRunners(ctx *context.APIContext) {
|
||||
// required: false
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunnersResponse"
|
||||
// "$ref": "#/responses/RunnerList"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
@@ -63,7 +63,7 @@ func GetRunner(ctx *context.APIContext) {
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunner"
|
||||
// "$ref": "#/responses/Runner"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
@@ -115,7 +115,7 @@ func UpdateRunner(ctx *context.APIContext) {
|
||||
// "$ref": "#/definitions/EditActionRunnerOption"
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunner"
|
||||
// "$ref": "#/responses/Runner"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
|
||||
@@ -11,11 +11,9 @@
|
||||
//
|
||||
// Consumes:
|
||||
// - application/json
|
||||
// - text/plain
|
||||
//
|
||||
// Produces:
|
||||
// - application/json
|
||||
// - text/html
|
||||
//
|
||||
// Security:
|
||||
// - BasicAuth :
|
||||
@@ -202,7 +200,7 @@ func repoAssignment() func(ctx *context.APIContext) {
|
||||
if needTwoFactor {
|
||||
ctx.Repo.Permission = access_model.PermissionNoAccess()
|
||||
} else {
|
||||
ctx.Repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
ctx.Repo.Permission, err = access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
@@ -492,7 +492,7 @@ func (Action) ListRunners(ctx *context.APIContext) {
|
||||
// required: false
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunnersResponse"
|
||||
// "$ref": "#/responses/RunnerList"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
@@ -520,7 +520,7 @@ func (Action) GetRunner(ctx *context.APIContext) {
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunner"
|
||||
// "$ref": "#/responses/Runner"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
@@ -582,7 +582,7 @@ func (Action) UpdateRunner(ctx *context.APIContext) {
|
||||
// "$ref": "#/definitions/EditActionRunnerOption"
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunner"
|
||||
// "$ref": "#/responses/Runner"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
|
||||
@@ -576,7 +576,7 @@ func GetTeamRepos(ctx *context.APIContext) {
|
||||
}
|
||||
repos := make([]*api.Repository, len(teamRepos))
|
||||
for i, repo := range teamRepos {
|
||||
permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
@@ -628,7 +628,7 @@ func GetTeamRepo(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
@@ -561,7 +561,7 @@ func (Action) ListRunners(ctx *context.APIContext) {
|
||||
// required: false
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunnersResponse"
|
||||
// "$ref": "#/responses/RunnerList"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
@@ -594,7 +594,7 @@ func (Action) GetRunner(ctx *context.APIContext) {
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunner"
|
||||
// "$ref": "#/responses/Runner"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
@@ -666,7 +666,7 @@ func (Action) UpdateRunner(ctx *context.APIContext) {
|
||||
// "$ref": "#/definitions/EditActionRunnerOption"
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunner"
|
||||
// "$ref": "#/responses/Runner"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
@@ -1192,7 +1192,7 @@ func GetWorkflowRun(ctx *context.APIContext) {
|
||||
// - name: run
|
||||
// in: path
|
||||
// description: id of the run
|
||||
// type: string
|
||||
// type: integer
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
|
||||
@@ -291,7 +291,7 @@ func GetRepoPermissions(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
permission, err := access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, collaborator)
|
||||
permission, err := access_model.GetIndividualUserRepoPermission(ctx, ctx.Repo.Repository, collaborator)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
@@ -71,7 +71,7 @@ func ListForks(ctx *context.APIContext) {
|
||||
|
||||
apiForks := make([]*api.Repository, len(forks))
|
||||
for i, fork := range forks {
|
||||
permission, err := access_model.GetUserRepoPermission(ctx, fork, ctx.Doer)
|
||||
permission, err := access_model.GetDoerRepoPermission(ctx, fork, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
@@ -726,6 +726,9 @@ func EditIssue(ctx *context.APIContext) {
|
||||
// swagger:operation PATCH /repos/{owner}/{repo}/issues/{index} issue issueEditIssue
|
||||
// ---
|
||||
// summary: Edit an issue. If using deadline only the date will be taken into account, and time of day ignored.
|
||||
// description: |
|
||||
// Pass `content_version` to enable optimistic locking on body edits.
|
||||
// If the version doesn't match the current value, the request fails with 409 Conflict.
|
||||
// consumes:
|
||||
// - application/json
|
||||
// produces:
|
||||
@@ -785,6 +788,15 @@ func EditIssue(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
// Fail fast: if content_version is provided and already stale, reject
|
||||
// before any mutations. The DB-level check in ChangeContent still
|
||||
// handles concurrent requests.
|
||||
// TODO: wrap all mutations in a transaction to fully prevent partial writes.
|
||||
if form.ContentVersion != nil && *form.ContentVersion != issue.ContentVersion {
|
||||
ctx.APIError(http.StatusConflict, issues_model.ErrIssueAlreadyChanged)
|
||||
return
|
||||
}
|
||||
|
||||
if len(form.Title) > 0 {
|
||||
err = issue_service.ChangeTitle(ctx, issue, ctx.Doer, form.Title)
|
||||
if err != nil {
|
||||
@@ -793,10 +805,14 @@ func EditIssue(ctx *context.APIContext) {
|
||||
}
|
||||
}
|
||||
if form.Body != nil {
|
||||
err = issue_service.ChangeContent(ctx, issue, ctx.Doer, *form.Body, issue.ContentVersion)
|
||||
contentVersion := issue.ContentVersion
|
||||
if form.ContentVersion != nil {
|
||||
contentVersion = *form.ContentVersion
|
||||
}
|
||||
err = issue_service.ChangeContent(ctx, issue, ctx.Doer, *form.Body, contentVersion)
|
||||
if err != nil {
|
||||
if errors.Is(err, issues_model.ErrIssueAlreadyChanged) {
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
ctx.APIError(http.StatusConflict, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ func isXRefCommentAccessible(ctx stdCtx.Context, user *user_model.User, c *issue
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
perm, err := access_model.GetUserRepoPermission(ctx, c.RefRepo, user)
|
||||
perm, err := access_model.GetDoerRepoPermission(ctx, c.RefRepo, user)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func GetIssueDependencies(ctx *context.APIContext) {
|
||||
perm = existPerm
|
||||
} else {
|
||||
var err error
|
||||
perm, err = access_model.GetUserRepoPermission(ctx, &blocker.Repository, ctx.Doer)
|
||||
perm, err = access_model.GetDoerRepoPermission(ctx, &blocker.Repository, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
@@ -351,7 +351,7 @@ func GetIssueBlocks(ctx *context.APIContext) {
|
||||
perm = existPerm
|
||||
} else {
|
||||
var err error
|
||||
perm, err = access_model.GetUserRepoPermission(ctx, &depMeta.Repository, ctx.Doer)
|
||||
perm, err = access_model.GetDoerRepoPermission(ctx, &depMeta.Repository, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
@@ -537,7 +537,7 @@ func getPermissionForRepo(ctx *context.APIContext, repo *repo_model.Repository)
|
||||
return &ctx.Repo.Permission
|
||||
}
|
||||
|
||||
perm, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
perm, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return nil
|
||||
|
||||
@@ -175,7 +175,7 @@ func DeleteIssueCommentReaction(ctx *context.APIContext) {
|
||||
// schema:
|
||||
// "$ref": "#/definitions/EditReactionOption"
|
||||
// responses:
|
||||
// "200":
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
@@ -248,8 +248,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
// ToDo respond 204
|
||||
ctx.Status(http.StatusOK)
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,7 +407,7 @@ func DeleteIssueReaction(ctx *context.APIContext) {
|
||||
// schema:
|
||||
// "$ref": "#/definitions/EditReactionOption"
|
||||
// responses:
|
||||
// "200":
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
@@ -464,7 +463,6 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
// ToDo respond 204
|
||||
ctx.Status(http.StatusOK)
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
@@ -657,6 +657,15 @@ func EditPullRequest(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
// Fail fast: if content_version is provided and already stale, reject
|
||||
// before any mutations. The DB-level check in ChangeContent still
|
||||
// handles concurrent requests.
|
||||
// TODO: wrap all mutations in a transaction to fully prevent partial writes.
|
||||
if form.ContentVersion != nil && *form.ContentVersion != issue.ContentVersion {
|
||||
ctx.APIError(http.StatusConflict, issues_model.ErrIssueAlreadyChanged)
|
||||
return
|
||||
}
|
||||
|
||||
if len(form.Title) > 0 {
|
||||
err = issue_service.ChangeTitle(ctx, issue, ctx.Doer, form.Title)
|
||||
if err != nil {
|
||||
@@ -665,10 +674,14 @@ func EditPullRequest(ctx *context.APIContext) {
|
||||
}
|
||||
}
|
||||
if form.Body != nil {
|
||||
err = issue_service.ChangeContent(ctx, issue, ctx.Doer, *form.Body, issue.ContentVersion)
|
||||
contentVersion := issue.ContentVersion
|
||||
if form.ContentVersion != nil {
|
||||
contentVersion = *form.ContentVersion
|
||||
}
|
||||
err = issue_service.ChangeContent(ctx, issue, ctx.Doer, *form.Body, contentVersion)
|
||||
if err != nil {
|
||||
if errors.Is(err, issues_model.ErrIssueAlreadyChanged) {
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
ctx.APIError(http.StatusConflict, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -898,6 +911,8 @@ func MergePullRequest(ctx *context.APIContext) {
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "405":
|
||||
@@ -1113,7 +1128,7 @@ func parseCompareInfo(ctx *context.APIContext, compareParam string) (result *git
|
||||
}()
|
||||
|
||||
// user should have permission to read baseRepo's codes and pulls, NOT headRepo's
|
||||
permBase, err := access_model.GetUserRepoPermission(ctx, baseRepo, ctx.Doer)
|
||||
permBase, err := access_model.GetDoerRepoPermission(ctx, baseRepo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return nil, nil
|
||||
@@ -1127,7 +1142,7 @@ func parseCompareInfo(ctx *context.APIContext, compareParam string) (result *git
|
||||
|
||||
// user should have permission to read headRepo's codes
|
||||
// TODO: could the logic be simplified if the headRepo is the same as the baseRepo? Need to think more about it.
|
||||
permHead, err := access_model.GetUserRepoPermission(ctx, headRepo, ctx.Doer)
|
||||
permHead, err := access_model.GetDoerRepoPermission(ctx, headRepo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return nil, nil
|
||||
|
||||
@@ -833,7 +833,7 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions
|
||||
return
|
||||
}
|
||||
|
||||
permDoer, err := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, ctx.Doer)
|
||||
permDoer, err := access_model.GetDoerRepoPermission(ctx, pr.Issue.Repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
@@ -221,7 +221,7 @@ func Search(ctx *context.APIContext) {
|
||||
})
|
||||
return
|
||||
}
|
||||
permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, api.SearchError{
|
||||
OK: false,
|
||||
@@ -588,7 +588,7 @@ func GetByID(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
@@ -37,7 +37,7 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) {
|
||||
|
||||
apiRepos := make([]*api.Repository, 0, len(repos))
|
||||
for i := range repos {
|
||||
permission, err := access_model.GetUserRepoPermission(ctx, repos[i], ctx.Doer)
|
||||
permission, err := access_model.GetDoerRepoPermission(ctx, repos[i], ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
@@ -123,7 +123,7 @@ func ListMyRepos(ctx *context.APIContext) {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
}
|
||||
permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
|
||||
permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func ListRunners(ctx *context.APIContext) {
|
||||
// required: false
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunnersResponse"
|
||||
// "$ref": "#/responses/RunnerList"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
@@ -63,7 +63,7 @@ func GetRunner(ctx *context.APIContext) {
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunner"
|
||||
// "$ref": "#/responses/Runner"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
@@ -115,7 +115,7 @@ func UpdateRunner(ctx *context.APIContext) {
|
||||
// "$ref": "#/definitions/EditActionRunnerOption"
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/definitions/ActionRunner"
|
||||
// "$ref": "#/responses/Runner"
|
||||
// "400":
|
||||
// "$ref": "#/responses/error"
|
||||
// "404":
|
||||
|
||||
@@ -31,7 +31,7 @@ func getStarredRepos(ctx *context.APIContext, user *user_model.User, private boo
|
||||
|
||||
repos := make([]*api.Repository, len(starredRepos))
|
||||
for i, starred := range starredRepos {
|
||||
permission, err := access_model.GetUserRepoPermission(ctx, starred, user)
|
||||
permission, err := access_model.GetIndividualUserRepoPermission(ctx, starred, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Loaded 100 of 335 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user