diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 0f222ecd..846b08f8 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -13,7 +13,7 @@ jobs:
name: Lint Frontend
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: pnpm/action-setup@v4
with:
package_json_file: "frontend/package.json"
@@ -31,7 +31,7 @@ jobs:
name: Lint Backend
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: "1.25.x"
@@ -43,7 +43,7 @@ jobs:
name: Test
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: "1.25.x"
@@ -53,7 +53,7 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-go@v6
@@ -77,7 +77,7 @@ jobs:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-go@v6
@@ -97,7 +97,7 @@ jobs:
uses: docker/setup-buildx-action@v3
- name: Install Task
uses: go-task/setup-task@v1
- - run: task build-frontend
+ - run: task build:frontend
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 8eec9747..5b21ccba 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install Task
@@ -28,25 +28,25 @@ jobs:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
name: Build and Release Docs
permissions:
- contents: read
- deployments: write
- pull-requests: write
+ pages: write
+ id-token: write
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install Task
uses: go-task/setup-task@v1
- name: Build site
run: task docs
- - name: Deploy to Cloudflare Pages
- uses: cloudflare/wrangler-action@v3
+ - name: Upload static files as artifact
+ uses: actions/upload-pages-artifact@v4
with:
- apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
- accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- command: pages deploy www/public --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }}
- gitHubToken: ${{ secrets.GITHUB_TOKEN }}
-
+ path: www/public
+ - name: Deploy to GitHub Pages
+ uses: actions/deploy-pages@v4
diff --git a/.golangci.yml b/.golangci.yml
index 32d944f3..8819f48b 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -2,8 +2,13 @@ version: "2"
linters:
default: standard
+ enable:
+ - gocritic
+ - govet
+ - revive
exclusions:
presets:
- std-error-handling
+ - comments
paths:
- frontend/
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 57b7b44a..be192ef8 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -17,6 +17,7 @@ builds:
- linux
- windows
- freebsd
+ - openbsd
goarch:
- amd64
- "386"
@@ -30,6 +31,12 @@ builds:
ignore:
- goos: darwin
goarch: "386"
+ # Experimental, may not work properly
+ - goos: openbsd
+ goarch: riscv64
+ # Broken as of Go 1.24, deprecated as of Go 1.26
+ - goos: windows
+ goarch: arm
- goos: freebsd
goarch: arm
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 70d61c71..0f49dca9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,187 @@
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
+## [2.55.0](https://github.com/filebrowser/filebrowser/compare/v2.54.0...v2.55.0) (2026-01-18)
+
+
+### Features
+
+* added cut, copy, paste and show command palette functions in header ([#5648](https://github.com/filebrowser/filebrowser/issues/5648)) ([785b7ab](https://github.com/filebrowser/filebrowser/commit/785b7abb7ba7a86cc0deae1052c319ff714c222c))
+* update translations ([#5677](https://github.com/filebrowser/filebrowser/issues/5677)) ([e7ea1ad](https://github.com/filebrowser/filebrowser/commit/e7ea1ad27d3d17e249489d3338be40bfea15e2a1))
+
+
+### Bug Fixes
+
+* prevent context menu clicks from clearing file selection ([#5681](https://github.com/filebrowser/filebrowser/issues/5681)) ([59ca0c3](https://github.com/filebrowser/filebrowser/commit/59ca0c340afc7774747c70ede9a5a5a3c9349d6b))
+* request current password when deleting users ([#5667](https://github.com/filebrowser/filebrowser/issues/5667)) ([cfa6c58](https://github.com/filebrowser/filebrowser/commit/cfa6c5864e5e7673aa9f3180e4964e0db92cc4da))
+* retain file selection when closing the editor ([#5693](https://github.com/filebrowser/filebrowser/issues/5693)) ([4094fb3](https://github.com/filebrowser/filebrowser/commit/4094fb359babac70e88d0ed4bfe3bd100744aad6))
+
+## [2.54.0](https://github.com/filebrowser/filebrowser/compare/v2.53.1...v2.54.0) (2026-01-10)
+
+
+### Features
+
+* add "redirect after copy/move" user setting ([#5662](https://github.com/filebrowser/filebrowser/issues/5662)) ([fda8a99](https://github.com/filebrowser/filebrowser/commit/fda8a992929b1466e75fb2813f2c4e293c12d244))
+* force file sync while uploading file ([#5668](https://github.com/filebrowser/filebrowser/issues/5668)) ([4fd18a3](https://github.com/filebrowser/filebrowser/commit/4fd18a382c31bbe7059d6733ffa371e70051865b))
+* update translations ([#5659](https://github.com/filebrowser/filebrowser/issues/5659)) ([464b581](https://github.com/filebrowser/filebrowser/commit/464b581953139c17e3276b774e381e4052827125))
+
+
+### Bug Fixes
+
+* clear selection by clicking on empty area ([#5663](https://github.com/filebrowser/filebrowser/issues/5663)) ([208535a](https://github.com/filebrowser/filebrowser/commit/208535a8cc23254de0013dfab9008486707ee6c2))
+* hide "change password form" in noauth setting ([#5652](https://github.com/filebrowser/filebrowser/issues/5652)) ([219582c](https://github.com/filebrowser/filebrowser/commit/219582c0b03fd90979b1d1398dba7919d086a23f))
+
+## [2.53.1](https://github.com/filebrowser/filebrowser/compare/v2.53.0...v2.53.1) (2026-01-03)
+
+
+### Bug Fixes
+
+* download path encoding file paths ([#5655](https://github.com/filebrowser/filebrowser/issues/5655)) ([ffa893e](https://github.com/filebrowser/filebrowser/commit/ffa893e9ac387a49dba5917a41df7c3b7ce120fc))
+* request a password to change sensitive user data ([#5629](https://github.com/filebrowser/filebrowser/issues/5629)) ([b8151a0](https://github.com/filebrowser/filebrowser/commit/b8151a038a1ea55afae8073b439b74e364cac12f))
+
+## [2.53.0](https://github.com/filebrowser/filebrowser/compare/v2.52.0...v2.53.0) (2025-12-29)
+
+
+### Features
+
+* add "disable image resolution calculation" flag ([#5638](https://github.com/filebrowser/filebrowser/issues/5638)) ([a2d80c6](https://github.com/filebrowser/filebrowser/commit/a2d80c62c1c17962e566f68fb7cac6960ed3e4cb))
+* support streaming response for search results ([#5630](https://github.com/filebrowser/filebrowser/issues/5630)) ([20bfd13](https://github.com/filebrowser/filebrowser/commit/20bfd131c6a4fca48a645b52171c2d1cc3ce92b7))
+* update translations ([a12a612](https://github.com/filebrowser/filebrowser/commit/a12a612970d6cc3dfbca1b35ef3a60a887a4effb))
+* update translations ([#5626](https://github.com/filebrowser/filebrowser/issues/5626)) ([f899756](https://github.com/filebrowser/filebrowser/commit/f89975603e29b9f1fc05aec58afb42bbd56ed696))
+* update translations ([#5631](https://github.com/filebrowser/filebrowser/issues/5631)) ([032d6c7](https://github.com/filebrowser/filebrowser/commit/032d6c7520a64686c9d9b1218562256f629b4703))
+
+
+### Bug Fixes
+
+* conversion of backslashes in file paths for archive creation ([#5637](https://github.com/filebrowser/filebrowser/issues/5637)) ([9595f39](https://github.com/filebrowser/filebrowser/commit/9595f3939c1c129ed875a47adcc4fbcfad9a0e65))
+* Don't crash on invalid config import ([#5640](https://github.com/filebrowser/filebrowser/issues/5640)) ([79d1aa9](https://github.com/filebrowser/filebrowser/commit/79d1aa9229b076ee8e3b71d6cf061fc90738f4da))
+* fix nil deref in config set command ([#5641](https://github.com/filebrowser/filebrowser/issues/5641)) ([60b1ee8](https://github.com/filebrowser/filebrowser/commit/60b1ee8bb9e18b21d7f2c04cb1cc90046cecd3e1))
+
+## [2.52.0](https://github.com/filebrowser/filebrowser/compare/v2.51.2...v2.52.0) (2025-12-13)
+
+
+### Features
+
+* sync translations with Transifex ([7fa3432](https://github.com/filebrowser/filebrowser/commit/7fa3432f25610bbb55a718bc709b9a7bf41d92f0))
+* update translations ([#5615](https://github.com/filebrowser/filebrowser/issues/5615)) ([3fdca6d](https://github.com/filebrowser/filebrowser/commit/3fdca6dfd9a18c3f4895b4ef3cbd216824dbb57a))
+
+
+### Bug Fixes
+
+* display the directory name in the shared folder view ([#5617](https://github.com/filebrowser/filebrowser/issues/5617)) ([6d4c867](https://github.com/filebrowser/filebrowser/commit/6d4c86767239dad4f09f30f48678f2f3a716eb12))
+* hide the context menu when changing the route ([#5613](https://github.com/filebrowser/filebrowser/issues/5613)) ([cf96657](https://github.com/filebrowser/filebrowser/commit/cf966578d8c6beab111b74f495bac6bdec173f41))
+
+## [2.51.2](https://github.com/filebrowser/filebrowser/compare/v2.51.1...v2.51.2) (2025-12-07)
+
+
+### Bug Fixes
+
+* **frontend:** add missing i18n strings ([c171599](https://github.com/filebrowser/filebrowser/commit/c1715992bda46517f801c1aa496df8a3b42a4e4d))
+
+## [2.51.1](https://github.com/filebrowser/filebrowser/compare/v2.51.0...v2.51.1) (2025-12-07)
+
+
+### Bug Fixes
+
+* **frontend:** csv viewer i18n strings ([4cbb4b7](https://github.com/filebrowser/filebrowser/commit/4cbb4b73af816104475f15c1d996640b56203602))
+* prevent the right-click from selecting multiple items when the "single-click" option is active ([#5608](https://github.com/filebrowser/filebrowser/issues/5608)) ([152f830](https://github.com/filebrowser/filebrowser/commit/152f8302f7cda21bde37692b175c22c124233f45))
+
+## [2.51.0](https://github.com/filebrowser/filebrowser/compare/v2.50.0...v2.51.0) (2025-12-06)
+
+
+### Features
+
+* update translations ([2d88c06](https://github.com/filebrowser/filebrowser/commit/2d88c067611e936056dbbf04247f1c1c709b2a09))
+
+
+### Bug Fixes
+
+* added column separator select (comma, semicolon and both) in CSV viewer ([#5604](https://github.com/filebrowser/filebrowser/issues/5604)) ([204a3f0](https://github.com/filebrowser/filebrowser/commit/204a3f0eeaa0c68781b60651bf27c4b27eac44e6))
+
+
+### Refactorings
+
+* cleanup package names ([#5605](https://github.com/filebrowser/filebrowser/issues/5605)) ([f029c30](https://github.com/filebrowser/filebrowser/commit/f029c3005e450cfbebb074c42dbdf65db9c8d56a))
+
+## [2.50.0](https://github.com/filebrowser/filebrowser/compare/v2.49.0...v2.50.0) (2025-11-30)
+
+
+### Features
+
+* configurable logout page URL for proxy/hook auth ([#3884](https://github.com/filebrowser/filebrowser/issues/3884)) ([b9ac45d](https://github.com/filebrowser/filebrowser/commit/b9ac45d5dac4b4eb2ba364629090fbf306cffd2b))
+* render CSVs as table ([#5569](https://github.com/filebrowser/filebrowser/issues/5569)) ([982405e](https://github.com/filebrowser/filebrowser/commit/982405ec944f94baf43594b0ed2f06329ff4e9ed))
+* update frontend/src/i18n/hr.json ([279a5cc](https://github.com/filebrowser/filebrowser/commit/279a5ccd1e8d7bde4568b63cb3c506af48b6c618))
+* update translations ([78e0395](https://github.com/filebrowser/filebrowser/commit/78e039596070a3a9e643a693cc99960c69dcfe92))
+
+
+### Bug Fixes
+
+* do not close editor if save failed ([701522a](https://github.com/filebrowser/filebrowser/commit/701522a0600cfa542469540ed764630c0ba1a732)), closes [#5591](https://github.com/filebrowser/filebrowser/issues/5591)
+
+## [2.49.0](https://github.com/filebrowser/filebrowser/compare/v2.48.2...v2.49.0) (2025-11-22)
+
+
+### Features
+
+* add "copy download link to clipboard" button to Share prompt ([#5173](https://github.com/filebrowser/filebrowser/issues/5173)) ([d48f566](https://github.com/filebrowser/filebrowser/commit/d48f5665d6975c4cbbdf9be20dc2e0106db02f01))
+* add Bulgarian language ([8db2411](https://github.com/filebrowser/filebrowser/commit/8db2411cd43a23ae3292a817e3524cfdb5ae9b86))
+* Updates for project File Browser ([#5566](https://github.com/filebrowser/filebrowser/issues/5566)) ([54306bd](https://github.com/filebrowser/filebrowser/commit/54306bdc8700fac489326ae81e28ac5db0580d13))
+
+
+### Bug Fixes
+
+* display friendly error message for password validation on signup ([#5563](https://github.com/filebrowser/filebrowser/issues/5563)) ([6d5aa35](https://github.com/filebrowser/filebrowser/commit/6d5aa355e433d613e5a3ae137f410c63baeddf0f))
+
+## [2.48.2](https://github.com/filebrowser/filebrowser/compare/v2.48.1...v2.48.2) (2025-11-18)
+
+
+### Bug Fixes
+
+* add transitionary support for FB_BASEURL ([984ea7b](https://github.com/filebrowser/filebrowser/commit/984ea7b569e3bd33b6f91ebdf63684a618d51e94))
+
+
+### Refactorings
+
+* rename python for clarification ([fd7b70c](https://github.com/filebrowser/filebrowser/commit/fd7b70cf38ac67c8c9ff79f2e7fde5e2ec45a1de))
+
+## [2.48.1](https://github.com/filebrowser/filebrowser/compare/v2.48.0...v2.48.1) (2025-11-17)
+
+
+### Bug Fixes
+
+* options should only override if set ([420adea](https://github.com/filebrowser/filebrowser/commit/420adea7e61a1c182cddd6fb2544a0752e5709f7))
+
+## [2.48.0](https://github.com/filebrowser/filebrowser/compare/v2.47.0...v2.48.0) (2025-11-17)
+
+
+### Features
+
+* consistent flags and environment variables ([#5549](https://github.com/filebrowser/filebrowser/issues/5549)) ([0a0cb80](https://github.com/filebrowser/filebrowser/commit/0a0cb8046fce52f1ff926171b34bcdb7cd39aab3))
+
+
+### Bug Fixes
+
+* add tokenExpirationTime to `config init` and troubleshoot docs ([#5546](https://github.com/filebrowser/filebrowser/issues/5546)) ([8c5dc76](https://github.com/filebrowser/filebrowser/commit/8c5dc7641e6f8aadd9e5d5d3b25a2ad9f1ec9a1e))
+* use all available flags in quick setup ([f41585f](https://github.com/filebrowser/filebrowser/commit/f41585f0392d65c08c01ab65b62d3eeb04c03b7d))
+
+
+### Refactorings
+
+* reuse logic for config init and set ([89be0b1](https://github.com/filebrowser/filebrowser/commit/89be0b1873527987dd2dddac746e93b8bc684d46))
+
+## [2.47.0](https://github.com/filebrowser/filebrowser/compare/v2.46.1...v2.47.0) (2025-11-16)
+
+
+### Features
+
+* add TUS settings to the command line ([#5556](https://github.com/filebrowser/filebrowser/issues/5556)) ([e24e1f1](https://github.com/filebrowser/filebrowser/commit/e24e1f1abae9e80add620c4ad65660ca1b575a49))
+* remove importer of v1 config ([#5550](https://github.com/filebrowser/filebrowser/issues/5550)) ([ceb5e72](https://github.com/filebrowser/filebrowser/commit/ceb5e723f3ee2c966bb561a804015246450280ca))
+
+
+### Bug Fixes
+
+* exit 0 when gracefully shutting down ([#5555](https://github.com/filebrowser/filebrowser/issues/5555)) ([5de4099](https://github.com/filebrowser/filebrowser/commit/5de4099cba2cf012d4a213c8eb29c412fc72c151))
+
## [2.46.1](https://github.com/filebrowser/filebrowser/compare/v2.46.0...v2.46.1) (2025-11-15)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d6e694f1..311a2fd7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -86,7 +86,7 @@ task docs
To start a local server on port `8000` to view the built documentation:
```bash
-task docs-serve
+task docs:serve
```
## Release
diff --git a/Dockerfile b/Dockerfile
index 8bd825da..92bbe1d4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
## Multistage build: First stage fetches dependencies
-FROM alpine:3.22 AS fetcher
+FROM alpine:3.23 AS fetcher
# install and copy ca-certificates, mailcap, and tini-static; download JSON.sh
RUN apk update && \
diff --git a/Dockerfile.s6 b/Dockerfile.s6
index 2a1218b2..8b363cb3 100644
--- a/Dockerfile.s6
+++ b/Dockerfile.s6
@@ -1,4 +1,4 @@
-FROM ghcr.io/linuxserver/baseimage-alpine:3.22
+FROM ghcr.io/linuxserver/baseimage-alpine:3.23
RUN apk update && \
apk --no-cache add ca-certificates mailcap jq libcap
diff --git a/Taskfile.yml b/Taskfile.yml
index 9721317f..378e3409 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -10,14 +10,14 @@ vars:
-v ./CONTRIBUTING.md:/docs/docs/contributing.md
tasks:
- build-frontend:
+ build:frontend:
desc: Build frontend assets
dir: frontend
cmds:
- pnpm install --frozen-lockfile
- pnpm run build
- build-backend:
+ build:backend:
desc: Build backend binary
cmds:
- go build -ldflags='-s -w -X "github.com/filebrowser/filebrowser/v2/version.Version={{.VERSION}}" -X "github.com/filebrowser/filebrowser/v2/version.CommitSHA={{.GIT_COMMIT}}"' -o filebrowser .
@@ -30,16 +30,16 @@ tasks:
build:
desc: Build both frontend and backend
cmds:
- - task: build-frontend
- - task: build-backend
+ - task: build:frontend
+ - task: build:backend
- release-make:
+ release:make:
internal: true
prompt: Do you wish to proceed?
cmds:
- pnpm dlx commit-and-tag-version -s
- release-dry-run:
+ release:dry-run:
internal: true
cmds:
- pnpm dlx commit-and-tag-version --dry-run --skip
@@ -47,10 +47,24 @@ tasks:
release:
desc: Create a new release
cmds:
- - task: release-dry-run
- - task: release-make
+ - task: docs:cli:generate
+ - git add www/docs/cli
+ - |
+ if [[ `git status www/docs/cli --porcelain` ]]; then
+ git commit -m 'chore(docs): update CLI documentation'
+ fi
+ - task: release:dry-run
+ - task: release:make
- docs-image-make:
+ docs:cli:generate:
+ cmds:
+ - rm -rf www/docs/cli
+ - mkdir -p www/docs/cli
+ - go run . docs
+ generates:
+ - www/docs/cli
+
+ docs:docker:generate:
internal: true
cmds:
- docker build -f www/Dockerfile --progress=plain -t filebrowser.site www
@@ -59,11 +73,11 @@ tasks:
desc: Generate documentation
cmds:
- rm -rf www/public
- - task: docs-image-make
+ - task: docs:docker:generate
- docker run --rm {{.SITE_DOCKER_FLAGS}} filebrowser.site build -d "public"
- docs-serve:
+ docs:serve:
desc: Serve documentation
cmds:
- - task: docs-image-make
+ - task: docs:docker:generate
- docker run --rm -it -p 8000:8000 {{.SITE_DOCKER_FLAGS}} filebrowser.site
diff --git a/auth/hook.go b/auth/hook.go
index 2ecb12f3..0c5efac5 100644
--- a/auth/hook.go
+++ b/auth/hook.go
@@ -11,7 +11,7 @@ import (
"slices"
"strings"
- fbErrors "github.com/filebrowser/filebrowser/v2/errors"
+ fberrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/files"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users"
@@ -103,7 +103,7 @@ func (a *HookAuth) RunCommand() (string, error) {
command[i] = os.Expand(arg, envMapping)
}
- cmd := exec.Command(command[0], command[1:]...) //nolint:gosec
+ cmd := exec.Command(command[0], command[1:]...)
cmd.Env = append(os.Environ(), fmt.Sprintf("USERNAME=%s", a.Cred.Username))
cmd.Env = append(cmd.Env, fmt.Sprintf("PASSWORD=%s", a.Cred.Password))
out, err := cmd.Output()
@@ -146,7 +146,7 @@ func (a *HookAuth) GetValues(s string) {
// SaveUser updates the existing user or creates a new one when not found
func (a *HookAuth) SaveUser() (*users.User, error) {
u, err := a.Users.Get(a.Server.Root, a.Cred.Username)
- if err != nil && !errors.Is(err, fbErrors.ErrNotExist) {
+ if err != nil && !errors.Is(err, fberrors.ErrNotExist) {
return nil, err
}
@@ -158,16 +158,17 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
// create user with the provided credentials
d := &users.User{
- Username: a.Cred.Username,
- Password: pass,
- Scope: a.Settings.Defaults.Scope,
- Locale: a.Settings.Defaults.Locale,
- ViewMode: a.Settings.Defaults.ViewMode,
- SingleClick: a.Settings.Defaults.SingleClick,
- Sorting: a.Settings.Defaults.Sorting,
- Perm: a.Settings.Defaults.Perm,
- Commands: a.Settings.Defaults.Commands,
- HideDotfiles: a.Settings.Defaults.HideDotfiles,
+ Username: a.Cred.Username,
+ Password: pass,
+ Scope: a.Settings.Defaults.Scope,
+ Locale: a.Settings.Defaults.Locale,
+ ViewMode: a.Settings.Defaults.ViewMode,
+ SingleClick: a.Settings.Defaults.SingleClick,
+ RedirectAfterCopyMove: a.Settings.Defaults.RedirectAfterCopyMove,
+ Sorting: a.Settings.Defaults.Sorting,
+ Perm: a.Settings.Defaults.Perm,
+ Commands: a.Settings.Defaults.Commands,
+ HideDotfiles: a.Settings.Defaults.HideDotfiles,
}
u = a.GetUser(d)
@@ -219,13 +220,14 @@ func (a *HookAuth) GetUser(d *users.User) *users.User {
Download: isAdmin || a.Fields.GetBoolean("user.perm.download", d.Perm.Download),
}
user := users.User{
- ID: d.ID,
- Username: d.Username,
- Password: d.Password,
- Scope: a.Fields.GetString("user.scope", d.Scope),
- Locale: a.Fields.GetString("user.locale", d.Locale),
- ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
- SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
+ ID: d.ID,
+ Username: d.Username,
+ Password: d.Password,
+ Scope: a.Fields.GetString("user.scope", d.Scope),
+ Locale: a.Fields.GetString("user.locale", d.Locale),
+ ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
+ SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
+ RedirectAfterCopyMove: a.Fields.GetBoolean("user.redirectAfterCopyMove", d.RedirectAfterCopyMove),
Sorting: files.Sorting{
Asc: a.Fields.GetBoolean("user.sorting.asc", d.Sorting.Asc),
By: a.Fields.GetString("user.sorting.by", d.Sorting.By),
@@ -251,6 +253,7 @@ var validHookFields = []string{
"user.locale",
"user.viewMode",
"user.singleClick",
+ "user.redirectAfterCopyMove",
"user.sorting.by",
"user.sorting.asc",
"user.commands",
diff --git a/auth/json.go b/auth/json.go
index 81f430b3..2284dc7f 100644
--- a/auth/json.go
+++ b/auth/json.go
@@ -14,6 +14,10 @@ import (
// MethodJSONAuth is used to identify json auth.
const MethodJSONAuth settings.AuthMethod = "json"
+// dummyHash is used to prevent user enumeration timing attacks.
+// It MUST be a valid bcrypt hash.
+const dummyHash = "$2a$10$O4mEMeOL/nit6zqe.WQXauLRbRlzb3IgLHsa26Pf0N/GiU9b.wK1m"
+
type jsonCred struct {
Password string `json:"password"`
Username string `json:"username"`
@@ -40,7 +44,7 @@ func (a JSONAuth) Auth(r *http.Request, usr users.Store, _ *settings.Settings, s
// If ReCaptcha is enabled, check the code.
if a.ReCaptcha != nil && a.ReCaptcha.Secret != "" {
- ok, err := a.ReCaptcha.Ok(cred.ReCaptcha) //nolint:govet
+ ok, err := a.ReCaptcha.Ok(cred.ReCaptcha)
if err != nil {
return nil, err
@@ -52,7 +56,17 @@ func (a JSONAuth) Auth(r *http.Request, usr users.Store, _ *settings.Settings, s
}
u, err := usr.Get(srv.Root, cred.Username)
- if err != nil || !users.CheckPwd(cred.Password, u.Password) {
+
+ hash := dummyHash
+ if err == nil {
+ hash = u.Password
+ }
+
+ if !users.CheckPwd(cred.Password, hash) {
+ return nil, os.ErrPermission
+ }
+
+ if err != nil {
return nil, os.ErrPermission
}
diff --git a/auth/proxy.go b/auth/proxy.go
index 301aa292..3f4a627c 100644
--- a/auth/proxy.go
+++ b/auth/proxy.go
@@ -4,7 +4,7 @@ import (
"errors"
"net/http"
- fbErrors "github.com/filebrowser/filebrowser/v2/errors"
+ fberrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users"
)
@@ -21,7 +21,7 @@ type ProxyAuth struct {
func (a ProxyAuth) Auth(r *http.Request, usr users.Store, setting *settings.Settings, srv *settings.Server) (*users.User, error) {
username := r.Header.Get(a.Header)
user, err := usr.Get(srv.Root, username)
- if errors.Is(err, fbErrors.ErrNotExist) {
+ if errors.Is(err, fberrors.ErrNotExist) {
return a.createUser(usr, setting, srv, username)
}
return user, err
diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go
new file mode 100644
index 00000000..e4b45c47
--- /dev/null
+++ b/cmd/cmd_test.go
@@ -0,0 +1,35 @@
+package cmd
+
+import (
+ "testing"
+
+ "github.com/samber/lo"
+ "github.com/spf13/cobra"
+)
+
+// TestEnvCollisions ensures that there are no collisions in the produced environment
+// variable names for all commands and their flags.
+func TestEnvCollisions(t *testing.T) {
+ testEnvCollisions(t, rootCmd)
+}
+
+func testEnvCollisions(t *testing.T, cmd *cobra.Command) {
+ for _, cmd := range cmd.Commands() {
+ testEnvCollisions(t, cmd)
+ }
+
+ replacements := generateEnvKeyReplacements(cmd)
+ envVariables := []string{}
+
+ for i := range replacements {
+ if i%2 != 0 {
+ envVariables = append(envVariables, replacements[i])
+ }
+ }
+
+ duplicates := lo.FindDuplicates(envVariables)
+
+ if len(duplicates) > 0 {
+ t.Errorf("Found duplicate environment variable keys for command %q: %v", cmd.Name(), duplicates)
+ }
+}
diff --git a/cmd/cmds_add.go b/cmd/cmds_add.go
index a4d17061..a209b83f 100644
--- a/cmd/cmds_add.go
+++ b/cmd/cmds_add.go
@@ -15,18 +15,18 @@ var cmdsAddCmd = &cobra.Command{
Short: "Add a command to run on a specific event",
Long: `Add a command to run on a specific event.`,
Args: cobra.MinimumNArgs(2),
- RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
- s, err := d.store.Settings.Get()
+ RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
+ s, err := st.Settings.Get()
if err != nil {
return err
}
command := strings.Join(args[1:], " ")
s.Commands[args[0]] = append(s.Commands[args[0]], command)
- err = d.store.Settings.Save(s)
+ err = st.Settings.Save(s)
if err != nil {
return err
}
printEvents(s.Commands)
return nil
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/cmds_ls.go b/cmd/cmds_ls.go
index fa901a56..694be178 100644
--- a/cmd/cmds_ls.go
+++ b/cmd/cmds_ls.go
@@ -14,12 +14,13 @@ var cmdsLsCmd = &cobra.Command{
Short: "List all commands for each event",
Long: `List all commands for each event.`,
Args: cobra.NoArgs,
- RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
- s, err := d.store.Settings.Get()
+ RunE: withStore(func(cmd *cobra.Command, _ []string, st *store) error {
+ s, err := st.Settings.Get()
if err != nil {
return err
}
- evt, err := getString(cmd.Flags(), "event")
+
+ evt, err := cmd.Flags().GetString("event")
if err != nil {
return err
}
@@ -32,6 +33,7 @@ var cmdsLsCmd = &cobra.Command{
show["after_"+evt] = s.Commands["after_"+evt]
printEvents(show)
}
+
return nil
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/cmds_rm.go b/cmd/cmds_rm.go
index 34089388..861f495f 100644
--- a/cmd/cmds_rm.go
+++ b/cmd/cmds_rm.go
@@ -35,8 +35,8 @@ including 'index_end'.`,
return nil
},
- RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
- s, err := d.store.Settings.Get()
+ RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
+ s, err := st.Settings.Get()
if err != nil {
return err
}
@@ -55,11 +55,11 @@ including 'index_end'.`,
}
s.Commands[evt] = append(s.Commands[evt][:i], s.Commands[evt][f+1:]...)
- err = d.store.Settings.Save(s)
+ err = st.Settings.Save(s)
if err != nil {
return err
}
printEvents(s.Commands)
return nil
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/config.go b/cmd/config.go
index 84474f4c..5b3314ed 100644
--- a/cmd/config.go
+++ b/cmd/config.go
@@ -2,7 +2,7 @@ package cmd
import (
"encoding/json"
- nerrors "errors"
+ "errors"
"fmt"
"os"
"strings"
@@ -12,7 +12,7 @@ import (
"github.com/spf13/pflag"
"github.com/filebrowser/filebrowser/v2/auth"
- "github.com/filebrowser/filebrowser/v2/errors"
+ fberrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/settings"
)
@@ -30,15 +30,22 @@ var configCmd = &cobra.Command{
func addConfigFlags(flags *pflag.FlagSet) {
addServerFlags(flags)
addUserFlags(flags)
+
flags.BoolP("signup", "s", false, "allow users to signup")
- flags.Bool("hide-login-button", false, "hide login button from public pages")
- flags.Bool("create-user-dir", false, "generate user's home directory automatically")
- flags.Uint("minimum-password-length", settings.DefaultMinimumPasswordLength, "minimum password length for new users")
+ flags.Bool("hideLoginButton", false, "hide login button from public pages")
+ flags.Bool("createUserDir", false, "generate user's home directory automatically")
+ flags.Uint("minimumPasswordLength", settings.DefaultMinimumPasswordLength, "minimum password length for new users")
flags.String("shell", "", "shell command to which other commands should be appended")
+ // NB: these are string so they can be presented as octal in the help text
+ // as that's the conventional representation for modes in Unix.
+ flags.String("fileMode", fmt.Sprintf("%O", settings.DefaultFileMode), "mode bits that new files are created with")
+ flags.String("dirMode", fmt.Sprintf("%O", settings.DefaultDirMode), "mode bits that new directories are created with")
+
flags.String("auth.method", string(auth.MethodJSONAuth), "authentication type")
flags.String("auth.header", "", "HTTP header for auth.method=proxy")
flags.String("auth.command", "", "command for auth.method=hook")
+ flags.String("auth.logoutPage", "", "url of custom logout page")
flags.String("recaptcha.host", "https://www.google.com", "use another host for ReCAPTCHA. recaptcha.net might be useful in China")
flags.String("recaptcha.key", "", "ReCaptcha site key")
@@ -50,14 +57,13 @@ func addConfigFlags(flags *pflag.FlagSet) {
flags.String("branding.files", "", "path to directory with images and custom styles")
flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links")
flags.Bool("branding.disableUsedPercentage", false, "disable used disk percentage graph")
- // NB: these are string so they can be presented as octal in the help text
- // as that's the conventional representation for modes in Unix.
- flags.String("file-mode", fmt.Sprintf("%O", settings.DefaultFileMode), "Mode bits that new files are created with")
- flags.String("dir-mode", fmt.Sprintf("%O", settings.DefaultDirMode), "Mode bits that new directories are created with")
+
+ flags.Uint64("tus.chunkSize", settings.DefaultTusChunkSize, "the tus chunk size")
+ flags.Uint16("tus.retryCount", settings.DefaultTusRetryCount, "the tus retry count")
}
func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) {
- methodStr, err := getString(flags, "auth.method")
+ methodStr, err := flags.GetString("auth.method")
if err != nil {
return "", nil, err
}
@@ -88,17 +94,17 @@ func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.Auth
}
func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
- header, err := getString(flags, "auth.header")
+ header, err := flags.GetString("auth.header")
if err != nil {
return nil, err
}
- if header == "" {
+ if header == "" && defaultAuther != nil {
header = defaultAuther["header"].(string)
}
if header == "" {
- return nil, nerrors.New("you must set the flag 'auth.header' for method 'proxy'")
+ return nil, errors.New("you must set the flag 'auth.header' for method 'proxy'")
}
return &auth.ProxyAuth{Header: header}, nil
@@ -110,15 +116,17 @@ func getNoAuth() auth.Auther {
func getJSONAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
jsonAuth := &auth.JSONAuth{}
- host, err := getString(flags, "recaptcha.host")
+ host, err := flags.GetString("recaptcha.host")
if err != nil {
return nil, err
}
- key, err := getString(flags, "recaptcha.key")
+
+ key, err := flags.GetString("recaptcha.key")
if err != nil {
return nil, err
}
- secret, err := getString(flags, "recaptcha.secret")
+
+ secret, err := flags.GetString("recaptcha.secret")
if err != nil {
return nil, err
}
@@ -146,17 +154,16 @@ func getJSONAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (au
}
func getHookAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
- command, err := getString(flags, "auth.command")
+ command, err := flags.GetString("auth.command")
if err != nil {
return nil, err
}
-
if command == "" {
command = defaultAuther["command"].(string)
}
if command == "" {
- return nil, nerrors.New("you must set the flag 'auth.command' for method 'hook'")
+ return nil, errors.New("you must set the flag 'auth.command' for method 'hook'")
}
return &auth.HookAuth{Command: command}, nil
@@ -179,7 +186,7 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.
case auth.MethodHookAuth:
auther, err = getHookAuth(flags, defaultAuther)
default:
- return "", nil, errors.ErrInvalidAuthMethod
+ return "", nil, fberrors.ErrInvalidAuthMethod
}
if err != nil {
@@ -195,9 +202,11 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
fmt.Fprintf(w, "Hide Login Button:\t%t\n", set.HideLoginButton)
fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir)
+ fmt.Fprintf(w, "Logout Page:\t%s\n", set.LogoutPage)
fmt.Fprintf(w, "Minimum Password Length:\t%d\n", set.MinimumPasswordLength)
fmt.Fprintf(w, "Auth Method:\t%s\n", set.AuthMethod)
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
+
fmt.Fprintln(w, "\nBranding:")
fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name)
fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Branding.Files)
@@ -205,6 +214,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "\tDisable used disk percentage graph:\t%t\n", set.Branding.DisableUsedPercentage)
fmt.Fprintf(w, "\tColor:\t%s\n", set.Branding.Color)
fmt.Fprintf(w, "\tTheme:\t%s\n", set.Branding.Theme)
+
fmt.Fprintln(w, "\nServer:")
fmt.Fprintf(w, "\tLog:\t%s\n", ser.Log)
fmt.Fprintf(w, "\tPort:\t%s\n", ser.Port)
@@ -214,20 +224,32 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "\tAddress:\t%s\n", ser.Address)
fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert)
fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey)
+ fmt.Fprintf(w, "\tToken Expiration Time:\t%s\n", ser.TokenExpirationTime)
fmt.Fprintf(w, "\tExec Enabled:\t%t\n", ser.EnableExec)
+ fmt.Fprintf(w, "\tThumbnails Enabled:\t%t\n", ser.EnableThumbnails)
+ fmt.Fprintf(w, "\tResize Preview:\t%t\n", ser.ResizePreview)
+ fmt.Fprintf(w, "\tType Detection by Header:\t%t\n", ser.TypeDetectionByHeader)
+
+ fmt.Fprintln(w, "\nTUS:")
+ fmt.Fprintf(w, "\tChunk size:\t%d\n", set.Tus.ChunkSize)
+ fmt.Fprintf(w, "\tRetry count:\t%d\n", set.Tus.RetryCount)
+
fmt.Fprintln(w, "\nDefaults:")
fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope)
fmt.Fprintf(w, "\tHideDotfiles:\t%t\n", set.Defaults.HideDotfiles)
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode)
fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.Defaults.SingleClick)
+ fmt.Fprintf(w, "\tRedirect after Copy/Move:\t%t\n", set.Defaults.RedirectAfterCopyMove)
fmt.Fprintf(w, "\tFile Creation Mode:\t%O\n", set.FileMode)
fmt.Fprintf(w, "\tDirectory Creation Mode:\t%O\n", set.DirMode)
fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " "))
fmt.Fprintf(w, "\tAce editor syntax highlighting theme:\t%s\n", set.Defaults.AceEditorTheme)
+
fmt.Fprintf(w, "\tSorting:\n")
fmt.Fprintf(w, "\t\tBy:\t%s\n", set.Defaults.Sorting.By)
fmt.Fprintf(w, "\t\tAsc:\t%t\n", set.Defaults.Sorting.Asc)
+
fmt.Fprintf(w, "\tPermissions:\n")
fmt.Fprintf(w, "\t\tAdmin:\t%t\n", set.Defaults.Perm.Admin)
fmt.Fprintf(w, "\t\tExecute:\t%t\n", set.Defaults.Perm.Execute)
@@ -237,6 +259,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "\t\tDelete:\t%t\n", set.Defaults.Perm.Delete)
fmt.Fprintf(w, "\t\tShare:\t%t\n", set.Defaults.Perm.Share)
fmt.Fprintf(w, "\t\tDownload:\t%t\n", set.Defaults.Perm.Download)
+
w.Flush()
b, err := json.MarshalIndent(auther, "", " ")
@@ -246,3 +269,123 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Printf("\nAuther configuration (raw):\n\n%s\n\n", string(b))
return nil
}
+
+func getSettings(flags *pflag.FlagSet, set *settings.Settings, ser *settings.Server, auther auth.Auther, all bool) (auth.Auther, error) {
+ errs := []error{}
+ hasAuth := false
+
+ visit := func(flag *pflag.Flag) {
+ var err error
+
+ switch flag.Name {
+ // Server flags from [addServerFlags]
+ case "address":
+ ser.Address, err = flags.GetString(flag.Name)
+ case "log":
+ ser.Log, err = flags.GetString(flag.Name)
+ case "port":
+ ser.Port, err = flags.GetString(flag.Name)
+ case "cert":
+ ser.TLSCert, err = flags.GetString(flag.Name)
+ case "key":
+ ser.TLSKey, err = flags.GetString(flag.Name)
+ case "root":
+ ser.Root, err = flags.GetString(flag.Name)
+ case "socket":
+ ser.Socket, err = flags.GetString(flag.Name)
+ case "baseURL":
+ ser.BaseURL, err = flags.GetString(flag.Name)
+ case "tokenExpirationTime":
+ ser.TokenExpirationTime, err = flags.GetString(flag.Name)
+ case "disableThumbnails":
+ ser.EnableThumbnails, err = flags.GetBool(flag.Name)
+ ser.EnableThumbnails = !ser.EnableThumbnails
+ case "disablePreviewResize":
+ ser.ResizePreview, err = flags.GetBool(flag.Name)
+ ser.ResizePreview = !ser.ResizePreview
+ case "disableExec":
+ ser.EnableExec, err = flags.GetBool(flag.Name)
+ ser.EnableExec = !ser.EnableExec
+ case "disableTypeDetectionByHeader":
+ ser.TypeDetectionByHeader, err = flags.GetBool(flag.Name)
+ ser.TypeDetectionByHeader = !ser.TypeDetectionByHeader
+ case "disableImageResolutionCalc":
+ ser.ImageResolutionCal, err = flags.GetBool(flag.Name)
+ ser.ImageResolutionCal = !ser.ImageResolutionCal
+
+ // Settings flags from [addConfigFlags]
+ case "signup":
+ set.Signup, err = flags.GetBool(flag.Name)
+ case "hideLoginButton":
+ set.HideLoginButton, err = flags.GetBool(flag.Name)
+ case "createUserDir":
+ set.CreateUserDir, err = flags.GetBool(flag.Name)
+ case "minimumPasswordLength":
+ set.MinimumPasswordLength, err = flags.GetUint(flag.Name)
+ case "shell":
+ var shell string
+ shell, err = flags.GetString(flag.Name)
+ if err == nil {
+ set.Shell = convertCmdStrToCmdArray(shell)
+ }
+ case "fileMode":
+ set.FileMode, err = getAndParseFileMode(flags, flag.Name)
+ case "dirMode":
+ set.DirMode, err = getAndParseFileMode(flags, flag.Name)
+ case "auth.method":
+ hasAuth = true
+ case "auth.logoutPage":
+ set.LogoutPage, err = flags.GetString(flag.Name)
+ case "branding.name":
+ set.Branding.Name, err = flags.GetString(flag.Name)
+ case "branding.theme":
+ set.Branding.Theme, err = flags.GetString(flag.Name)
+ case "branding.color":
+ set.Branding.Color, err = flags.GetString(flag.Name)
+ case "branding.files":
+ set.Branding.Files, err = flags.GetString(flag.Name)
+ case "branding.disableExternal":
+ set.Branding.DisableExternal, err = flags.GetBool(flag.Name)
+ case "branding.disableUsedPercentage":
+ set.Branding.DisableUsedPercentage, err = flags.GetBool(flag.Name)
+ case "tus.chunkSize":
+ set.Tus.ChunkSize, err = flags.GetUint64(flag.Name)
+ case "tus.retryCount":
+ set.Tus.RetryCount, err = flags.GetUint16(flag.Name)
+ }
+
+ if err != nil {
+ errs = append(errs, err)
+ }
+ }
+
+ if all {
+ flags.VisitAll(visit)
+ } else {
+ flags.Visit(visit)
+ }
+
+ err := errors.Join(errs...)
+ if err != nil {
+ return nil, err
+ }
+
+ err = getUserDefaults(flags, &set.Defaults, all)
+ if err != nil {
+ return nil, err
+ }
+
+ if all {
+ set.AuthMethod, auther, err = getAuthentication(flags)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ set.AuthMethod, auther, err = getAuthentication(flags, hasAuth, set, auther)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return auther, nil
+}
diff --git a/cmd/config_cat.go b/cmd/config_cat.go
index 39b1f664..b8d2f48f 100644
--- a/cmd/config_cat.go
+++ b/cmd/config_cat.go
@@ -13,19 +13,19 @@ var configCatCmd = &cobra.Command{
Short: "Prints the configuration",
Long: `Prints the configuration.`,
Args: cobra.NoArgs,
- RunE: python(func(_ *cobra.Command, _ []string, d *pythonData) error {
- set, err := d.store.Settings.Get()
+ RunE: withStore(func(_ *cobra.Command, _ []string, st *store) error {
+ set, err := st.Settings.Get()
if err != nil {
return err
}
- ser, err := d.store.Settings.GetServer()
+ ser, err := st.Settings.GetServer()
if err != nil {
return err
}
- auther, err := d.store.Auth.Get(set.AuthMethod)
+ auther, err := st.Auth.Get(set.AuthMethod)
if err != nil {
return err
}
return printSettings(ser, set, auther)
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/config_export.go b/cmd/config_export.go
index 9877fb63..b19c10b6 100644
--- a/cmd/config_export.go
+++ b/cmd/config_export.go
@@ -15,18 +15,18 @@ var configExportCmd = &cobra.Command{
json or yaml file. This exported configuration can be changed,
and imported again with 'config import' command.`,
Args: jsonYamlArg,
- RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
- settings, err := d.store.Settings.Get()
+ RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
+ settings, err := st.Settings.Get()
if err != nil {
return err
}
- server, err := d.store.Settings.GetServer()
+ server, err := st.Settings.GetServer()
if err != nil {
return err
}
- auther, err := d.store.Auth.Get(settings.AuthMethod)
+ auther, err := st.Auth.Get(settings.AuthMethod)
if err != nil {
return err
}
@@ -42,5 +42,5 @@ and imported again with 'config import' command.`,
return err
}
return nil
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/config_import.go b/cmd/config_import.go
index 7763517d..9a838721 100644
--- a/cmd/config_import.go
+++ b/cmd/config_import.go
@@ -34,11 +34,11 @@ database.
The path must be for a json or yaml file.`,
Args: jsonYamlArg,
- RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
+ RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
var key []byte
var err error
- if d.hadDB {
- settings, settingErr := d.store.Settings.Get()
+ if st.databaseExisted {
+ settings, settingErr := st.Settings.Get()
if settingErr != nil {
return settingErr
}
@@ -53,13 +53,17 @@ The path must be for a json or yaml file.`,
return err
}
+ if file.Settings == nil || file.Server == nil {
+ return errors.New("invalid configuration file: 'settings' or 'server' fields are missing. Please ensure you are importing a file generated by the 'config export' command")
+ }
+
file.Settings.Key = key
- err = d.store.Settings.Save(file.Settings)
+ err = st.Settings.Save(file.Settings)
if err != nil {
return err
}
- err = d.store.Settings.SaveServer(file.Server)
+ err = st.Settings.SaveServer(file.Server)
if err != nil {
return err
}
@@ -98,13 +102,13 @@ The path must be for a json or yaml file.`,
return autherErr
}
- err = d.store.Auth.Save(auther)
+ err = st.Auth.Save(auther)
if err != nil {
return err
}
return printSettings(file.Server, file.Settings, auther)
- }, pythonConfig{allowNoDB: true}),
+ }, storeOptions{allowsNoDatabase: true}),
}
func getAuther(sample auth.Auther, data interface{}) (interface{}, error) {
diff --git a/cmd/config_init.go b/cmd/config_init.go
index 693b6ace..359d02a3 100644
--- a/cmd/config_init.go
+++ b/cmd/config_init.go
@@ -22,158 +22,31 @@ this options can be changed in the future with the command
to the defaults when creating new users and you don't
override the options.`,
Args: cobra.NoArgs,
- RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
- defaults := settings.UserDefaults{}
+ RunE: withStore(func(cmd *cobra.Command, _ []string, st *store) error {
flags := cmd.Flags()
- err := getUserDefaults(flags, &defaults, true)
- if err != nil {
- return err
- }
- authMethod, auther, err := getAuthentication(flags)
+
+ // Initialize config
+ s := &settings.Settings{Key: generateKey()}
+ ser := &settings.Server{}
+
+ // Fill config with options
+ auther, err := getSettings(flags, s, ser, nil, true)
if err != nil {
return err
}
- key := generateKey()
-
- signup, err := getBool(flags, "signup")
+ // Save updated config
+ err = st.Settings.Save(s)
if err != nil {
return err
}
- hideLoginButton, err := getBool(flags, "hide-login-button")
+ err = st.Settings.SaveServer(ser)
if err != nil {
return err
}
- createUserDir, err := getBool(flags, "create-user-dir")
- if err != nil {
- return err
- }
-
- minLength, err := getUint(flags, "minimum-password-length")
- if err != nil {
- return err
- }
-
- shell, err := getString(flags, "shell")
- if err != nil {
- return err
- }
-
- brandingName, err := getString(flags, "branding.name")
- if err != nil {
- return err
- }
-
- brandingDisableExternal, err := getBool(flags, "branding.disableExternal")
- if err != nil {
- return err
- }
-
- brandingDisableUsedPercentage, err := getBool(flags, "branding.disableUsedPercentage")
- if err != nil {
- return err
- }
-
- brandingTheme, err := getString(flags, "branding.theme")
- if err != nil {
- return err
- }
-
- brandingFiles, err := getString(flags, "branding.files")
- if err != nil {
- return err
- }
-
- s := &settings.Settings{
- Key: key,
- Signup: signup,
- HideLoginButton: hideLoginButton,
- CreateUserDir: createUserDir,
- MinimumPasswordLength: minLength,
- Shell: convertCmdStrToCmdArray(shell),
- AuthMethod: authMethod,
- Defaults: defaults,
- Branding: settings.Branding{
- Name: brandingName,
- DisableExternal: brandingDisableExternal,
- DisableUsedPercentage: brandingDisableUsedPercentage,
- Theme: brandingTheme,
- Files: brandingFiles,
- },
- }
-
- s.FileMode, err = getMode(flags, "file-mode")
- if err != nil {
- return err
- }
-
- s.DirMode, err = getMode(flags, "dir-mode")
- if err != nil {
- return err
- }
-
- address, err := getString(flags, "address")
- if err != nil {
- return err
- }
-
- socket, err := getString(flags, "socket")
- if err != nil {
- return err
- }
-
- root, err := getString(flags, "root")
- if err != nil {
- return err
- }
-
- baseURL, err := getString(flags, "baseurl")
- if err != nil {
- return err
- }
-
- tlsKey, err := getString(flags, "key")
- if err != nil {
- return err
- }
-
- cert, err := getString(flags, "cert")
- if err != nil {
- return err
- }
-
- port, err := getString(flags, "port")
- if err != nil {
- return err
- }
-
- log, err := getString(flags, "log")
- if err != nil {
- return err
- }
-
- ser := &settings.Server{
- Address: address,
- Socket: socket,
- Root: root,
- BaseURL: baseURL,
- TLSKey: tlsKey,
- TLSCert: cert,
- Port: port,
- Log: log,
- }
-
- err = d.store.Settings.Save(s)
- if err != nil {
- return err
- }
- err = d.store.Settings.SaveServer(ser)
- if err != nil {
- return err
- }
- err = d.store.Auth.Save(auther)
+ err = st.Auth.Save(auther)
if err != nil {
return err
}
@@ -184,5 +57,5 @@ Now add your first user via 'filebrowser users add' and then you just
need to call the main command to boot up the server.
`)
return printSettings(ser, s, auther)
- }, pythonConfig{noDB: true}),
+ }, storeOptions{expectsNoDatabase: true}),
}
diff --git a/cmd/config_set.go b/cmd/config_set.go
index 255ef470..df357a02 100644
--- a/cmd/config_set.go
+++ b/cmd/config_set.go
@@ -2,7 +2,6 @@ package cmd
import (
"github.com/spf13/cobra"
- "github.com/spf13/pflag"
)
func init() {
@@ -16,107 +15,47 @@ var configSetCmd = &cobra.Command{
Long: `Updates the configuration. Set the flags for the options
you want to change. Other options will remain unchanged.`,
Args: cobra.NoArgs,
- RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
+ RunE: withStore(func(cmd *cobra.Command, _ []string, st *store) error {
flags := cmd.Flags()
- set, err := d.store.Settings.Get()
+
+ // Read existing config
+ set, err := st.Settings.Get()
if err != nil {
return err
}
- ser, err := d.store.Settings.GetServer()
+ ser, err := st.Settings.GetServer()
if err != nil {
return err
}
- hasAuth := false
- flags.Visit(func(flag *pflag.Flag) {
- if err != nil {
- return
- }
- switch flag.Name {
- case "baseurl":
- ser.BaseURL, err = getString(flags, flag.Name)
- case "root":
- ser.Root, err = getString(flags, flag.Name)
- case "socket":
- ser.Socket, err = getString(flags, flag.Name)
- case "cert":
- ser.TLSCert, err = getString(flags, flag.Name)
- case "key":
- ser.TLSKey, err = getString(flags, flag.Name)
- case "address":
- ser.Address, err = getString(flags, flag.Name)
- case "port":
- ser.Port, err = getString(flags, flag.Name)
- case "log":
- ser.Log, err = getString(flags, flag.Name)
- case "hide-login-button":
- set.HideLoginButton, err = getBool(flags, flag.Name)
- case "signup":
- set.Signup, err = getBool(flags, flag.Name)
- case "auth.method":
- hasAuth = true
- case "shell":
- var shell string
- shell, err = getString(flags, flag.Name)
- set.Shell = convertCmdStrToCmdArray(shell)
- case "create-user-dir":
- set.CreateUserDir, err = getBool(flags, flag.Name)
- case "minimum-password-length":
- set.MinimumPasswordLength, err = getUint(flags, flag.Name)
- case "branding.name":
- set.Branding.Name, err = getString(flags, flag.Name)
- case "branding.color":
- set.Branding.Color, err = getString(flags, flag.Name)
- case "branding.theme":
- set.Branding.Theme, err = getString(flags, flag.Name)
- case "branding.disableExternal":
- set.Branding.DisableExternal, err = getBool(flags, flag.Name)
- case "branding.disableUsedPercentage":
- set.Branding.DisableUsedPercentage, err = getBool(flags, flag.Name)
- case "branding.files":
- set.Branding.Files, err = getString(flags, flag.Name)
- case "file-mode":
- set.FileMode, err = getMode(flags, flag.Name)
- case "dir-mode":
- set.DirMode, err = getMode(flags, flag.Name)
- }
- })
-
+ auther, err := st.Auth.Get(set.AuthMethod)
if err != nil {
return err
}
- err = getUserDefaults(flags, &set.Defaults, false)
+ // Get updated config
+ auther, err = getSettings(flags, set, ser, auther, false)
if err != nil {
return err
}
- // read the defaults
- auther, err := d.store.Auth.Get(set.AuthMethod)
+ // Save updated config
+ err = st.Auth.Save(auther)
if err != nil {
return err
}
- // check if there are new flags for existing auth method
- set.AuthMethod, auther, err = getAuthentication(flags, hasAuth, set, auther)
+ err = st.Settings.Save(set)
if err != nil {
return err
}
- err = d.store.Auth.Save(auther)
- if err != nil {
- return err
- }
- err = d.store.Settings.Save(set)
- if err != nil {
- return err
- }
- err = d.store.Settings.SaveServer(ser)
+ err = st.Settings.SaveServer(ser)
if err != nil {
return err
}
return printSettings(ser, set, auther)
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/docs.go b/cmd/docs.go
index 90e5a259..d65a29be 100644
--- a/cmd/docs.go
+++ b/cmd/docs.go
@@ -3,36 +3,18 @@ package cmd
import (
"bytes"
"fmt"
- "io"
"os"
- "path/filepath"
- "sort"
+ "path"
+ "regexp"
"strings"
"github.com/spf13/cobra"
- "github.com/spf13/pflag"
+ "github.com/spf13/cobra/doc"
)
func init() {
rootCmd.AddCommand(docsCmd)
- docsCmd.Flags().StringP("path", "p", "./docs", "path to save the docs")
-}
-
-func printToc(names []string) {
- for i, name := range names {
- name = strings.TrimSuffix(name, filepath.Ext(name))
- name = strings.ReplaceAll(name, "-", " ")
- names[i] = name
- }
-
- sort.Strings(names)
-
- toc := ""
- for _, name := range names {
- toc += "* [" + name + "](cli/" + strings.ReplaceAll(name, " ", "-") + ".md)\n"
- }
-
- fmt.Println(toc)
+ docsCmd.Flags().String("out", "www/docs/cli", "directory to write the docs to")
}
var docsCmd = &cobra.Command{
@@ -40,115 +22,61 @@ var docsCmd = &cobra.Command{
Hidden: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
- dir, err := getString(cmd.Flags(), "path")
+ outputDir, err := cmd.Flags().GetString("out")
if err != nil {
return err
}
- err = generateDocs(rootCmd, dir)
+ tempDir, err := os.MkdirTemp(os.TempDir(), "filebrowser-docs-")
if err != nil {
return err
}
- names := []string{}
+ defer os.RemoveAll(tempDir)
- err = filepath.Walk(dir, func(_ string, info os.FileInfo, err error) error {
- if err != nil || info.IsDir() {
- return err
- }
+ rootCmd.Root().DisableAutoGenTag = true
- if !strings.HasPrefix(info.Name(), "filebrowser") {
- return nil
- }
-
- names = append(names, info.Name())
- return nil
+ err = doc.GenMarkdownTreeCustom(cmd.Root(), tempDir, func(_ string) string {
+ return ""
+ }, func(s string) string {
+ return s
})
if err != nil {
return err
}
- printToc(names)
- return nil
- },
-}
-
-func generateDocs(cmd *cobra.Command, dir string) error {
- for _, c := range cmd.Commands() {
- if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
- continue
- }
-
- err := generateDocs(c, dir)
+ entries, err := os.ReadDir(tempDir)
if err != nil {
return err
}
- }
- basename := strings.ReplaceAll(cmd.CommandPath(), " ", "-") + ".md"
- filename := filepath.Join(dir, basename)
- f, err := os.Create(filename)
- if err != nil {
- return err
- }
- defer f.Close()
- return generateMarkdown(cmd, f)
-}
-
-func generateMarkdown(cmd *cobra.Command, w io.Writer) error {
- cmd.InitDefaultHelpCmd()
- cmd.InitDefaultHelpFlag()
-
- buf := new(bytes.Buffer)
- name := cmd.CommandPath()
-
- short := cmd.Short
- long := cmd.Long
- if long == "" {
- long = short
- }
-
- buf.WriteString("---\ndescription: " + short + "\n---\n\n")
- buf.WriteString("# " + name + "\n\n")
- buf.WriteString("## Synopsis\n\n")
- buf.WriteString(long + "\n\n")
-
- if cmd.Runnable() {
- _, _ = fmt.Fprintf(buf, "```\n%s\n```\n\n", cmd.UseLine())
- }
-
- if cmd.Example != "" {
- buf.WriteString("## Examples\n\n")
- _, _ = fmt.Fprintf(buf, "```\n%s\n```\n\n", cmd.Example)
- }
-
- printOptions(buf, cmd)
- _, err := buf.WriteTo(w)
- return err
-}
-
-func generateFlagsTable(fs *pflag.FlagSet, buf io.StringWriter) {
- _, _ = buf.WriteString("| Name | Shorthand | Usage |\n")
- _, _ = buf.WriteString("|------|-----------|-------|\n")
-
- fs.VisitAll(func(f *pflag.Flag) {
- _, _ = buf.WriteString("|" + f.Name + "|" + f.Shorthand + "|" + f.Usage + "|\n")
- })
-}
-
-func printOptions(buf *bytes.Buffer, cmd *cobra.Command) {
- flags := cmd.NonInheritedFlags()
- flags.SetOutput(buf)
- if flags.HasAvailableFlags() {
- buf.WriteString("## Options\n\n")
- generateFlagsTable(flags, buf)
- buf.WriteString("\n")
- }
-
- parentFlags := cmd.InheritedFlags()
- parentFlags.SetOutput(buf)
- if parentFlags.HasAvailableFlags() {
- buf.WriteString("### Inherited\n\n")
- generateFlagsTable(parentFlags, buf)
- buf.WriteString("\n")
- }
+ headerRegex := regexp.MustCompile(`(?m)^(##)(.*)$`)
+ linkRegex := regexp.MustCompile(`\(filebrowser(.*)\.md\)`)
+
+ fmt.Println("Generated Documents:")
+
+ for _, entry := range entries {
+ srcPath := path.Join(tempDir, entry.Name())
+ dstPath := path.Join(outputDir, strings.ReplaceAll(entry.Name(), "_", "-"))
+
+ data, err := os.ReadFile(srcPath)
+ if err != nil {
+ return err
+ }
+
+ data = headerRegex.ReplaceAll(data, []byte("#$2"))
+ data = linkRegex.ReplaceAllFunc(data, func(b []byte) []byte {
+ return bytes.ReplaceAll(b, []byte("_"), []byte("-"))
+ })
+ data = bytes.ReplaceAll(data, []byte("## SEE ALSO"), []byte("## See Also"))
+
+ err = os.WriteFile(dstPath, data, 0666)
+ if err != nil {
+ return err
+ }
+
+ fmt.Println("- " + dstPath)
+ }
+
+ return nil
+ },
}
diff --git a/cmd/root.go b/cmd/root.go
index d8be251a..981eec4f 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -13,20 +13,17 @@ import (
"os"
"os/signal"
"path/filepath"
- "strings"
"syscall"
"time"
- homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/afero"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
- v "github.com/spf13/viper"
+ "github.com/spf13/viper"
lumberjack "gopkg.in/natefinch/lumberjack.v2"
"github.com/filebrowser/filebrowser/v2/auth"
"github.com/filebrowser/filebrowser/v2/diskcache"
- fbErrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/frontend"
fbhttp "github.com/filebrowser/filebrowser/v2/http"
"github.com/filebrowser/filebrowser/v2/img"
@@ -36,28 +33,67 @@ import (
)
var (
- cfgFile string
+ flagNamesMigrations = map[string]string{
+ "file-mode": "fileMode",
+ "dir-mode": "dirMode",
+ "hide-login-button": "hideLoginButton",
+ "create-user-dir": "createUserDir",
+ "minimum-password-length": "minimumPasswordLength",
+ "socket-perm": "socketPerm",
+ "disable-thumbnails": "disableThumbnails",
+ "disable-preview-resize": "disablePreviewResize",
+ "disable-exec": "disableExec",
+ "disable-type-detection-by-header": "disableTypeDetectionByHeader",
+ "img-processors": "imageProcessors",
+ "cache-dir": "cacheDir",
+ "token-expiration-time": "tokenExpirationTime",
+ "baseurl": "baseURL",
+ }
+
+ warnedFlags = map[string]bool{}
)
+// TODO(remove): remove after July 2026.
+func migrateFlagNames(_ *pflag.FlagSet, name string) pflag.NormalizedName {
+ if newName, ok := flagNamesMigrations[name]; ok {
+
+ if !warnedFlags[name] {
+ warnedFlags[name] = true
+ log.Printf("DEPRECATION NOTICE: Flag --%s has been deprecated, use --%s instead\n", name, newName)
+ }
+
+ name = newName
+ }
+
+ return pflag.NormalizedName(name)
+}
+
func init() {
- cobra.OnInitialize(initConfig)
rootCmd.SilenceUsage = true
+ rootCmd.SetGlobalNormalizationFunc(migrateFlagNames)
+
cobra.MousetrapHelpText = ""
rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n")
- flags := rootCmd.Flags()
+ // Flags available across the whole program
persistent := rootCmd.PersistentFlags()
-
- persistent.StringVarP(&cfgFile, "config", "c", "", "config file path")
+ persistent.StringP("config", "c", "", "config file path")
persistent.StringP("database", "d", "./filebrowser.db", "database path")
- flags.Bool("noauth", false, "use the noauth auther when using quick setup")
- flags.String("username", "admin", "username for the first user when using quick config")
- flags.String("password", "", "hashed password for the first user when using quick config")
+ // Runtime flags for the root command
+ flags := rootCmd.Flags()
+ flags.Bool("noauth", false, "use the noauth auther when using quick setup")
+ flags.String("username", "admin", "username for the first user when using quick setup")
+ flags.String("password", "", "hashed password for the first user when using quick setup")
+ flags.Uint32("socketPerm", 0666, "unix socket file permissions")
+ flags.String("cacheDir", "", "file cache directory (disabled if empty)")
+ flags.Int("imageProcessors", 4, "image processors count")
addServerFlags(flags)
}
+// addServerFlags adds server related flags to the given FlagSet. These flags are available
+// in both the root command, config set and config init commands.
func addServerFlags(flags *pflag.FlagSet) {
flags.StringP("address", "a", "127.0.0.1", "address to listen on")
flags.StringP("log", "l", "stdout", "log output")
@@ -66,15 +102,13 @@ func addServerFlags(flags *pflag.FlagSet) {
flags.StringP("key", "k", "", "tls key")
flags.StringP("root", "r", ".", "root to prepend to relative paths")
flags.String("socket", "", "socket to listen to (cannot be used with address, port, cert nor key flags)")
- flags.Uint32("socket-perm", 0666, "unix socket file permissions")
- flags.StringP("baseurl", "b", "", "base url")
- flags.String("cache-dir", "", "file cache directory (disabled if empty)")
- flags.String("token-expiration-time", "2h", "user session timeout")
- flags.Int("img-processors", 4, "image processors count") //nolint:mnd
- flags.Bool("disable-thumbnails", false, "disable image thumbnails")
- flags.Bool("disable-preview-resize", false, "disable resize of image previews")
- flags.Bool("disable-exec", true, "disables Command Runner feature")
- flags.Bool("disable-type-detection-by-header", false, "disables type detection by reading file headers")
+ flags.StringP("baseURL", "b", "", "base url")
+ flags.String("tokenExpirationTime", "2h", "user session timeout")
+ flags.Bool("disableThumbnails", false, "disable image thumbnails")
+ flags.Bool("disablePreviewResize", false, "disable resize of image previews")
+ flags.Bool("disableExec", true, "disables Command Runner feature")
+ flags.Bool("disableTypeDetectionByHeader", false, "disables type detection by reading file headers")
+ flags.Bool("disableImageResolutionCalc", false, "disables image resolution calculation by reading image files")
}
var rootCmd = &cobra.Command{
@@ -89,65 +123,60 @@ it. Don't worry: you don't need to setup a separate database server.
We're using Bolt DB which is a single file database and all managed
by ourselves.
-For this specific command, all the flags you have available (except
-"config" for the configuration file), can be given either through
-environment variables or configuration files.
+For this command, all flags are available as environmental variables,
+except for "--config", which specifies the configuration file to use.
+The environment variables are prefixed by "FB_" followed by the flag name in
+UPPER_SNAKE_CASE. For example, the flag "--disablePreviewResize" is available
+as FB_DISABLE_PREVIEW_RESIZE.
-If you don't set "config", it will look for a configuration file called
-.filebrowser.{json, toml, yaml, yml} in the following directories:
+If "--config" is not specified, File Browser will look for a configuration
+file named .filebrowser.{json, toml, yaml, yml} in the following directories:
- ./
- $HOME/
- /etc/filebrowser/
+**Note:** Only the options listed below can be set via the config file or
+environment variables. Other configuration options live exclusively in the
+database and so they must be set by the "config set" or "config
+import" commands.
+
The precedence of the configuration values are as follows:
-- flags
-- environment variables
-- configuration file
-- database values
-- defaults
-
-The environment variables are prefixed by "FB_" followed by the option
-name in caps. So to set "database" via an env variable, you should
-set FB_DATABASE.
+- Flags
+- Environment variables
+- Configuration file
+- Database values
+- Defaults
Also, if the database path doesn't exist, File Browser will enter into
the quick setup mode and a new database will be bootstrapped and a new
user created with the credentials from options "username" and "password".`,
- RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
- log.Println(cfgFile)
-
- if !d.hadDB {
- err := quickSetup(cmd.Flags(), *d)
+ RunE: withViperAndStore(func(_ *cobra.Command, _ []string, v *viper.Viper, st *store) error {
+ if !st.databaseExisted {
+ err := quickSetup(v, st.Storage)
if err != nil {
return err
}
}
// build img service
- workersCount, err := cmd.Flags().GetInt("img-processors")
- if err != nil {
- return err
- }
- if workersCount < 1 {
+ imgWorkersCount := v.GetInt("imageProcessors")
+ if imgWorkersCount < 1 {
return errors.New("image resize workers count could not be < 1")
}
- imgSvc := img.New(workersCount)
+ imageService := img.New(imgWorkersCount)
var fileCache diskcache.Interface = diskcache.NewNoOp()
- cacheDir, err := cmd.Flags().GetString("cache-dir")
- if err != nil {
- return err
- }
+ cacheDir := v.GetString("cacheDir")
if cacheDir != "" {
- if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet
+ if err := os.MkdirAll(cacheDir, 0700); err != nil {
return fmt.Errorf("can't make directory %s: %w", cacheDir, err)
}
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
}
- server, err := getRunParams(cmd.Flags(), d.store)
+ server, err := getServerSettings(v, st.Storage)
if err != nil {
return err
}
@@ -169,16 +198,13 @@ user created with the credentials from options "username" and "password".`,
if err != nil {
return err
}
- socketPerm, err := cmd.Flags().GetUint32("socket-perm") //nolint:govet
- if err != nil {
- return err
- }
+ socketPerm := v.GetUint32("socketPerm")
err = os.Chmod(server.Socket, os.FileMode(socketPerm))
if err != nil {
return err
}
case server.TLSKey != "" && server.TLSCert != "":
- cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:govet
+ cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey)
if err != nil {
return err
}
@@ -201,7 +227,7 @@ user created with the credentials from options "username" and "password".`,
panic(err)
}
- handler, err := fbhttp.NewHandler(imgSvc, fileCache, d.store, server, assetsFs)
+ handler, err := fbhttp.NewHandler(imageService, fileCache, st.Storage, server, assetsFs)
if err != nil {
return err
}
@@ -233,7 +259,7 @@ user created with the credentials from options "username" and "password".`,
sig := <-sigc
log.Println("Got signal:", sig)
- shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second) //nolint:mnd
+ shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second)
defer shutdownRelease()
if err := srv.Shutdown(shutdownCtx); err != nil {
@@ -241,66 +267,82 @@ user created with the credentials from options "username" and "password".`,
}
log.Println("Graceful shutdown complete.")
- switch sig {
- case syscall.SIGHUP:
- d.err = fbErrors.ErrSighup
- case syscall.SIGINT:
- d.err = fbErrors.ErrSigint
- case syscall.SIGQUIT:
- d.err = fbErrors.ErrSigquit
- case syscall.SIGTERM:
- d.err = fbErrors.ErrSigTerm
- }
-
- return d.err
- }, pythonConfig{allowNoDB: true}),
+ return nil
+ }, storeOptions{allowsNoDatabase: true}),
}
-//nolint:gocyclo
-func getRunParams(flags *pflag.FlagSet, st *storage.Storage) (*settings.Server, error) {
+func getServerSettings(v *viper.Viper, st *storage.Storage) (*settings.Server, error) {
server, err := st.Settings.GetServer()
if err != nil {
return nil, err
}
- if val, set := getStringParamB(flags, "root"); set {
- server.Root = val
- }
-
- if val, set := getStringParamB(flags, "baseurl"); set {
- server.BaseURL = val
- }
-
- if val, set := getStringParamB(flags, "log"); set {
- server.Log = val
- }
-
isSocketSet := false
isAddrSet := false
- if val, set := getStringParamB(flags, "address"); set {
- server.Address = val
- isAddrSet = isAddrSet || set
+ if v.IsSet("address") {
+ server.Address = v.GetString("address")
+ isAddrSet = true
}
- if val, set := getStringParamB(flags, "port"); set {
- server.Port = val
- isAddrSet = isAddrSet || set
+ if v.IsSet("log") {
+ server.Log = v.GetString("log")
}
- if val, set := getStringParamB(flags, "key"); set {
- server.TLSKey = val
- isAddrSet = isAddrSet || set
+ if v.IsSet("port") {
+ server.Port = v.GetString("port")
+ isAddrSet = true
}
- if val, set := getStringParamB(flags, "cert"); set {
- server.TLSCert = val
- isAddrSet = isAddrSet || set
+ if v.IsSet("cert") {
+ server.TLSCert = v.GetString("cert")
+ isAddrSet = true
}
- if val, set := getStringParamB(flags, "socket"); set {
- server.Socket = val
- isSocketSet = isSocketSet || set
+ if v.IsSet("key") {
+ server.TLSKey = v.GetString("key")
+ isAddrSet = true
+ }
+
+ if v.IsSet("root") {
+ server.Root = v.GetString("root")
+ }
+
+ if v.IsSet("socket") {
+ server.Socket = v.GetString("socket")
+ isSocketSet = true
+ }
+
+ if v.IsSet("baseURL") {
+ server.BaseURL = v.GetString("baseURL")
+ // TODO(remove): remove after July 2026.
+ } else if v := os.Getenv("FB_BASEURL"); v != "" {
+ log.Println("DEPRECATION NOTICE: Environment variable FB_BASEURL has been deprecated, use FB_BASE_URL instead")
+ server.BaseURL = v
+ }
+
+ if v.IsSet("tokenExpirationTime") {
+ server.TokenExpirationTime = v.GetString("tokenExpirationTime")
+ }
+
+ if v.IsSet("disableThumbnails") {
+ server.EnableThumbnails = !v.GetBool("disableThumbnails")
+ }
+
+ if v.IsSet("disablePreviewResize") {
+ server.ResizePreview = !v.GetBool("disablePreviewResize")
+ }
+
+ if v.IsSet("disableTypeDetectionByHeader") {
+ server.TypeDetectionByHeader = !v.GetBool("disableTypeDetectionByHeader")
+ }
+
+ if v.IsSet("disableImageResolutionCalc") {
+ server.ImageResolutionCal = !v.GetBool("disableImageResolutionCalc")
+ }
+
+ if v.IsSet("disableExec") {
+ server.EnableExec = !v.GetBool("disableExec")
}
if isAddrSet && isSocketSet {
@@ -312,18 +354,6 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) (*settings.Server,
server.Socket = ""
}
- disableThumbnails := getBoolParam(flags, "disable-thumbnails")
- server.EnableThumbnails = !disableThumbnails
-
- disablePreviewResize := getBoolParam(flags, "disable-preview-resize")
- server.ResizePreview = !disablePreviewResize
-
- disableTypeDetectionByHeader := getBoolParam(flags, "disable-type-detection-by-header")
- server.TypeDetectionByHeader = !disableTypeDetectionByHeader
-
- disableExec := getBoolParam(flags, "disable-exec")
- server.EnableExec = !disableExec
-
if server.EnableExec {
log.Println("WARNING: Command Runner feature enabled!")
log.Println("WARNING: This feature has known security vulnerabilities and should not")
@@ -331,71 +361,9 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) (*settings.Server,
log.Println("WARNING: read https://github.com/filebrowser/filebrowser/issues/5199")
}
- if val, set := getStringParamB(flags, "token-expiration-time"); set {
- server.TokenExpirationTime = val
- }
-
return server, nil
}
-// getBoolParamB returns a parameter as a string and a boolean to tell if it is different from the default
-//
-// NOTE: we could simply bind the flags to viper and use IsSet.
-// Although there is a bug on Viper that always returns true on IsSet
-// if a flag is binded. Our alternative way is to manually check
-// the flag and then the value from env/config/gotten by viper.
-// https://github.com/spf13/viper/pull/331
-func getBoolParamB(flags *pflag.FlagSet, key string) (value, ok bool) {
- value, _ = flags.GetBool(key)
-
- // If set on Flags, use it.
- if flags.Changed(key) {
- return value, true
- }
-
- // If set through viper (env, config), return it.
- if v.IsSet(key) {
- return v.GetBool(key), true
- }
-
- // Otherwise use default value on flags.
- return value, false
-}
-
-func getBoolParam(flags *pflag.FlagSet, key string) bool {
- val, _ := getBoolParamB(flags, key)
- return val
-}
-
-// getStringParamB returns a parameter as a string and a boolean to tell if it is different from the default
-//
-// NOTE: we could simply bind the flags to viper and use IsSet.
-// Although there is a bug on Viper that always returns true on IsSet
-// if a flag is binded. Our alternative way is to manually check
-// the flag and then the value from env/config/gotten by viper.
-// https://github.com/spf13/viper/pull/331
-func getStringParamB(flags *pflag.FlagSet, key string) (string, bool) {
- value, _ := flags.GetString(key)
-
- // If set on Flags, use it.
- if flags.Changed(key) {
- return value, true
- }
-
- // If set through viper (env, config), return it.
- if v.IsSet(key) {
- return v.GetString(key), true
- }
-
- // Otherwise use default value on flags.
- return value, false
-}
-
-func getStringParam(flags *pflag.FlagSet, key string) string {
- val, _ := getStringParamB(flags, key)
- return val
-}
-
func setupLog(logMethod string) {
switch logMethod {
case "stdout":
@@ -414,7 +382,7 @@ func setupLog(logMethod string) {
}
}
-func quickSetup(flags *pflag.FlagSet, d pythonData) error {
+func quickSetup(v *viper.Viper, s *storage.Storage) error {
log.Println("Performing quick setup")
set := &settings.Settings{
@@ -425,10 +393,11 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) error {
MinimumPasswordLength: settings.DefaultMinimumPasswordLength,
UserHomeBasePath: settings.DefaultUsersHomeBasePath,
Defaults: settings.UserDefaults{
- Scope: ".",
- Locale: "en",
- SingleClick: false,
- AceEditorTheme: getStringParam(flags, "defaults.aceEditorTheme"),
+ Scope: ".",
+ Locale: "en",
+ SingleClick: false,
+ RedirectAfterCopyMove: true,
+ AceEditorTheme: v.GetString("defaults.aceEditorTheme"),
Perm: users.Permissions{
Admin: false,
Execute: true,
@@ -452,39 +421,45 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) error {
}
var err error
- if _, noauth := getStringParamB(flags, "noauth"); noauth {
+ if v.GetBool("noauth") {
set.AuthMethod = auth.MethodNoAuth
- err = d.store.Auth.Save(&auth.NoAuth{})
+ err = s.Auth.Save(&auth.NoAuth{})
} else {
set.AuthMethod = auth.MethodJSONAuth
- err = d.store.Auth.Save(&auth.JSONAuth{})
+ err = s.Auth.Save(&auth.JSONAuth{})
}
if err != nil {
return err
}
- err = d.store.Settings.Save(set)
+ err = s.Settings.Save(set)
if err != nil {
return err
}
ser := &settings.Server{
- BaseURL: getStringParam(flags, "baseurl"),
- Port: getStringParam(flags, "port"),
- Log: getStringParam(flags, "log"),
- TLSKey: getStringParam(flags, "key"),
- TLSCert: getStringParam(flags, "cert"),
- Address: getStringParam(flags, "address"),
- Root: getStringParam(flags, "root"),
+ BaseURL: v.GetString("baseURL"),
+ Port: v.GetString("port"),
+ Log: v.GetString("log"),
+ TLSKey: v.GetString("key"),
+ TLSCert: v.GetString("cert"),
+ Address: v.GetString("address"),
+ Root: v.GetString("root"),
+ TokenExpirationTime: v.GetString("tokenExpirationTime"),
+ EnableThumbnails: !v.GetBool("disableThumbnails"),
+ ResizePreview: !v.GetBool("disablePreviewResize"),
+ EnableExec: !v.GetBool("disableExec"),
+ TypeDetectionByHeader: !v.GetBool("disableTypeDetectionByHeader"),
+ ImageResolutionCal: !v.GetBool("disableImageResolutionCalc"),
}
- err = d.store.Settings.SaveServer(ser)
+ err = s.Settings.SaveServer(ser)
if err != nil {
return err
}
- username := getStringParam(flags, "username")
- password := getStringParam(flags, "password")
+ username := v.GetString("username")
+ password := v.GetString("password")
if password == "" {
var pwd string
@@ -515,34 +490,5 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) error {
set.Defaults.Apply(user)
user.Perm.Admin = true
- return d.store.Users.Save(user)
-}
-
-func initConfig() {
- if cfgFile == "" {
- home, err := homedir.Dir()
- if err != nil {
- panic(err)
- }
- v.AddConfigPath(".")
- v.AddConfigPath(home)
- v.AddConfigPath("/etc/filebrowser/")
- v.SetConfigName(".filebrowser")
- } else {
- v.SetConfigFile(cfgFile)
- }
-
- v.SetEnvPrefix("FB")
- v.AutomaticEnv()
- v.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_"))
-
- if err := v.ReadInConfig(); err != nil {
- var configParseError v.ConfigParseError
- if errors.As(err, &configParseError) {
- panic(err)
- }
- cfgFile = "No config file used"
- } else {
- cfgFile = "Using config file: " + v.ConfigFileUsed()
- }
+ return s.Users.Save(user)
}
diff --git a/cmd/rule_rm.go b/cmd/rule_rm.go
index 26e801ae..8ed8f151 100644
--- a/cmd/rule_rm.go
+++ b/cmd/rule_rm.go
@@ -40,7 +40,7 @@ including 'index_end'.`,
return nil
},
- RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
+ RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
i, err := strconv.Atoi(args[0])
if err != nil {
return err
@@ -55,14 +55,14 @@ including 'index_end'.`,
user := func(u *users.User) error {
u.Rules = append(u.Rules[:i], u.Rules[f+1:]...)
- return d.store.Users.Save(u)
+ return st.Users.Save(u)
}
global := func(s *settings.Settings) error {
s.Rules = append(s.Rules[:i], s.Rules[f+1:]...)
- return d.store.Settings.Save(s)
+ return st.Settings.Save(s)
}
- return runRules(d.store, cmd, user, global)
- }, pythonConfig{}),
+ return runRules(st.Storage, cmd, user, global)
+ }, storeOptions{}),
}
diff --git a/cmd/rules.go b/cmd/rules.go
index ffa5b1ae..bdb1d1cf 100644
--- a/cmd/rules.go
+++ b/cmd/rules.go
@@ -69,11 +69,12 @@ func runRules(st *storage.Storage, cmd *cobra.Command, usersFn func(*users.User)
}
func getUserIdentifier(flags *pflag.FlagSet) (interface{}, error) {
- id, err := getUint(flags, "id")
+ id, err := flags.GetUint("id")
if err != nil {
return nil, err
}
- username, err := getString(flags, "username")
+
+ username, err := flags.GetString("username")
if err != nil {
return nil, err
}
diff --git a/cmd/rules_add.go b/cmd/rules_add.go
index 9d1f0cf9..3b34d940 100644
--- a/cmd/rules_add.go
+++ b/cmd/rules_add.go
@@ -21,15 +21,19 @@ var rulesAddCmd = &cobra.Command{
Short: "Add a global rule or user rule",
Long: `Add a global rule or user rule.`,
Args: cobra.ExactArgs(1),
- RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
- allow, err := getBool(cmd.Flags(), "allow")
+ RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
+ flags := cmd.Flags()
+
+ allow, err := flags.GetBool("allow")
if err != nil {
return err
}
- regex, err := getBool(cmd.Flags(), "regex")
+
+ regex, err := flags.GetBool("regex")
if err != nil {
return err
}
+
exp := args[0]
if regex {
@@ -49,14 +53,14 @@ var rulesAddCmd = &cobra.Command{
user := func(u *users.User) error {
u.Rules = append(u.Rules, rule)
- return d.store.Users.Save(u)
+ return st.Users.Save(u)
}
global := func(s *settings.Settings) error {
s.Rules = append(s.Rules, rule)
- return d.store.Settings.Save(s)
+ return st.Settings.Save(s)
}
- return runRules(d.store, cmd, user, global)
- }, pythonConfig{}),
+ return runRules(st.Storage, cmd, user, global)
+ }, storeOptions{}),
}
diff --git a/cmd/rules_ls.go b/cmd/rules_ls.go
index 67a279dc..9aa073d0 100644
--- a/cmd/rules_ls.go
+++ b/cmd/rules_ls.go
@@ -13,7 +13,7 @@ var rulesLsCommand = &cobra.Command{
Short: "List global rules or user specific rules",
Long: `List global rules or user specific rules.`,
Args: cobra.NoArgs,
- RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
- return runRules(d.store, cmd, nil, nil)
- }, pythonConfig{}),
+ RunE: withStore(func(cmd *cobra.Command, _ []string, st *store) error {
+ return runRules(st.Storage, cmd, nil, nil)
+ }, storeOptions{}),
}
diff --git a/cmd/upgrade.go b/cmd/upgrade.go
deleted file mode 100644
index 7142b151..00000000
--- a/cmd/upgrade.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package cmd
-
-import (
- "github.com/spf13/cobra"
-
- "github.com/filebrowser/filebrowser/v2/storage/bolt/importer"
-)
-
-func init() {
- rootCmd.AddCommand(upgradeCmd)
-
- upgradeCmd.Flags().String("old.database", "", "")
- upgradeCmd.Flags().String("old.config", "", "")
- _ = upgradeCmd.MarkFlagRequired("old.database")
-}
-
-var upgradeCmd = &cobra.Command{
- Use: "upgrade",
- Short: "Upgrades an old configuration",
- Long: `Upgrades an old configuration. This command DOES NOT
-import share links because they are incompatible with
-this version.`,
- Args: cobra.NoArgs,
- RunE: func(cmd *cobra.Command, _ []string) error {
- flags := cmd.Flags()
- oldDB, err := getString(flags, "old.database")
- if err != nil {
- return err
- }
- oldConf, err := getString(flags, "old.config")
- if err != nil {
- return err
- }
- db, err := getString(flags, "database")
- if err != nil {
- return err
- }
- return importer.Import(oldDB, oldConf, db)
- },
-}
diff --git a/cmd/users.go b/cmd/users.go
index c272877d..66487862 100644
--- a/cmd/users.go
+++ b/cmd/users.go
@@ -30,13 +30,14 @@ func printUsers(usrs []*users.User) {
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock")
for _, u := range usrs {
- fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t\n",
+ fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t\n",
u.ID,
u.Username,
u.Scope,
u.Locale,
u.ViewMode,
u.SingleClick,
+ u.RedirectAfterCopyMove,
u.Perm.Admin,
u.Perm.Execute,
u.Perm.Create,
@@ -77,69 +78,72 @@ func addUserFlags(flags *pflag.FlagSet) {
flags.String("locale", "en", "locale for users")
flags.String("viewMode", string(users.ListViewMode), "view mode for users")
flags.Bool("singleClick", false, "use single clicks only")
+ flags.Bool("redirectAfterCopyMove", false, "redirect to destination after copy/move")
flags.Bool("dateFormat", false, "use date format (true for absolute time, false for relative)")
flags.Bool("hideDotfiles", false, "hide dotfiles")
flags.String("aceEditorTheme", "", "ace editor's syntax highlighting theme for users")
}
-func getViewMode(flags *pflag.FlagSet) (users.ViewMode, error) {
- viewModeStr, err := getString(flags, "viewMode")
+func getAndParseViewMode(flags *pflag.FlagSet) (users.ViewMode, error) {
+ viewModeStr, err := flags.GetString("viewMode")
if err != nil {
return "", err
}
+
viewMode := users.ViewMode(viewModeStr)
if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode {
return "", errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\"")
}
+
return viewMode, nil
}
-//nolint:gocyclo
func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) error {
- var visitErr error
+ errs := []error{}
+
visit := func(flag *pflag.Flag) {
- if visitErr != nil {
- return
- }
var err error
switch flag.Name {
case "scope":
- defaults.Scope, err = getString(flags, flag.Name)
+ defaults.Scope, err = flags.GetString(flag.Name)
case "locale":
- defaults.Locale, err = getString(flags, flag.Name)
+ defaults.Locale, err = flags.GetString(flag.Name)
case "viewMode":
- defaults.ViewMode, err = getViewMode(flags)
+ defaults.ViewMode, err = getAndParseViewMode(flags)
case "singleClick":
- defaults.SingleClick, err = getBool(flags, flag.Name)
+ defaults.SingleClick, err = flags.GetBool(flag.Name)
+ case "redirectAfterCopyMove":
+ defaults.RedirectAfterCopyMove, err = flags.GetBool(flag.Name)
case "aceEditorTheme":
- defaults.AceEditorTheme, err = getString(flags, flag.Name)
+ defaults.AceEditorTheme, err = flags.GetString(flag.Name)
case "perm.admin":
- defaults.Perm.Admin, err = getBool(flags, flag.Name)
+ defaults.Perm.Admin, err = flags.GetBool(flag.Name)
case "perm.execute":
- defaults.Perm.Execute, err = getBool(flags, flag.Name)
+ defaults.Perm.Execute, err = flags.GetBool(flag.Name)
case "perm.create":
- defaults.Perm.Create, err = getBool(flags, flag.Name)
+ defaults.Perm.Create, err = flags.GetBool(flag.Name)
case "perm.rename":
- defaults.Perm.Rename, err = getBool(flags, flag.Name)
+ defaults.Perm.Rename, err = flags.GetBool(flag.Name)
case "perm.modify":
- defaults.Perm.Modify, err = getBool(flags, flag.Name)
+ defaults.Perm.Modify, err = flags.GetBool(flag.Name)
case "perm.delete":
- defaults.Perm.Delete, err = getBool(flags, flag.Name)
+ defaults.Perm.Delete, err = flags.GetBool(flag.Name)
case "perm.share":
- defaults.Perm.Share, err = getBool(flags, flag.Name)
+ defaults.Perm.Share, err = flags.GetBool(flag.Name)
case "perm.download":
- defaults.Perm.Download, err = getBool(flags, flag.Name)
+ defaults.Perm.Download, err = flags.GetBool(flag.Name)
case "commands":
defaults.Commands, err = flags.GetStringSlice(flag.Name)
case "sorting.by":
- defaults.Sorting.By, err = getString(flags, flag.Name)
+ defaults.Sorting.By, err = flags.GetString(flag.Name)
case "sorting.asc":
- defaults.Sorting.Asc, err = getBool(flags, flag.Name)
+ defaults.Sorting.Asc, err = flags.GetBool(flag.Name)
case "hideDotfiles":
- defaults.HideDotfiles, err = getBool(flags, flag.Name)
+ defaults.HideDotfiles, err = flags.GetBool(flag.Name)
}
+
if err != nil {
- visitErr = err
+ errs = append(errs, err)
}
}
@@ -148,5 +152,6 @@ func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all
} else {
flags.Visit(visit)
}
- return visitErr
+
+ return errors.Join(errs...)
}
diff --git a/cmd/users_add.go b/cmd/users_add.go
index dce7ff98..daf59aa3 100644
--- a/cmd/users_add.go
+++ b/cmd/users_add.go
@@ -16,12 +16,13 @@ var usersAddCmd = &cobra.Command{
Short: "Create a new user",
Long: `Create a new user and add it to the database.`,
Args: cobra.ExactArgs(2),
- RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
- s, err := d.store.Settings.Get()
+ RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
+ flags := cmd.Flags()
+ s, err := st.Settings.Get()
if err != nil {
return err
}
- err = getUserDefaults(cmd.Flags(), &s.Defaults, false)
+ err = getUserDefaults(flags, &s.Defaults, false)
if err != nil {
return err
}
@@ -31,39 +32,36 @@ var usersAddCmd = &cobra.Command{
return err
}
- lockPassword, err := getBool(cmd.Flags(), "lockPassword")
- if err != nil {
- return err
- }
-
- dateFormat, err := getBool(cmd.Flags(), "dateFormat")
- if err != nil {
- return err
- }
-
- hideDotfiles, err := getBool(cmd.Flags(), "hideDotfiles")
- if err != nil {
- return err
- }
-
user := &users.User{
- Username: args[0],
- Password: password,
- LockPassword: lockPassword,
- DateFormat: dateFormat,
- HideDotfiles: hideDotfiles,
+ Username: args[0],
+ Password: password,
+ }
+
+ user.LockPassword, err = flags.GetBool("lockPassword")
+ if err != nil {
+ return err
+ }
+
+ user.DateFormat, err = flags.GetBool("dateFormat")
+ if err != nil {
+ return err
+ }
+
+ user.HideDotfiles, err = flags.GetBool("hideDotfiles")
+ if err != nil {
+ return err
}
s.Defaults.Apply(user)
- servSettings, err := d.store.Settings.GetServer()
+ servSettings, err := st.Settings.GetServer()
if err != nil {
return err
}
// since getUserDefaults() polluted s.Defaults.Scope
// which makes the Scope not the one saved in the db
// we need the right s.Defaults.Scope here
- s2, err := d.store.Settings.Get()
+ s2, err := st.Settings.Get()
if err != nil {
return err
}
@@ -74,11 +72,11 @@ var usersAddCmd = &cobra.Command{
}
user.Scope = userHome
- err = d.store.Users.Save(user)
+ err = st.Users.Save(user)
if err != nil {
return err
}
printUsers([]*users.User{user})
return nil
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/users_export.go b/cmd/users_export.go
index d6009a37..9bbec6d8 100644
--- a/cmd/users_export.go
+++ b/cmd/users_export.go
@@ -14,8 +14,8 @@ var usersExportCmd = &cobra.Command{
Long: `Export all users to a json or yaml file. Please indicate the
path to the file where you want to write the users.`,
Args: jsonYamlArg,
- RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
- list, err := d.store.Users.Gets("")
+ RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
+ list, err := st.Users.Gets("")
if err != nil {
return err
}
@@ -25,5 +25,5 @@ path to the file where you want to write the users.`,
return err
}
return nil
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/users_find.go b/cmd/users_find.go
index 0dea071a..09bc8d47 100644
--- a/cmd/users_find.go
+++ b/cmd/users_find.go
@@ -26,7 +26,7 @@ var usersLsCmd = &cobra.Command{
RunE: findUsers,
}
-var findUsers = python(func(_ *cobra.Command, args []string, d *pythonData) error {
+var findUsers = withStore(func(_ *cobra.Command, args []string, st *store) error {
var (
list []*users.User
user *users.User
@@ -36,14 +36,14 @@ var findUsers = python(func(_ *cobra.Command, args []string, d *pythonData) erro
if len(args) == 1 {
username, id := parseUsernameOrID(args[0])
if username != "" {
- user, err = d.store.Users.Get("", username)
+ user, err = st.Users.Get("", username)
} else {
- user, err = d.store.Users.Get("", id)
+ user, err = st.Users.Get("", id)
}
list = []*users.User{user}
} else {
- list, err = d.store.Users.Gets("")
+ list, err = st.Users.Gets("")
}
if err != nil {
@@ -51,4 +51,4 @@ var findUsers = python(func(_ *cobra.Command, args []string, d *pythonData) erro
}
printUsers(list)
return nil
-}, pythonConfig{})
+}, storeOptions{})
diff --git a/cmd/users_import.go b/cmd/users_import.go
index d20dca68..73effca6 100644
--- a/cmd/users_import.go
+++ b/cmd/users_import.go
@@ -25,7 +25,8 @@ file. You can use this command to import new users to your
installation. For that, just don't place their ID on the files
list or set it to 0.`,
Args: jsonYamlArg,
- RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
+ RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
+ flags := cmd.Flags()
fd, err := os.Open(args[0])
if err != nil {
return err
@@ -45,13 +46,13 @@ list or set it to 0.`,
}
}
- replace, err := getBool(cmd.Flags(), "replace")
+ replace, err := flags.GetBool("replace")
if err != nil {
return err
}
if replace {
- oldUsers, userImportErr := d.store.Users.Gets("")
+ oldUsers, userImportErr := st.Users.Gets("")
if userImportErr != nil {
return userImportErr
}
@@ -62,20 +63,20 @@ list or set it to 0.`,
}
for _, user := range oldUsers {
- err = d.store.Users.Delete(user.ID)
+ err = st.Users.Delete(user.ID)
if err != nil {
return err
}
}
}
- overwrite, err := getBool(cmd.Flags(), "overwrite")
+ overwrite, err := flags.GetBool("overwrite")
if err != nil {
return err
}
for _, user := range list {
- onDB, err := d.store.Users.Get("", user.ID)
+ onDB, err := st.Users.Get("", user.ID)
// User exists in DB.
if err == nil {
@@ -87,7 +88,7 @@ list or set it to 0.`,
// with the new username. If there is, print an error and cancel the
// operation
if user.Username != onDB.Username {
- if conflictuous, err := d.store.Users.Get("", user.Username); err == nil { //nolint:govet
+ if conflictuous, err := st.Users.Get("", user.Username); err == nil {
return usernameConflictError(user.Username, conflictuous.ID, user.ID)
}
}
@@ -97,13 +98,13 @@ list or set it to 0.`,
user.ID = 0
}
- err = d.store.Users.Save(user)
+ err = st.Users.Save(user)
if err != nil {
return err
}
}
return nil
- }, pythonConfig{}),
+ }, storeOptions{}),
}
func usernameConflictError(username string, originalID, newID uint) error {
diff --git a/cmd/users_rm.go b/cmd/users_rm.go
index 55b973f4..492a55c3 100644
--- a/cmd/users_rm.go
+++ b/cmd/users_rm.go
@@ -15,14 +15,14 @@ var usersRmCmd = &cobra.Command{
Short: "Delete a user by username or id",
Long: `Delete a user by username or id`,
Args: cobra.ExactArgs(1),
- RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
+ RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
username, id := parseUsernameOrID(args[0])
var err error
if username != "" {
- err = d.store.Users.Delete(username)
+ err = st.Users.Delete(username)
} else {
- err = d.store.Users.Delete(id)
+ err = st.Users.Delete(id)
}
if err != nil {
@@ -30,5 +30,5 @@ var usersRmCmd = &cobra.Command{
}
fmt.Println("user deleted successfully")
return nil
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/users_update.go b/cmd/users_update.go
index a939e605..e9a484fc 100644
--- a/cmd/users_update.go
+++ b/cmd/users_update.go
@@ -21,19 +21,20 @@ var usersUpdateCmd = &cobra.Command{
Long: `Updates an existing user. Set the flags for the
options you want to change.`,
Args: cobra.ExactArgs(1),
- RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
- username, id := parseUsernameOrID(args[0])
+ RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
flags := cmd.Flags()
- password, err := getString(flags, "password")
- if err != nil {
- return err
- }
- newUsername, err := getString(flags, "username")
+ username, id := parseUsernameOrID(args[0])
+ password, err := flags.GetString("password")
if err != nil {
return err
}
- s, err := d.store.Settings.Get()
+ newUsername, err := flags.GetString("username")
+ if err != nil {
+ return err
+ }
+
+ s, err := st.Settings.Get()
if err != nil {
return err
}
@@ -41,46 +42,50 @@ options you want to change.`,
var (
user *users.User
)
-
if id != 0 {
- user, err = d.store.Users.Get("", id)
+ user, err = st.Users.Get("", id)
} else {
- user, err = d.store.Users.Get("", username)
+ user, err = st.Users.Get("", username)
}
-
if err != nil {
return err
}
defaults := settings.UserDefaults{
- Scope: user.Scope,
- Locale: user.Locale,
- ViewMode: user.ViewMode,
- SingleClick: user.SingleClick,
- Perm: user.Perm,
- Sorting: user.Sorting,
- Commands: user.Commands,
+ Scope: user.Scope,
+ Locale: user.Locale,
+ ViewMode: user.ViewMode,
+ SingleClick: user.SingleClick,
+ RedirectAfterCopyMove: user.RedirectAfterCopyMove,
+ Perm: user.Perm,
+ Sorting: user.Sorting,
+ Commands: user.Commands,
}
+
err = getUserDefaults(flags, &defaults, false)
if err != nil {
return err
}
+
user.Scope = defaults.Scope
user.Locale = defaults.Locale
user.ViewMode = defaults.ViewMode
user.SingleClick = defaults.SingleClick
+ user.RedirectAfterCopyMove = defaults.RedirectAfterCopyMove
user.Perm = defaults.Perm
user.Commands = defaults.Commands
user.Sorting = defaults.Sorting
- user.LockPassword, err = getBool(flags, "lockPassword")
+ user.LockPassword, err = flags.GetBool("lockPassword")
if err != nil {
return err
}
- user.DateFormat, err = getBool(flags, "dateFormat")
+
+ user.DateFormat, err = flags.GetBool("dateFormat")
if err != nil {
return err
}
- user.HideDotfiles, err = getBool(flags, "hideDotfiles")
+
+ user.HideDotfiles, err = flags.GetBool("hideDotfiles")
if err != nil {
return err
}
@@ -96,11 +101,11 @@ options you want to change.`,
}
}
- err = d.store.Users.Update(user)
+ err = st.Users.Update(user)
if err != nil {
return err
}
printUsers([]*users.User{user})
return nil
- }, pythonConfig{}),
+ }, storeOptions{}),
}
diff --git a/cmd/utils.go b/cmd/utils.go
index 8e5168af..ee637fa3 100644
--- a/cmd/utils.go
+++ b/cmd/utils.go
@@ -12,8 +12,11 @@ import (
"strings"
"github.com/asdine/storm/v3"
+ homedir "github.com/mitchellh/go-homedir"
+ "github.com/samber/lo"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
+ "github.com/spf13/viper"
yaml "gopkg.in/yaml.v3"
"github.com/filebrowser/filebrowser/v2/settings"
@@ -21,32 +24,22 @@ import (
"github.com/filebrowser/filebrowser/v2/storage/bolt"
)
-const dbPerms = 0640
+const databasePermissions = 0640
-func getString(flags *pflag.FlagSet, flag string) (string, error) {
- return flags.GetString(flag)
-}
-
-func getMode(flags *pflag.FlagSet, flag string) (fs.FileMode, error) {
- s, err := getString(flags, flag)
+func getAndParseFileMode(flags *pflag.FlagSet, name string) (fs.FileMode, error) {
+ mode, err := flags.GetString(name)
if err != nil {
return 0, err
}
- b, err := strconv.ParseUint(s, 0, 32)
+
+ b, err := strconv.ParseUint(mode, 0, 32)
if err != nil {
return 0, err
}
+
return fs.FileMode(b), nil
}
-func getBool(flags *pflag.FlagSet, flag string) (bool, error) {
- return flags.GetBool(flag)
-}
-
-func getUint(flags *pflag.FlagSet, flag string) (uint, error) {
- return flags.GetUint(flag)
-}
-
func generateKey() []byte {
k, err := settings.GenerateKey()
if err != nil {
@@ -55,20 +48,6 @@ func generateKey() []byte {
return k
}
-type cobraFunc func(cmd *cobra.Command, args []string) error
-type pythonFunc func(cmd *cobra.Command, args []string, data *pythonData) error
-
-type pythonConfig struct {
- noDB bool
- allowNoDB bool
-}
-
-type pythonData struct {
- hadDB bool
- store *storage.Storage
- err error
-}
-
func dbExists(path string) (bool, error) {
stat, err := os.Stat(path)
if err == nil {
@@ -79,7 +58,7 @@ func dbExists(path string) (bool, error) {
d := filepath.Dir(path)
_, err = os.Stat(d)
if os.IsNotExist(err) {
- if err := os.MkdirAll(d, 0700); err != nil { //nolint:govet
+ if err := os.MkdirAll(d, 0700); err != nil {
return false, err
}
return false, nil
@@ -89,42 +68,137 @@ func dbExists(path string) (bool, error) {
return false, err
}
-func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
+// Generate the replacements for all environment variables. This allows to
+// use FB_BRANDING_DISABLE_EXTERNAL environment variables, even when the
+// option name is branding.disableExternal.
+func generateEnvKeyReplacements(cmd *cobra.Command) []string {
+ replacements := []string{}
+
+ cmd.Flags().VisitAll(func(f *pflag.Flag) {
+ oldName := strings.ToUpper(f.Name)
+ newName := strings.ToUpper(lo.SnakeCase(f.Name))
+ replacements = append(replacements, oldName, newName)
+ })
+
+ return replacements
+}
+
+func initViper(cmd *cobra.Command) (*viper.Viper, error) {
+ v := viper.New()
+
+ // Get config file from flag
+ cfgFile, err := cmd.Flags().GetString("config")
+ if err != nil {
+ return nil, err
+ }
+
+ // Configuration file
+ if cfgFile == "" {
+ home, err := homedir.Dir()
+ if err != nil {
+ return nil, err
+ }
+ v.AddConfigPath(".")
+ v.AddConfigPath(home)
+ v.AddConfigPath("/etc/filebrowser/")
+ v.SetConfigName(".filebrowser")
+ } else {
+ v.SetConfigFile(cfgFile)
+ }
+
+ // Environment variables
+ v.SetEnvPrefix("FB")
+ v.AutomaticEnv()
+ v.SetEnvKeyReplacer(strings.NewReplacer(generateEnvKeyReplacements(cmd)...))
+
+ // Bind the flags
+ err = v.BindPFlags(cmd.Flags())
+ if err != nil {
+ return nil, err
+ }
+
+ // Read in configuration
+ if err := v.ReadInConfig(); err != nil {
+ if errors.Is(err, viper.ConfigParseError{}) {
+ return nil, err
+ }
+
+ log.Println("No config file used")
+ } else {
+ log.Printf("Using config file: %s", v.ConfigFileUsed())
+ }
+
+ // Return Viper
+ return v, nil
+}
+
+type store struct {
+ *storage.Storage
+ databaseExisted bool
+}
+
+type storeOptions struct {
+ expectsNoDatabase bool
+ allowsNoDatabase bool
+}
+
+type cobraFunc func(cmd *cobra.Command, args []string) error
+
+// withViperAndStore initializes Viper and the storage.Store and passes them to the callback function.
+// This function should only be used by [withStore] and the root command. No other command should call
+// this function directly.
+func withViperAndStore(fn func(cmd *cobra.Command, args []string, v *viper.Viper, store *store) error, options storeOptions) cobraFunc {
return func(cmd *cobra.Command, args []string) error {
- data := &pythonData{hadDB: true}
-
- path := getStringParam(cmd.Flags(), "database")
- absPath, err := filepath.Abs(path)
+ v, err := initViper(cmd)
if err != nil {
- panic(err)
+ return err
}
+
+ path, err := filepath.Abs(v.GetString("database"))
+ if err != nil {
+ return err
+ }
+
exists, err := dbExists(path)
-
- if err != nil {
- panic(err)
- } else if exists && cfg.noDB {
- log.Fatal(absPath + " already exists")
- } else if !exists && !cfg.noDB && !cfg.allowNoDB {
- log.Fatal(absPath + " does not exist. Please run 'filebrowser config init' first.")
- } else if !exists && !cfg.noDB {
- log.Println("Warning: filebrowser.db can't be found. Initialing in " + strings.TrimSuffix(absPath, "filebrowser.db"))
+ switch {
+ case err != nil:
+ return err
+ case exists && options.expectsNoDatabase:
+ log.Fatal(path + " already exists")
+ case !exists && !options.expectsNoDatabase && !options.allowsNoDatabase:
+ log.Fatal(path + " does not exist. Please run 'filebrowser config init' first.")
+ case !exists && !options.expectsNoDatabase:
+ log.Println("WARNING: filebrowser.db can't be found. Initialing in " + strings.TrimSuffix(path, "filebrowser.db"))
}
- log.Println("Using database: " + absPath)
- data.hadDB = exists
- db, err := storm.Open(path, storm.BoltOptions(dbPerms, nil))
+ log.Println("Using database: " + path)
+
+ db, err := storm.Open(path, storm.BoltOptions(databasePermissions, nil))
if err != nil {
return err
}
defer db.Close()
- data.store, err = bolt.NewStorage(db)
+
+ storage, err := bolt.NewStorage(db)
if err != nil {
return err
}
- return fn(cmd, args, data)
+
+ store := &store{
+ Storage: storage,
+ databaseExisted: exists,
+ }
+
+ return fn(cmd, args, v, store)
}
}
+func withStore(fn func(cmd *cobra.Command, args []string, store *store) error, options storeOptions) cobraFunc {
+ return withViperAndStore(func(cmd *cobra.Command, args []string, _ *viper.Viper, store *store) error {
+ return fn(cmd, args, store)
+ }, options)
+}
+
func marshal(filename string, data interface{}) error {
fd, err := os.Create(filename)
if err != nil {
diff --git a/diskcache/file_cache.go b/diskcache/file_cache.go
index cd5e27c7..b2979e4b 100644
--- a/diskcache/file_cache.go
+++ b/diskcache/file_cache.go
@@ -2,7 +2,7 @@ package diskcache
import (
"context"
- "crypto/sha1" //nolint:gosec
+ "crypto/sha1"
"encoding/hex"
"errors"
"fmt"
@@ -103,7 +103,7 @@ func (f *FileCache) getScopedLocks(key string) (lock sync.Locker) {
}
func (f *FileCache) getFileName(key string) string {
- hasher := sha1.New() //nolint:gosec
+ hasher := sha1.New()
_, _ = hasher.Write([]byte(key))
hash := hex.EncodeToString(hasher.Sum(nil))
return fmt.Sprintf("%s/%s/%s", hash[:1], hash[1:3], hash)
diff --git a/diskcache/file_cache_test.go b/diskcache/file_cache_test.go
index 31d58c8e..c6c750c0 100644
--- a/diskcache/file_cache_test.go
+++ b/diskcache/file_cache_test.go
@@ -25,12 +25,12 @@ func TestFileCache(t *testing.T) {
// store new key
err := cache.Store(ctx, key, []byte(value))
require.NoError(t, err)
- checkValue(t, ctx, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, value)
+ checkValue(ctx, t, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, value)
// update existing key
err = cache.Store(ctx, key, []byte(newValue))
require.NoError(t, err)
- checkValue(t, ctx, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, newValue)
+ checkValue(ctx, t, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, newValue)
// delete key
err = cache.Delete(ctx, key)
@@ -40,7 +40,7 @@ func TestFileCache(t *testing.T) {
require.False(t, exists)
}
-func checkValue(t *testing.T, ctx context.Context, fs afero.Fs, fileFullPath string, cache *FileCache, key, wantValue string) { //nolint:revive
+func checkValue(ctx context.Context, t *testing.T, fs afero.Fs, fileFullPath string, cache *FileCache, key, wantValue string) {
t.Helper()
// check actual file content
b, err := afero.ReadFile(fs, fileFullPath)
diff --git a/docker/common/defaults/settings.json b/docker/common/defaults/settings.json
index e787ef87..cf7fb4ee 100644
--- a/docker/common/defaults/settings.json
+++ b/docker/common/defaults/settings.json
@@ -5,4 +5,4 @@
"log": "stdout",
"database": "/database/filebrowser.db",
"root": "/srv"
-}
\ No newline at end of file
+}
diff --git a/errors/errors.go b/errors/errors.go
index f8abee59..748354a8 100644
--- a/errors/errors.go
+++ b/errors/errors.go
@@ -1,40 +1,28 @@
-package errors
+package fberrors
import (
"errors"
"fmt"
- "os"
- "syscall"
-)
-
-const (
- ExitCodeSigTerm = 128 + int(syscall.SIGTERM)
- ExitCodeSighup = 128 + int(syscall.SIGHUP)
- ExitCodeSigint = 128 + int(syscall.SIGINT)
- ExitCodeSigquit = 128 + int(syscall.SIGQUIT)
)
var (
- ErrEmptyKey = errors.New("empty key")
- ErrExist = errors.New("the resource already exists")
- ErrNotExist = errors.New("the resource does not exist")
- ErrEmptyPassword = errors.New("password is empty")
- ErrEasyPassword = errors.New("password is too easy")
- ErrEmptyUsername = errors.New("username is empty")
- ErrEmptyRequest = errors.New("empty request")
- ErrScopeIsRelative = errors.New("scope is a relative path")
- ErrInvalidDataType = errors.New("invalid data type")
- ErrIsDirectory = errors.New("file is directory")
- ErrInvalidOption = errors.New("invalid option")
- ErrInvalidAuthMethod = errors.New("invalid auth method")
- ErrPermissionDenied = errors.New("permission denied")
- ErrInvalidRequestParams = errors.New("invalid request params")
- ErrSourceIsParent = errors.New("source is parent")
- ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
- ErrSigTerm = errors.New("exit on signal: sigterm")
- ErrSighup = errors.New("exit on signal: sighup")
- ErrSigint = errors.New("exit on signal: sigint")
- ErrSigquit = errors.New("exit on signal: sigquit")
+ ErrEmptyKey = errors.New("empty key")
+ ErrExist = errors.New("the resource already exists")
+ ErrNotExist = errors.New("the resource does not exist")
+ ErrEmptyPassword = errors.New("password is empty")
+ ErrEasyPassword = errors.New("password is too easy")
+ ErrEmptyUsername = errors.New("username is empty")
+ ErrEmptyRequest = errors.New("empty request")
+ ErrScopeIsRelative = errors.New("scope is a relative path")
+ ErrInvalidDataType = errors.New("invalid data type")
+ ErrIsDirectory = errors.New("file is directory")
+ ErrInvalidOption = errors.New("invalid option")
+ ErrInvalidAuthMethod = errors.New("invalid auth method")
+ ErrPermissionDenied = errors.New("permission denied")
+ ErrInvalidRequestParams = errors.New("invalid request params")
+ ErrSourceIsParent = errors.New("source is parent")
+ ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
+ ErrCurrentPasswordIncorrect = errors.New("the current password is incorrect")
)
type ErrShortPassword struct {
@@ -44,44 +32,3 @@ type ErrShortPassword struct {
func (e ErrShortPassword) Error() string {
return fmt.Sprintf("password is too short, minimum length is %d", e.MinimumLength)
}
-
-// GetExitCode returns the exit code for a given error.
-func GetExitCode(err error) int {
- if err == nil {
- return 0
- }
-
- exitCodeMap := map[error]int{
- ErrSigTerm: ExitCodeSigTerm,
- ErrSighup: ExitCodeSighup,
- ErrSigint: ExitCodeSigint,
- ErrSigquit: ExitCodeSigquit,
- }
-
- for e, code := range exitCodeMap {
- if errors.Is(err, e) {
- return code
- }
- }
-
- if exitErr, ok := err.(interface{ ExitCode() int }); ok {
- return exitErr.ExitCode()
- }
-
- var pathErr *os.PathError
- if errors.As(err, &pathErr) {
- return 1
- }
-
- var syscallErr *os.SyscallError
- if errors.As(err, &syscallErr) {
- return 1
- }
-
- var errno syscall.Errno
- if errors.As(err, &errno) {
- return 1
- }
-
- return 1
-}
diff --git a/files/file.go b/files/file.go
index 8e27e549..2ba432dc 100644
--- a/files/file.go
+++ b/files/file.go
@@ -1,8 +1,8 @@
package files
import (
- "crypto/md5" //nolint:gosec
- "crypto/sha1" //nolint:gosec
+ "crypto/md5"
+ "crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
@@ -23,7 +23,7 @@ import (
"github.com/spf13/afero"
- fbErrors "github.com/filebrowser/filebrowser/v2/errors"
+ fberrors "github.com/filebrowser/filebrowser/v2/errors"
"github.com/filebrowser/filebrowser/v2/rules"
)
@@ -60,6 +60,7 @@ type FileOptions struct {
Modify bool
Expand bool
ReadHeader bool
+ CalcImgRes bool
Token string
Checker rules.Checker
Content bool
@@ -90,13 +91,13 @@ func NewFileInfo(opts *FileOptions) (*FileInfo, error) {
if opts.Expand {
if file.IsDir {
- if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:govet
+ if err := file.readListing(opts.Checker, opts.ReadHeader, opts.CalcImgRes); err != nil {
return nil, err
}
return file, nil
}
- err = file.detectType(opts.Modify, opts.Content, true)
+ err = file.detectType(opts.Modify, opts.Content, true, opts.CalcImgRes)
if err != nil {
return nil, err
}
@@ -168,7 +169,7 @@ func stat(opts *FileOptions) (*FileInfo, error) {
// algorithm. The checksums data is saved on File object.
func (i *FileInfo) Checksum(algo string) error {
if i.IsDir {
- return fbErrors.ErrIsDirectory
+ return fberrors.ErrIsDirectory
}
if i.Checksums == nil {
@@ -183,7 +184,6 @@ func (i *FileInfo) Checksum(algo string) error {
var h hash.Hash
- //nolint:gosec
switch algo {
case "md5":
h = md5.New()
@@ -194,7 +194,7 @@ func (i *FileInfo) Checksum(algo string) error {
case "sha512":
h = sha512.New()
default:
- return fbErrors.ErrInvalidOption
+ return fberrors.ErrInvalidOption
}
_, err = io.Copy(h, reader)
@@ -219,7 +219,7 @@ func (i *FileInfo) RealPath() string {
return i.Path
}
-func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
+func (i *FileInfo) detectType(modify, saveContent, readHeader bool, calcImgRes bool) error {
if IsNamedPipe(i.Mode) {
i.Type = "blob"
return nil
@@ -250,11 +250,13 @@ func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
return nil
case strings.HasPrefix(mimetype, "image"):
i.Type = "image"
- resolution, err := calculateImageResolution(i.Fs, i.Path)
- if err != nil {
- log.Printf("Error calculating image resolution: %v", err)
- } else {
- i.Resolution = resolution
+ if calcImgRes {
+ resolution, err := calculateImageResolution(i.Fs, i.Path)
+ if err != nil {
+ log.Printf("Error calculating image resolution: %v", err)
+ } else {
+ i.Resolution = resolution
+ }
}
return nil
case strings.HasSuffix(mimetype, "pdf"):
@@ -388,7 +390,7 @@ func (i *FileInfo) addSubtitle(fPath string) {
i.Subtitles = append(i.Subtitles, fPath)
}
-func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
+func (i *FileInfo) readListing(checker rules.Checker, readHeader bool, calcImgRes bool) error {
afs := &afero.Afero{Fs: i.Fs}
dir, err := afs.ReadDir(i.Path)
if err != nil {
@@ -435,7 +437,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
currentDir: dir,
}
- if !file.IsDir && strings.HasPrefix(mime.TypeByExtension(file.Extension), "image/") {
+ if !file.IsDir && strings.HasPrefix(mime.TypeByExtension(file.Extension), "image/") && calcImgRes {
resolution, err := calculateImageResolution(file.Fs, file.Path)
if err != nil {
log.Printf("Error calculating resolution for image %s: %v", file.Path, err)
@@ -452,7 +454,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
if isInvalidLink {
file.Type = "invalid_link"
} else {
- err := file.detectType(true, false, readHeader)
+ err := file.detectType(true, false, readHeader, calcImgRes)
if err != nil {
return err
}
diff --git a/files/mime.go b/files/mime.go
index 33fd93bd..baa4d6d5 100644
--- a/files/mime.go
+++ b/files/mime.go
@@ -600,7 +600,6 @@ var types = map[string]string{
".epub": "application/epub+zip",
}
-//nolint:gochecknoinits
func init() {
for ext, typ := range types {
// skip errors
diff --git a/frontend/index.html b/frontend/index.html
index b3de6804..19308a95 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -39,6 +39,7 @@
DisableUsedPercentage: false,
EnableExec: true,
EnableThumbs: true,
+ LogoutPage: "",
LoginPage: true,
Name: "",
NoAuth: false,
diff --git a/frontend/package.json b/frontend/package.json
index ade91ff1..44144b3a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -71,5 +71,5 @@
"vite-plugin-compression2": "^2.3.1",
"vue-tsc": "^3.1.3"
},
- "packageManager": "pnpm@10.22.0+sha512.bf049efe995b28f527fd2b41ae0474ce29186f7edcb3bf545087bd61fbbebb2bf75362d1307fda09c2d288e1e499787ac12d4fcb617a974718a6051f2eee741c"
+ "packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48"
}
diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml
index 4f4907ee..d3b79699 100644
--- a/frontend/pnpm-lock.yaml
+++ b/frontend/pnpm-lock.yaml
@@ -10,22 +10,22 @@ importers:
dependencies:
'@chenfengyuan/vue-number-input':
specifier: ^2.0.1
- version: 2.0.1(vue@3.5.24(typescript@5.9.3))
+ version: 2.0.1(vue@3.5.26(typescript@5.9.3))
'@vueuse/core':
specifier: ^14.0.0
- version: 14.0.0(vue@3.5.24(typescript@5.9.3))
+ version: 14.1.0(vue@3.5.26(typescript@5.9.3))
'@vueuse/integrations':
specifier: ^14.0.0
- version: 14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.24(typescript@5.9.3))
+ version: 14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.26(typescript@5.9.3))
ace-builds:
specifier: ^1.43.2
- version: 1.43.4
+ version: 1.43.5
dayjs:
specifier: ^1.11.13
version: 1.11.19
dompurify:
specifier: ^3.2.6
- version: 3.3.0
+ version: 3.3.1
epubjs:
specifier: ^0.3.93
version: 0.3.93
@@ -40,10 +40,10 @@ importers:
version: 4.0.0
lodash-es:
specifier: ^4.17.21
- version: 4.17.21
+ version: 4.17.22
marked:
specifier: ^17.0.0
- version: 17.0.0
+ version: 17.0.1
material-icons:
specifier: ^1.13.14
version: 1.13.14
@@ -52,13 +52,13 @@ importers:
version: 8.0.1
pinia:
specifier: ^3.0.4
- version: 3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3))
+ version: 3.0.4(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3))
pretty-bytes:
specifier: ^7.1.0
version: 7.1.0
qrcode.vue:
specifier: ^3.6.0
- version: 3.6.0(vue@3.5.24(typescript@5.9.3))
+ version: 3.6.0(vue@3.5.26(typescript@5.9.3))
tus-js-client:
specifier: ^4.3.1
version: 4.3.1
@@ -73,95 +73,95 @@ importers:
version: 0.2.30
videojs-mobile-ui:
specifier: ^1.1.1
- version: 1.1.1(video.js@8.23.4)
+ version: 1.1.3(video.js@8.23.4)
vue:
specifier: ^3.5.17
- version: 3.5.24(typescript@5.9.3)
+ version: 3.5.26(typescript@5.9.3)
vue-final-modal:
specifier: ^4.5.5
- version: 4.5.5(@vueuse/core@14.0.0(vue@3.5.24(typescript@5.9.3)))(@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.24(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.24(typescript@5.9.3))
+ version: 4.5.5(@vueuse/core@14.1.0(vue@3.5.26(typescript@5.9.3)))(@vueuse/integrations@14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.26(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.26(typescript@5.9.3))
vue-i18n:
specifier: ^11.1.10
- version: 11.1.12(vue@3.5.24(typescript@5.9.3))
+ version: 11.2.8(vue@3.5.26(typescript@5.9.3))
vue-lazyload:
specifier: ^3.0.0
version: 3.0.0
vue-reader:
specifier: ^1.2.17
- version: 1.3.3
+ version: 1.3.4
vue-router:
specifier: ^4.5.1
- version: 4.6.3(vue@3.5.24(typescript@5.9.3))
+ version: 4.6.4(vue@3.5.26(typescript@5.9.3))
vue-toastification:
specifier: ^2.0.0-rc.5
- version: 2.0.0-rc.5(vue@3.5.24(typescript@5.9.3))
+ version: 2.0.0-rc.5(vue@3.5.26(typescript@5.9.3))
devDependencies:
'@intlify/unplugin-vue-i18n':
specifier: ^11.0.1
- version: 11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1)(rollup@4.52.5)(typescript@5.9.3)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))
+ version: 11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2)(rollup@4.55.1)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))
'@tsconfig/node24':
specifier: ^24.0.2
- version: 24.0.2
+ version: 24.0.4
'@types/lodash-es':
specifier: ^4.17.12
version: 4.17.12
'@types/node':
specifier: ^24.10.1
- version: 24.10.1
+ version: 24.10.9
'@typescript-eslint/eslint-plugin':
specifier: ^8.37.0
- version: 8.46.4(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)
+ version: 8.53.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)
'@vitejs/plugin-legacy':
specifier: ^7.2.1
- version: 7.2.1(terser@5.44.1)(vite@7.2.2(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))
+ version: 7.2.1(terser@5.46.0)(vite@7.3.1(@types/node@24.10.9)(terser@5.46.0)(yaml@2.8.2))
'@vitejs/plugin-vue':
specifier: ^6.0.1
- version: 6.0.1(vite@7.2.2(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))(vue@3.5.24(typescript@5.9.3))
+ version: 6.0.3(vite@7.3.1(@types/node@24.10.9)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))
'@vue/eslint-config-prettier':
specifier: ^10.2.0
- version: 10.2.0(eslint@9.39.1)(prettier@3.6.2)
+ version: 10.2.0(eslint@9.39.2)(prettier@3.8.0)
'@vue/eslint-config-typescript':
specifier: ^14.6.0
- version: 14.6.0(eslint-plugin-vue@10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)
+ version: 14.6.0(eslint-plugin-vue@10.7.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(vue-eslint-parser@10.2.0(eslint@9.39.2)))(eslint@9.39.2)(typescript@5.9.3)
'@vue/tsconfig':
specifier: ^0.8.1
- version: 0.8.1(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3))
+ version: 0.8.1(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3))
autoprefixer:
specifier: ^10.4.21
- version: 10.4.22(postcss@8.5.6)
+ version: 10.4.23(postcss@8.5.6)
eslint:
specifier: ^9.31.0
- version: 9.39.1
+ version: 9.39.2
eslint-config-prettier:
specifier: ^10.1.5
- version: 10.1.8(eslint@9.39.1)
+ version: 10.1.8(eslint@9.39.2)
eslint-plugin-prettier:
specifier: ^5.5.1
- version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2)
+ version: 5.5.5(eslint-config-prettier@10.1.8(eslint@9.39.2))(eslint@9.39.2)(prettier@3.8.0)
eslint-plugin-vue:
specifier: ^10.5.1
- version: 10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1))
+ version: 10.7.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(vue-eslint-parser@10.2.0(eslint@9.39.2))
postcss:
specifier: ^8.5.6
version: 8.5.6
prettier:
specifier: ^3.6.2
- version: 3.6.2
+ version: 3.8.0
terser:
specifier: ^5.43.1
- version: 5.44.1
+ version: 5.46.0
typescript:
specifier: ^5.9.3
version: 5.9.3
vite:
specifier: ^7.2.2
- version: 7.2.2(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0)
+ version: 7.3.1(@types/node@24.10.9)(terser@5.46.0)(yaml@2.8.2)
vite-plugin-compression2:
specifier: ^2.3.1
- version: 2.3.1(rollup@4.52.5)
+ version: 2.4.0(rollup@4.55.1)
vue-tsc:
specifier: ^3.1.3
- version: 3.1.3(typescript@5.9.3)
+ version: 3.2.2(typescript@5.9.3)
packages:
@@ -665,158 +665,314 @@ packages:
peerDependencies:
vue: ^3.0.0
- '@esbuild/aix-ppc64@0.25.11':
- resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==}
+ '@esbuild/aix-ppc64@0.25.12':
+ resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
- '@esbuild/android-arm64@0.25.11':
- resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==}
+ '@esbuild/aix-ppc64@0.27.2':
+ resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.25.12':
+ resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
- '@esbuild/android-arm@0.25.11':
- resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==}
+ '@esbuild/android-arm64@0.27.2':
+ resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.25.12':
+ resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
- '@esbuild/android-x64@0.25.11':
- resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==}
+ '@esbuild/android-arm@0.27.2':
+ resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.25.12':
+ resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
- '@esbuild/darwin-arm64@0.25.11':
- resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==}
+ '@esbuild/android-x64@0.27.2':
+ resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.25.12':
+ resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
- '@esbuild/darwin-x64@0.25.11':
- resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==}
+ '@esbuild/darwin-arm64@0.27.2':
+ resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.25.12':
+ resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
- '@esbuild/freebsd-arm64@0.25.11':
- resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==}
+ '@esbuild/darwin-x64@0.27.2':
+ resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.25.12':
+ resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
- '@esbuild/freebsd-x64@0.25.11':
- resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==}
+ '@esbuild/freebsd-arm64@0.27.2':
+ resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.25.12':
+ resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
- '@esbuild/linux-arm64@0.25.11':
- resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==}
+ '@esbuild/freebsd-x64@0.27.2':
+ resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.25.12':
+ resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
- '@esbuild/linux-arm@0.25.11':
- resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==}
+ '@esbuild/linux-arm64@0.27.2':
+ resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.25.12':
+ resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
- '@esbuild/linux-ia32@0.25.11':
- resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==}
+ '@esbuild/linux-arm@0.27.2':
+ resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.25.12':
+ resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
- '@esbuild/linux-loong64@0.25.11':
- resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==}
+ '@esbuild/linux-ia32@0.27.2':
+ resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.25.12':
+ resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
- '@esbuild/linux-mips64el@0.25.11':
- resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==}
+ '@esbuild/linux-loong64@0.27.2':
+ resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.25.12':
+ resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
- '@esbuild/linux-ppc64@0.25.11':
- resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==}
+ '@esbuild/linux-mips64el@0.27.2':
+ resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.25.12':
+ resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
- '@esbuild/linux-riscv64@0.25.11':
- resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==}
+ '@esbuild/linux-ppc64@0.27.2':
+ resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.25.12':
+ resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
- '@esbuild/linux-s390x@0.25.11':
- resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==}
+ '@esbuild/linux-riscv64@0.27.2':
+ resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.25.12':
+ resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
- '@esbuild/linux-x64@0.25.11':
- resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==}
+ '@esbuild/linux-s390x@0.27.2':
+ resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.25.12':
+ resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
- '@esbuild/netbsd-arm64@0.25.11':
- resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==}
+ '@esbuild/linux-x64@0.27.2':
+ resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
- '@esbuild/netbsd-x64@0.25.11':
- resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==}
+ '@esbuild/netbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.25.12':
+ resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
- '@esbuild/openbsd-arm64@0.25.11':
- resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==}
+ '@esbuild/netbsd-x64@0.27.2':
+ resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.25.12':
+ resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
- '@esbuild/openbsd-x64@0.25.11':
- resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==}
+ '@esbuild/openbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.25.12':
+ resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
- '@esbuild/openharmony-arm64@0.25.11':
- resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==}
+ '@esbuild/openbsd-x64@0.27.2':
+ resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.25.12':
+ resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
- '@esbuild/sunos-x64@0.25.11':
- resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==}
+ '@esbuild/openharmony-arm64@0.27.2':
+ resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.25.12':
+ resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
- '@esbuild/win32-arm64@0.25.11':
- resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==}
+ '@esbuild/sunos-x64@0.27.2':
+ resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.25.12':
+ resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
- '@esbuild/win32-ia32@0.25.11':
- resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==}
+ '@esbuild/win32-arm64@0.27.2':
+ resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.25.12':
+ resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
- '@esbuild/win32-x64@0.25.11':
- resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==}
+ '@esbuild/win32-ia32@0.27.2':
+ resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.25.12':
+ resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.27.2':
+ resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
@@ -827,6 +983,12 @@ packages:
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ '@eslint-community/eslint-utils@4.9.1':
+ resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
'@eslint-community/regexpp@4.12.2':
resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
@@ -843,12 +1005,12 @@ packages:
resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/eslintrc@3.3.1':
- resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
+ '@eslint/eslintrc@3.3.3':
+ resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/js@9.39.1':
- resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==}
+ '@eslint/js@9.39.2':
+ resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/object-schema@2.1.7':
@@ -875,8 +1037,8 @@ packages:
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
engines: {node: '>=18.18'}
- '@intlify/bundle-utils@11.0.1':
- resolution: {integrity: sha512-5l10G5wE2cQRsZMS9y0oSFMOLW5IG/SgbkIUltqnwF1EMRrRbUAHFiPabXdGTHeexCsMTcxj/1w9i0rzjJU9IQ==}
+ '@intlify/bundle-utils@11.0.3':
+ resolution: {integrity: sha512-dURCDz1rQXwAb1+Hv4NDit6aZSRaAt4zUYBPEeaDCe3FSs8dMtdF6kEvgd9JwsYFSTAHcvbTs2CqwBjjt9Ltsw==}
engines: {node: '>= 20'}
peerDependencies:
petite-vue-i18n: '*'
@@ -887,20 +1049,24 @@ packages:
vue-i18n:
optional: true
- '@intlify/core-base@11.1.12':
- resolution: {integrity: sha512-whh0trqRsSqVLNEUCwU59pyJZYpU8AmSWl8M3Jz2Mv5ESPP6kFh4juas2NpZ1iCvy7GlNRffUD1xr84gceimjg==}
+ '@intlify/core-base@11.2.8':
+ resolution: {integrity: sha512-nBq6Y1tVkjIUsLsdOjDSJj4AsjvD0UG3zsg9Fyc+OivwlA/oMHSKooUy9tpKj0HqZ+NWFifweHavdljlBLTwdA==}
engines: {node: '>= 16'}
- '@intlify/message-compiler@11.1.12':
- resolution: {integrity: sha512-Fv9iQSJoJaXl4ZGkOCN1LDM3trzze0AS2zRz2EHLiwenwL6t0Ki9KySYlyr27yVOj5aVz0e55JePO+kELIvfdQ==}
+ '@intlify/message-compiler@11.2.8':
+ resolution: {integrity: sha512-A5n33doOjmHsBtCN421386cG1tWp5rpOjOYPNsnpjIJbQ4POF0QY2ezhZR9kr0boKwaHjbOifvyQvHj2UTrDFQ==}
engines: {node: '>= 16'}
- '@intlify/shared@11.1.12':
- resolution: {integrity: sha512-Om86EjuQtA69hdNj3GQec9ZC0L0vPSAnXzB3gP/gyJ7+mA7t06d9aOAiqMZ+xEOsumGP4eEBlfl8zF2LOTzf2A==}
+ '@intlify/shared@11.2.2':
+ resolution: {integrity: sha512-OtCmyFpSXxNu/oET/aN6HtPCbZ01btXVd0f3w00YsHOb13Kverk1jzA2k47pAekM55qbUw421fvPF1yxZ+gicw==}
engines: {node: '>= 16'}
- '@intlify/unplugin-vue-i18n@11.0.1':
- resolution: {integrity: sha512-nH5NJdNjy/lO6Ne8LDtZzv4SbpVsMhPE+LbvBDmMeIeJDiino8sOJN2QB3MXzTliYTnqe3aB9Fw5+LJ/XVaXCg==}
+ '@intlify/shared@11.2.8':
+ resolution: {integrity: sha512-l6e4NZyUgv8VyXXH4DbuucFOBmxLF56C/mqh2tvApbzl2Hrhi1aTDcuv5TKdxzfHYmpO3UB0Cz04fgDT9vszfw==}
+ engines: {node: '>= 16'}
+
+ '@intlify/unplugin-vue-i18n@11.0.3':
+ resolution: {integrity: sha512-iQuik0nXfdVZ5ab+IEyBFEuvMQ213zfbUpBXaEdHPk8DV+qB2CT/SdFuDhfUDRRBZc/e0qoLlfmc9urhnRYVWw==}
engines: {node: '>= 20'}
peerDependencies:
petite-vue-i18n: '*'
@@ -965,8 +1131,8 @@ packages:
resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
- '@rolldown/pluginutils@1.0.0-beta.29':
- resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==}
+ '@rolldown/pluginutils@1.0.0-beta.53':
+ resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==}
'@rollup/pluginutils@5.3.0':
resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
@@ -977,118 +1143,133 @@ packages:
rollup:
optional: true
- '@rollup/rollup-android-arm-eabi@4.52.5':
- resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==}
+ '@rollup/rollup-android-arm-eabi@4.55.1':
+ resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==}
cpu: [arm]
os: [android]
- '@rollup/rollup-android-arm64@4.52.5':
- resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==}
+ '@rollup/rollup-android-arm64@4.55.1':
+ resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==}
cpu: [arm64]
os: [android]
- '@rollup/rollup-darwin-arm64@4.52.5':
- resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==}
+ '@rollup/rollup-darwin-arm64@4.55.1':
+ resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==}
cpu: [arm64]
os: [darwin]
- '@rollup/rollup-darwin-x64@4.52.5':
- resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==}
+ '@rollup/rollup-darwin-x64@4.55.1':
+ resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==}
cpu: [x64]
os: [darwin]
- '@rollup/rollup-freebsd-arm64@4.52.5':
- resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==}
+ '@rollup/rollup-freebsd-arm64@4.55.1':
+ resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==}
cpu: [arm64]
os: [freebsd]
- '@rollup/rollup-freebsd-x64@4.52.5':
- resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==}
+ '@rollup/rollup-freebsd-x64@4.55.1':
+ resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==}
cpu: [x64]
os: [freebsd]
- '@rollup/rollup-linux-arm-gnueabihf@4.52.5':
- resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==}
+ '@rollup/rollup-linux-arm-gnueabihf@4.55.1':
+ resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==}
cpu: [arm]
os: [linux]
- '@rollup/rollup-linux-arm-musleabihf@4.52.5':
- resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==}
+ '@rollup/rollup-linux-arm-musleabihf@4.55.1':
+ resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==}
cpu: [arm]
os: [linux]
- '@rollup/rollup-linux-arm64-gnu@4.52.5':
- resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==}
+ '@rollup/rollup-linux-arm64-gnu@4.55.1':
+ resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==}
cpu: [arm64]
os: [linux]
- '@rollup/rollup-linux-arm64-musl@4.52.5':
- resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==}
+ '@rollup/rollup-linux-arm64-musl@4.55.1':
+ resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==}
cpu: [arm64]
os: [linux]
- '@rollup/rollup-linux-loong64-gnu@4.52.5':
- resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==}
+ '@rollup/rollup-linux-loong64-gnu@4.55.1':
+ resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==}
cpu: [loong64]
os: [linux]
- '@rollup/rollup-linux-ppc64-gnu@4.52.5':
- resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==}
+ '@rollup/rollup-linux-loong64-musl@4.55.1':
+ resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.55.1':
+ resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==}
cpu: [ppc64]
os: [linux]
- '@rollup/rollup-linux-riscv64-gnu@4.52.5':
- resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==}
+ '@rollup/rollup-linux-ppc64-musl@4.55.1':
+ resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.55.1':
+ resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==}
cpu: [riscv64]
os: [linux]
- '@rollup/rollup-linux-riscv64-musl@4.52.5':
- resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==}
+ '@rollup/rollup-linux-riscv64-musl@4.55.1':
+ resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==}
cpu: [riscv64]
os: [linux]
- '@rollup/rollup-linux-s390x-gnu@4.52.5':
- resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==}
+ '@rollup/rollup-linux-s390x-gnu@4.55.1':
+ resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==}
cpu: [s390x]
os: [linux]
- '@rollup/rollup-linux-x64-gnu@4.52.5':
- resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==}
+ '@rollup/rollup-linux-x64-gnu@4.55.1':
+ resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==}
cpu: [x64]
os: [linux]
- '@rollup/rollup-linux-x64-musl@4.52.5':
- resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==}
+ '@rollup/rollup-linux-x64-musl@4.55.1':
+ resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==}
cpu: [x64]
os: [linux]
- '@rollup/rollup-openharmony-arm64@4.52.5':
- resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==}
+ '@rollup/rollup-openbsd-x64@4.55.1':
+ resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.55.1':
+ resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==}
cpu: [arm64]
os: [openharmony]
- '@rollup/rollup-win32-arm64-msvc@4.52.5':
- resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==}
+ '@rollup/rollup-win32-arm64-msvc@4.55.1':
+ resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==}
cpu: [arm64]
os: [win32]
- '@rollup/rollup-win32-ia32-msvc@4.52.5':
- resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==}
+ '@rollup/rollup-win32-ia32-msvc@4.55.1':
+ resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==}
cpu: [ia32]
os: [win32]
- '@rollup/rollup-win32-x64-gnu@4.52.5':
- resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==}
+ '@rollup/rollup-win32-x64-gnu@4.55.1':
+ resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==}
cpu: [x64]
os: [win32]
- '@rollup/rollup-win32-x64-msvc@4.52.5':
- resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==}
+ '@rollup/rollup-win32-x64-msvc@4.55.1':
+ resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==}
cpu: [x64]
os: [win32]
- '@tsconfig/node24@24.0.2':
- resolution: {integrity: sha512-CNeOLUPI9PjbBc1DSIqb3GF/u+3kX/TDe9DKCzoI62mYI4dEDrMQ0r/9+SfYACP4UNMbiTlz7n8H7Rx/xTisQg==}
+ '@tsconfig/node24@24.0.4':
+ resolution: {integrity: sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA==}
'@types/estree@1.0.8':
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
@@ -1106,8 +1287,8 @@ packages:
'@types/lodash@4.17.13':
resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==}
- '@types/node@24.10.1':
- resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
+ '@types/node@24.10.9':
+ resolution: {integrity: sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==}
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
@@ -1123,11 +1304,11 @@ packages:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/eslint-plugin@8.46.4':
- resolution: {integrity: sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==}
+ '@typescript-eslint/eslint-plugin@8.53.0':
+ resolution: {integrity: sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- '@typescript-eslint/parser': ^8.46.4
+ '@typescript-eslint/parser': ^8.53.0
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
@@ -1144,8 +1325,14 @@ packages:
peerDependencies:
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/project-service@8.46.4':
- resolution: {integrity: sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==}
+ '@typescript-eslint/project-service@8.49.0':
+ resolution: {integrity: sha512-/wJN0/DKkmRUMXjZUXYZpD1NEQzQAAn9QWfGwo+Ai8gnzqH7tvqS7oNVdTjKqOcPyVIdZdyCMoqN66Ia789e7g==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.0.0'
+
+ '@typescript-eslint/project-service@8.53.0':
+ resolution: {integrity: sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
@@ -1154,8 +1341,12 @@ packages:
resolution: {integrity: sha512-0vGq0yiU1gbjKob2q691ybTg9JX6ShiVXAAfm2jGf3q0hdP6/BruaFjL/ManAR/lj05AvYCH+5bbVo0VtzmjOA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/scope-manager@8.46.4':
- resolution: {integrity: sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==}
+ '@typescript-eslint/scope-manager@8.49.0':
+ resolution: {integrity: sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/scope-manager@8.53.0':
+ resolution: {integrity: sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/tsconfig-utils@8.37.0':
@@ -1164,8 +1355,14 @@ packages:
peerDependencies:
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/tsconfig-utils@8.46.4':
- resolution: {integrity: sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==}
+ '@typescript-eslint/tsconfig-utils@8.49.0':
+ resolution: {integrity: sha512-8prixNi1/6nawsRYxet4YOhnbW+W9FK/bQPxsGB1D3ZrDzbJ5FXw5XmzxZv82X3B+ZccuSxo/X8q9nQ+mFecWA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.0.0'
+
+ '@typescript-eslint/tsconfig-utils@8.53.0':
+ resolution: {integrity: sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
@@ -1177,8 +1374,8 @@ packages:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/type-utils@8.46.4':
- resolution: {integrity: sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==}
+ '@typescript-eslint/type-utils@8.53.0':
+ resolution: {integrity: sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -1188,8 +1385,12 @@ packages:
resolution: {integrity: sha512-ax0nv7PUF9NOVPs+lmQ7yIE7IQmAf8LGcXbMvHX5Gm+YJUYNAl340XkGnrimxZ0elXyoQJuN5sbg6C4evKA4SQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/types@8.46.4':
- resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==}
+ '@typescript-eslint/types@8.49.0':
+ resolution: {integrity: sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/types@8.53.0':
+ resolution: {integrity: sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.37.0':
@@ -1198,8 +1399,14 @@ packages:
peerDependencies:
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/typescript-estree@8.46.4':
- resolution: {integrity: sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==}
+ '@typescript-eslint/typescript-estree@8.49.0':
+ resolution: {integrity: sha512-jrLdRuAbPfPIdYNppHJ/D0wN+wwNfJ32YTAm10eJVsFmrVpXQnDWBn8niCSMlWjvml8jsce5E/O+86IQtTbJWA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <6.0.0'
+
+ '@typescript-eslint/typescript-estree@8.53.0':
+ resolution: {integrity: sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
@@ -1211,8 +1418,8 @@ packages:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0'
- '@typescript-eslint/utils@8.46.4':
- resolution: {integrity: sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==}
+ '@typescript-eslint/utils@8.53.0':
+ resolution: {integrity: sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -1222,8 +1429,12 @@ packages:
resolution: {integrity: sha512-YzfhzcTnZVPiLfP/oeKtDp2evwvHLMe0LOy7oe+hb9KKIumLNohYS9Hgp1ifwpu42YWxhZE8yieggz6JpqO/1w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/visitor-keys@8.46.4':
- resolution: {integrity: sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==}
+ '@typescript-eslint/visitor-keys@8.49.0':
+ resolution: {integrity: sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/visitor-keys@8.53.0':
+ resolution: {integrity: sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@videojs/http-streaming@3.17.2':
@@ -1246,33 +1457,33 @@ packages:
terser: ^5.16.0
vite: ^7.0.0
- '@vitejs/plugin-vue@6.0.1':
- resolution: {integrity: sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==}
+ '@vitejs/plugin-vue@6.0.3':
+ resolution: {integrity: sha512-TlGPkLFLVOY3T7fZrwdvKpjprR3s4fxRln0ORDo1VQ7HHyxJwTlrjKU3kpVWTlaAjIEuCTokmjkZnr8Tpc925w==}
engines: {node: ^20.19.0 || >=22.12.0}
peerDependencies:
- vite: ^5.0.0 || ^6.0.0 || ^7.0.0
+ vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
vue: ^3.2.25
- '@volar/language-core@2.4.23':
- resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==}
+ '@volar/language-core@2.4.27':
+ resolution: {integrity: sha512-DjmjBWZ4tJKxfNC1F6HyYERNHPYS7L7OPFyCrestykNdUZMFYzI9WTyvwPcaNaHlrEUwESHYsfEw3isInncZxQ==}
- '@volar/source-map@2.4.23':
- resolution: {integrity: sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==}
+ '@volar/source-map@2.4.27':
+ resolution: {integrity: sha512-ynlcBReMgOZj2i6po+qVswtDUeeBRCTgDurjMGShbm8WYZgJ0PA4RmtebBJ0BCYol1qPv3GQF6jK7C9qoVc7lg==}
- '@volar/typescript@2.4.23':
- resolution: {integrity: sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==}
+ '@volar/typescript@2.4.27':
+ resolution: {integrity: sha512-eWaYCcl/uAPInSK2Lze6IqVWaBu/itVqR5InXcHXFyles4zO++Mglt3oxdgj75BDcv1Knr9Y93nowS8U3wqhxg==}
- '@vue/compiler-core@3.5.24':
- resolution: {integrity: sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==}
+ '@vue/compiler-core@3.5.26':
+ resolution: {integrity: sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==}
- '@vue/compiler-dom@3.5.24':
- resolution: {integrity: sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==}
+ '@vue/compiler-dom@3.5.26':
+ resolution: {integrity: sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==}
- '@vue/compiler-sfc@3.5.24':
- resolution: {integrity: sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==}
+ '@vue/compiler-sfc@3.5.26':
+ resolution: {integrity: sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==}
- '@vue/compiler-ssr@3.5.24':
- resolution: {integrity: sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==}
+ '@vue/compiler-ssr@3.5.26':
+ resolution: {integrity: sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==}
'@vue/devtools-api@6.6.4':
resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
@@ -1303,30 +1514,25 @@ packages:
typescript:
optional: true
- '@vue/language-core@3.1.3':
- resolution: {integrity: sha512-KpR1F/eGAG9D1RZ0/T6zWJs6dh/pRLfY5WupecyYKJ1fjVmDMgTPw9wXmKv2rBjo4zCJiOSiyB8BDP1OUwpMEA==}
+ '@vue/language-core@3.2.2':
+ resolution: {integrity: sha512-5DAuhxsxBN9kbriklh3Q5AMaJhyOCNiQJvCskN9/30XOpdLiqZU9Q+WvjArP17ubdGEyZtBzlIeG5nIjEbNOrQ==}
+
+ '@vue/reactivity@3.5.26':
+ resolution: {integrity: sha512-9EnYB1/DIiUYYnzlnUBgwU32NNvLp/nhxLXeWRhHUEeWNTn1ECxX8aGO7RTXeX6PPcxe3LLuNBFoJbV4QZ+CFQ==}
+
+ '@vue/runtime-core@3.5.26':
+ resolution: {integrity: sha512-xJWM9KH1kd201w5DvMDOwDHYhrdPTrAatn56oB/LRG4plEQeZRQLw0Bpwih9KYoqmzaxF0OKSn6swzYi84e1/Q==}
+
+ '@vue/runtime-dom@3.5.26':
+ resolution: {integrity: sha512-XLLd/+4sPC2ZkN/6+V4O4gjJu6kSDbHAChvsyWgm1oGbdSO3efvGYnm25yCjtFm/K7rrSDvSfPDgN1pHgS4VNQ==}
+
+ '@vue/server-renderer@3.5.26':
+ resolution: {integrity: sha512-TYKLXmrwWKSodyVuO1WAubucd+1XlLg4set0YoV+Hu8Lo79mp/YMwWV5mC5FgtsDxX3qo1ONrxFaTP1OQgy1uA==}
peerDependencies:
- typescript: '*'
- peerDependenciesMeta:
- typescript:
- optional: true
+ vue: 3.5.26
- '@vue/reactivity@3.5.24':
- resolution: {integrity: sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==}
-
- '@vue/runtime-core@3.5.24':
- resolution: {integrity: sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==}
-
- '@vue/runtime-dom@3.5.24':
- resolution: {integrity: sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==}
-
- '@vue/server-renderer@3.5.24':
- resolution: {integrity: sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==}
- peerDependencies:
- vue: 3.5.24
-
- '@vue/shared@3.5.24':
- resolution: {integrity: sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==}
+ '@vue/shared@3.5.26':
+ resolution: {integrity: sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==}
'@vue/tsconfig@0.8.1':
resolution: {integrity: sha512-aK7feIWPXFSUhsCP9PFqPyFOcz4ENkb8hZ2pneL6m2UjCkccvaOhC/5KCKluuBufvp2KzkbdA2W2pk20vLzu3g==}
@@ -1339,13 +1545,13 @@ packages:
vue:
optional: true
- '@vueuse/core@14.0.0':
- resolution: {integrity: sha512-d6tKRWkZE8IQElX2aHBxXOMD478fHIYV+Dzm2y9Ag122ICBpNKtGICiXKOhWU3L1kKdttDD9dCMS4bGP3jhCTQ==}
+ '@vueuse/core@14.1.0':
+ resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==}
peerDependencies:
vue: ^3.5.0
- '@vueuse/integrations@14.0.0':
- resolution: {integrity: sha512-5A0X7q9qyLtM3xyghq5nK/NEESf7cpcZlkQgXTMuW4JWiAMYxc1ImdhhGrk4negFBsq3ejvAlRmLdNrkcTzk1Q==}
+ '@vueuse/integrations@14.1.0':
+ resolution: {integrity: sha512-eNQPdisnO9SvdydTIXnTE7c29yOsJBD/xkwEyQLdhDC/LKbqrFpXHb3uS//7NcIrQO3fWVuvMGp8dbK6mNEMCA==}
peerDependencies:
async-validator: ^4
axios: ^1
@@ -1386,11 +1592,11 @@ packages:
universal-cookie:
optional: true
- '@vueuse/metadata@14.0.0':
- resolution: {integrity: sha512-6yoGqbJcMldVCevkFiHDBTB1V5Hq+G/haPlGIuaFZHpXC0HADB0EN1ryQAAceiW+ryS3niUwvdFbGiqHqBrfVA==}
+ '@vueuse/metadata@14.1.0':
+ resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==}
- '@vueuse/shared@14.0.0':
- resolution: {integrity: sha512-mTCA0uczBgurRlwVaQHfG0Ja7UdGe4g9mwffiJmvLiTtp1G4AQyIjej6si/k8c8pUwTfVpNufck+23gXptPAkw==}
+ '@vueuse/shared@14.1.0':
+ resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==}
peerDependencies:
vue: ^3.5.0
@@ -1403,8 +1609,8 @@ packages:
resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==}
engines: {node: '>=10.0.0'}
- ace-builds@1.43.4:
- resolution: {integrity: sha512-8hAxVfo2ImICd69BWlZwZlxe9rxDGDjuUhh+WeWgGDvfBCE+r3lkynkQvIovDz4jcMi8O7bsEaFygaDT+h9sBA==}
+ ace-builds@1.43.5:
+ resolution: {integrity: sha512-iH5FLBKdB7SVn9GR37UgA/tpQS8OTWIxWAuq3Ofaw+Qbc69FfPXsXd9jeW7KRG2xKpKMqBDnu0tHBrCWY5QI7A==}
acorn-jsx@5.3.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
@@ -1422,8 +1628,8 @@ packages:
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
- alien-signals@3.1.0:
- resolution: {integrity: sha512-yufC6VpSy8tK3I0lO67pjumo5JvDQVQyr38+3OHqe6CHl1t2VZekKZ7EKKZSqk0cRmE7U7tfZbpXiKNzuc+ckg==}
+ alien-signals@3.1.2:
+ resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
@@ -1432,8 +1638,8 @@ packages:
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
- autoprefixer@10.4.22:
- resolution: {integrity: sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==}
+ autoprefixer@10.4.23:
+ resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
peerDependencies:
@@ -1461,6 +1667,10 @@ packages:
resolution: {integrity: sha512-73lC1ugzwoaWCLJ1LvOgrR5xsMLTqSKIEoMHVtL9E/HNk0PXtTM76ZIm84856/SF7Nv8mPZxKoBsgpm0tR1u1Q==}
hasBin: true
+ baseline-browser-mapping@2.9.7:
+ resolution: {integrity: sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==}
+ hasBin: true
+
birpc@2.8.0:
resolution: {integrity: sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==}
@@ -1489,6 +1699,11 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
+ browserslist@4.28.1:
+ resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
@@ -1499,6 +1714,9 @@ packages:
caniuse-lite@1.0.30001754:
resolution: {integrity: sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==}
+ caniuse-lite@1.0.30001760:
+ resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==}
+
chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
@@ -1544,8 +1762,8 @@ packages:
engines: {node: '>=4'}
hasBin: true
- csstype@3.1.3:
- resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
custom-error-instance@2.1.1:
resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==}
@@ -1572,14 +1790,17 @@ packages:
dom-walk@0.1.2:
resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==}
- dompurify@3.3.0:
- resolution: {integrity: sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==}
+ dompurify@3.3.1:
+ resolution: {integrity: sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==}
electron-to-chromium@1.5.250:
resolution: {integrity: sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==}
- entities@4.5.0:
- resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ electron-to-chromium@1.5.267:
+ resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==}
+
+ entities@7.0.0:
+ resolution: {integrity: sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==}
engines: {node: '>=0.12'}
epubjs@0.3.93:
@@ -1596,8 +1817,13 @@ packages:
resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==}
engines: {node: '>=0.12'}
- esbuild@0.25.11:
- resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==}
+ esbuild@0.25.12:
+ resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ esbuild@0.27.2:
+ resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
engines: {node: '>=18'}
hasBin: true
@@ -1620,8 +1846,8 @@ packages:
peerDependencies:
eslint: '>=7.0.0'
- eslint-plugin-prettier@5.5.4:
- resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==}
+ eslint-plugin-prettier@5.5.5:
+ resolution: {integrity: sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
'@types/eslint': '>=8.0.0'
@@ -1634,8 +1860,8 @@ packages:
eslint-config-prettier:
optional: true
- eslint-plugin-vue@10.5.1:
- resolution: {integrity: sha512-SbR9ZBUFKgvWAbq3RrdCtWaW0IKm6wwUiApxf3BVTNfqUIo4IQQmreMg2iHFJJ6C/0wss3LXURBJ1OwS/MhFcQ==}
+ eslint-plugin-vue@10.7.0:
+ resolution: {integrity: sha512-r2XFCK4qlo1sxEoAMIoTTX0PZAdla0JJDt1fmYiworZUX67WeEGqm+JbyAg3M+pGiJ5U6Mp5WQbontXWtIW7TA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
'@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
@@ -1660,8 +1886,8 @@ packages:
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- eslint@9.39.1:
- resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==}
+ eslint@9.39.2:
+ resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
hasBin: true
peerDependencies:
@@ -1728,8 +1954,8 @@ packages:
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
- fastq@1.18.0:
- resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==}
+ fastq@1.19.1:
+ resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
@@ -1874,8 +2100,8 @@ packages:
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
- js-yaml@4.1.0:
- resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ js-yaml@4.1.1:
+ resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
jsesc@3.1.0:
@@ -1897,8 +2123,8 @@ packages:
engines: {node: '>=6'}
hasBin: true
- jsonc-eslint-parser@2.4.0:
- resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==}
+ jsonc-eslint-parser@2.4.2:
+ resolution: {integrity: sha512-1e4qoRgnn448pRuMvKGsFFymUCquZV0mpGgOyIKNgD3JVDTsVJyRBGH/Fm0tBb8WsWGgmB1mDe6/yJMQM37DUA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
jszip@3.10.1:
@@ -1928,8 +2154,8 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
- lodash-es@4.17.21:
- resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
+ lodash-es@4.17.22:
+ resolution: {integrity: sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q==}
lodash._baseiteratee@4.7.0:
resolution: {integrity: sha512-nqB9M+wITz0BX/Q2xg6fQ8mLkyfF7MU7eE+MNBNjTHFKeKaZAPEzEg+E8LWxKWf1DQVflNEn9N49yAuqKh2mWQ==}
@@ -1973,8 +2199,8 @@ packages:
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
- marked@17.0.0:
- resolution: {integrity: sha512-KkDYEWEEiYJw/KC+DVm1zzlpMQSMIu6YRltkcCvwheCp8HWPXCk9JwOmHJKBlGfzcpzcIt6x3sMnTsRm/51oDg==}
+ marked@17.0.1:
+ resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==}
engines: {node: '>= 20'}
hasBin: true
@@ -2038,10 +2264,6 @@ packages:
node-releases@2.0.27:
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
- normalize-range@0.1.2:
- resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
- engines: {node: '>=0.10.0'}
-
normalize.css@8.0.1:
resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==}
@@ -2114,8 +2336,8 @@ packages:
resolution: {integrity: sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==}
hasBin: true
- postcss-selector-parser@6.1.2:
- resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
+ postcss-selector-parser@7.1.1:
+ resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==}
engines: {node: '>=4'}
postcss-value-parser@4.2.0:
@@ -2129,12 +2351,12 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
- prettier-linter-helpers@1.0.0:
- resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
+ prettier-linter-helpers@1.0.1:
+ resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==}
engines: {node: '>=6.0.0'}
- prettier@3.6.2:
- resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
+ prettier@3.8.0:
+ resolution: {integrity: sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==}
engines: {node: '>=14'}
hasBin: true
@@ -2207,15 +2429,15 @@ packages:
resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
engines: {node: '>= 4'}
- reusify@1.0.4:
- resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ reusify@1.1.0:
+ resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
rfdc@1.4.1:
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
- rollup@4.52.5:
- resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==}
+ rollup@4.55.1:
+ resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
@@ -2282,21 +2504,21 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
- synckit@0.11.11:
- resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==}
+ synckit@0.11.12:
+ resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==}
engines: {node: ^14.18.0 || >=16.0.0}
systemjs@6.15.1:
resolution: {integrity: sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==}
- tabbable@6.3.0:
- resolution: {integrity: sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==}
+ tabbable@6.4.0:
+ resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==}
tar-mini@0.2.0:
resolution: {integrity: sha512-+qfUHz700DWnRutdUsxRRVZ38G1Qr27OetwaMYTdg8hcPxf46U0S1Zf76dQMWRBmusOt2ZCK5kbIaiLkoGO7WQ==}
- terser@5.44.1:
- resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==}
+ terser@5.46.0:
+ resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==}
engines: {node: '>=10'}
hasBin: true
@@ -2308,8 +2530,8 @@ packages:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
- ts-api-utils@2.1.0:
- resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==}
+ ts-api-utils@2.4.0:
+ resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==}
engines: {node: '>=18.12'}
peerDependencies:
typescript: '>=4.8.4'
@@ -2356,8 +2578,8 @@ packages:
resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==}
engines: {node: '>=4'}
- unplugin@2.3.10:
- resolution: {integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==}
+ unplugin@2.3.11:
+ resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==}
engines: {node: '>=18.12.0'}
update-browserslist-db@1.1.4:
@@ -2366,6 +2588,12 @@ packages:
peerDependencies:
browserslist: '>= 4.21.0'
+ update-browserslist-db@1.2.2:
+ resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
@@ -2393,8 +2621,8 @@ packages:
videojs-hotkeys@0.2.30:
resolution: {integrity: sha512-G8kEQZPapoWDoEajh2Nroy4bCN1qVEul5AuzZqBS7ZCG45K7hqTYKgf1+fmYvG8m8u84sZmVMUvSWZBjaFW66Q==}
- videojs-mobile-ui@1.1.1:
- resolution: {integrity: sha512-q7vx74++bqu2763Tc/GG4qFcMt42emC8uXe/z+zFVpBIiysgAf89AgorE6m30YHWtVJWgbRIyzFVYNOxCk9qow==}
+ videojs-mobile-ui@1.1.3:
+ resolution: {integrity: sha512-LyWIRZBQWRouUQ9i9HBBvhwFL1uZkg3Adt52nT+e297dwpOgTaELO7gCXgvj5f6a2AfEb8a5AQMY4SLeIf8cqw==}
engines: {node: '>=14', npm: '>=6'}
peerDependencies:
video.js: ^8
@@ -2402,11 +2630,11 @@ packages:
videojs-vtt.js@0.15.5:
resolution: {integrity: sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==}
- vite-plugin-compression2@2.3.1:
- resolution: {integrity: sha512-bnhLTsurtvOiiP6EMISIKVsOMCeTAjE6FJbyqQus3W4mtAxF7pCuC4puUIAiCgNs98tOCpqo6GIXJXTLufzIaw==}
+ vite-plugin-compression2@2.4.0:
+ resolution: {integrity: sha512-8J4CBF1+dM1I06azba/eXJuJHinLF0Am7lUvRH8AZpu0otJoBaDEnxrIEr5iPZJSwH0AEglJGYCveh7pN52jCg==}
- vite@7.2.2:
- resolution: {integrity: sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==}
+ vite@7.3.1:
+ resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -2462,8 +2690,8 @@ packages:
focus-trap: '>=7.2.0'
vue: '>=3.2.0'
- vue-i18n@11.1.12:
- resolution: {integrity: sha512-BnstPj3KLHLrsqbVU2UOrPmr0+Mv11bsUZG0PyCOzsawCivk8W00GMXHeVUWIDOgNaScCuZah47CZFE+Wnl8mw==}
+ vue-i18n@11.2.8:
+ resolution: {integrity: sha512-vJ123v/PXCZntd6Qj5Jumy7UBmIuE92VrtdX+AXr+1WzdBHojiBxnAxdfctUFL+/JIN+VQH4BhsfTtiGsvVObg==}
engines: {node: '>= 16'}
peerDependencies:
vue: ^3.0.0
@@ -2471,11 +2699,11 @@ packages:
vue-lazyload@3.0.0:
resolution: {integrity: sha512-h2keL/Rj550dLgesgOtXJS9qOiSMmuJNeVlfNAYV1/IYwOQYaWk5mFJlwRxmZDK9YC5gECcFLYYj7z1lKSf9ug==}
- vue-reader@1.3.3:
- resolution: {integrity: sha512-Rpd9szXrnlyK1TxBsy/5He8W077ALFxrDLzOiD6HIzsJNj4miKs6nDljj4HdSliKbZ7LYvUMOitW9TL+5J5Ecg==}
+ vue-reader@1.3.4:
+ resolution: {integrity: sha512-QYTX9hlrV71gL/1vMejcBLLS9Ool29XMZcLQwvL0Ep1F//o0ymzYbKX2Lre+4BUBkVq49/GmmGCmAJACsJL9tw==}
- vue-router@4.6.3:
- resolution: {integrity: sha512-ARBedLm9YlbvQomnmq91Os7ck6efydTSpRP3nuOKCvgJOHNrhRoJDSKtee8kcL1Vf7nz6U+PMBL+hTvR3bTVQg==}
+ vue-router@4.6.4:
+ resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==}
peerDependencies:
vue: ^3.5.0
@@ -2484,14 +2712,14 @@ packages:
peerDependencies:
vue: ^3.0.2
- vue-tsc@3.1.3:
- resolution: {integrity: sha512-StMNfZHwPIXQgY3KxPKM0Jsoc8b46mDV3Fn2UlHCBIwRJApjqrSwqeMYgWf0zpN+g857y74pv7GWuBm+UqQe1w==}
+ vue-tsc@3.2.2:
+ resolution: {integrity: sha512-r9YSia/VgGwmbbfC06hDdAatH634XJ9nVl6Zrnz1iK4ucp8Wu78kawplXnIDa3MSu1XdQQePTHLXYwPDWn+nyQ==}
hasBin: true
peerDependencies:
typescript: '>=5.0.0'
- vue@3.5.24:
- resolution: {integrity: sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==}
+ vue@3.5.26:
+ resolution: {integrity: sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
@@ -2517,13 +2745,13 @@ packages:
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
- yaml-eslint-parser@1.2.3:
- resolution: {integrity: sha512-4wZWvE398hCP7O8n3nXKu/vdq1HcH01ixYlCREaJL5NUMwQ0g3MaGFUBNSlmBtKmhbtVG/Cm6lyYmSVTEVil8A==}
+ yaml-eslint-parser@1.3.2:
+ resolution: {integrity: sha512-odxVsHAkZYYglR30aPYRY4nUGJnoJ2y1ww2HDvZALo0BDETv9kWbi16J52eHs+PWRNmF4ub6nZqfVOeesOvntg==}
engines: {node: ^14.17.0 || >=16.0.0}
- yaml@2.7.0:
- resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==}
- engines: {node: '>= 14'}
+ yaml@2.8.2:
+ resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==}
+ engines: {node: '>= 14.6'}
hasBin: true
yocto-queue@0.1.0:
@@ -3186,91 +3414,174 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
- '@chenfengyuan/vue-number-input@2.0.1(vue@3.5.24(typescript@5.9.3))':
+ '@chenfengyuan/vue-number-input@2.0.1(vue@3.5.26(typescript@5.9.3))':
dependencies:
- vue: 3.5.24(typescript@5.9.3)
+ vue: 3.5.26(typescript@5.9.3)
- '@esbuild/aix-ppc64@0.25.11':
+ '@esbuild/aix-ppc64@0.25.12':
optional: true
- '@esbuild/android-arm64@0.25.11':
+ '@esbuild/aix-ppc64@0.27.2':
optional: true
- '@esbuild/android-arm@0.25.11':
+ '@esbuild/android-arm64@0.25.12':
optional: true
- '@esbuild/android-x64@0.25.11':
+ '@esbuild/android-arm64@0.27.2':
optional: true
- '@esbuild/darwin-arm64@0.25.11':
+ '@esbuild/android-arm@0.25.12':
optional: true
- '@esbuild/darwin-x64@0.25.11':
+ '@esbuild/android-arm@0.27.2':
optional: true
- '@esbuild/freebsd-arm64@0.25.11':
+ '@esbuild/android-x64@0.25.12':
optional: true
- '@esbuild/freebsd-x64@0.25.11':
+ '@esbuild/android-x64@0.27.2':
optional: true
- '@esbuild/linux-arm64@0.25.11':
+ '@esbuild/darwin-arm64@0.25.12':
optional: true
- '@esbuild/linux-arm@0.25.11':
+ '@esbuild/darwin-arm64@0.27.2':
optional: true
- '@esbuild/linux-ia32@0.25.11':
+ '@esbuild/darwin-x64@0.25.12':
optional: true
- '@esbuild/linux-loong64@0.25.11':
+ '@esbuild/darwin-x64@0.27.2':
optional: true
- '@esbuild/linux-mips64el@0.25.11':
+ '@esbuild/freebsd-arm64@0.25.12':
optional: true
- '@esbuild/linux-ppc64@0.25.11':
+ '@esbuild/freebsd-arm64@0.27.2':
optional: true
- '@esbuild/linux-riscv64@0.25.11':
+ '@esbuild/freebsd-x64@0.25.12':
optional: true
- '@esbuild/linux-s390x@0.25.11':
+ '@esbuild/freebsd-x64@0.27.2':
optional: true
- '@esbuild/linux-x64@0.25.11':
+ '@esbuild/linux-arm64@0.25.12':
optional: true
- '@esbuild/netbsd-arm64@0.25.11':
+ '@esbuild/linux-arm64@0.27.2':
optional: true
- '@esbuild/netbsd-x64@0.25.11':
+ '@esbuild/linux-arm@0.25.12':
optional: true
- '@esbuild/openbsd-arm64@0.25.11':
+ '@esbuild/linux-arm@0.27.2':
optional: true
- '@esbuild/openbsd-x64@0.25.11':
+ '@esbuild/linux-ia32@0.25.12':
optional: true
- '@esbuild/openharmony-arm64@0.25.11':
+ '@esbuild/linux-ia32@0.27.2':
optional: true
- '@esbuild/sunos-x64@0.25.11':
+ '@esbuild/linux-loong64@0.25.12':
optional: true
- '@esbuild/win32-arm64@0.25.11':
+ '@esbuild/linux-loong64@0.27.2':
optional: true
- '@esbuild/win32-ia32@0.25.11':
+ '@esbuild/linux-mips64el@0.25.12':
optional: true
- '@esbuild/win32-x64@0.25.11':
+ '@esbuild/linux-mips64el@0.27.2':
optional: true
- '@eslint-community/eslint-utils@4.9.0(eslint@9.39.1)':
+ '@esbuild/linux-ppc64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.27.2':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.27.2':
+ optional: true
+
+ '@esbuild/linux-s390x@0.25.12':
+ optional: true
+
+ '@esbuild/linux-s390x@0.27.2':
+ optional: true
+
+ '@esbuild/linux-x64@0.25.12':
+ optional: true
+
+ '@esbuild/linux-x64@0.27.2':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.25.12':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.27.2':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.25.12':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.27.2':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/sunos-x64@0.25.12':
+ optional: true
+
+ '@esbuild/sunos-x64@0.27.2':
+ optional: true
+
+ '@esbuild/win32-arm64@0.25.12':
+ optional: true
+
+ '@esbuild/win32-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/win32-ia32@0.25.12':
+ optional: true
+
+ '@esbuild/win32-ia32@0.27.2':
+ optional: true
+
+ '@esbuild/win32-x64@0.25.12':
+ optional: true
+
+ '@esbuild/win32-x64@0.27.2':
+ optional: true
+
+ '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)':
dependencies:
- eslint: 9.39.1
+ eslint: 9.39.2
+ eslint-visitor-keys: 3.4.3
+
+ '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2)':
+ dependencies:
+ eslint: 9.39.2
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.2': {}
@@ -3291,7 +3602,7 @@ snapshots:
dependencies:
'@types/json-schema': 7.0.15
- '@eslint/eslintrc@3.3.1':
+ '@eslint/eslintrc@3.3.3':
dependencies:
ajv: 6.12.6
debug: 4.4.3
@@ -3299,13 +3610,13 @@ snapshots:
globals: 14.0.0
ignore: 5.3.2
import-fresh: 3.3.1
- js-yaml: 4.1.0
+ js-yaml: 4.1.1
minimatch: 3.1.2
strip-json-comments: 3.1.1
transitivePeerDependencies:
- supports-color
- '@eslint/js@9.39.1': {}
+ '@eslint/js@9.39.2': {}
'@eslint/object-schema@2.1.7': {}
@@ -3325,49 +3636,51 @@ snapshots:
'@humanwhocodes/retry@0.4.3': {}
- '@intlify/bundle-utils@11.0.1(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))':
+ '@intlify/bundle-utils@11.0.3(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))':
dependencies:
- '@intlify/message-compiler': 11.1.12
- '@intlify/shared': 11.1.12
+ '@intlify/message-compiler': 11.2.8
+ '@intlify/shared': 11.2.2
acorn: 8.15.0
- esbuild: 0.25.11
+ esbuild: 0.25.12
escodegen: 2.1.0
estree-walker: 2.0.2
- jsonc-eslint-parser: 2.4.0
+ jsonc-eslint-parser: 2.4.2
source-map-js: 1.2.1
- yaml-eslint-parser: 1.2.3
+ yaml-eslint-parser: 1.3.2
optionalDependencies:
- vue-i18n: 11.1.12(vue@3.5.24(typescript@5.9.3))
+ vue-i18n: 11.2.8(vue@3.5.26(typescript@5.9.3))
- '@intlify/core-base@11.1.12':
+ '@intlify/core-base@11.2.8':
dependencies:
- '@intlify/message-compiler': 11.1.12
- '@intlify/shared': 11.1.12
+ '@intlify/message-compiler': 11.2.8
+ '@intlify/shared': 11.2.8
- '@intlify/message-compiler@11.1.12':
+ '@intlify/message-compiler@11.2.8':
dependencies:
- '@intlify/shared': 11.1.12
+ '@intlify/shared': 11.2.8
source-map-js: 1.2.1
- '@intlify/shared@11.1.12': {}
+ '@intlify/shared@11.2.2': {}
- '@intlify/unplugin-vue-i18n@11.0.1(@vue/compiler-dom@3.5.24)(eslint@9.39.1)(rollup@4.52.5)(typescript@5.9.3)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))':
+ '@intlify/shared@11.2.8': {}
+
+ '@intlify/unplugin-vue-i18n@11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2)(rollup@4.55.1)(typescript@5.9.3)(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))':
dependencies:
- '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
- '@intlify/bundle-utils': 11.0.1(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))
- '@intlify/shared': 11.1.12
- '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))
- '@rollup/pluginutils': 5.3.0(rollup@4.52.5)
- '@typescript-eslint/scope-manager': 8.46.4
- '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3)
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2)
+ '@intlify/bundle-utils': 11.0.3(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))
+ '@intlify/shared': 11.2.2
+ '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.2.2)(@vue/compiler-dom@3.5.26)(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))
+ '@rollup/pluginutils': 5.3.0(rollup@4.55.1)
+ '@typescript-eslint/scope-manager': 8.49.0
+ '@typescript-eslint/typescript-estree': 8.49.0(typescript@5.9.3)
debug: 4.4.3
fast-glob: 3.3.3
pathe: 2.0.3
picocolors: 1.1.1
- unplugin: 2.3.10
- vue: 3.5.24(typescript@5.9.3)
+ unplugin: 2.3.11
+ vue: 3.5.26(typescript@5.9.3)
optionalDependencies:
- vue-i18n: 11.1.12(vue@3.5.24(typescript@5.9.3))
+ vue-i18n: 11.2.8(vue@3.5.26(typescript@5.9.3))
transitivePeerDependencies:
- '@vue/compiler-dom'
- eslint
@@ -3375,14 +3688,14 @@ snapshots:
- supports-color
- typescript
- '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.24)(vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))':
+ '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.2.2)(@vue/compiler-dom@3.5.26)(vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)))(vue@3.5.26(typescript@5.9.3))':
dependencies:
'@babel/parser': 7.28.5
optionalDependencies:
- '@intlify/shared': 11.1.12
- '@vue/compiler-dom': 3.5.24
- vue: 3.5.24(typescript@5.9.3)
- vue-i18n: 11.1.12(vue@3.5.24(typescript@5.9.3))
+ '@intlify/shared': 11.2.2
+ '@vue/compiler-dom': 3.5.26
+ vue: 3.5.26(typescript@5.9.3)
+ vue-i18n: 11.2.8(vue@3.5.26(typescript@5.9.3))
'@jridgewell/gen-mapping@0.3.13':
dependencies:
@@ -3418,87 +3731,96 @@ snapshots:
'@nodelib/fs.walk@1.2.8':
dependencies:
'@nodelib/fs.scandir': 2.1.5
- fastq: 1.18.0
+ fastq: 1.19.1
'@pkgr/core@0.2.9': {}
- '@rolldown/pluginutils@1.0.0-beta.29': {}
+ '@rolldown/pluginutils@1.0.0-beta.53': {}
- '@rollup/pluginutils@5.3.0(rollup@4.52.5)':
+ '@rollup/pluginutils@5.3.0(rollup@4.55.1)':
dependencies:
'@types/estree': 1.0.8
estree-walker: 2.0.2
picomatch: 4.0.3
optionalDependencies:
- rollup: 4.52.5
+ rollup: 4.55.1
- '@rollup/rollup-android-arm-eabi@4.52.5':
+ '@rollup/rollup-android-arm-eabi@4.55.1':
optional: true
- '@rollup/rollup-android-arm64@4.52.5':
+ '@rollup/rollup-android-arm64@4.55.1':
optional: true
- '@rollup/rollup-darwin-arm64@4.52.5':
+ '@rollup/rollup-darwin-arm64@4.55.1':
optional: true
- '@rollup/rollup-darwin-x64@4.52.5':
+ '@rollup/rollup-darwin-x64@4.55.1':
optional: true
- '@rollup/rollup-freebsd-arm64@4.52.5':
+ '@rollup/rollup-freebsd-arm64@4.55.1':
optional: true
- '@rollup/rollup-freebsd-x64@4.52.5':
+ '@rollup/rollup-freebsd-x64@4.55.1':
optional: true
- '@rollup/rollup-linux-arm-gnueabihf@4.52.5':
+ '@rollup/rollup-linux-arm-gnueabihf@4.55.1':
optional: true
- '@rollup/rollup-linux-arm-musleabihf@4.52.5':
+ '@rollup/rollup-linux-arm-musleabihf@4.55.1':
optional: true
- '@rollup/rollup-linux-arm64-gnu@4.52.5':
+ '@rollup/rollup-linux-arm64-gnu@4.55.1':
optional: true
- '@rollup/rollup-linux-arm64-musl@4.52.5':
+ '@rollup/rollup-linux-arm64-musl@4.55.1':
optional: true
- '@rollup/rollup-linux-loong64-gnu@4.52.5':
+ '@rollup/rollup-linux-loong64-gnu@4.55.1':
optional: true
- '@rollup/rollup-linux-ppc64-gnu@4.52.5':
+ '@rollup/rollup-linux-loong64-musl@4.55.1':
optional: true
- '@rollup/rollup-linux-riscv64-gnu@4.52.5':
+ '@rollup/rollup-linux-ppc64-gnu@4.55.1':
optional: true
- '@rollup/rollup-linux-riscv64-musl@4.52.5':
+ '@rollup/rollup-linux-ppc64-musl@4.55.1':
optional: true
- '@rollup/rollup-linux-s390x-gnu@4.52.5':
+ '@rollup/rollup-linux-riscv64-gnu@4.55.1':
optional: true
- '@rollup/rollup-linux-x64-gnu@4.52.5':
+ '@rollup/rollup-linux-riscv64-musl@4.55.1':
optional: true
- '@rollup/rollup-linux-x64-musl@4.52.5':
+ '@rollup/rollup-linux-s390x-gnu@4.55.1':
optional: true
- '@rollup/rollup-openharmony-arm64@4.52.5':
+ '@rollup/rollup-linux-x64-gnu@4.55.1':
optional: true
- '@rollup/rollup-win32-arm64-msvc@4.52.5':
+ '@rollup/rollup-linux-x64-musl@4.55.1':
optional: true
- '@rollup/rollup-win32-ia32-msvc@4.52.5':
+ '@rollup/rollup-openbsd-x64@4.55.1':
optional: true
- '@rollup/rollup-win32-x64-gnu@4.52.5':
+ '@rollup/rollup-openharmony-arm64@4.55.1':
optional: true
- '@rollup/rollup-win32-x64-msvc@4.52.5':
+ '@rollup/rollup-win32-arm64-msvc@4.55.1':
optional: true
- '@tsconfig/node24@24.0.2': {}
+ '@rollup/rollup-win32-ia32-msvc@4.55.1':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.55.1':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.55.1':
+ optional: true
+
+ '@tsconfig/node24@24.0.4': {}
'@types/estree@1.0.8': {}
@@ -3514,7 +3836,7 @@ snapshots:
'@types/lodash@4.17.13': {}
- '@types/node@24.10.1':
+ '@types/node@24.10.9':
dependencies:
undici-types: 7.16.0
@@ -3523,48 +3845,47 @@ snapshots:
'@types/web-bluetooth@0.0.21': {}
- '@typescript-eslint/eslint-plugin@8.37.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)':
+ '@typescript-eslint/eslint-plugin@8.37.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
- '@typescript-eslint/parser': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
+ '@typescript-eslint/parser': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.37.0
- '@typescript-eslint/type-utils': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
- '@typescript-eslint/utils': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
+ '@typescript-eslint/type-utils': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.37.0
- eslint: 9.39.1
+ eslint: 9.39.2
graphemer: 1.4.0
ignore: 7.0.5
natural-compare: 1.4.0
- ts-api-utils: 2.1.0(typescript@5.9.3)
+ ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/eslint-plugin@8.46.4(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)':
+ '@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
- '@typescript-eslint/parser': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
- '@typescript-eslint/scope-manager': 8.46.4
- '@typescript-eslint/type-utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3)
- '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3)
- '@typescript-eslint/visitor-keys': 8.46.4
- eslint: 9.39.1
- graphemer: 1.4.0
+ '@typescript-eslint/parser': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
+ '@typescript-eslint/scope-manager': 8.53.0
+ '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3)
+ '@typescript-eslint/visitor-keys': 8.53.0
+ eslint: 9.39.2
ignore: 7.0.5
natural-compare: 1.4.0
- ts-api-utils: 2.1.0(typescript@5.9.3)
+ ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3)':
+ '@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/scope-manager': 8.37.0
'@typescript-eslint/types': 8.37.0
'@typescript-eslint/typescript-estree': 8.37.0(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.37.0
debug: 4.4.3
- eslint: 9.39.1
+ eslint: 9.39.2
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -3578,10 +3899,19 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/project-service@8.46.4(typescript@5.9.3)':
+ '@typescript-eslint/project-service@8.49.0(typescript@5.9.3)':
dependencies:
- '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3)
- '@typescript-eslint/types': 8.46.4
+ '@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3)
+ '@typescript-eslint/types': 8.49.0
+ debug: 4.4.3
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/project-service@8.53.0(typescript@5.9.3)':
+ dependencies:
+ '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3)
+ '@typescript-eslint/types': 8.53.0
debug: 4.4.3
typescript: 5.9.3
transitivePeerDependencies:
@@ -3592,46 +3922,57 @@ snapshots:
'@typescript-eslint/types': 8.37.0
'@typescript-eslint/visitor-keys': 8.37.0
- '@typescript-eslint/scope-manager@8.46.4':
+ '@typescript-eslint/scope-manager@8.49.0':
dependencies:
- '@typescript-eslint/types': 8.46.4
- '@typescript-eslint/visitor-keys': 8.46.4
+ '@typescript-eslint/types': 8.49.0
+ '@typescript-eslint/visitor-keys': 8.49.0
+
+ '@typescript-eslint/scope-manager@8.53.0':
+ dependencies:
+ '@typescript-eslint/types': 8.53.0
+ '@typescript-eslint/visitor-keys': 8.53.0
'@typescript-eslint/tsconfig-utils@8.37.0(typescript@5.9.3)':
dependencies:
typescript: 5.9.3
- '@typescript-eslint/tsconfig-utils@8.46.4(typescript@5.9.3)':
+ '@typescript-eslint/tsconfig-utils@8.49.0(typescript@5.9.3)':
dependencies:
typescript: 5.9.3
- '@typescript-eslint/type-utils@8.37.0(eslint@9.39.1)(typescript@5.9.3)':
+ '@typescript-eslint/tsconfig-utils@8.53.0(typescript@5.9.3)':
+ dependencies:
+ typescript: 5.9.3
+
+ '@typescript-eslint/type-utils@8.37.0(eslint@9.39.2)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/types': 8.37.0
'@typescript-eslint/typescript-estree': 8.37.0(typescript@5.9.3)
- '@typescript-eslint/utils': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
debug: 4.4.3
- eslint: 9.39.1
- ts-api-utils: 2.1.0(typescript@5.9.3)
+ eslint: 9.39.2
+ ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/type-utils@8.46.4(eslint@9.39.1)(typescript@5.9.3)':
+ '@typescript-eslint/type-utils@8.53.0(eslint@9.39.2)(typescript@5.9.3)':
dependencies:
- '@typescript-eslint/types': 8.46.4
- '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3)
- '@typescript-eslint/utils': 8.46.4(eslint@9.39.1)(typescript@5.9.3)
+ '@typescript-eslint/types': 8.53.0
+ '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3)
+ '@typescript-eslint/utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3)
debug: 4.4.3
- eslint: 9.39.1
- ts-api-utils: 2.1.0(typescript@5.9.3)
+ eslint: 9.39.2
+ ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@8.37.0': {}
- '@typescript-eslint/types@8.46.4': {}
+ '@typescript-eslint/types@8.49.0': {}
+
+ '@typescript-eslint/types@8.53.0': {}
'@typescript-eslint/typescript-estree@8.37.0(typescript@5.9.3)':
dependencies:
@@ -3644,45 +3985,59 @@ snapshots:
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.7.3
- ts-api-utils: 2.1.0(typescript@5.9.3)
+ ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/typescript-estree@8.46.4(typescript@5.9.3)':
+ '@typescript-eslint/typescript-estree@8.49.0(typescript@5.9.3)':
dependencies:
- '@typescript-eslint/project-service': 8.46.4(typescript@5.9.3)
- '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3)
- '@typescript-eslint/types': 8.46.4
- '@typescript-eslint/visitor-keys': 8.46.4
+ '@typescript-eslint/project-service': 8.49.0(typescript@5.9.3)
+ '@typescript-eslint/tsconfig-utils': 8.49.0(typescript@5.9.3)
+ '@typescript-eslint/types': 8.49.0
+ '@typescript-eslint/visitor-keys': 8.49.0
debug: 4.4.3
- fast-glob: 3.3.3
- is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.7.3
- ts-api-utils: 2.1.0(typescript@5.9.3)
+ tinyglobby: 0.2.15
+ ts-api-utils: 2.4.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.37.0(eslint@9.39.1)(typescript@5.9.3)':
+ '@typescript-eslint/typescript-estree@8.53.0(typescript@5.9.3)':
dependencies:
- '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
+ '@typescript-eslint/project-service': 8.53.0(typescript@5.9.3)
+ '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3)
+ '@typescript-eslint/types': 8.53.0
+ '@typescript-eslint/visitor-keys': 8.53.0
+ debug: 4.4.3
+ minimatch: 9.0.5
+ semver: 7.7.3
+ tinyglobby: 0.2.15
+ ts-api-utils: 2.4.0(typescript@5.9.3)
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/utils@8.37.0(eslint@9.39.2)(typescript@5.9.3)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2)
'@typescript-eslint/scope-manager': 8.37.0
'@typescript-eslint/types': 8.37.0
'@typescript-eslint/typescript-estree': 8.37.0(typescript@5.9.3)
- eslint: 9.39.1
+ eslint: 9.39.2
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.46.4(eslint@9.39.1)(typescript@5.9.3)':
+ '@typescript-eslint/utils@8.53.0(eslint@9.39.2)(typescript@5.9.3)':
dependencies:
- '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
- '@typescript-eslint/scope-manager': 8.46.4
- '@typescript-eslint/types': 8.46.4
- '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3)
- eslint: 9.39.1
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2)
+ '@typescript-eslint/scope-manager': 8.53.0
+ '@typescript-eslint/types': 8.53.0
+ '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3)
+ eslint: 9.39.2
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -3692,9 +4047,14 @@ snapshots:
'@typescript-eslint/types': 8.37.0
eslint-visitor-keys: 4.2.1
- '@typescript-eslint/visitor-keys@8.46.4':
+ '@typescript-eslint/visitor-keys@8.49.0':
dependencies:
- '@typescript-eslint/types': 8.46.4
+ '@typescript-eslint/types': 8.49.0
+ eslint-visitor-keys: 4.2.1
+
+ '@typescript-eslint/visitor-keys@8.53.0':
+ dependencies:
+ '@typescript-eslint/types': 8.53.0
eslint-visitor-keys: 4.2.1
'@videojs/http-streaming@3.17.2(video.js@8.23.4)':
@@ -3719,7 +4079,7 @@ snapshots:
global: 4.4.0
is-function: 1.0.2
- '@vitejs/plugin-legacy@7.2.1(terser@5.44.1)(vite@7.2.2(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))':
+ '@vitejs/plugin-legacy@7.2.1(terser@5.46.0)(vite@7.3.1(@types/node@24.10.9)(terser@5.46.0)(yaml@2.8.2))':
dependencies:
'@babel/core': 7.28.5
'@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5)
@@ -3733,58 +4093,58 @@ snapshots:
magic-string: 0.30.21
regenerator-runtime: 0.14.1
systemjs: 6.15.1
- terser: 5.44.1
- vite: 7.2.2(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0)
+ terser: 5.46.0
+ vite: 7.3.1(@types/node@24.10.9)(terser@5.46.0)(yaml@2.8.2)
transitivePeerDependencies:
- supports-color
- '@vitejs/plugin-vue@6.0.1(vite@7.2.2(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))(vue@3.5.24(typescript@5.9.3))':
+ '@vitejs/plugin-vue@6.0.3(vite@7.3.1(@types/node@24.10.9)(terser@5.46.0)(yaml@2.8.2))(vue@3.5.26(typescript@5.9.3))':
dependencies:
- '@rolldown/pluginutils': 1.0.0-beta.29
- vite: 7.2.2(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0)
- vue: 3.5.24(typescript@5.9.3)
+ '@rolldown/pluginutils': 1.0.0-beta.53
+ vite: 7.3.1(@types/node@24.10.9)(terser@5.46.0)(yaml@2.8.2)
+ vue: 3.5.26(typescript@5.9.3)
- '@volar/language-core@2.4.23':
+ '@volar/language-core@2.4.27':
dependencies:
- '@volar/source-map': 2.4.23
+ '@volar/source-map': 2.4.27
- '@volar/source-map@2.4.23': {}
+ '@volar/source-map@2.4.27': {}
- '@volar/typescript@2.4.23':
+ '@volar/typescript@2.4.27':
dependencies:
- '@volar/language-core': 2.4.23
+ '@volar/language-core': 2.4.27
path-browserify: 1.0.1
vscode-uri: 3.1.0
- '@vue/compiler-core@3.5.24':
+ '@vue/compiler-core@3.5.26':
dependencies:
'@babel/parser': 7.28.5
- '@vue/shared': 3.5.24
- entities: 4.5.0
+ '@vue/shared': 3.5.26
+ entities: 7.0.0
estree-walker: 2.0.2
source-map-js: 1.2.1
- '@vue/compiler-dom@3.5.24':
+ '@vue/compiler-dom@3.5.26':
dependencies:
- '@vue/compiler-core': 3.5.24
- '@vue/shared': 3.5.24
+ '@vue/compiler-core': 3.5.26
+ '@vue/shared': 3.5.26
- '@vue/compiler-sfc@3.5.24':
+ '@vue/compiler-sfc@3.5.26':
dependencies:
'@babel/parser': 7.28.5
- '@vue/compiler-core': 3.5.24
- '@vue/compiler-dom': 3.5.24
- '@vue/compiler-ssr': 3.5.24
- '@vue/shared': 3.5.24
+ '@vue/compiler-core': 3.5.26
+ '@vue/compiler-dom': 3.5.26
+ '@vue/compiler-ssr': 3.5.26
+ '@vue/shared': 3.5.26
estree-walker: 2.0.2
magic-string: 0.30.21
postcss: 8.5.6
source-map-js: 1.2.1
- '@vue/compiler-ssr@3.5.24':
+ '@vue/compiler-ssr@3.5.26':
dependencies:
- '@vue/compiler-dom': 3.5.24
- '@vue/shared': 3.5.24
+ '@vue/compiler-dom': 3.5.26
+ '@vue/shared': 3.5.26
'@vue/devtools-api@6.6.4': {}
@@ -3806,96 +4166,94 @@ snapshots:
dependencies:
rfdc: 1.4.1
- '@vue/eslint-config-prettier@10.2.0(eslint@9.39.1)(prettier@3.6.2)':
+ '@vue/eslint-config-prettier@10.2.0(eslint@9.39.2)(prettier@3.8.0)':
dependencies:
- eslint: 9.39.1
- eslint-config-prettier: 10.1.8(eslint@9.39.1)
- eslint-plugin-prettier: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2)
- prettier: 3.6.2
+ eslint: 9.39.2
+ eslint-config-prettier: 10.1.8(eslint@9.39.2)
+ eslint-plugin-prettier: 5.5.5(eslint-config-prettier@10.1.8(eslint@9.39.2))(eslint@9.39.2)(prettier@3.8.0)
+ prettier: 3.8.0
transitivePeerDependencies:
- '@types/eslint'
- '@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)':
+ '@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.7.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(vue-eslint-parser@10.2.0(eslint@9.39.2)))(eslint@9.39.2)(typescript@5.9.3)':
dependencies:
- '@typescript-eslint/utils': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
- eslint: 9.39.1
- eslint-plugin-vue: 10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1))
+ '@typescript-eslint/utils': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
+ eslint: 9.39.2
+ eslint-plugin-vue: 10.7.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(vue-eslint-parser@10.2.0(eslint@9.39.2))
fast-glob: 3.3.3
- typescript-eslint: 8.37.0(eslint@9.39.1)(typescript@5.9.3)
- vue-eslint-parser: 10.2.0(eslint@9.39.1)
+ typescript-eslint: 8.37.0(eslint@9.39.2)(typescript@5.9.3)
+ vue-eslint-parser: 10.2.0(eslint@9.39.2)
optionalDependencies:
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
- '@vue/language-core@3.1.3(typescript@5.9.3)':
+ '@vue/language-core@3.2.2':
dependencies:
- '@volar/language-core': 2.4.23
- '@vue/compiler-dom': 3.5.24
- '@vue/shared': 3.5.24
- alien-signals: 3.1.0
+ '@volar/language-core': 2.4.27
+ '@vue/compiler-dom': 3.5.26
+ '@vue/shared': 3.5.26
+ alien-signals: 3.1.2
muggle-string: 0.4.1
path-browserify: 1.0.1
picomatch: 4.0.3
+
+ '@vue/reactivity@3.5.26':
+ dependencies:
+ '@vue/shared': 3.5.26
+
+ '@vue/runtime-core@3.5.26':
+ dependencies:
+ '@vue/reactivity': 3.5.26
+ '@vue/shared': 3.5.26
+
+ '@vue/runtime-dom@3.5.26':
+ dependencies:
+ '@vue/reactivity': 3.5.26
+ '@vue/runtime-core': 3.5.26
+ '@vue/shared': 3.5.26
+ csstype: 3.2.3
+
+ '@vue/server-renderer@3.5.26(vue@3.5.26(typescript@5.9.3))':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.26
+ '@vue/shared': 3.5.26
+ vue: 3.5.26(typescript@5.9.3)
+
+ '@vue/shared@3.5.26': {}
+
+ '@vue/tsconfig@0.8.1(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3))':
optionalDependencies:
typescript: 5.9.3
+ vue: 3.5.26(typescript@5.9.3)
- '@vue/reactivity@3.5.24':
- dependencies:
- '@vue/shared': 3.5.24
-
- '@vue/runtime-core@3.5.24':
- dependencies:
- '@vue/reactivity': 3.5.24
- '@vue/shared': 3.5.24
-
- '@vue/runtime-dom@3.5.24':
- dependencies:
- '@vue/reactivity': 3.5.24
- '@vue/runtime-core': 3.5.24
- '@vue/shared': 3.5.24
- csstype: 3.1.3
-
- '@vue/server-renderer@3.5.24(vue@3.5.24(typescript@5.9.3))':
- dependencies:
- '@vue/compiler-ssr': 3.5.24
- '@vue/shared': 3.5.24
- vue: 3.5.24(typescript@5.9.3)
-
- '@vue/shared@3.5.24': {}
-
- '@vue/tsconfig@0.8.1(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3))':
- optionalDependencies:
- typescript: 5.9.3
- vue: 3.5.24(typescript@5.9.3)
-
- '@vueuse/core@14.0.0(vue@3.5.24(typescript@5.9.3))':
+ '@vueuse/core@14.1.0(vue@3.5.26(typescript@5.9.3))':
dependencies:
'@types/web-bluetooth': 0.0.21
- '@vueuse/metadata': 14.0.0
- '@vueuse/shared': 14.0.0(vue@3.5.24(typescript@5.9.3))
- vue: 3.5.24(typescript@5.9.3)
+ '@vueuse/metadata': 14.1.0
+ '@vueuse/shared': 14.1.0(vue@3.5.26(typescript@5.9.3))
+ vue: 3.5.26(typescript@5.9.3)
- '@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.24(typescript@5.9.3))':
+ '@vueuse/integrations@14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.26(typescript@5.9.3))':
dependencies:
- '@vueuse/core': 14.0.0(vue@3.5.24(typescript@5.9.3))
- '@vueuse/shared': 14.0.0(vue@3.5.24(typescript@5.9.3))
- vue: 3.5.24(typescript@5.9.3)
+ '@vueuse/core': 14.1.0(vue@3.5.26(typescript@5.9.3))
+ '@vueuse/shared': 14.1.0(vue@3.5.26(typescript@5.9.3))
+ vue: 3.5.26(typescript@5.9.3)
optionalDependencies:
focus-trap: 7.6.2
jwt-decode: 4.0.0
- '@vueuse/metadata@14.0.0': {}
+ '@vueuse/metadata@14.1.0': {}
- '@vueuse/shared@14.0.0(vue@3.5.24(typescript@5.9.3))':
+ '@vueuse/shared@14.1.0(vue@3.5.26(typescript@5.9.3))':
dependencies:
- vue: 3.5.24(typescript@5.9.3)
+ vue: 3.5.26(typescript@5.9.3)
'@xmldom/xmldom@0.7.13': {}
'@xmldom/xmldom@0.8.11': {}
- ace-builds@1.43.4: {}
+ ace-builds@1.43.5: {}
acorn-jsx@5.3.2(acorn@8.15.0):
dependencies:
@@ -3917,7 +4275,7 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
- alien-signals@3.1.0: {}
+ alien-signals@3.1.2: {}
ansi-styles@4.3.0:
dependencies:
@@ -3925,12 +4283,11 @@ snapshots:
argparse@2.0.1: {}
- autoprefixer@10.4.22(postcss@8.5.6):
+ autoprefixer@10.4.23(postcss@8.5.6):
dependencies:
- browserslist: 4.28.0
- caniuse-lite: 1.0.30001754
+ browserslist: 4.28.1
+ caniuse-lite: 1.0.30001760
fraction.js: 5.3.4
- normalize-range: 0.1.2
picocolors: 1.1.1
postcss: 8.5.6
postcss-value-parser: 4.2.0
@@ -3963,6 +4320,8 @@ snapshots:
baseline-browser-mapping@2.8.26: {}
+ baseline-browser-mapping@2.9.7: {}
+
birpc@2.8.0: {}
boolbase@1.0.0: {}
@@ -3993,12 +4352,22 @@ snapshots:
node-releases: 2.0.27
update-browserslist-db: 1.1.4(browserslist@4.28.0)
+ browserslist@4.28.1:
+ dependencies:
+ baseline-browser-mapping: 2.9.7
+ caniuse-lite: 1.0.30001760
+ electron-to-chromium: 1.5.267
+ node-releases: 2.0.27
+ update-browserslist-db: 1.2.2(browserslist@4.28.1)
+
buffer-from@1.1.2: {}
callsites@3.1.0: {}
caniuse-lite@1.0.30001754: {}
+ caniuse-lite@1.0.30001760: {}
+
chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
@@ -4041,7 +4410,7 @@ snapshots:
cssesc@3.0.0: {}
- csstype@3.1.3: {}
+ csstype@3.2.3: {}
custom-error-instance@2.1.1: {}
@@ -4060,13 +4429,15 @@ snapshots:
dom-walk@0.1.2: {}
- dompurify@3.3.0:
+ dompurify@3.3.1:
optionalDependencies:
'@types/trusted-types': 2.0.7
electron-to-chromium@1.5.250: {}
- entities@4.5.0: {}
+ electron-to-chromium@1.5.267: {}
+
+ entities@7.0.0: {}
epubjs@0.3.93:
dependencies:
@@ -4098,34 +4469,63 @@ snapshots:
d: 1.0.2
ext: 1.7.0
- esbuild@0.25.11:
+ esbuild@0.25.12:
optionalDependencies:
- '@esbuild/aix-ppc64': 0.25.11
- '@esbuild/android-arm': 0.25.11
- '@esbuild/android-arm64': 0.25.11
- '@esbuild/android-x64': 0.25.11
- '@esbuild/darwin-arm64': 0.25.11
- '@esbuild/darwin-x64': 0.25.11
- '@esbuild/freebsd-arm64': 0.25.11
- '@esbuild/freebsd-x64': 0.25.11
- '@esbuild/linux-arm': 0.25.11
- '@esbuild/linux-arm64': 0.25.11
- '@esbuild/linux-ia32': 0.25.11
- '@esbuild/linux-loong64': 0.25.11
- '@esbuild/linux-mips64el': 0.25.11
- '@esbuild/linux-ppc64': 0.25.11
- '@esbuild/linux-riscv64': 0.25.11
- '@esbuild/linux-s390x': 0.25.11
- '@esbuild/linux-x64': 0.25.11
- '@esbuild/netbsd-arm64': 0.25.11
- '@esbuild/netbsd-x64': 0.25.11
- '@esbuild/openbsd-arm64': 0.25.11
- '@esbuild/openbsd-x64': 0.25.11
- '@esbuild/openharmony-arm64': 0.25.11
- '@esbuild/sunos-x64': 0.25.11
- '@esbuild/win32-arm64': 0.25.11
- '@esbuild/win32-ia32': 0.25.11
- '@esbuild/win32-x64': 0.25.11
+ '@esbuild/aix-ppc64': 0.25.12
+ '@esbuild/android-arm': 0.25.12
+ '@esbuild/android-arm64': 0.25.12
+ '@esbuild/android-x64': 0.25.12
+ '@esbuild/darwin-arm64': 0.25.12
+ '@esbuild/darwin-x64': 0.25.12
+ '@esbuild/freebsd-arm64': 0.25.12
+ '@esbuild/freebsd-x64': 0.25.12
+ '@esbuild/linux-arm': 0.25.12
+ '@esbuild/linux-arm64': 0.25.12
+ '@esbuild/linux-ia32': 0.25.12
+ '@esbuild/linux-loong64': 0.25.12
+ '@esbuild/linux-mips64el': 0.25.12
+ '@esbuild/linux-ppc64': 0.25.12
+ '@esbuild/linux-riscv64': 0.25.12
+ '@esbuild/linux-s390x': 0.25.12
+ '@esbuild/linux-x64': 0.25.12
+ '@esbuild/netbsd-arm64': 0.25.12
+ '@esbuild/netbsd-x64': 0.25.12
+ '@esbuild/openbsd-arm64': 0.25.12
+ '@esbuild/openbsd-x64': 0.25.12
+ '@esbuild/openharmony-arm64': 0.25.12
+ '@esbuild/sunos-x64': 0.25.12
+ '@esbuild/win32-arm64': 0.25.12
+ '@esbuild/win32-ia32': 0.25.12
+ '@esbuild/win32-x64': 0.25.12
+
+ esbuild@0.27.2:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.2
+ '@esbuild/android-arm': 0.27.2
+ '@esbuild/android-arm64': 0.27.2
+ '@esbuild/android-x64': 0.27.2
+ '@esbuild/darwin-arm64': 0.27.2
+ '@esbuild/darwin-x64': 0.27.2
+ '@esbuild/freebsd-arm64': 0.27.2
+ '@esbuild/freebsd-x64': 0.27.2
+ '@esbuild/linux-arm': 0.27.2
+ '@esbuild/linux-arm64': 0.27.2
+ '@esbuild/linux-ia32': 0.27.2
+ '@esbuild/linux-loong64': 0.27.2
+ '@esbuild/linux-mips64el': 0.27.2
+ '@esbuild/linux-ppc64': 0.27.2
+ '@esbuild/linux-riscv64': 0.27.2
+ '@esbuild/linux-s390x': 0.27.2
+ '@esbuild/linux-x64': 0.27.2
+ '@esbuild/netbsd-arm64': 0.27.2
+ '@esbuild/netbsd-x64': 0.27.2
+ '@esbuild/openbsd-arm64': 0.27.2
+ '@esbuild/openbsd-x64': 0.27.2
+ '@esbuild/openharmony-arm64': 0.27.2
+ '@esbuild/sunos-x64': 0.27.2
+ '@esbuild/win32-arm64': 0.27.2
+ '@esbuild/win32-ia32': 0.27.2
+ '@esbuild/win32-x64': 0.27.2
escalade@3.2.0: {}
@@ -4139,31 +4539,31 @@ snapshots:
optionalDependencies:
source-map: 0.6.1
- eslint-config-prettier@10.1.8(eslint@9.39.1):
+ eslint-config-prettier@10.1.8(eslint@9.39.2):
dependencies:
- eslint: 9.39.1
+ eslint: 9.39.2
- eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2):
+ eslint-plugin-prettier@5.5.5(eslint-config-prettier@10.1.8(eslint@9.39.2))(eslint@9.39.2)(prettier@3.8.0):
dependencies:
- eslint: 9.39.1
- prettier: 3.6.2
- prettier-linter-helpers: 1.0.0
- synckit: 0.11.11
+ eslint: 9.39.2
+ prettier: 3.8.0
+ prettier-linter-helpers: 1.0.1
+ synckit: 0.11.12
optionalDependencies:
- eslint-config-prettier: 10.1.8(eslint@9.39.1)
+ eslint-config-prettier: 10.1.8(eslint@9.39.2)
- eslint-plugin-vue@10.5.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)):
+ eslint-plugin-vue@10.7.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(vue-eslint-parser@10.2.0(eslint@9.39.2)):
dependencies:
- '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
- eslint: 9.39.1
+ '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2)
+ eslint: 9.39.2
natural-compare: 1.4.0
nth-check: 2.1.1
- postcss-selector-parser: 6.1.2
+ postcss-selector-parser: 7.1.1
semver: 7.7.3
- vue-eslint-parser: 10.2.0(eslint@9.39.1)
+ vue-eslint-parser: 10.2.0(eslint@9.39.2)
xml-name-validator: 4.0.0
optionalDependencies:
- '@typescript-eslint/parser': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
+ '@typescript-eslint/parser': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
eslint-scope@8.4.0:
dependencies:
@@ -4174,15 +4574,15 @@ snapshots:
eslint-visitor-keys@4.2.1: {}
- eslint@9.39.1:
+ eslint@9.39.2:
dependencies:
- '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
+ '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2)
'@eslint-community/regexpp': 4.12.2
'@eslint/config-array': 0.21.1
'@eslint/config-helpers': 0.4.2
'@eslint/core': 0.17.0
- '@eslint/eslintrc': 3.3.1
- '@eslint/js': 9.39.1
+ '@eslint/eslintrc': 3.3.3
+ '@eslint/js': 9.39.2
'@eslint/plugin-kit': 0.4.1
'@humanfs/node': 0.16.7
'@humanwhocodes/module-importer': 1.0.1
@@ -4273,9 +4673,9 @@ snapshots:
fast-levenshtein@2.0.6: {}
- fastq@1.18.0:
+ fastq@1.19.1:
dependencies:
- reusify: 1.0.4
+ reusify: 1.1.0
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
@@ -4305,7 +4705,7 @@ snapshots:
focus-trap@7.6.2:
dependencies:
- tabbable: 6.3.0
+ tabbable: 6.4.0
fraction.js@5.3.4: {}
@@ -4384,7 +4784,7 @@ snapshots:
js-tokens@4.0.0: {}
- js-yaml@4.1.0:
+ js-yaml@4.1.1:
dependencies:
argparse: 2.0.1
@@ -4398,7 +4798,7 @@ snapshots:
json5@2.2.3: {}
- jsonc-eslint-parser@2.4.0:
+ jsonc-eslint-parser@2.4.2:
dependencies:
acorn: 8.15.0
eslint-visitor-keys: 3.4.3
@@ -4439,7 +4839,7 @@ snapshots:
dependencies:
p-locate: 5.0.0
- lodash-es@4.17.21: {}
+ lodash-es@4.17.22: {}
lodash._baseiteratee@4.7.0:
dependencies:
@@ -4487,7 +4887,7 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
- marked@17.0.0: {}
+ marked@17.0.1: {}
marks-pane@1.0.9: {}
@@ -4540,8 +4940,6 @@ snapshots:
node-releases@2.0.27: {}
- normalize-range@0.1.2: {}
-
normalize.css@8.0.1: {}
nth-check@2.1.1:
@@ -4591,10 +4989,10 @@ snapshots:
picomatch@4.0.3: {}
- pinia@3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)):
+ pinia@3.0.4(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3)):
dependencies:
'@vue/devtools-api': 7.7.8
- vue: 3.5.24(typescript@5.9.3)
+ vue: 3.5.26(typescript@5.9.3)
optionalDependencies:
typescript: 5.9.3
@@ -4602,7 +5000,7 @@ snapshots:
dependencies:
'@babel/runtime': 7.28.4
- postcss-selector-parser@6.1.2:
+ postcss-selector-parser@7.1.1:
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
@@ -4617,11 +5015,11 @@ snapshots:
prelude-ls@1.2.1: {}
- prettier-linter-helpers@1.0.0:
+ prettier-linter-helpers@1.0.1:
dependencies:
fast-diff: 1.3.0
- prettier@3.6.2: {}
+ prettier@3.8.0: {}
pretty-bytes@7.1.0: {}
@@ -4637,9 +5035,9 @@ snapshots:
punycode@2.3.1: {}
- qrcode.vue@3.6.0(vue@3.5.24(typescript@5.9.3)):
+ qrcode.vue@3.6.0(vue@3.5.26(typescript@5.9.3)):
dependencies:
- vue: 3.5.24(typescript@5.9.3)
+ vue: 3.5.26(typescript@5.9.3)
querystringify@2.2.0: {}
@@ -4690,36 +5088,39 @@ snapshots:
retry@0.12.0: {}
- reusify@1.0.4: {}
+ reusify@1.1.0: {}
rfdc@1.4.1: {}
- rollup@4.52.5:
+ rollup@4.55.1:
dependencies:
'@types/estree': 1.0.8
optionalDependencies:
- '@rollup/rollup-android-arm-eabi': 4.52.5
- '@rollup/rollup-android-arm64': 4.52.5
- '@rollup/rollup-darwin-arm64': 4.52.5
- '@rollup/rollup-darwin-x64': 4.52.5
- '@rollup/rollup-freebsd-arm64': 4.52.5
- '@rollup/rollup-freebsd-x64': 4.52.5
- '@rollup/rollup-linux-arm-gnueabihf': 4.52.5
- '@rollup/rollup-linux-arm-musleabihf': 4.52.5
- '@rollup/rollup-linux-arm64-gnu': 4.52.5
- '@rollup/rollup-linux-arm64-musl': 4.52.5
- '@rollup/rollup-linux-loong64-gnu': 4.52.5
- '@rollup/rollup-linux-ppc64-gnu': 4.52.5
- '@rollup/rollup-linux-riscv64-gnu': 4.52.5
- '@rollup/rollup-linux-riscv64-musl': 4.52.5
- '@rollup/rollup-linux-s390x-gnu': 4.52.5
- '@rollup/rollup-linux-x64-gnu': 4.52.5
- '@rollup/rollup-linux-x64-musl': 4.52.5
- '@rollup/rollup-openharmony-arm64': 4.52.5
- '@rollup/rollup-win32-arm64-msvc': 4.52.5
- '@rollup/rollup-win32-ia32-msvc': 4.52.5
- '@rollup/rollup-win32-x64-gnu': 4.52.5
- '@rollup/rollup-win32-x64-msvc': 4.52.5
+ '@rollup/rollup-android-arm-eabi': 4.55.1
+ '@rollup/rollup-android-arm64': 4.55.1
+ '@rollup/rollup-darwin-arm64': 4.55.1
+ '@rollup/rollup-darwin-x64': 4.55.1
+ '@rollup/rollup-freebsd-arm64': 4.55.1
+ '@rollup/rollup-freebsd-x64': 4.55.1
+ '@rollup/rollup-linux-arm-gnueabihf': 4.55.1
+ '@rollup/rollup-linux-arm-musleabihf': 4.55.1
+ '@rollup/rollup-linux-arm64-gnu': 4.55.1
+ '@rollup/rollup-linux-arm64-musl': 4.55.1
+ '@rollup/rollup-linux-loong64-gnu': 4.55.1
+ '@rollup/rollup-linux-loong64-musl': 4.55.1
+ '@rollup/rollup-linux-ppc64-gnu': 4.55.1
+ '@rollup/rollup-linux-ppc64-musl': 4.55.1
+ '@rollup/rollup-linux-riscv64-gnu': 4.55.1
+ '@rollup/rollup-linux-riscv64-musl': 4.55.1
+ '@rollup/rollup-linux-s390x-gnu': 4.55.1
+ '@rollup/rollup-linux-x64-gnu': 4.55.1
+ '@rollup/rollup-linux-x64-musl': 4.55.1
+ '@rollup/rollup-openbsd-x64': 4.55.1
+ '@rollup/rollup-openharmony-arm64': 4.55.1
+ '@rollup/rollup-win32-arm64-msvc': 4.55.1
+ '@rollup/rollup-win32-ia32-msvc': 4.55.1
+ '@rollup/rollup-win32-x64-gnu': 4.55.1
+ '@rollup/rollup-win32-x64-msvc': 4.55.1
fsevents: 2.3.3
run-parallel@1.2.0:
@@ -4769,17 +5170,17 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
- synckit@0.11.11:
+ synckit@0.11.12:
dependencies:
'@pkgr/core': 0.2.9
systemjs@6.15.1: {}
- tabbable@6.3.0: {}
+ tabbable@6.4.0: {}
tar-mini@0.2.0: {}
- terser@5.44.1:
+ terser@5.46.0:
dependencies:
'@jridgewell/source-map': 0.3.11
acorn: 8.15.0
@@ -4795,7 +5196,7 @@ snapshots:
dependencies:
is-number: 7.0.0
- ts-api-utils@2.1.0(typescript@5.9.3):
+ ts-api-utils@2.4.0(typescript@5.9.3):
dependencies:
typescript: 5.9.3
@@ -4815,13 +5216,13 @@ snapshots:
type@2.7.3: {}
- typescript-eslint@8.37.0(eslint@9.39.1)(typescript@5.9.3):
+ typescript-eslint@8.37.0(eslint@9.39.2)(typescript@5.9.3):
dependencies:
- '@typescript-eslint/eslint-plugin': 8.37.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)
- '@typescript-eslint/parser': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
+ '@typescript-eslint/eslint-plugin': 8.37.0(@typescript-eslint/parser@8.37.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)
+ '@typescript-eslint/parser': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
'@typescript-eslint/typescript-estree': 8.37.0(typescript@5.9.3)
- '@typescript-eslint/utils': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
- eslint: 9.39.1
+ '@typescript-eslint/utils': 8.37.0(eslint@9.39.2)(typescript@5.9.3)
+ eslint: 9.39.2
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
@@ -4841,7 +5242,7 @@ snapshots:
unicode-property-aliases-ecmascript@2.2.0: {}
- unplugin@2.3.10:
+ unplugin@2.3.11:
dependencies:
'@jridgewell/remapping': 2.3.5
acorn: 8.15.0
@@ -4854,6 +5255,12 @@ snapshots:
escalade: 3.2.0
picocolors: 1.1.1
+ update-browserslist-db@1.2.2(browserslist@4.28.1):
+ dependencies:
+ browserslist: 4.28.1
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
uri-js@4.4.1:
dependencies:
punycode: 2.3.1
@@ -4893,7 +5300,7 @@ snapshots:
videojs-hotkeys@0.2.30: {}
- videojs-mobile-ui@1.1.1(video.js@8.23.4):
+ videojs-mobile-ui@1.1.3(video.js@8.23.4):
dependencies:
global: 4.4.0
video.js: 8.23.4
@@ -4902,33 +5309,33 @@ snapshots:
dependencies:
global: 4.4.0
- vite-plugin-compression2@2.3.1(rollup@4.52.5):
+ vite-plugin-compression2@2.4.0(rollup@4.55.1):
dependencies:
- '@rollup/pluginutils': 5.3.0(rollup@4.52.5)
+ '@rollup/pluginutils': 5.3.0(rollup@4.55.1)
tar-mini: 0.2.0
transitivePeerDependencies:
- rollup
- vite@7.2.2(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0):
+ vite@7.3.1(@types/node@24.10.9)(terser@5.46.0)(yaml@2.8.2):
dependencies:
- esbuild: 0.25.11
+ esbuild: 0.27.2
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
postcss: 8.5.6
- rollup: 4.52.5
+ rollup: 4.55.1
tinyglobby: 0.2.15
optionalDependencies:
- '@types/node': 24.10.1
+ '@types/node': 24.10.9
fsevents: 2.3.3
- terser: 5.44.1
- yaml: 2.7.0
+ terser: 5.46.0
+ yaml: 2.8.2
vscode-uri@3.1.0: {}
- vue-eslint-parser@10.2.0(eslint@9.39.1):
+ vue-eslint-parser@10.2.0(eslint@9.39.2):
dependencies:
debug: 4.4.3
- eslint: 9.39.1
+ eslint: 9.39.2
eslint-scope: 8.4.0
eslint-visitor-keys: 4.2.1
espree: 10.4.0
@@ -4937,48 +5344,48 @@ snapshots:
transitivePeerDependencies:
- supports-color
- vue-final-modal@4.5.5(@vueuse/core@14.0.0(vue@3.5.24(typescript@5.9.3)))(@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.24(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.24(typescript@5.9.3)):
+ vue-final-modal@4.5.5(@vueuse/core@14.1.0(vue@3.5.26(typescript@5.9.3)))(@vueuse/integrations@14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.26(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.26(typescript@5.9.3)):
dependencies:
- '@vueuse/core': 14.0.0(vue@3.5.24(typescript@5.9.3))
- '@vueuse/integrations': 14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.24(typescript@5.9.3))
+ '@vueuse/core': 14.1.0(vue@3.5.26(typescript@5.9.3))
+ '@vueuse/integrations': 14.1.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.26(typescript@5.9.3))
focus-trap: 7.6.2
- vue: 3.5.24(typescript@5.9.3)
+ vue: 3.5.26(typescript@5.9.3)
- vue-i18n@11.1.12(vue@3.5.24(typescript@5.9.3)):
+ vue-i18n@11.2.8(vue@3.5.26(typescript@5.9.3)):
dependencies:
- '@intlify/core-base': 11.1.12
- '@intlify/shared': 11.1.12
+ '@intlify/core-base': 11.2.8
+ '@intlify/shared': 11.2.8
'@vue/devtools-api': 6.6.4
- vue: 3.5.24(typescript@5.9.3)
+ vue: 3.5.26(typescript@5.9.3)
vue-lazyload@3.0.0: {}
- vue-reader@1.3.3:
+ vue-reader@1.3.4:
dependencies:
epubjs: 0.3.93
- vue-router@4.6.3(vue@3.5.24(typescript@5.9.3)):
+ vue-router@4.6.4(vue@3.5.26(typescript@5.9.3)):
dependencies:
'@vue/devtools-api': 6.6.4
- vue: 3.5.24(typescript@5.9.3)
+ vue: 3.5.26(typescript@5.9.3)
- vue-toastification@2.0.0-rc.5(vue@3.5.24(typescript@5.9.3)):
+ vue-toastification@2.0.0-rc.5(vue@3.5.26(typescript@5.9.3)):
dependencies:
- vue: 3.5.24(typescript@5.9.3)
+ vue: 3.5.26(typescript@5.9.3)
- vue-tsc@3.1.3(typescript@5.9.3):
+ vue-tsc@3.2.2(typescript@5.9.3):
dependencies:
- '@volar/typescript': 2.4.23
- '@vue/language-core': 3.1.3(typescript@5.9.3)
+ '@volar/typescript': 2.4.27
+ '@vue/language-core': 3.2.2
typescript: 5.9.3
- vue@3.5.24(typescript@5.9.3):
+ vue@3.5.26(typescript@5.9.3):
dependencies:
- '@vue/compiler-dom': 3.5.24
- '@vue/compiler-sfc': 3.5.24
- '@vue/runtime-dom': 3.5.24
- '@vue/server-renderer': 3.5.24(vue@3.5.24(typescript@5.9.3))
- '@vue/shared': 3.5.24
+ '@vue/compiler-dom': 3.5.26
+ '@vue/compiler-sfc': 3.5.26
+ '@vue/runtime-dom': 3.5.26
+ '@vue/server-renderer': 3.5.26(vue@3.5.26(typescript@5.9.3))
+ '@vue/shared': 3.5.26
optionalDependencies:
typescript: 5.9.3
@@ -4994,12 +5401,11 @@ snapshots:
yallist@3.1.1: {}
- yaml-eslint-parser@1.2.3:
+ yaml-eslint-parser@1.3.2:
dependencies:
eslint-visitor-keys: 3.4.3
- lodash: 4.17.21
- yaml: 2.7.0
+ yaml: 2.8.2
- yaml@2.7.0: {}
+ yaml@2.8.2: {}
yocto-queue@0.1.0: {}
diff --git a/frontend/src/api/pub.ts b/frontend/src/api/pub.ts
index 964cb030..5070cae3 100644
--- a/frontend/src/api/pub.ts
+++ b/frontend/src/api/pub.ts
@@ -41,12 +41,12 @@ export function download(
let url = `${baseURL}/api/public/dl/${hash}`;
if (files.length === 1) {
- url += encodeURIComponent(files[0]) + "?";
+ url += files[0] + "?";
} else {
let arg = "";
for (const file of files) {
- arg += encodeURIComponent(file) + ",";
+ arg += file + ",";
}
arg = arg.substring(0, arg.length - 1);
diff --git a/frontend/src/api/search.ts b/frontend/src/api/search.ts
index 6fa02d06..63cbdaa1 100644
--- a/frontend/src/api/search.ts
+++ b/frontend/src/api/search.ts
@@ -1,7 +1,12 @@
-import { fetchURL, removePrefix } from "./utils";
+import { fetchURL, removePrefix, StatusError } from "./utils";
import url from "../utils/url";
-export default async function search(base: string, query: string) {
+export default async function search(
+ base: string,
+ query: string,
+ signal: AbortSignal,
+ callback: (item: ResourceItem) => void
+) {
base = removePrefix(base);
query = encodeURIComponent(query);
@@ -9,19 +14,60 @@ export default async function search(base: string, query: string) {
base += "/";
}
- const res = await fetchURL(`/api/search${base}?query=${query}`, {});
+ const res = await fetchURL(`/api/search${base}?query=${query}`, { signal });
+ if (!res.body) {
+ throw new StatusError("000 No connection", 0);
+ }
+ try {
+ // Try streaming approach first (modern browsers)
+ if (res.body && typeof res.body.pipeThrough === "function") {
+ const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
+ let buffer = "";
+ while (true) {
+ const { done, value } = await reader.read();
+ if (value) {
+ buffer += value;
+ }
+ const lines = buffer.split(/\n/);
+ let lastLine = lines.pop();
+ // Save incomplete last line
+ if (!lastLine) {
+ lastLine = "";
+ }
+ buffer = lastLine;
- let data = await res.json();
-
- data = data.map((item: ResourceItem & { dir: boolean }) => {
- item.url = `/files${base}` + url.encodePath(item.path);
-
- if (item.dir) {
- item.url += "/";
+ for (const line of lines) {
+ if (line) {
+ const item = JSON.parse(line) as ResourceItem;
+ item.url = `/files${base}` + url.encodePath(item.path);
+ if (item.isDir) {
+ item.url += "/";
+ }
+ callback(item);
+ }
+ }
+ if (done) break;
+ }
+ } else {
+ // Fallback for browsers without streaming support (e.g., Safari)
+ const text = await res.text();
+ const lines = text.split(/\n/);
+ for (const line of lines) {
+ if (line) {
+ const item = JSON.parse(line) as ResourceItem;
+ item.url = `/files${base}` + url.encodePath(item.path);
+ if (item.isDir) {
+ item.url += "/";
+ }
+ callback(item);
+ }
+ }
}
-
- return item;
- });
-
- return data;
+ } catch (e) {
+ // Check if the error is an intentional cancellation
+ if (e instanceof Error && e.name === "AbortError") {
+ throw new StatusError("000 No connection", 0, true);
+ }
+ throw e;
+ }
}
diff --git a/frontend/src/api/users.ts b/frontend/src/api/users.ts
index 78096b49..dc45e084 100644
--- a/frontend/src/api/users.ts
+++ b/frontend/src/api/users.ts
@@ -8,12 +8,13 @@ export async function get(id: number) {
return fetchJSON
- autorenew
- {{ displayError }} {{ $t("files.lonely") }}
+
+
+
+
+
+
+
+
+ {{ header || `Column ${index + 1}` }}
+
+
+
+
+
+ {{ cell }}
+
+
+ + {{ t("settings.redirectAfterCopyMove") }} +
{{ t("settings.setDateFormat") }} @@ -44,7 +52,7 @@ -
+ + +