diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index ae0368861abfe..0b0cfbafd918f 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,11 +1,14 @@
blank_issues_enabled: false
contact_links:
- - name: I have a question or need support
+ - name: ✋ I have a question or need support
url: https://discord.immich.app
about: We use GitHub for tracking bugs, please check out our Discord channel for freaky fast support.
- - name: Feature Request
+ - name: 📷 My photo or video has a date, time, or timezone problem
+ url: https://github.com/immich-app/immich/discussions/12650
+ about: Upload a sample file to this discussion and we will take a look
+ - name: 🌟 Feature request
url: https://github.com/immich-app/immich/discussions/new?category=feature-request
about: Please use our GitHub Discussion for making feature requests.
- - name: I'm unsure where to go
+ - name: 🫣 I'm unsure where to go
url: https://discord.immich.app
about: If you are unsure where to go, then joining our Discord is recommended; Just ask!
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 2c7d1708395e2..0000000000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-version: 2
-updates:
- # Maintain dependencies for GitHub Actions
- - package-ecosystem: "github-actions"
- directory: "/"
- schedule:
- interval: "daily"
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 2a9abc7840381..c0c52f1d7e4b9 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -35,6 +35,4 @@ documentation:
- machine-learning/app/**
changelog:translation:
- - changed-files:
- - any-glob-to-any-file:
- - web/src/lib/i18n/*.json
+ - head-branch: ['^chore/translations$']
diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml
index 5292075cce902..94d33b600663b 100644
--- a/.github/workflows/cli.yml
+++ b/.github/workflows/cli.yml
@@ -59,7 +59,7 @@ jobs:
uses: docker/setup-qemu-action@v3.2.0
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3.6.1
+ uses: docker/setup-buildx-action@v3.7.0
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
@@ -88,7 +88,7 @@ jobs:
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
- name: Build and push image
- uses: docker/build-push-action@v6.7.0
+ uses: docker/build-push-action@v6.9.0
with:
file: cli/Dockerfile
platforms: linux/amd64,linux/arm64
diff --git a/.github/workflows/docker-cleanup.yml b/.github/workflows/docker-cleanup.yml
index bd0ec91d14d86..6f2c573a9f435 100644
--- a/.github/workflows/docker-cleanup.yml
+++ b/.github/workflows/docker-cleanup.yml
@@ -22,7 +22,7 @@ concurrency:
jobs:
cleanup-images:
name: Cleanup Stale Images Tags for ${{ matrix.primary-name }}
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
@@ -48,7 +48,7 @@ jobs:
cleanup-untagged-images:
name: Cleanup Untagged Images Tags for ${{ matrix.primary-name }}
- runs-on: ubuntu-22.04
+ runs-on: ubuntu-24.04
needs:
- cleanup-images
strategy:
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 8a2ba9f841434..b9e7138f9514f 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -43,7 +43,7 @@ jobs:
retag_ml:
name: Re-Tag ML
needs: pre-job
- if: ${{ needs.pre-job.outputs.should_run_ml == 'false' }}
+ if: ${{ needs.pre-job.outputs.should_run_ml == 'false' && !github.event.pull_request.head.repo.fork }}
runs-on: ubuntu-latest
strategy:
matrix:
@@ -51,8 +51,6 @@ jobs:
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
- # Skip when PR from a fork
- if: ${{ !github.event.pull_request.head.repo.fork }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -68,7 +66,7 @@ jobs:
retag_server:
name: Re-Tag Server
needs: pre-job
- if: ${{ needs.pre-job.outputs.should_run_server == 'false' }}
+ if: ${{ needs.pre-job.outputs.should_run_server == 'false' && !github.event.pull_request.head.repo.fork }}
runs-on: ubuntu-latest
strategy:
matrix:
@@ -76,8 +74,6 @@ jobs:
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
- # Skip when PR from a fork
- if: ${{ !github.event.pull_request.head.repo.fork }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@@ -128,7 +124,7 @@ jobs:
uses: docker/setup-qemu-action@v3.2.0
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3.6.1
+ uses: docker/setup-buildx-action@v3.7.0
- name: Login to Docker Hub
# Only push to Docker Hub when making a release
@@ -177,7 +173,7 @@ jobs:
fi
- name: Build and push image
- uses: docker/build-push-action@v6.7.0
+ uses: docker/build-push-action@v6.9.0
with:
context: ${{ env.context }}
file: ${{ env.file }}
@@ -219,7 +215,7 @@ jobs:
uses: docker/setup-qemu-action@v3.2.0
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3.6.1
+ uses: docker/setup-buildx-action@v3.7.0
- name: Login to Docker Hub
# Only push to Docker Hub when making a release
@@ -268,7 +264,7 @@ jobs:
fi
- name: Build and push image
- uses: docker/build-push-action@v6.7.0
+ uses: docker/build-push-action@v6.9.0
with:
context: ${{ env.context }}
file: ${{ env.file }}
diff --git a/.github/workflows/pr-label-validation.yml b/.github/workflows/pr-label-validation.yml
index 1557b3d15cfba..754d4096132b6 100644
--- a/.github/workflows/pr-label-validation.yml
+++ b/.github/workflows/pr-label-validation.yml
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
issues: write
- pull-requests: read
+ pull-requests: write
steps:
- name: Require PR to have a changelog label
uses: mheap/github-action-required-labels@v5
diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml
index 94567c1cd567e..196f8faf599ba 100644
--- a/.github/workflows/static_analysis.yml
+++ b/.github/workflows/static_analysis.yml
@@ -56,6 +56,10 @@ jobs:
run: dart format lib/ --set-exit-if-changed
working-directory: ./mobile
+ - name: Run dart custom_lint
+ run: dart run custom_lint
+ working-directory: ./mobile
+
# Enable after riverpod generator migration is completed
# - name: Run dart custom lint
# run: dart run custom_lint
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 24e3e086235f0..064e3c27616f7 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -80,7 +80,7 @@ jobs:
run: npm run check
if: ${{ !cancelled() }}
- - name: Run unit tests & coverage
+ - name: Run small tests & coverage
run: npm run test:cov
if: ${{ !cancelled() }}
@@ -243,6 +243,26 @@ jobs:
run: npm run check
if: ${{ !cancelled() }}
+ medium-tests-server:
+ name: Medium Tests (Server)
+ needs: pre-job
+ if: ${{ needs.pre-job.outputs.should_run_server == 'true' }}
+ runs-on: mich
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ submodules: 'recursive'
+
+ - name: Production build
+ if: ${{ !cancelled() }}
+ run: docker compose -f e2e/docker-compose.yml build
+
+ - name: Run medium tests
+ if: ${{ !cancelled() }}
+ run: make test-medium
+
e2e-tests-server-cli:
name: End-to-End Tests (Server & CLI)
needs: pre-job
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 7a88b7f3e12d4..ed3da9f667d01 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -5,8 +5,8 @@
"type": "node",
"request": "attach",
"restart": true,
- "port": 9230,
- "name": "Immich Server",
+ "port": 9231,
+ "name": "Immich API Server",
"remoteRoot": "/usr/src/app",
"localRoot": "${workspaceFolder}/server"
},
@@ -14,8 +14,8 @@
"type": "node",
"request": "attach",
"restart": true,
- "port": 9231,
- "name": "Immich Microservices",
+ "port": 9230,
+ "name": "Immich Workers",
"remoteRoot": "/usr/src/app",
"localRoot": "${workspaceFolder}/server"
}
diff --git a/Makefile b/Makefile
index 349a5c5e920ef..2096cf86df09c 100644
--- a/Makefile
+++ b/Makefile
@@ -66,6 +66,18 @@ test-e2e:
docker compose -f ./e2e/docker-compose.yml build
npm --prefix e2e run test
npm --prefix e2e run test:web
+test-medium:
+ docker run \
+ --rm \
+ -v ./server/src:/usr/src/app/src \
+ -v ./server/test:/usr/src/app/test \
+ -v ./server/vitest.config.medium.mjs:/usr/src/app/vitest.config.medium.mjs \
+ -v ./server/tsconfig.json:/usr/src/app/tsconfig.json \
+ -e NODE_ENV=development \
+ immich-server:latest \
+ -c "npm ci && npm run test:medium -- --run"
+test-medium-dev:
+ docker exec -it immich_server /bin/sh -c "npm run test:medium"
build-all: $(foreach M,$(MODULES),build-$M) ;
install-all: $(foreach M,$(MODULES),install-$M) ;
diff --git a/README.md b/README.md
index 44c38e6d14813..5c4b9c39edd1d 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@
Português BrasileiroSvenskaالعربية
+Tiếng Việt
diff --git a/cli/.nvmrc b/cli/.nvmrc
index 3516580bbbc04..2a393af592b8c 100644
--- a/cli/.nvmrc
+++ b/cli/.nvmrc
@@ -1 +1 @@
-20.17.0
+20.18.0
diff --git a/cli/Dockerfile b/cli/Dockerfile
index e3cce6d448249..b08aba9d3c2b5 100644
--- a/cli/Dockerfile
+++ b/cli/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:20.17.0-alpine3.20@sha256:1a526b97cace6b4006256570efa1a29cd1fe4b96a5301f8d48e87c5139438a45 AS core
+FROM node:20.17.0-alpine3.20@sha256:2d07db07a2df6830718ae2a47db6fedce6745f5bcd174c398f2acdda90a11c03 AS core
WORKDIR /usr/src/open-api/typescript-sdk
COPY open-api/typescript-sdk/package*.json open-api/typescript-sdk/tsconfig*.json ./
diff --git a/cli/package-lock.json b/cli/package-lock.json
index f443c141b9e06..17a99b01f16b1 100644
--- a/cli/package-lock.json
+++ b/cli/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@immich/cli",
- "version": "2.2.18",
+ "version": "2.2.23",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@immich/cli",
- "version": "2.2.18",
+ "version": "2.2.23",
"license": "GNU Affero General Public License version 3",
"dependencies": {
"fast-glob": "^3.3.2",
@@ -24,7 +24,7 @@
"@types/cli-progress": "^3.11.0",
"@types/lodash-es": "^4.17.12",
"@types/mock-fs": "^4.13.1",
- "@types/node": "^20.16.2",
+ "@types/node": "^20.16.10",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@vitest/coverage-v8": "^2.0.5",
@@ -52,14 +52,14 @@
},
"../open-api/typescript-sdk": {
"name": "@immich/sdk",
- "version": "1.114.0",
+ "version": "1.117.0",
"dev": true,
"license": "GNU Affero General Public License version 3",
"dependencies": {
"@oazapfts/runtime": "^1.0.2"
},
"devDependencies": {
- "@types/node": "^20.16.2",
+ "@types/node": "^20.16.10",
"typescript": "^5.3.3"
}
},
@@ -765,6 +765,16 @@
"node": "*"
}
},
+ "node_modules/@eslint/core": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz",
+ "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
"node_modules/@eslint/eslintrc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
@@ -825,9 +835,9 @@
}
},
"node_modules/@eslint/js": {
- "version": "9.9.1",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.1.tgz",
- "integrity": "sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==",
+ "version": "9.11.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz",
+ "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -844,6 +854,19 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz",
+ "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
"node_modules/@humanwhocodes/module-importer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
@@ -1299,6 +1322,13 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/lodash": {
"version": "4.17.0",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz",
@@ -1324,9 +1354,9 @@
}
},
"node_modules/@types/node": {
- "version": "20.16.3",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.3.tgz",
- "integrity": "sha512-/wdGiWRkMOm53gAsSyFMXFZHbVg7C6CbkrzHNpaHoYfsUWPg7m6ZRKtvQjgvQ9i8WT540a3ydRlRQbxjY30XxQ==",
+ "version": "20.16.11",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz",
+ "integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1340,17 +1370,17 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.3.0.tgz",
- "integrity": "sha512-FLAIn63G5KH+adZosDYiutqkOkYEx0nvcwNNfJAf+c7Ae/H35qWwTYvPZUKFj5AS+WfHG/WJJfWnDnyNUlp8UA==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.0.tgz",
+ "integrity": "sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.3.0",
- "@typescript-eslint/type-utils": "8.3.0",
- "@typescript-eslint/utils": "8.3.0",
- "@typescript-eslint/visitor-keys": "8.3.0",
+ "@typescript-eslint/scope-manager": "8.8.0",
+ "@typescript-eslint/type-utils": "8.8.0",
+ "@typescript-eslint/utils": "8.8.0",
+ "@typescript-eslint/visitor-keys": "8.8.0",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
@@ -1374,16 +1404,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.3.0.tgz",
- "integrity": "sha512-h53RhVyLu6AtpUzVCYLPhZGL5jzTD9fZL+SYf/+hYOx2bDkyQXztXSc4tbvKYHzfMXExMLiL9CWqJmVz6+78IQ==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.0.tgz",
+ "integrity": "sha512-uEFUsgR+tl8GmzmLjRqz+VrDv4eoaMqMXW7ruXfgThaAShO9JTciKpEsB+TvnfFfbg5IpujgMXVV36gOJRLtZg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.3.0",
- "@typescript-eslint/types": "8.3.0",
- "@typescript-eslint/typescript-estree": "8.3.0",
- "@typescript-eslint/visitor-keys": "8.3.0",
+ "@typescript-eslint/scope-manager": "8.8.0",
+ "@typescript-eslint/types": "8.8.0",
+ "@typescript-eslint/typescript-estree": "8.8.0",
+ "@typescript-eslint/visitor-keys": "8.8.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1403,14 +1433,14 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.3.0.tgz",
- "integrity": "sha512-mz2X8WcN2nVu5Hodku+IR8GgCOl4C0G/Z1ruaWN4dgec64kDBabuXyPAr+/RgJtumv8EEkqIzf3X2U5DUKB2eg==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.0.tgz",
+ "integrity": "sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.3.0",
- "@typescript-eslint/visitor-keys": "8.3.0"
+ "@typescript-eslint/types": "8.8.0",
+ "@typescript-eslint/visitor-keys": "8.8.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1421,14 +1451,14 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.3.0.tgz",
- "integrity": "sha512-wrV6qh//nLbfXZQoj32EXKmwHf4b7L+xXLrP3FZ0GOUU72gSvLjeWUl5J5Ue5IwRxIV1TfF73j/eaBapxx99Lg==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.0.tgz",
+ "integrity": "sha512-IKwJSS7bCqyCeG4NVGxnOP6lLT9Okc3Zj8hLO96bpMkJab+10HIfJbMouLrlpyOr3yrQ1cA413YPFiGd1mW9/Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "8.3.0",
- "@typescript-eslint/utils": "8.3.0",
+ "@typescript-eslint/typescript-estree": "8.8.0",
+ "@typescript-eslint/utils": "8.8.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
},
@@ -1446,9 +1476,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.3.0.tgz",
- "integrity": "sha512-y6sSEeK+facMaAyixM36dQ5NVXTnKWunfD1Ft4xraYqxP0lC0POJmIaL/mw72CUMqjY9qfyVfXafMeaUj0noWw==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.0.tgz",
+ "integrity": "sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1460,14 +1490,14 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.3.0.tgz",
- "integrity": "sha512-Mq7FTHl0R36EmWlCJWojIC1qn/ZWo2YiWYc1XVtasJ7FIgjo0MVv9rZWXEE7IK2CGrtwe1dVOxWwqXUdNgfRCA==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.0.tgz",
+ "integrity": "sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/types": "8.3.0",
- "@typescript-eslint/visitor-keys": "8.3.0",
+ "@typescript-eslint/types": "8.8.0",
+ "@typescript-eslint/visitor-keys": "8.8.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -1489,16 +1519,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.3.0.tgz",
- "integrity": "sha512-F77WwqxIi/qGkIGOGXNBLV7nykwfjLsdauRB/DOFPdv6LTF3BHHkBpq81/b5iMPSF055oO2BiivDJV4ChvNtXA==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.0.tgz",
+ "integrity": "sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "8.3.0",
- "@typescript-eslint/types": "8.3.0",
- "@typescript-eslint/typescript-estree": "8.3.0"
+ "@typescript-eslint/scope-manager": "8.8.0",
+ "@typescript-eslint/types": "8.8.0",
+ "@typescript-eslint/typescript-estree": "8.8.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1512,13 +1542,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.3.0.tgz",
- "integrity": "sha512-RmZwrTbQ9QveF15m/Cl28n0LXD6ea2CjkhH5rQ55ewz3H24w+AMCJHPVYaZ8/0HoG8Z3cLLFFycRXxeO2tz9FA==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.0.tgz",
+ "integrity": "sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.3.0",
+ "@typescript-eslint/types": "8.8.0",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
@@ -1530,19 +1560,20 @@
}
},
"node_modules/@vitest/coverage-v8": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.0.5.tgz",
- "integrity": "sha512-qeFcySCg5FLO2bHHSa0tAZAOnAUbp4L6/A5JDuj9+bt53JREl8hpLjLHEWF0e/gWc8INVpJaqA7+Ene2rclpZg==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.2.tgz",
+ "integrity": "sha512-b7kHrFrs2urS0cOk5N10lttI8UdJ/yP3nB4JYTREvR5o18cR99yPpK4gK8oQgI42BVv0ILWYUSYB7AXkAUDc0g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.3.0",
"@bcoe/v8-coverage": "^0.2.3",
- "debug": "^4.3.5",
+ "debug": "^4.3.6",
"istanbul-lib-coverage": "^3.2.2",
"istanbul-lib-report": "^3.0.1",
"istanbul-lib-source-maps": "^5.0.6",
"istanbul-reports": "^3.1.7",
- "magic-string": "^0.30.10",
+ "magic-string": "^0.30.11",
"magicast": "^0.3.4",
"std-env": "^3.7.0",
"test-exclude": "^7.0.1",
@@ -1552,17 +1583,24 @@
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
- "vitest": "2.0.5"
+ "@vitest/browser": "2.1.2",
+ "vitest": "2.1.2"
+ },
+ "peerDependenciesMeta": {
+ "@vitest/browser": {
+ "optional": true
+ }
}
},
"node_modules/@vitest/expect": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz",
- "integrity": "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.2.tgz",
+ "integrity": "sha512-FEgtlN8mIUSEAAnlvn7mP8vzaWhEaAEvhSXCqrsijM7K6QqjB11qoRZYEd4AKSCDz8p0/+yH5LzhZ47qt+EyPg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@vitest/spy": "2.0.5",
- "@vitest/utils": "2.0.5",
+ "@vitest/spy": "2.1.2",
+ "@vitest/utils": "2.1.2",
"chai": "^5.1.1",
"tinyrainbow": "^1.2.0"
},
@@ -1570,11 +1608,40 @@
"url": "https://opencollective.com/vitest"
}
},
+ "node_modules/@vitest/mocker": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.2.tgz",
+ "integrity": "sha512-ExElkCGMS13JAJy+812fw1aCv2QO/LBK6CyO4WOPAzLTmve50gydOlWhgdBJPx2ztbADUq3JVI0C5U+bShaeEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "^2.1.0-beta.1",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.11"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@vitest/spy": "2.1.2",
+ "msw": "^2.3.5",
+ "vite": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@vitest/pretty-format": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.5.tgz",
- "integrity": "sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.2.tgz",
+ "integrity": "sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"tinyrainbow": "^1.2.0"
},
@@ -1583,12 +1650,13 @@
}
},
"node_modules/@vitest/runner": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.5.tgz",
- "integrity": "sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.2.tgz",
+ "integrity": "sha512-UCsPtvluHO3u7jdoONGjOSil+uON5SSvU9buQh3lP7GgUXHp78guN1wRmZDX4wGK6J10f9NUtP6pO+SFquoMlw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@vitest/utils": "2.0.5",
+ "@vitest/utils": "2.1.2",
"pathe": "^1.1.2"
},
"funding": {
@@ -1596,13 +1664,14 @@
}
},
"node_modules/@vitest/snapshot": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.5.tgz",
- "integrity": "sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.2.tgz",
+ "integrity": "sha512-xtAeNsZ++aRIYIUsek7VHzry/9AcxeULlegBvsdLncLmNCR6tR8SRjn8BbDP4naxtccvzTqZ+L1ltZlRCfBZFA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "2.0.5",
- "magic-string": "^0.30.10",
+ "@vitest/pretty-format": "2.1.2",
+ "magic-string": "^0.30.11",
"pathe": "^1.1.2"
},
"funding": {
@@ -1610,10 +1679,11 @@
}
},
"node_modules/@vitest/spy": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz",
- "integrity": "sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.2.tgz",
+ "integrity": "sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"tinyspy": "^3.0.0"
},
@@ -1622,13 +1692,13 @@
}
},
"node_modules/@vitest/utils": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.5.tgz",
- "integrity": "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.2.tgz",
+ "integrity": "sha512-zMO2KdYy6mx56btx9JvAqAZ6EyS3g49krMPPrgOp1yxGZiA93HumGk+bZ5jIZtOg5/VBYl5eBmGRQHqq4FG6uQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@vitest/pretty-format": "2.0.5",
- "estree-walker": "^3.0.3",
+ "@vitest/pretty-format": "2.1.2",
"loupe": "^3.1.1",
"tinyrainbow": "^1.2.0"
},
@@ -1710,6 +1780,7 @@
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
"integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=12"
}
@@ -1800,6 +1871,7 @@
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
"integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -1838,6 +1910,7 @@
"resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz",
"integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"assertion-error": "^2.0.1",
"check-error": "^2.1.1",
@@ -1870,6 +1943,7 @@
"resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
"integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 16"
}
@@ -2014,6 +2088,7 @@
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
"integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -2112,20 +2187,24 @@
}
},
"node_modules/eslint": {
- "version": "9.9.1",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.1.tgz",
- "integrity": "sha512-dHvhrbfr4xFQ9/dq+jcVneZMyRYLjggWjk6RVsIiHsP8Rz6yZ8LvZ//iU4TrZF+SXWG+JkNF2OyiZRvzgRDqMg==",
+ "version": "9.11.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz",
+ "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.11.0",
"@eslint/config-array": "^0.18.0",
+ "@eslint/core": "^0.6.0",
"@eslint/eslintrc": "^3.1.0",
- "@eslint/js": "9.9.1",
+ "@eslint/js": "9.11.1",
+ "@eslint/plugin-kit": "^0.2.0",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.3.0",
"@nodelib/fs.walk": "^1.2.8",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -2145,7 +2224,6 @@
"is-glob": "^4.0.0",
"is-path-inside": "^3.0.3",
"json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
"lodash.merge": "^4.6.2",
"minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
@@ -2277,6 +2355,13 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/eslint/node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/eslint/node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -2289,9 +2374,9 @@
}
},
"node_modules/eslint/node_modules/eslint-visitor-keys": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz",
- "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz",
+ "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -2383,6 +2468,7 @@
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@types/estree": "^1.0.0"
}
@@ -2396,29 +2482,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/execa": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
- "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
- "dev": true,
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^8.0.1",
- "human-signals": "^5.0.0",
- "is-stream": "^3.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^5.1.0",
- "onetime": "^6.0.0",
- "signal-exit": "^4.1.0",
- "strip-final-newline": "^3.0.0"
- },
- "engines": {
- "node": ">=16.17"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -2577,27 +2640,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/get-func-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
- "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
- "dev": true,
- "engines": {
- "node": "*"
- }
- },
- "node_modules/get-stream": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
- "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
- "dev": true,
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/glob": {
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
@@ -2631,9 +2673,9 @@
}
},
"node_modules/globals": {
- "version": "15.9.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
- "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
+ "version": "15.10.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.10.0.tgz",
+ "integrity": "sha512-tqFIbz83w4Y5TCbtgjZjApohbuh7K9BxGYFm7ifwDR240tvdb7P9x+/9VvUKlmkPoiknoJtanI8UOrqxS3a7lQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -2688,15 +2730,6 @@
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
},
- "node_modules/human-signals": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
- "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
- "dev": true,
- "engines": {
- "node": ">=16.17.0"
- }
- },
"node_modules/ignore": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
@@ -2818,18 +2851,6 @@
"node": ">=8"
}
},
- "node_modules/is-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
- "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -3012,13 +3033,11 @@
"dev": true
},
"node_modules/loupe": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz",
- "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz",
+ "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==",
"dev": true,
- "dependencies": {
- "get-func-name": "^2.0.1"
- }
+ "license": "MIT"
},
"node_modules/lru-cache": {
"version": "10.4.3",
@@ -3061,12 +3080,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true
- },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -3087,18 +3100,6 @@
"node": ">=8.6"
}
},
- "node_modules/mimic-fn": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
- "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@@ -3134,10 +3135,11 @@
}
},
"node_modules/mock-fs": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.2.0.tgz",
- "integrity": "sha512-2dF2R6YMSZbpip1V1WHKGLNjr/k48uQClqMVb5H3MOvwc9qhYis3/IWbj02qIg/Y8MDXKFF4c5v0rxx2o6xTZw==",
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.3.0.tgz",
+ "integrity": "sha512-IMvz1X+RF7vf+ur7qUenXMR7/FSKSIqS3HqFHXcyNI7G0FbpFO8L5lfsUJhl+bhK1AiulVHWKUSxebWauPA+xQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=12.0.0"
}
@@ -3219,48 +3221,6 @@
"semver": "bin/semver"
}
},
- "node_modules/npm-run-path": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
- "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
- "dev": true,
- "dependencies": {
- "path-key": "^4.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm-run-path/node_modules/path-key": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
- "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/onetime": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
- "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
- "dev": true,
- "dependencies": {
- "mimic-fn": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/optionator": {
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
@@ -3397,21 +3357,23 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
"integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/pathval": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
"integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 14.16"
}
},
"node_modules/picocolors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
- "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
+ "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
"dev": true,
"license": "ISC"
},
@@ -3436,9 +3398,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.41",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
- "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
+ "version": "8.4.47",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
+ "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"dev": true,
"funding": [
{
@@ -3457,8 +3419,8 @@
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
- "picocolors": "^1.0.1",
- "source-map-js": "^1.2.0"
+ "picocolors": "^1.1.0",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
@@ -3502,21 +3464,17 @@
}
},
"node_modules/prettier-plugin-organize-imports": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.0.0.tgz",
- "integrity": "sha512-vnKSdgv9aOlqKeEFGhf9SCBsTyzDSyScy1k7E0R1Uo4L0cTcOV7c1XQaT7jfXIOc/p08WLBfN2QUQA9zDSZMxA==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.1.0.tgz",
+ "integrity": "sha512-5aWRdCgv645xaa58X8lOxzZoiHAldAPChljr/MT0crXVOWTZ+Svl4hIWlz+niYSlO6ikE5UXkN1JrRvIP2ut0A==",
"dev": true,
"license": "MIT",
"peerDependencies": {
- "@vue/language-plugin-pug": "^2.0.24",
"prettier": ">=2.0",
"typescript": ">=2.9",
- "vue-tsc": "^2.0.24"
+ "vue-tsc": "^2.1.0"
},
"peerDependenciesMeta": {
- "@vue/language-plugin-pug": {
- "optional": true
- },
"vue-tsc": {
"optional": true
}
@@ -3827,10 +3785,11 @@
}
},
"node_modules/source-map-js": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
- "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
@@ -3933,18 +3892,6 @@
"node": ">=8"
}
},
- "node_modules/strip-final-newline": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
- "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/strip-indent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
@@ -4031,10 +3978,18 @@
"dev": true
},
"node_modules/tinybench": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz",
- "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==",
- "dev": true
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz",
+ "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/tinypool": {
"version": "1.0.0",
@@ -4055,10 +4010,11 @@
}
},
"node_modules/tinyspy": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz",
- "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
+ "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=14.0.0"
}
@@ -4140,9 +4096,9 @@
}
},
"node_modules/typescript": {
- "version": "5.5.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
- "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
+ "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -4210,14 +4166,14 @@
}
},
"node_modules/vite": {
- "version": "5.4.2",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz",
- "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
+ "version": "5.4.8",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
+ "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.21.3",
- "postcss": "^8.4.41",
+ "postcss": "^8.4.43",
"rollup": "^4.20.0"
},
"bin": {
@@ -4270,15 +4226,15 @@
}
},
"node_modules/vite-node": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.5.tgz",
- "integrity": "sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.2.tgz",
+ "integrity": "sha512-HPcGNN5g/7I2OtPjLqgOtCRu/qhVvBxTUD3qzitmL0SrG1cWFzxzhMDWussxSbrRYWqnKf8P2jiNhPMSN+ymsQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"cac": "^6.7.14",
- "debug": "^4.3.5",
+ "debug": "^4.3.6",
"pathe": "^1.1.2",
- "tinyrainbow": "^1.2.0",
"vite": "^5.0.0"
},
"bin": {
@@ -4312,29 +4268,30 @@
}
},
"node_modules/vitest": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.5.tgz",
- "integrity": "sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.2.tgz",
+ "integrity": "sha512-veNjLizOMkRrJ6xxb+pvxN6/QAWg95mzcRjtmkepXdN87FNfxAss9RKe2far/G9cQpipfgP2taqg0KiWsquj8A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@ampproject/remapping": "^2.3.0",
- "@vitest/expect": "2.0.5",
- "@vitest/pretty-format": "^2.0.5",
- "@vitest/runner": "2.0.5",
- "@vitest/snapshot": "2.0.5",
- "@vitest/spy": "2.0.5",
- "@vitest/utils": "2.0.5",
+ "@vitest/expect": "2.1.2",
+ "@vitest/mocker": "2.1.2",
+ "@vitest/pretty-format": "^2.1.2",
+ "@vitest/runner": "2.1.2",
+ "@vitest/snapshot": "2.1.2",
+ "@vitest/spy": "2.1.2",
+ "@vitest/utils": "2.1.2",
"chai": "^5.1.1",
- "debug": "^4.3.5",
- "execa": "^8.0.1",
- "magic-string": "^0.30.10",
+ "debug": "^4.3.6",
+ "magic-string": "^0.30.11",
"pathe": "^1.1.2",
"std-env": "^3.7.0",
- "tinybench": "^2.8.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^0.3.0",
"tinypool": "^1.0.0",
"tinyrainbow": "^1.2.0",
"vite": "^5.0.0",
- "vite-node": "2.0.5",
+ "vite-node": "2.1.2",
"why-is-node-running": "^2.3.0"
},
"bin": {
@@ -4349,8 +4306,8 @@
"peerDependencies": {
"@edge-runtime/vm": "*",
"@types/node": "^18.0.0 || >=20.0.0",
- "@vitest/browser": "2.0.5",
- "@vitest/ui": "2.0.5",
+ "@vitest/browser": "2.1.2",
+ "@vitest/ui": "2.1.2",
"happy-dom": "*",
"jsdom": "*"
},
@@ -4535,9 +4492,9 @@
}
},
"node_modules/yaml": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
- "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==",
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz",
+ "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==",
"dev": true,
"license": "ISC",
"bin": {
diff --git a/cli/package.json b/cli/package.json
index 0d560c8456585..03d248feb8bf4 100644
--- a/cli/package.json
+++ b/cli/package.json
@@ -1,6 +1,6 @@
{
"name": "@immich/cli",
- "version": "2.2.18",
+ "version": "2.2.23",
"description": "Command Line Interface (CLI) for Immich",
"type": "module",
"exports": "./dist/index.js",
@@ -20,7 +20,7 @@
"@types/cli-progress": "^3.11.0",
"@types/lodash-es": "^4.17.12",
"@types/mock-fs": "^4.13.1",
- "@types/node": "^20.16.2",
+ "@types/node": "^20.16.10",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@vitest/coverage-v8": "^2.0.5",
@@ -67,6 +67,6 @@
"lodash-es": "^4.17.21"
},
"volta": {
- "node": "20.17.0"
+ "node": "20.18.0"
}
}
diff --git a/deployment/modules/cloudflare/docs-release/.terraform.lock.hcl b/deployment/modules/cloudflare/docs-release/.terraform.lock.hcl
index 096177bb05366..6419c16dad324 100644
--- a/deployment/modules/cloudflare/docs-release/.terraform.lock.hcl
+++ b/deployment/modules/cloudflare/docs-release/.terraform.lock.hcl
@@ -2,37 +2,37 @@
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/cloudflare/cloudflare" {
- version = "4.40.0"
- constraints = "4.40.0"
+ version = "4.43.0"
+ constraints = "4.43.0"
hashes = [
- "h1:GP2N1tXrmpxu+qEDvFAmkfv9aeZNhag3bchyJpGpYbU=",
- "h1:HDJKZBQkVU0kQl4gViQ5L7EcFLn9hB0iuvO+ORJiDS4=",
- "h1:KrbeEsZoCJOnnX68yNI5h3QhMjc5bBCQW4yvYaEFq3s=",
- "h1:LelwnzU0OVn6g2+T9Ub9XdpC+vbheraIL/qgXhWBs/k=",
- "h1:TIq9CynfWrKgCxKL97Akj89cYlvJKn/AL4UXogd8/FM=",
- "h1:Uoy5oPdm1ipDG7yIMCUN1IXMpsTGXahPw3I0rVA/6wA=",
- "h1:Wunfpm+IZhENdoimrh4iXiakVnCsfKOHo80yJUjMQXM=",
- "h1:cRdCuahMOFrNyldnCInqGQRBT1DTkRPSfPnaf5r05iw=",
- "h1:k+zpXg8BO7gdbTIfSGyQisHhs5aVWQVbPLa5uUdr2UA=",
- "h1:kWNrzZ8Rh0OpHikexkmwJIIucD6SMZPi4oGyDsKJitw=",
- "h1:lomfTTjK78BdSEVTFcJUBQRy7IQHuGQImMaPWaYpfgQ=",
- "h1:oWcWlZe52ZRyLQciNe94RaWzhHifSTu03nlK0uL7rlM=",
- "h1:p3JJrhGEPlPQP7Uwy9FNMdvqCyD8tuT4lnXuJ+pSF/M=",
- "h1:wtB0sKxG2K/H41hWJI4uJdImWquuaP34Sip5LmfE410=",
- "zh:01742e5946f936548f8e42120287ffc757abf97e7cbbe34e25c266a438fb54fd",
- "zh:08d81f5a5aab4cc269f983b8c6b5be0e278105136aca9681740802619577371f",
- "zh:0d75131ba70902cfc94a7a5900369bdde56528b2aad6e10b164449cc97d57396",
- "zh:3890a715a012e197541daacdacb8cceec6d364814daa4640ddfe98a8ba9036cb",
- "zh:58254ce5ebe1faed4664df86210c39d660bcdc60280f17b25fe4d4dbea21ea8c",
- "zh:6b0abc1adbc2edee79368ce9f7338ebcb5d0bf941e8d7d9ac505b750f20f80a2",
- "zh:81cc415d1477174a1ca288d25fdb57e5ee488c2d7f61f265ef995b255a53b0ce",
- "zh:8680140c7fe5beaefe61c5cfa471bf88422dc0c0f05dad6d3cb482d4ffd22be4",
+ "h1:2kDVLD36BOVgBzI9p0WIQ+xjFfMmjaItA0l8SyZWEPo=",
+ "h1:2sGJDAwFEgO8+3y+2suYO+yrjNOzSsihad0hbM3+jPg=",
+ "h1:A1WPQFcdD+7FrFBFrKcx4CiSr75xSmsO93C0e5NBAeQ=",
+ "h1:BuXs/1ohmF4fWyOErY6vNbm7DaEIfbLSepSiZ2ol9I8=",
+ "h1:QPh+X19oyo808sqdeJaVqahZcQgcG1jCi3DA5zpjz6U=",
+ "h1:RI7c7dhSJoIkfou5b8ITRpM5MqsQD3FULj1h/rI4rJk=",
+ "h1:gdI5JTCPjewdGq1bhGAs+V5qCcmJ73N2gtMfuFybJp4=",
+ "h1:h4lnJpCIYZ7dsN9IO2mmwNdWNiQYEPoAEUjLF2sZ5kc=",
+ "h1:jTaExrX/eR7vGT5wayGqH8ZtXS2zyk0WmD3zbAKFIQU=",
+ "h1:l5NKJUOQJ1mHl1eekeXaxUZ+g+8Yv4aGcIN9vuK6GL4=",
+ "h1:sNbvm66/2vc8B/khyioOO8eNaU8nb89x693AN7fQheU=",
+ "h1:tXS4g1yE420AU4mvZ7RrYI+yYTutkRID3l+W0gBH4BM=",
+ "h1:vA+kES7uqmKA9K0U45IXR94jaTQZCHZLCHqMUeGxKMI=",
+ "h1:zV131k79+ob9p4jrLDgztDNvZvt8fvrrzpn0nPikBw8=",
+ "zh:006d111d6eafe6eeb5df2f91bd0ca320f979bd71f8cd8c475f10b2bd94acba55",
+ "zh:031fbb5cac23a841dc18e270cbfcd3ce9f4ba504edbd3c78931f7ed9827220a8",
+ "zh:07a72fe8b55afee99529bf4169ab6abfac5eabcd10968c29101925bcd358b09f",
+ "zh:0d14727d011c2d9df4c3058f527d2409223449ab48b46cbc86922eb553ef77c1",
+ "zh:155ce1333672d26cd18a5866b0761489d91682beffee58e45c3a1b68e8491d3d",
+ "zh:35a2a1939a965335b29ebdbfd759d93a97c0f589d9cd218f537dee6f600e3fb9",
+ "zh:52912fe421e7d911431f77788db2ea13836efd65a2e82385adb52c6a84d4ee90",
+ "zh:57374318d9194ea1db08884b0541a9055823d5970ad48f9a57547ac231163007",
+ "zh:5fb942b9e2553c058fe09fe12fb39dd175cd6715bb41c059c1a70df2bfc64dc1",
+ "zh:63cabd2bda201b09b35a3279d1f813ab71394b9b90fc5cf8962a5eba207803bc",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
- "zh:a491d26236122ccb83dac8cb490d2c0aa1f4d3a0b4abe99300fd49b1a624f42f",
- "zh:a70d9c469dc8d55715ba77c9d1a4ede1fdebf79e60ee18438a0844868db54e0d",
- "zh:a7fcb7d5c4222e14ec6d9a15adf8b9a083d84b102c3d0e4a0d102df5a1360b62",
- "zh:b4f9677174fabd199c8ebd2e9e5eb3528cf887e700569a4fb61eef4e070cec5e",
- "zh:c27f0f7519221d75dae4a3787a59e05acd5cc9a0d30a390eff349a77d20d52e6",
- "zh:db00d8605dbf43ca42fe1481a6c67fdcaa73debb7d2a0f613cb95ae5c5e7150e",
+ "zh:978ee67d3d53970a5c474ab40b00adee97f4153b16804a2b6b7ee205ae69d18a",
+ "zh:bbafdbef631b5c80570087817b42b16b1a76d556d692853a71c47fb48663cf00",
+ "zh:be91b3f2a697cbbb41f65aad2600972d0ede1e962a7d8a00bb3177cb77d86666",
+ "zh:efe168ad4aaa6156ce5a31d4e50e9d54d38ee5a5888412f9e690c0de5d619683",
]
}
diff --git a/deployment/modules/cloudflare/docs-release/config.tf b/deployment/modules/cloudflare/docs-release/config.tf
index 63c96fc49805b..74ea6d5816f8e 100644
--- a/deployment/modules/cloudflare/docs-release/config.tf
+++ b/deployment/modules/cloudflare/docs-release/config.tf
@@ -5,7 +5,7 @@ terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
- version = "4.40.0"
+ version = "4.43.0"
}
}
}
diff --git a/deployment/modules/cloudflare/docs/.terraform.lock.hcl b/deployment/modules/cloudflare/docs/.terraform.lock.hcl
index 096177bb05366..6419c16dad324 100644
--- a/deployment/modules/cloudflare/docs/.terraform.lock.hcl
+++ b/deployment/modules/cloudflare/docs/.terraform.lock.hcl
@@ -2,37 +2,37 @@
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/cloudflare/cloudflare" {
- version = "4.40.0"
- constraints = "4.40.0"
+ version = "4.43.0"
+ constraints = "4.43.0"
hashes = [
- "h1:GP2N1tXrmpxu+qEDvFAmkfv9aeZNhag3bchyJpGpYbU=",
- "h1:HDJKZBQkVU0kQl4gViQ5L7EcFLn9hB0iuvO+ORJiDS4=",
- "h1:KrbeEsZoCJOnnX68yNI5h3QhMjc5bBCQW4yvYaEFq3s=",
- "h1:LelwnzU0OVn6g2+T9Ub9XdpC+vbheraIL/qgXhWBs/k=",
- "h1:TIq9CynfWrKgCxKL97Akj89cYlvJKn/AL4UXogd8/FM=",
- "h1:Uoy5oPdm1ipDG7yIMCUN1IXMpsTGXahPw3I0rVA/6wA=",
- "h1:Wunfpm+IZhENdoimrh4iXiakVnCsfKOHo80yJUjMQXM=",
- "h1:cRdCuahMOFrNyldnCInqGQRBT1DTkRPSfPnaf5r05iw=",
- "h1:k+zpXg8BO7gdbTIfSGyQisHhs5aVWQVbPLa5uUdr2UA=",
- "h1:kWNrzZ8Rh0OpHikexkmwJIIucD6SMZPi4oGyDsKJitw=",
- "h1:lomfTTjK78BdSEVTFcJUBQRy7IQHuGQImMaPWaYpfgQ=",
- "h1:oWcWlZe52ZRyLQciNe94RaWzhHifSTu03nlK0uL7rlM=",
- "h1:p3JJrhGEPlPQP7Uwy9FNMdvqCyD8tuT4lnXuJ+pSF/M=",
- "h1:wtB0sKxG2K/H41hWJI4uJdImWquuaP34Sip5LmfE410=",
- "zh:01742e5946f936548f8e42120287ffc757abf97e7cbbe34e25c266a438fb54fd",
- "zh:08d81f5a5aab4cc269f983b8c6b5be0e278105136aca9681740802619577371f",
- "zh:0d75131ba70902cfc94a7a5900369bdde56528b2aad6e10b164449cc97d57396",
- "zh:3890a715a012e197541daacdacb8cceec6d364814daa4640ddfe98a8ba9036cb",
- "zh:58254ce5ebe1faed4664df86210c39d660bcdc60280f17b25fe4d4dbea21ea8c",
- "zh:6b0abc1adbc2edee79368ce9f7338ebcb5d0bf941e8d7d9ac505b750f20f80a2",
- "zh:81cc415d1477174a1ca288d25fdb57e5ee488c2d7f61f265ef995b255a53b0ce",
- "zh:8680140c7fe5beaefe61c5cfa471bf88422dc0c0f05dad6d3cb482d4ffd22be4",
+ "h1:2kDVLD36BOVgBzI9p0WIQ+xjFfMmjaItA0l8SyZWEPo=",
+ "h1:2sGJDAwFEgO8+3y+2suYO+yrjNOzSsihad0hbM3+jPg=",
+ "h1:A1WPQFcdD+7FrFBFrKcx4CiSr75xSmsO93C0e5NBAeQ=",
+ "h1:BuXs/1ohmF4fWyOErY6vNbm7DaEIfbLSepSiZ2ol9I8=",
+ "h1:QPh+X19oyo808sqdeJaVqahZcQgcG1jCi3DA5zpjz6U=",
+ "h1:RI7c7dhSJoIkfou5b8ITRpM5MqsQD3FULj1h/rI4rJk=",
+ "h1:gdI5JTCPjewdGq1bhGAs+V5qCcmJ73N2gtMfuFybJp4=",
+ "h1:h4lnJpCIYZ7dsN9IO2mmwNdWNiQYEPoAEUjLF2sZ5kc=",
+ "h1:jTaExrX/eR7vGT5wayGqH8ZtXS2zyk0WmD3zbAKFIQU=",
+ "h1:l5NKJUOQJ1mHl1eekeXaxUZ+g+8Yv4aGcIN9vuK6GL4=",
+ "h1:sNbvm66/2vc8B/khyioOO8eNaU8nb89x693AN7fQheU=",
+ "h1:tXS4g1yE420AU4mvZ7RrYI+yYTutkRID3l+W0gBH4BM=",
+ "h1:vA+kES7uqmKA9K0U45IXR94jaTQZCHZLCHqMUeGxKMI=",
+ "h1:zV131k79+ob9p4jrLDgztDNvZvt8fvrrzpn0nPikBw8=",
+ "zh:006d111d6eafe6eeb5df2f91bd0ca320f979bd71f8cd8c475f10b2bd94acba55",
+ "zh:031fbb5cac23a841dc18e270cbfcd3ce9f4ba504edbd3c78931f7ed9827220a8",
+ "zh:07a72fe8b55afee99529bf4169ab6abfac5eabcd10968c29101925bcd358b09f",
+ "zh:0d14727d011c2d9df4c3058f527d2409223449ab48b46cbc86922eb553ef77c1",
+ "zh:155ce1333672d26cd18a5866b0761489d91682beffee58e45c3a1b68e8491d3d",
+ "zh:35a2a1939a965335b29ebdbfd759d93a97c0f589d9cd218f537dee6f600e3fb9",
+ "zh:52912fe421e7d911431f77788db2ea13836efd65a2e82385adb52c6a84d4ee90",
+ "zh:57374318d9194ea1db08884b0541a9055823d5970ad48f9a57547ac231163007",
+ "zh:5fb942b9e2553c058fe09fe12fb39dd175cd6715bb41c059c1a70df2bfc64dc1",
+ "zh:63cabd2bda201b09b35a3279d1f813ab71394b9b90fc5cf8962a5eba207803bc",
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
- "zh:a491d26236122ccb83dac8cb490d2c0aa1f4d3a0b4abe99300fd49b1a624f42f",
- "zh:a70d9c469dc8d55715ba77c9d1a4ede1fdebf79e60ee18438a0844868db54e0d",
- "zh:a7fcb7d5c4222e14ec6d9a15adf8b9a083d84b102c3d0e4a0d102df5a1360b62",
- "zh:b4f9677174fabd199c8ebd2e9e5eb3528cf887e700569a4fb61eef4e070cec5e",
- "zh:c27f0f7519221d75dae4a3787a59e05acd5cc9a0d30a390eff349a77d20d52e6",
- "zh:db00d8605dbf43ca42fe1481a6c67fdcaa73debb7d2a0f613cb95ae5c5e7150e",
+ "zh:978ee67d3d53970a5c474ab40b00adee97f4153b16804a2b6b7ee205ae69d18a",
+ "zh:bbafdbef631b5c80570087817b42b16b1a76d556d692853a71c47fb48663cf00",
+ "zh:be91b3f2a697cbbb41f65aad2600972d0ede1e962a7d8a00bb3177cb77d86666",
+ "zh:efe168ad4aaa6156ce5a31d4e50e9d54d38ee5a5888412f9e690c0de5d619683",
]
}
diff --git a/deployment/modules/cloudflare/docs/config.tf b/deployment/modules/cloudflare/docs/config.tf
index 63c96fc49805b..74ea6d5816f8e 100644
--- a/deployment/modules/cloudflare/docs/config.tf
+++ b/deployment/modules/cloudflare/docs/config.tf
@@ -5,7 +5,7 @@ terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
- version = "4.40.0"
+ version = "4.43.0"
}
}
}
diff --git a/deployment/modules/cloudflare/docs/domain.tf b/deployment/modules/cloudflare/docs/domain.tf
index 80997c2e87176..a28fb4c0f80a9 100644
--- a/deployment/modules/cloudflare/docs/domain.tf
+++ b/deployment/modules/cloudflare/docs/domain.tf
@@ -18,7 +18,7 @@ output "immich_app_branch_subdomain" {
}
output "immich_app_branch_pages_hostname" {
- value = cloudflare_record.immich_app_branch_subdomain.value
+ value = cloudflare_record.immich_app_branch_subdomain.content
}
output "pages_project_name" {
diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml
index 16ed032dfb1c1..3d0f72425faca 100644
--- a/docker/docker-compose.dev.yml
+++ b/docker/docker-compose.dev.yml
@@ -36,6 +36,10 @@ services:
IMMICH_BUILD_URL: https://github.com/immich-app/immich/actions/runs/9654404849
IMMICH_BUILD_IMAGE: development
IMMICH_BUILD_IMAGE_URL: https://github.com/immich-app/immich/pkgs/container/immich-server
+ IMMICH_THIRD_PARTY_SOURCE_URL: https://github.com/immich-app/immich/
+ IMMICH_THIRD_PARTY_BUG_FEATURE_URL: https://github.com/immich-app/immich/issues
+ IMMICH_THIRD_PARTY_DOCUMENTATION_URL: https://immich.app/docs
+ IMMICH_THIRD_PARTY_SUPPORT_URL: https://immich.app/docs/third-party
ulimits:
nofile:
soft: 1048576
@@ -43,6 +47,7 @@ services:
ports:
- 3001:3001
- 9230:9230
+ - 9231:9231
depends_on:
- redis
- database
@@ -98,7 +103,7 @@ services:
redis:
container_name: immich_redis
- image: redis:6.2-alpine@sha256:d72905e7e3d53aa237968c0724f7bb22165c6a2068a06e66a361e4add0df75fd
+ image: redis:6.2-alpine@sha256:2ba50e1ac3a0ea17b736ce9db2b0a9f6f8b85d4c27d5f5accc6a416d8f42c6d5
healthcheck:
test: redis-cli ping || exit 1
diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml
index 3e62e7f5619ab..299516d16f07d 100644
--- a/docker/docker-compose.prod.yml
+++ b/docker/docker-compose.prod.yml
@@ -47,7 +47,7 @@ services:
redis:
container_name: immich_redis
- image: redis:6.2-alpine@sha256:d72905e7e3d53aa237968c0724f7bb22165c6a2068a06e66a361e4add0df75fd
+ image: redis:6.2-alpine@sha256:2ba50e1ac3a0ea17b736ce9db2b0a9f6f8b85d4c27d5f5accc6a416d8f42c6d5
healthcheck:
test: redis-cli ping || exit 1
restart: always
@@ -91,7 +91,7 @@ services:
command: ['./run.sh', '-disable-reporting']
ports:
- 3000:3000
- image: grafana/grafana:11.2.0-ubuntu@sha256:8e2c13739563c3da9d45de96c6bcb63ba617cac8c571c060112c7fc8ad6914e9
+ image: grafana/grafana:11.2.2-ubuntu@sha256:2bef00403c18d27919ff19d64fd6253fa713b3880304e92f69109e14221ac843
volumes:
- grafana-data:/var/lib/grafana
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 2f7d41271dcdd..3072c96c58b3b 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -48,7 +48,7 @@ services:
redis:
container_name: immich_redis
- image: docker.io/redis:6.2-alpine@sha256:d72905e7e3d53aa237968c0724f7bb22165c6a2068a06e66a361e4add0df75fd
+ image: docker.io/redis:6.2-alpine@sha256:2ba50e1ac3a0ea17b736ce9db2b0a9f6f8b85d4c27d5f5accc6a416d8f42c6d5
healthcheck:
test: redis-cli ping || exit 1
restart: always
diff --git a/docker/hwaccel.transcoding.yml b/docker/hwaccel.transcoding.yml
index bd4e2a46b8b39..33fb7b3c06273 100644
--- a/docker/hwaccel.transcoding.yml
+++ b/docker/hwaccel.transcoding.yml
@@ -51,5 +51,4 @@ services:
volumes:
- /usr/lib/wsl:/usr/lib/wsl
environment:
- - LD_LIBRARY_PATH=/usr/lib/wsl/lib
- LIBVA_DRIVER_NAME=d3d12
diff --git a/docs/.nvmrc b/docs/.nvmrc
index 3516580bbbc04..2a393af592b8c 100644
--- a/docs/.nvmrc
+++ b/docs/.nvmrc
@@ -1 +1 @@
-20.17.0
+20.18.0
diff --git a/docs/docs/FAQ.mdx b/docs/docs/FAQ.mdx
index b1a24e1788a2f..b328d3a047099 100644
--- a/docs/docs/FAQ.mdx
+++ b/docs/docs/FAQ.mdx
@@ -187,7 +187,7 @@ However, when the trash is emptied, the files will re-appear in the main timelin
### How does smart search work?
-Immich uses CLIP models. For more information about CLIP and its capabilities, read about it [here](https://openai.com/research/clip).
+Immich uses CLIP models. An ML model converts each image to an "embedding", which is essentially a string of numbers that semantically encodes what is in the image. The same is done for the text that you enter when you do a search, and that text embedding is then compared with those of the images to find similar ones. As such, there are no "tags", "labels", or "descriptions" generated that you can look at. For more information about CLIP and its capabilities, read about it [here](https://openai.com/research/clip).
### How does facial recognition work?
@@ -333,7 +333,11 @@ You may need to add mount points or docker volumes for the following internal co
- `immich-machine-learning:/.cache`
- `redis:/data`
-The non-root user/group needs read/write access to the volume mounts, including `UPLOAD_LOCATION`.
+The non-root user/group needs read/write access to the volume mounts, including `UPLOAD_LOCATION` and `/cache` for machine-learning.
+
+:::note Docker Compose Volumes
+The Docker Compose top level volume element does not support non-root access, all of the above volumes must be local volume mounts.
+:::
For a further hardened system, you can add the following block to every container except for `immich_postgres`.
diff --git a/docs/docs/administration/backup-and-restore.md b/docs/docs/administration/backup-and-restore.md
index 3d226dd0615df..19d716643b414 100644
--- a/docs/docs/administration/backup-and-restore.md
+++ b/docs/docs/administration/backup-and-restore.md
@@ -21,6 +21,8 @@ The recommended way to backup and restore the Immich database is to use the `pg_
It is not recommended to directly backup the `DB_DATA_LOCATION` folder. Doing so while the database is running can lead to a corrupted backup that cannot be restored.
:::
+### Manual Backup and Restore
+
@@ -29,16 +31,18 @@ docker exec -t immich_postgres pg_dumpall --clean --if-exists --username=postgre
```
```bash title='Restore'
-docker compose down -v # CAUTION! Deletes all Immich data to start from scratch.
-# rm -rf DB_DATA_LOCATION # CAUTION! Deletes all Immich data to start from scratch.
-docker compose pull # Update to latest version of Immich (if desired)
-docker compose create # Create Docker containers for Immich apps without running them.
+docker compose down -v # CAUTION! Deletes all Immich data to start from scratch
+## Uncomment the next line and replace DB_DATA_LOCATION with your Postgres path to permanently reset the Postgres database
+# rm -rf DB_DATA_LOCATION # CAUTION! Deletes all Immich data to start from scratch
+docker compose pull # Update to latest version of Immich (if desired)
+docker compose create # Create Docker containers for Immich apps without running them
docker start immich_postgres # Start Postgres server
-sleep 10 # Wait for Postgres server to start up
+sleep 10 # Wait for Postgres server to start up
+# Check the database user if you deviated from the default
gunzip < "/path/to/backup/dump.sql.gz" \
| sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" \
-| docker exec -i immich_postgres psql --username=postgres # Restore Backup
-docker compose up -d # Start remainder of Immich apps
+| docker exec -i immich_postgres psql --username=postgres # Restore Backup
+docker compose up -d # Start remainder of Immich apps
```
@@ -49,14 +53,16 @@ docker exec -t immich_postgres pg_dumpall --clean --if-exists --username=postgre
```
```powershell title='Restore'
-docker compose down -v # CAUTION! Deletes all Immich data to start from scratch.
-# Remove-Item -Recurse -Force DB_DATA_LOCATION # CAUTION! Deletes all Immich data to start from scratch.
-docker compose pull # Update to latest version of Immich (if desired)
-docker compose create # Create Docker containers for Immich apps without running them.
+docker compose down -v # CAUTION! Deletes all Immich data to start from scratch
+## Uncomment the next line and replace DB_DATA_LOCATION with your Postgres path to permanently reset the Postgres database
+# Remove-Item -Recurse -Force DB_DATA_LOCATION # CAUTION! Deletes all Immich data to start from scratch
+docker compose pull # Update to latest version of Immich (if desired)
+docker compose create # Create Docker containers for Immich apps without running them
docker start immich_postgres # Start Postgres server
-sleep 10 # Wait for Postgres server to start up
-gc "C:\path\to\backup\dump.sql" | docker exec -i immich_postgres psql --username=postgres # Restore Backup
-docker compose up -d # Start remainder of Immich apps
+sleep 10 # Wait for Postgres server to start up
+# Check the database user if you deviated from the default
+gc "C:\path\to\backup\dump.sql" | docker exec -i immich_postgres psql --username=postgres # Restore Backup
+docker compose up -d # Start remainder of Immich apps
```
@@ -68,6 +74,8 @@ Note that for the database restore to proceed properly, it requires a completely
Some deployment methods make it difficult to start the database without also starting the server or microservices. In these cases, you may set the environmental variable `DB_SKIP_MIGRATIONS=true` before starting the services. This will prevent the server from running migrations that interfere with the restore process. Note that both the server and microservices must have this variable set to prevent the migrations from running. Be sure to remove this variable and restart the services after the database is restored.
:::
+### Automatic Database Backups
+
The database dumps can also be automated (using [this image](https://github.com/prodrigestivill/docker-postgres-backup-local)) by editing the docker compose file to match the following:
```yaml
@@ -97,6 +105,7 @@ services:
Then you can restore with the same command but pointed at the latest dump.
```bash title='Automated Restore'
+# Be sure to check the username if you changed it from default
gunzip < db_dumps/last/immich-latest.sql.gz \
| sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" \
| docker exec -i immich_postgres psql --username=postgres
@@ -157,7 +166,7 @@ for more info read the [release notes](https://github.com/immich-app/immich/rele
- The Immich database containing all the information to allow the system to function properly.
**Note:** This folder will only appear to users who have made the changes mentioned in [v1.102.0](https://github.com/immich-app/immich/discussions/8930) (an optional, non-mandatory change) or who started with this version.
- - Stored in `UPLOAD_LOCATION/postgres`.
+ - Stored in `DB_DATA_LOCATION`.
:::danger
A backup of this folder does not constitute a backup of your database!
@@ -203,7 +212,7 @@ When you turn off the storage template engine, it will leave the assets in `UPLO
- The Immich database containing all the information to allow the system to function properly.
**Note:** This folder will only appear to users who have made the changes mentioned in [v1.102.0](https://github.com/immich-app/immich/discussions/8930) (an optional, non-mandatory change) or who started with this version.
- - Stored in `UPLOAD_LOCATION/postgres`.
+ - Stored in `DB_DATA_LOCATION`.
:::danger
A backup of this folder does not constitute a backup of your database!
diff --git a/docs/docs/administration/email-notification.mdx b/docs/docs/administration/email-notification.mdx
index 4a2a0b5a837f7..93b1051053069 100644
--- a/docs/docs/administration/email-notification.mdx
+++ b/docs/docs/administration/email-notification.mdx
@@ -8,13 +8,11 @@ Immich supports the option to send notifications via Email for the following eve
## SMTP settings
-You can access the settings panel from the web at `Administration -> Settings -> Notification settings`
+You can access the settings panel from the web at `Administration -> Settings -> Notification settings`.
-Under Email, enter the following details to connect with SMTP servers.
+Under Email, enter the required details to connect with an SMTP server.
-You can use the following [guide](/docs/guides/smtp-gmail) to use Gmail's SMTP server.
-
-
+You can use [this guide](/docs/guides/smtp-gmail) to use Gmail's SMTP server.
## User's notifications settings
diff --git a/docs/docs/administration/img/email-settings.png b/docs/docs/administration/img/email-settings.png
deleted file mode 100644
index a0d71354267fb..0000000000000
Binary files a/docs/docs/administration/img/email-settings.png and /dev/null differ
diff --git a/docs/docs/administration/postgres-standalone.md b/docs/docs/administration/postgres-standalone.md
index b5028c788e422..798555975f74c 100644
--- a/docs/docs/administration/postgres-standalone.md
+++ b/docs/docs/administration/postgres-standalone.md
@@ -13,9 +13,9 @@ Running with a pre-existing Postgres server can unlock powerful administrative f
You must install pgvecto.rs into your instance of Postgres using their [instructions][vectors-install]. After installation, add `shared_preload_libraries = 'vectors.so'` to your `postgresql.conf`. If you already have some `shared_preload_libraries` set, you can separate each extension with a comma. For example, `shared_preload_libraries = 'pg_stat_statements, vectors.so'`.
:::note
-Immich is known to work with Postgres versions 14, 15, and 16. Earlier versions are unsupported.
+Immich is known to work with Postgres versions 14, 15, and 16. Earlier versions are unsupported. Postgres 17 is nominally compatible, but pgvecto.rs does not have prebuilt images or packages for it as of writing.
-Make sure the installed version of pgvecto.rs is compatible with your version of Immich. For example, if your Immich version uses the dedicated database image `tensorchord/pgvecto-rs:pg14-v0.2.1`, you must install pgvecto.rs `>= 0.2.1, < 0.3.0`.
+Make sure the installed version of pgvecto.rs is compatible with your version of Immich. The current accepted range for pgvecto.rs is `>= 0.2.0, < 0.4.0`.
:::
## Specifying the connection URL
diff --git a/docs/docs/administration/reverse-proxy.md b/docs/docs/administration/reverse-proxy.md
index 1d2488f1192d8..c40fecbdc4c23 100644
--- a/docs/docs/administration/reverse-proxy.md
+++ b/docs/docs/administration/reverse-proxy.md
@@ -64,3 +64,43 @@ Below is an example config for Apache2 site configuration.
ProxyPreserveHost On
```
+
+### Traefik Proxy example config
+
+The example below is for Traefik version 3.
+
+The most important is to increase the `respondingTimeouts` of the entrypoint used by immich. In this example of entrypoint `websecure` for port `443`. Per default it's set to 60s which leeds to videos stop uploading after 1 minute (Error Code 499). With this config it will fail after 10 minutes which is in most cases enough. Increase it if needed.
+
+`traefik.yaml`
+
+```yaml
+[...]
+entryPoints:
+ websecure:
+ address: :443
+ # this section needs to be added
+ transport:
+ respondingTimeouts:
+ readTimeout: 600s
+ idleTimeout: 600s
+ writeTimeout: 600s
+```
+
+The second part is in the `docker-compose.yml` file where immich is in. Add the Traefik specific labels like in the example.
+
+`docker-compose.yml`
+
+```yaml
+services:
+ immich-server:
+ [...]
+ labels:
+ traefik.enable: true
+ # increase readingTimeouts for the entrypoint used here
+ traefik.http.routers.immich.entrypoints: websecure
+ traefik.http.routers.immich.rule: Host(`immich.your-domain.com`)
+ traefik.http.services.immich.loadbalancer.server.port: 3001
+```
+
+Keep in mind, that Traefik needs to communicate with the network where immich is in, usually done
+by adding the Traefik network to the `immich-server`.
diff --git a/docs/docs/administration/system-integrity.md b/docs/docs/administration/system-integrity.md
new file mode 100644
index 0000000000000..5440e42489d83
--- /dev/null
+++ b/docs/docs/administration/system-integrity.md
@@ -0,0 +1,47 @@
+# System Integrity
+
+## Folder checks
+
+:::info
+The folders considered for these checks include: `upload/`, `library/`, `thumbs/`, `encoded-video/`, `profile/`
+:::
+
+When Immich starts, it performs a series of checks in order to validate that it can read and write files to the volume mounts used by the storage system. If it cannot perform all the required operations, it will fail to start. The checks include:
+
+- Creating an initial hidden file (`.immich`) in each folder
+- Reading a hidden file (`.immich`) in each folder
+- Overwriting a hidden file (`.immich`) in each folder
+
+The checks are designed to catch the following situations:
+
+- Incorrect permissions (cannot read/write files)
+- Missing volume mount (`.immich` files should exist, but are missing)
+
+### Common issues
+
+:::note
+`.immich` files serve as markers and help keep track of volume mounts being used by Immich. Except for the situations listed below, they should never be manually created or deleted.
+:::
+
+#### Missing `.immich` files
+
+```
+Verifying system mount folder checks (enabled=true)
+...
+ENOENT: no such file or directory, open 'upload/encoded-video/.immich'
+```
+
+The above error messages show that the server has previously (successfully) written `.immich` files to each folder, but now does not detect them. This could be because any of the following:
+
+- Permission error - unable to read the file, but it exists
+- File does not exist - volume mount has changed and should be corrected
+- File does not exist - user manually deleted it and should be manually re-created (`touch .immich`)
+- File does not exist - user restored from a backup, but did not restore each folder (user should restore all folders or manually create `.immich` in any missing folders)
+
+### Ignoring the checks
+
+The checks are designed to catch common problems that we have seen users have in the past, but if you want to disable them you can set the following environment variable:
+
+```
+IMMICH_IGNORE_MOUNT_CHECK_ERRORS=true
+```
diff --git a/docs/docs/developer/architecture.mdx b/docs/docs/developer/architecture.mdx
index cf004a1119213..7b5debef4c0da 100644
--- a/docs/docs/developer/architecture.mdx
+++ b/docs/docs/developer/architecture.mdx
@@ -3,6 +3,7 @@ sidebar_position: 1
---
import AppArchitecture from './img/app-architecture.png';
+import MobileArchitecture from './img/immich_mobile_architecture.svg';
# Architecture
@@ -28,7 +29,14 @@ All three clients use [OpenAPI](./open-api.md) to auto-generate rest clients for
### Mobile App
-The mobile app is written in [Flutter](https://flutter.dev/). It uses [Isar Database](https://isar.dev/) for a local database and [Riverpod](https://riverpod.dev/) for state management.
+The mobile app is written in [Dart](https://dart.dev/) using [Flutter](https://flutter.dev/). Below is an architecture overview:
+
+
+
+The diagrams shows the target architecture, the current state of the code-base is not always following the architecture yet. New code and contributions should follow this architecture.
+Currently, it uses [Isar Database](https://isar.dev/) for a local database and [Riverpod](https://riverpod.dev/) for state management (providers).
+Entities and Models are the two types of data classes used. While entities are stored in the on-device database, models are ephemeral and only kept in memory.
+The Repositories should be the only place where other data classes are used internally (such as OpenAPI DTOs). However, their interfaces must not use foreign data classes!
### Web Client
diff --git a/docs/docs/developer/img/immich_mobile_architecture.drawio b/docs/docs/developer/img/immich_mobile_architecture.drawio
new file mode 100644
index 0000000000000..548cda09383f3
--- /dev/null
+++ b/docs/docs/developer/img/immich_mobile_architecture.drawio
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/docs/developer/img/immich_mobile_architecture.svg b/docs/docs/developer/img/immich_mobile_architecture.svg
new file mode 100644
index 0000000000000..71f28235bf649
--- /dev/null
+++ b/docs/docs/developer/img/immich_mobile_architecture.svg
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/docs/docs/developer/setup.md b/docs/docs/developer/setup.md
index 5f8d442aa85e8..32e79849efdcf 100644
--- a/docs/docs/developer/setup.md
+++ b/docs/docs/developer/setup.md
@@ -106,7 +106,7 @@ in User `settings.json` (`cmd + shift + p` and search for `Open User Settings JS
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.suggestSelection": "first",
"editor.tabCompletion": "onlySnippets",
- "editor.wordBasedSuggestions": false,
+ "editor.wordBasedSuggestions": "off",
"editor.defaultFormatter": "Dart-Code.dart-code"
}
}
diff --git a/docs/docs/features/hardware-transcoding.md b/docs/docs/features/hardware-transcoding.md
index deba45caccebc..e833bbef4f2b3 100644
--- a/docs/docs/features/hardware-transcoding.md
+++ b/docs/docs/features/hardware-transcoding.md
@@ -49,7 +49,7 @@ For RKMPP to work:
- You must have a supported Rockchip ARM SoC.
- Only RK3588 supports hardware tonemapping, other SoCs use slower software tonemapping while still using hardware encoding.
-- Tonemapping requires `/usr/lib/aarch64-linux-gnu/libmali.so.1` to be present on your host system. Install [`libmali-valhall-g610-g6p0-gbm`][libmali-rockchip] and modify the [`hwaccel.transcoding.yml`][hw-file] file:
+- Tonemapping requires `/usr/lib/aarch64-linux-gnu/libmali.so.1` to be present on your host system. Install the [`libmali`][libmali-rockchip] release that corresponds to your Mali GPU (`libmali-valhall-g610-g13p0-gbm` on RK3588) and modify the [`hwaccel.transcoding.yml`][hw-file] file:
- under `rkmpp` uncomment the 3 lines required for OpenCL tonemapping by removing the `#` symbol at the beginning of each line
- `- /dev/mali0:/dev/mali0`
- `- /etc/OpenCL:/etc/OpenCL:ro`
diff --git a/docs/docs/features/libraries.md b/docs/docs/features/libraries.md
index cdea1a11a51e1..17555469543c8 100644
--- a/docs/docs/features/libraries.md
+++ b/docs/docs/features/libraries.md
@@ -1,41 +1,21 @@
-# Libraries
+# External Libraries
-## Overview
+External libraries track assets stored in the filesystem outside of Immich. When the external library is scanned, Immich will load videos and photos from disk and create the corresponding assets. These assets will then be shown in the main timeline, and they will look and behave like any other asset, including viewing on the map, adding to albums, etc. Later, if a file is modified outside of Immich, you need to scan the library for the changes to show up.
-Immich supports the creation of libraries which is a top-level asset container. Currently, there are two types of libraries: traditional upload libraries that can sync with a mobile device, and external libraries, that keeps up to date with files on disk. Libraries are different from albums in that an asset can belong to multiple albums but only one library, and deleting a library deletes all assets contained within. As of August 2023, this is a new feature and libraries have a lot of potential for future development beyond what is documented here. This document attempts to describe the current state of libraries.
-
-## External Libraries
-
-External libraries tracks assets stored outside of Immich, i.e. in the file system. When the external library is scanned, Immich will read the metadata from the file and create an asset in the library for each image or video file. These items will then be shown in the main timeline, and they will look and behave like any other asset, including viewing on the map, adding to albums, etc.
-
-If a file is modified outside of Immich, the changes will not be reflected in immich until the library is scanned again. There are different ways to scan a library depending on the use case:
-
-- Scan Library Files: This is the default scan method and also the quickest. It will scan all files in the library and add new files to the library. It will notice if any files are missing (see below) but not check existing assets
-- Scan All Library Files: Same as above, but will check each existing asset to see if the modification time has changed. If it has, the asset will be updated. Since it has to check each asset, this is slower than Scan Library Files.
-- Force Scan All Library Files: Same as above, but will read each asset from disk no matter the modification time. This is useful in some cases where an asset has been modified externally but the modification time has not changed. This is the slowest way to scan because it reads each asset from disk.
+If an external asset is deleted from disk, Immich will move it to trash on rescan. To restore the asset, you need to restore the original file. After 30 days the file will be removed from trash, and any changes to metadata within Immich will be lost.
:::caution
-Due to aggressive caching it can take some time for a refreshed asset to appear correctly in the web view. You need to clear the cache in your browser to see the changes. This is a known issue and will be fixed in a future release. In Chrome, you need to open the developer console with F12, then reload the page with F5, and finally right click on the reload button and select "Empty Cache and Hard Reload".
+If you add metadata to an external asset in any way (i.e. add it to an album or edit the description), that metadata is only stored inside Immich and will not be persisted to the external asset file. If you move an asset to another location within the library all such metadata will be lost upon rescan. This is because the asset is considered a new asset after the move. This is a known issue and will be fixed in a future release.
:::
-In external libraries, the file path is used for duplicate detection. This means that if a file is moved to a different location, it will be added as a new asset. If the file is moved back to its original location, it will be added as a new asset. In contrast to upload libraries, two identical files can be uploaded if they are in different locations. This is a deliberate design choice to make Immich reflect the file system as closely as possible. Remember that duplication detection is only done within the same library, so if you have multiple external libraries, the same file can be added to multiple libraries.
-
:::caution
-If you add assets from an external library to an album and then move the asset to another location within the library, the asset will be removed from the album upon rescan. This is because the asset is considered a new asset after the move. This is a known issue and will be fixed in a future release.
+Due to aggressive caching it can take some time for a refreshed asset to appear correctly in the web view. You need to clear the cache in your browser to see the changes. This is a known issue and will be fixed in a future release. In Chrome, you need to open the developer console with F12, then reload the page with F5, and finally right click on the reload button and select "Empty Cache and Hard Reload".
:::
-### Deleted External Assets
-
-Note: Either a manual or scheduled library scan must have been performed to identify offline assets before this process will work.
-
-In all above scan methods, Immich will check if any files are missing. This can happen if files are deleted, or if they are on a storage location that is currently unavailable, like a network drive that is not mounted, or a USB drive that has been unplugged. In order to prevent accidental deletion of assets, Immich will not immediately delete an asset from the library if the file is missing. Instead, the asset will be internally marked as offline and will still be visible in the main timeline. If the file is moved back to its original location and the library is scanned again, the asset will be restored.
-
-Finally, files can be deleted from Immich via the `Remove Offline Files` job. This job can be found by the three dots menu for the associated external storage that was configured under Administration > Libraries (the same location described at [create external libraries](#create-external-libraries)). When this job is run, any assets marked as offline will then be removed from Immich. Run this job whenever files have been deleted from the file system and you want to remove them from Immich.
-
### Import Paths
External libraries use import paths to determine which files to scan. Each library can have multiple import paths so that files from different locations can be added to the same library. Import paths are scanned recursively, and if a file is in multiple import paths, it will only be added once. Each import file must be a readable directory that exists on the filesystem; the import path dialog will alert you of any paths that are not accessible.
@@ -66,9 +46,13 @@ Some basic examples:
- `**/Raw/**` will exclude all files in any directory named `Raw`
- `**/*.{tif,jpg}` will exclude all files with the extension `.tif` or `.jpg`
+Special characters such as @ should be escaped, for instance:
+
+- `**/\@eadir/**` will exclude all files in any directory named `@eadir`
+
### Automatic watching (EXPERIMENTAL)
-This feature - currently hidden in the config file - is considered experimental and for advanced users only. If enabled, it will allow automatic watching of the filesystem which means new assets are automatically imported to Immich without needing to rescan. Deleted assets are, as always, marked as offline and can be removed with the "Remove offline files" button.
+This feature - currently hidden in the config file - is considered experimental and for advanced users only. If enabled, it will allow automatic watching of the filesystem which means new assets are automatically imported to Immich without needing to rescan.
If your photos are on a network drive, automatic file watching likely won't work. In that case, you will have to rely on a periodic library refresh to pull in your changes.
@@ -84,7 +68,7 @@ In rare cases, the library watcher can hang, preventing Immich from starting up.
### Nightly job
-There is an automatic job that's run once a day and refreshes all modified files in all libraries as well as cleans up any libraries stuck in deletion.
+There is an automatic scan job that is scheduled to run once a day. This job also cleans up any libraries stuck in deletion.
## Usage
@@ -120,7 +104,7 @@ This will disallow the images from being deleted in the web UI, or adding metada
_Remember to run `docker compose up -d` to register the changes. Make sure you can see the mounted path in the container._
:::
-### Create External Libraries
+### Create A New Library
These actions must be performed by the Immich administrator.
@@ -144,7 +128,7 @@ Next, we'll add an exclusion pattern to filter out raw files.
- Enter `**/Raw/**` and click save.
- Click save
- Click the drop-down menu on the newly created library
-- Click on Scan Library Files
+- Click on Scan
The christmas trip library will now be scanned in the background. In the meantime, let's add the videos and old photos to another library.
@@ -161,7 +145,7 @@ If you get an error here, please rename the other external library to something
- Click on Add Path
- Enter `/mnt/media/videos` then click Add
- Click Save
-- Click on Scan Library Files
+- Click on Scan
Within seconds, the assets from the old-pics and videos folders should show up in the main timeline.
diff --git a/docs/docs/features/ml-hardware-acceleration.md b/docs/docs/features/ml-hardware-acceleration.md
index b20c3fc2b6315..ca1cb8edb1e99 100644
--- a/docs/docs/features/ml-hardware-acceleration.md
+++ b/docs/docs/features/ml-hardware-acceleration.md
@@ -38,7 +38,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele
- The GPU must have compute capability 5.2 or greater.
- The server must have the official NVIDIA driver installed.
-- The installed driver must be >= 545 (it must support CUDA 12.3.2).
+- The installed driver must be >= 535 (it must support CUDA 12.2).
- On Linux (except for WSL2), you also need to have [NVIDIA Container Toolkit][nvct] installed.
#### OpenVINO
@@ -53,6 +53,12 @@ You do not need to redo any machine learning jobs after enabling hardware accele
3. Still in `immich-machine-learning`, add one of -[armnn, cuda, openvino] to the `image` section's tag at the end of the line.
4. Redeploy the `immich-machine-learning` container with these updated settings.
+### Confirming Device Usage
+
+You can confirm the device is being recognized and used by checking its utilization. There are many tools to display this, such as `nvtop` for NVIDIA or Intel and `intel_gpu_top` for Intel.
+
+You can also check the logs of the `immich-machine-learning` container. When a Smart Search or Face Detection job begins, or when you search with text in Immich, you should either see a log for `Available ORT providers` containing the relevant provider (e.g. `CUDAExecutionProvider` in the case of CUDA), or a `Loaded ANN model` log entry without errors in the case of ARM NN.
+
#### Single Compose File
Some platforms, including Unraid and Portainer, do not support multiple Compose files as of writing. As an alternative, you can "inline" the relevant contents of the [`hwaccel.ml.yml`][hw-file] file into the `immich-machine-learning` service directly.
@@ -95,9 +101,22 @@ immich-machine-learning:
Once this is done, you can redeploy the `immich-machine-learning` container.
-:::info
-You can confirm the device is being recognized and used by checking its utilization (via `nvtop` for CUDA, `intel_gpu_top` for OpenVINO, etc.). You can also enable debug logging by setting `IMMICH_LOG_LEVEL=debug` in the `.env` file and restarting the `immich-machine-learning` container. When a Smart Search or Face Detection job begins, you should see a log for `Available ORT providers` containing the relevant provider. In the case of ARM NN, the absence of a `Could not load ANN shared libraries` log entry means it loaded successfully.
-:::
+#### Multi-GPU
+
+If you want to utilize multiple NVIDIA or Intel GPUs, you can set the `MACHINE_LEARNING_DEVICE_IDS` environmental variable to a comma-separated list of device IDs and set `MACHINE_LEARNING_WORKERS` to the number of listed devices. You can run a command such as `nvidia-smi -L` or `glxinfo -B` to see the currently available devices and their corresponding IDs.
+
+For example, if you have devices 0 and 1, set the values as follows:
+
+```
+MACHINE_LEARNING_DEVICE_IDS=0,1
+MACHINE_LEARNING_WORKERS=2
+```
+
+In this example, the machine learning service will spawn two workers, one of which will allocate models to device 0 and the other to device 1. Different requests will be processed by one worker or the other.
+
+This approach can be used to simply specify a particular device as well. For example, setting `MACHINE_LEARNING_DEVICE_IDS=1` will ensure device 1 is always used instead of device 0.
+
+Note that you should increase job concurrencies to increase overall utilization and more effectively distribute work across multiple GPUs. Additionally, each GPU must be able to load all models. It is not possible to distribute a single model to multiple GPUs that individually have insufficient VRAM, or to delegate a specific model to one GPU.
[hw-file]: https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml
[nvct]: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
diff --git a/docs/docs/guides/remote-access.md b/docs/docs/guides/remote-access.md
index 1ea068c3a0a79..6f401dfc5a5c3 100644
--- a/docs/docs/guides/remote-access.md
+++ b/docs/docs/guides/remote-access.md
@@ -27,7 +27,7 @@ You may use a VPN service to open an encrypted connection to your Immich instanc
If you are unable to open a port on your router for Wireguard or OpenVPN to your server, [Tailscale](https://tailscale.com/) is a good option. Tailscale mediates a peer-to-peer wireguard tunnel between your server and remote device, even if one or both of them are behind a [NAT firewall](https://en.wikipedia.org/wiki/Network_address_translation).
-:::tip Video toturial
+:::tip Video tutorial
You can learn how to set up Tailscale together with Immich with the [tutorial video](https://www.youtube.com/watch?v=Vt4PDUXB_fg) they created.
:::
diff --git a/docs/docs/guides/scaling-immich.md b/docs/docs/guides/scaling-immich.md
new file mode 100644
index 0000000000000..a8d916ae2a807
--- /dev/null
+++ b/docs/docs/guides/scaling-immich.md
@@ -0,0 +1,19 @@
+# Scaling Immich
+
+Immich is built with modern deployment practices in mind, and the backend is designed to be able to run multiple instances in parallel. When doing this, the only requirement you need to be aware of is that every instance needs to be connected to the shared infrastructure. That means they should all have access to the same Postgres and Redis instances, and have the same files mounted into the containers.
+
+Scaling can be useful for many reasons. Maybe you have a gaming PC that you want to use for transcoding and thumbnail generation, or perhaps you run a Kubernetes cluster across a handful of powerful servers that you want to make use of.
+
+:::info
+If you only have a single machine to run Immich on, scaling to multiple containers is unlikely to provide any benefit. An Immich container will run multiple background tasks at once, and you can increase their number from the admin panel.
+:::
+
+The details of how to scale across multiple machines will vary widely between different environments and require some knowledge to set up, and as such this guide gives no specific instructions. In some cases scaling up can be as easy as incrementing the amount of replicas on a Kubernetes deployment, in others it might need you to configure network tunnels or NFS mounts. The details are left as an exercise for the reader ;)
+
+## Workers
+
+By default, each running `immich-server` container comes with multiple internal workers. If you're scaling up only to handle more background tasks, you can choose to disable the worker responsible for the API. See [workers](../administration/jobs-workers.md) for more detail.
+
+## Scaling down
+
+In the same way you can scale up to multiple containers, you can also choose to scale down. All state is stored in Postgres, Redis, and the filesystem so there is no risk in stopping a running immich-server container, for example if you want to use your GPU to play some games. As long as there is an API worker running you will still be able to browse Immich, and jobs will wait to be processed until there is a worker available for them.
diff --git a/docs/docs/install/config-file.md b/docs/docs/install/config-file.md
index abbba8c6b39b5..b789d8653f168 100644
--- a/docs/docs/install/config-file.md
+++ b/docs/docs/install/config-file.md
@@ -20,6 +20,7 @@ The default configuration looks like this:
"acceptedVideoCodecs": ["h264"],
"targetAudioCodec": "aac",
"acceptedAudioCodecs": ["aac", "mp3", "libopus"],
+ "acceptedContainers": ["mov", "ogg", "webm"],
"targetResolution": "720",
"maxBitrate": "0",
"bframes": -1,
@@ -32,7 +33,8 @@ The default configuration looks like this:
"preferredHwDevice": "auto",
"transcode": "required",
"tonemap": "hable",
- "accel": "disabled"
+ "accel": "disabled",
+ "accelDecode": false
},
"job": {
"backgroundTask": {
@@ -60,10 +62,13 @@ The default configuration looks like this:
"concurrency": 5
},
"thumbnailGeneration": {
- "concurrency": 5
+ "concurrency": 3
},
"videoConversion": {
"concurrency": 1
+ },
+ "notifications": {
+ "concurrency": 5
}
},
"logging": {
@@ -78,40 +83,46 @@ The default configuration looks like this:
"modelName": "ViT-B-32__openai"
},
"duplicateDetection": {
- "enabled": false,
- "maxDistance": 0.03
+ "enabled": true,
+ "maxDistance": 0.01
},
"facialRecognition": {
"enabled": true,
"modelName": "buffalo_l",
"minScore": 0.7,
- "maxDistance": 0.6,
+ "maxDistance": 0.5,
"minFaces": 3
}
},
"map": {
"enabled": true,
- "lightStyle": "",
- "darkStyle": ""
+ "lightStyle": "https://tiles.immich.cloud/v1/style/light.json",
+ "darkStyle": "https://tiles.immich.cloud/v1/style/dark.json"
},
"reverseGeocoding": {
"enabled": true
},
+ "metadata": {
+ "faces": {
+ "import": false
+ }
+ },
"oauth": {
- "enabled": false,
- "issuerUrl": "",
+ "autoLaunch": false,
+ "autoRegister": true,
+ "buttonText": "Login with OAuth",
"clientId": "",
"clientSecret": "",
+ "defaultStorageQuota": 0,
+ "enabled": false,
+ "issuerUrl": "",
+ "mobileOverrideEnabled": false,
+ "mobileRedirectUri": "",
"scope": "openid email profile",
"signingAlgorithm": "RS256",
+ "profileSigningAlgorithm": "none",
"storageLabelClaim": "preferred_username",
- "storageQuotaClaim": "immich_quota",
- "defaultStorageQuota": 0,
- "buttonText": "Login with OAuth",
- "autoRegister": true,
- "autoLaunch": false,
- "mobileOverrideEnabled": false,
- "mobileRedirectUri": ""
+ "storageQuotaClaim": "immich_quota"
},
"passwordLogin": {
"enabled": true
@@ -122,11 +133,16 @@ The default configuration looks like this:
"template": "{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}"
},
"image": {
- "thumbnailFormat": "webp",
- "thumbnailSize": 250,
- "previewFormat": "jpeg",
- "previewSize": 1440,
- "quality": 80,
+ "thumbnail": {
+ "format": "webp",
+ "size": 250,
+ "quality": 80
+ },
+ "preview": {
+ "format": "jpeg",
+ "size": 1440,
+ "quality": 80
+ },
"colorspace": "p3",
"extractEmbedded": false
},
@@ -140,23 +156,35 @@ The default configuration looks like this:
"theme": {
"customCss": ""
},
- "user": {
- "deleteDelay": 7
- },
"library": {
"scan": {
"enabled": true,
"cronExpression": "0 0 * * *"
},
"watch": {
- "enabled": false,
- "usePolling": false,
- "interval": 10000
+ "enabled": false
}
},
"server": {
"externalDomain": "",
"loginPageMessage": ""
+ },
+ "notifications": {
+ "smtp": {
+ "enabled": false,
+ "from": "",
+ "replyTo": "",
+ "transport": {
+ "ignoreCert": false,
+ "host": "",
+ "port": 587,
+ "username": "",
+ "password": ""
+ }
+ }
+ },
+ "user": {
+ "deleteDelay": 7
}
}
```
diff --git a/docs/docs/install/docker-compose.mdx b/docs/docs/install/docker-compose.mdx
index 9ef63523a05ec..b73d51b4d240a 100644
--- a/docs/docs/install/docker-compose.mdx
+++ b/docs/docs/install/docker-compose.mdx
@@ -58,6 +58,7 @@ Optionally, you can enable hardware acceleration for machine learning and transc
- Populate `UPLOAD_LOCATION` with your preferred location for storing backup assets.
- Consider changing `DB_PASSWORD` to a custom value. Postgres is not publically exposed, so this password is only used for local authentication.
To avoid issues with Docker parsing this value, it is best to use only the characters `A-Za-z0-9`.
+- Set your timezone by uncommenting the `TZ=` line.
### Step 3 - Start the containers
@@ -80,6 +81,10 @@ The Compose file './docker-compose.yml' is invalid because:
See the previous paragraph about installing from the official docker repository.
:::
+:::info Health check start interval
+If you get an error `can't set healthcheck.start_interval as feature require Docker Engine v25 or later`, it helps to comment out the line for `start_interval` in the `database` section of the `docker-compose.yml` file.
+:::
+
:::tip
For more information on how to use the application, please refer to the [Post Installation](/docs/install/post-install.mdx) guide.
:::
diff --git a/docs/docs/install/environment-variables.md b/docs/docs/install/environment-variables.md
index a0cf71e044724..b8fdf72234ed8 100644
--- a/docs/docs/install/environment-variables.md
+++ b/docs/docs/install/environment-variables.md
@@ -27,23 +27,14 @@ If this should not work, try running `docker compose up -d --force-recreate`.
These environment variables are used by the `docker-compose.yml` file and do **NOT** affect the containers directly.
:::
-### Supported filesystems
-
-The Immich Postgres database (`DB_DATA_LOCATION`) must be located on a filesystem that supports user/group
-ownership and permissions (EXT2/3/4, ZFS, APFS, BTRFS, XFS, etc.). It will not work on any filesystem formatted in NTFS or ex/FAT/32.
-It will not work in WSL (Windows Subsystem for Linux) when using a mounted host directory (commonly under `/mnt`).
-If this is an issue, you can change the bind mount to a Docker volume instead.
-
-Regardless of filesystem, it is not recommended to use a network share for your database location due to performance and possible data loss issues.
-
## General
| Variable | Description | Default | Containers | Workers |
| :---------------------------------- | :---------------------------------------------------------------------------------------- | :--------------------------: | :----------------------- | :----------------- |
-| `TZ` | Timezone | | server | microservices |
+| `TZ` | Timezone | \*1 | server | microservices |
| `IMMICH_ENV` | Environment (production, development) | `production` | server, machine learning | api, microservices |
| `IMMICH_LOG_LEVEL` | Log Level (verbose, debug, log, warn, error) | `log` | server, machine learning | api, microservices |
-| `IMMICH_MEDIA_LOCATION` | Media Location inside the container ⚠️**You probably shouldn't set this**\*1⚠️ | `./upload`\*2 | server | api, microservices |
+| `IMMICH_MEDIA_LOCATION` | Media Location inside the container ⚠️**You probably shouldn't set this**\*2⚠️ | `./upload`\*3 | server | api, microservices |
| `IMMICH_CONFIG_FILE` | Path to config file | | server | api, microservices |
| `NO_COLOR` | Set to `true` to disable color-coded log output | `false` | server, machine learning | |
| `CPU_CORES` | Amount of cores available to the immich server | auto-detected cpu core count | server | |
@@ -51,17 +42,15 @@ Regardless of filesystem, it is not recommended to use a network share for your
| `IMMICH_MICROSERVICES_METRICS_PORT` | Port for the OTEL metrics | `8082` | server | microservices |
| `IMMICH_PROCESS_INVALID_IMAGES` | When `true`, generate thumbnails for invalid images | | server | microservices |
| `IMMICH_TRUSTED_PROXIES` | List of comma separated IPs set as trusted proxies | | server | api |
+| `IMMICH_IGNORE_MOUNT_CHECK_ERRORS` | See [System Integrity](/docs/administration/system-integrity) | | server | api, microservices |
-\*1: This path is where the Immich code looks for the files, which is internal to the docker container. Setting it to a path on your host will certainly break things, you should use the `UPLOAD_LOCATION` variable instead.
+\*1: `TZ` should be set to a `TZ identifier` from [this list][tz-list]. For example, `TZ="Etc/UTC"`.
+`TZ` is used by `exiftool` as a fallback in case the timezone cannot be determined from the image metadata. It is also used for logfile timestamps and cron job execution.
-\*2: With the default `WORKDIR` of `/usr/src/app`, this path will resolve to `/usr/src/app/upload`.
-It only need to be set if the Immich deployment method is changing.
+\*2: This path is where the Immich code looks for the files, which is internal to the docker container. Setting it to a path on your host will certainly break things, you should use the `UPLOAD_LOCATION` variable instead.
-:::tip
-`TZ` should be set to a `TZ identifier` from [this list][tz-list]. For example, `TZ="Etc/UTC"`.
-
-`TZ` is used by `exiftool` as a fallback in case the timezone cannot be determined from the image metadata. It is also used for logfile timestamps and cron job execution.
-:::
+\*3: With the default `WORKDIR` of `/usr/src/app`, this path will resolve to `/usr/src/app/upload`.
+It only need to be set if the Immich deployment method is changing.
## Workers
@@ -175,6 +164,7 @@ Redis (Sentinel) URL example JSON before encoding:
| `MACHINE_LEARNING_ANN` | Enable ARM-NN hardware acceleration if supported | `True` | machine learning |
| `MACHINE_LEARNING_ANN_FP16_TURBO` | Execute operations in FP16 precision: increasing speed, reducing precision (applies only to ARM-NN) | `False` | machine learning |
| `MACHINE_LEARNING_ANN_TUNING_LEVEL` | ARM-NN GPU tuning level (1: rapid, 2: normal, 3: exhaustive) | `2` | machine learning |
+| `MACHINE_LEARNING_DEVICE_IDS`\*4 | Device IDs to use in multi-GPU environments | `0` | machine learning |
\*1: It is recommended to begin with this parameter when changing the concurrency levels of the machine learning service and then tune the other ones.
@@ -182,6 +172,8 @@ Redis (Sentinel) URL example JSON before encoding:
\*3: For scenarios like HPA in K8S. https://github.com/immich-app/immich/discussions/12064
+\*4: Using multiple GPUs requires `MACHINE_LEARNING_WORKERS` to be set greater than 1. A single device is assigned to each worker in round-robin priority.
+
:::info
Other machine learning parameters can be tuned from the admin UI.
diff --git a/docs/docs/install/post-install.mdx b/docs/docs/install/post-install.mdx
index ba8aa2e9a35a6..bc1ee80b47d11 100644
--- a/docs/docs/install/post-install.mdx
+++ b/docs/docs/install/post-install.mdx
@@ -8,6 +8,7 @@ import StorageTemplate from '/docs/partials/_storage-template.md';
import MobileAppDownload from '/docs/partials/_mobile-app-download.md';
import MobileAppLogin from '/docs/partials/_mobile-app-login.md';
import MobileAppBackup from '/docs/partials/_mobile-app-backup.md';
+import ServerBackup from '/docs/partials/_server-backup.md';
# Post Install Steps
@@ -33,6 +34,10 @@ A list of common steps to take after installing Immich include:
-## Step 6 - Backup Your Library
+## Step 6 - Upload Your Library
+
+## Step 7 - Setup Server Backups
+
+
diff --git a/docs/docs/install/requirements.md b/docs/docs/install/requirements.md
index 88d85c7bee8cc..b96705203aa8f 100644
--- a/docs/docs/install/requirements.md
+++ b/docs/docs/install/requirements.md
@@ -23,7 +23,33 @@ Immich requires the command `docker compose` - the similarly named `docker-compo
- **RAM**: Minimum 4GB, recommended 6GB.
- **CPU**: Minimum 2 cores, recommended 4 cores.
- **Storage**: Recommended Unix-compatible filesystem (EXT4, ZFS, APFS, etc.) with support for user/group ownership and permissions.
- - This can present an issue for Windows users. See [here](/docs/install/environment-variables#supported-filesystems)
- for more details and alternatives.
+ - This can present an issue for Windows users. See below for details and an alternative setup.
- The generation of thumbnails and transcoded video can increase the size of the photo library by 10-20% on average.
- - Network shares are supported for the storage of image and video assets only.
+ - Network shares are supported for the storage of image and video assets only. It is not recommended to use a network share for your database location due to performance and possible data loss issues.
+
+### Special requirements for Windows users
+
+
+Database storage on Windows systems
+
+The Immich Postgres database (`DB_DATA_LOCATION`) must be located on a filesystem that supports user/group
+ownership and permissions (EXT2/3/4, ZFS, APFS, BTRFS, XFS, etc.). It will not work on any filesystem formatted in NTFS or ex/FAT/32.
+It will not work in WSL (Windows Subsystem for Linux) when using a mounted host directory (commonly under `/mnt`).
+If this is an issue, you can change the bind mount to a Docker volume instead as follows:
+
+Make the following change to `.env`:
+
+```diff
+- DB_DATA_LOCATION=./postgres
++ DB_DATA_LOCATION=pgdata
+```
+
+Add the following line to the bottom of `docker-compose.yml`:
+
+```diff
+volumes:
+ model-cache:
++ pgdata:
+```
+
+
diff --git a/docs/docs/install/truenas.md b/docs/docs/install/truenas.md
index 271cd52cabc95..ffb559ed1216b 100644
--- a/docs/docs/install/truenas.md
+++ b/docs/docs/install/truenas.md
@@ -30,6 +30,8 @@ You can organize these as one parent with seven child datasets, for example `mnt
:::info Permissions
The **pgData** dataset must be owned by the user `netdata` (UID 999) for postgres to start. The other datasets must be owned by the user `root` (UID 0) or a group that includes the user `root` (UID 0) for immich to have the necessary permissions.
+
+The **library** dataset must have [ACL mode](https://www.truenas.com/docs/core/coretutorials/storage/pools/permissions/#access-control-lists) set to `Passthrough` if you plan on using a [storage template](/docs/administration/storage-template.mdx) and the dataset is configured for network sharing (its ACL type is set to `SMB/NFSv4`). When the template is applied and files need to be moved from **uploads** to **library**, immich performs `chmod` internally and needs to be allowed to execute the command.
:::
## Installing the Immich Application
diff --git a/docs/docs/partials/_server-backup.md b/docs/docs/partials/_server-backup.md
new file mode 100644
index 0000000000000..7aab90a753c24
--- /dev/null
+++ b/docs/docs/partials/_server-backup.md
@@ -0,0 +1,2 @@
+Now that you have imported some pictures, you should setup server backups to preserve your memories.
+You can do so by following our [backup guide](/docs/administration/backup-and-restore.md).
diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js
index a94a54b60c81a..16d654b46bc58 100644
--- a/docs/docusaurus.config.js
+++ b/docs/docusaurus.config.js
@@ -72,14 +72,9 @@ const config = {
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
- colorMode: {
- defaultMode: 'dark',
- },
announcementBar: {
id: 'site_announcement_immich',
content: `⚠️ The project is under very active development. Expect bugs and changes. Do not use it as the only way to store your photos and videos!`,
- backgroundColor: '#593f00',
- textColor: '#ffefc9',
isCloseable: false,
},
docs: {
@@ -201,7 +196,7 @@ const config = {
darkTheme: prism.themes.dracula,
additionalLanguages: ['sql', 'diff', 'bash', 'powershell', 'nginx'],
},
- image: 'overview/img/feature-panel.png',
+ image: 'img/feature-panel.png',
}),
};
diff --git a/docs/package-lock.json b/docs/package-lock.json
index 05417ce1275a7..909263da859a4 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -6068,9 +6068,10 @@
}
},
"node_modules/docusaurus-lunr-search": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/docusaurus-lunr-search/-/docusaurus-lunr-search-3.4.0.tgz",
- "integrity": "sha512-GfllnNXCLgTSPH9TAKWmbn8VMfwpdOAZ1xl3T2GgX8Pm26qSDLfrrdVwjguaLfMJfzciFL97RKrAJlgrFM48yw==",
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/docusaurus-lunr-search/-/docusaurus-lunr-search-3.5.0.tgz",
+ "integrity": "sha512-k3zN4jYMi/prWInJILGKOxE+BVcgYinwj9+gcECsYm52tS+4ZKzXQzbPnVJAEXmvKOfFMcDFvS3MSmm6cEaxIQ==",
+ "license": "MIT",
"dependencies": {
"autocomplete.js": "^0.37.0",
"clsx": "^1.2.1",
@@ -6097,14 +6098,16 @@
}
},
"node_modules/docusaurus-lunr-search/node_modules/@types/unist": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
- "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "license": "MIT"
},
"node_modules/docusaurus-lunr-search/node_modules/bail": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz",
"integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==",
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -6114,6 +6117,7 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -6122,6 +6126,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "license": "MIT",
"engines": {
"node": ">=8"
}
@@ -6130,6 +6135,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz",
"integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==",
+ "license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wooorm"
@@ -6139,6 +6145,7 @@
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz",
"integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==",
+ "license": "MIT",
"dependencies": {
"bail": "^1.0.0",
"extend": "^3.0.0",
@@ -6156,6 +6163,7 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
"integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
+ "license": "MIT",
"dependencies": {
"@types/unist": "^2.0.2"
},
@@ -6168,6 +6176,7 @@
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz",
"integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==",
+ "license": "MIT",
"dependencies": {
"@types/unist": "^2.0.0",
"is-buffer": "^2.0.0",
@@ -6183,6 +6192,7 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
"integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
+ "license": "MIT",
"dependencies": {
"@types/unist": "^2.0.0",
"unist-util-stringify-position": "^2.0.0"
@@ -12705,9 +12715,9 @@
}
},
"node_modules/picocolors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
- "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
+ "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
"license": "ISC"
},
"node_modules/picomatch": {
@@ -12819,9 +12829,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.40",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz",
- "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==",
+ "version": "8.4.47",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
+ "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"funding": [
{
"type": "opencollective",
@@ -12839,8 +12849,8 @@
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
- "picocolors": "^1.0.1",
- "source-map-js": "^1.2.0"
+ "picocolors": "^1.1.0",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
@@ -15660,9 +15670,10 @@
}
},
"node_modules/source-map-js": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
- "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
@@ -16081,9 +16092,9 @@
}
},
"node_modules/tailwindcss": {
- "version": "3.4.10",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz",
- "integrity": "sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==",
+ "version": "3.4.13",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz",
+ "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==",
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
@@ -16443,9 +16454,9 @@
}
},
"node_modules/typescript": {
- "version": "5.5.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
- "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
+ "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
diff --git a/docs/package.json b/docs/package.json
index cdcdf53446884..b7fa64097d6e0 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -56,6 +56,6 @@
"node": ">=20"
},
"volta": {
- "node": "20.17.0"
+ "node": "20.18.0"
}
}
diff --git a/docs/src/components/community-guides.tsx b/docs/src/components/community-guides.tsx
index 6982853fade77..7f4206c97baf1 100644
--- a/docs/src/components/community-guides.tsx
+++ b/docs/src/components/community-guides.tsx
@@ -52,20 +52,20 @@ const guides: CommunityGuidesProps[] = [
function CommunityGuide({ title, description, url }: CommunityGuidesProps): JSX.Element {
return (
-
+
diff --git a/docs/src/components/svg-paths.ts b/docs/src/components/svg-paths.ts
new file mode 100644
index 0000000000000..112ed1d70fa85
--- /dev/null
+++ b/docs/src/components/svg-paths.ts
@@ -0,0 +1,2 @@
+export const discordPath =
+ 'M 9.1367188 3.8691406 C 9.1217187 3.8691406 9.1067969 3.8700938 9.0917969 3.8710938 C 8.9647969 3.8810937 5.9534375 4.1403594 4.0234375 5.6933594 C 3.0154375 6.6253594 1 12.073203 1 16.783203 C 1 16.866203 1.0215 16.946531 1.0625 17.019531 C 2.4535 19.462531 6.2473281 20.102859 7.1113281 20.130859 L 7.1269531 20.130859 C 7.2799531 20.130859 7.4236719 20.057594 7.5136719 19.933594 L 8.3886719 18.732422 C 6.0296719 18.122422 4.8248594 17.086391 4.7558594 17.025391 C 4.5578594 16.850391 4.5378906 16.549563 4.7128906 16.351562 C 4.8068906 16.244563 4.9383125 16.189453 5.0703125 16.189453 C 5.1823125 16.189453 5.2957188 16.228594 5.3867188 16.308594 C 5.4157187 16.334594 7.6340469 18.216797 11.998047 18.216797 C 16.370047 18.216797 18.589328 16.325641 18.611328 16.306641 C 18.702328 16.227641 18.815734 16.189453 18.927734 16.189453 C 19.059734 16.189453 19.190156 16.243562 19.285156 16.351562 C 19.459156 16.549563 19.441141 16.851391 19.244141 17.025391 C 19.174141 17.087391 17.968375 18.120469 15.609375 18.730469 L 16.484375 19.933594 C 16.574375 20.057594 16.718094 20.130859 16.871094 20.130859 L 16.886719 20.130859 C 17.751719 20.103859 21.5465 19.463531 22.9375 17.019531 C 22.9785 16.947531 23 16.866203 23 16.783203 C 23 12.073203 20.984172 6.624875 19.951172 5.671875 C 18.047172 4.140875 15.036203 3.8820937 14.908203 3.8710938 C 14.895203 3.8700938 14.880188 3.8691406 14.867188 3.8691406 C 14.681188 3.8691406 14.510594 3.9793906 14.433594 4.1503906 C 14.427594 4.1623906 14.362062 4.3138281 14.289062 4.5488281 C 15.548063 4.7608281 17.094141 5.1895937 18.494141 6.0585938 C 18.718141 6.1975938 18.787437 6.4917969 18.648438 6.7167969 C 18.558438 6.8627969 18.402188 6.9433594 18.242188 6.9433594 C 18.156188 6.9433594 18.069234 6.9200937 17.990234 6.8710938 C 15.584234 5.3800938 12.578 5.3046875 12 5.3046875 C 11.422 5.3046875 8.4157187 5.3810469 6.0117188 6.8730469 C 5.9327188 6.9210469 5.8457656 6.9433594 5.7597656 6.9433594 C 5.5997656 6.9433594 5.4425625 6.86475 5.3515625 6.71875 C 5.2115625 6.49375 5.2818594 6.1985938 5.5058594 6.0585938 C 6.9058594 5.1905937 8.4528906 4.7627812 9.7128906 4.5507812 C 9.6388906 4.3147813 9.5714062 4.1643437 9.5664062 4.1523438 C 9.4894063 3.9813438 9.3217188 3.8691406 9.1367188 3.8691406 z M 12 7.3046875 C 12.296 7.3046875 14.950594 7.3403125 16.933594 8.5703125 C 17.326594 8.8143125 17.777234 8.9453125 18.240234 8.9453125 C 18.633234 8.9453125 19.010656 8.8555 19.347656 8.6875 C 19.964656 10.2405 20.690828 12.686219 20.923828 15.199219 C 20.883828 15.143219 20.840922 15.089109 20.794922 15.037109 C 20.324922 14.498109 19.644687 14.191406 18.929688 14.191406 C 18.332687 14.191406 17.754078 14.405437 17.330078 14.773438 C 17.257078 14.832437 15.505 16.21875 12 16.21875 C 8.496 16.21875 6.7450313 14.834687 6.7070312 14.804688 C 6.2540312 14.407687 5.6742656 14.189453 5.0722656 14.189453 C 4.3612656 14.189453 3.6838438 14.494391 3.2148438 15.025391 C 3.1658438 15.080391 3.1201719 15.138266 3.0761719 15.197266 C 3.3091719 12.686266 4.0344375 10.235594 4.6484375 8.6835938 C 4.9864375 8.8525938 5.3657656 8.9433594 5.7597656 8.9433594 C 6.2217656 8.9433594 6.6724531 8.8143125 7.0644531 8.5703125 C 9.0494531 7.3393125 11.704 7.3046875 12 7.3046875 z M 8.890625 10.044922 C 7.966625 10.044922 7.2167969 10.901031 7.2167969 11.957031 C 7.2167969 13.013031 7.965625 13.869141 8.890625 13.869141 C 9.815625 13.869141 10.564453 13.013031 10.564453 11.957031 C 10.564453 10.900031 9.815625 10.044922 8.890625 10.044922 z M 15.109375 10.044922 C 14.185375 10.044922 13.435547 10.901031 13.435547 11.957031 C 13.435547 13.013031 14.184375 13.869141 15.109375 13.869141 C 16.034375 13.869141 16.783203 13.013031 16.783203 11.957031 C 16.783203 10.900031 16.033375 10.044922 15.109375 10.044922 z';
diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css
index 5ee7bf7393e57..f693ce701b3ab 100644
--- a/docs/src/css/custom.css
+++ b/docs/src/css/custom.css
@@ -7,11 +7,12 @@
@tailwind components;
@tailwind utilities;
-@import url('https://fonts.googleapis.com/css2?family=Overpass:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap');
+@import url('https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
html,
button {
- font-family: 'Overpass', sans-serif;
+ font-family: 'Be Vietnam Pro', sans-serif;
+ font-optical-sizing: auto;
}
img {
@@ -27,7 +28,6 @@ img {
--ifm-color-primary-light: #4250af;
--ifm-color-primary-lighter: #4250af;
--ifm-color-primary-lightest: #4250af;
- --ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
@@ -40,10 +40,28 @@ img {
--ifm-color-primary-light: #d5e4fc;
--ifm-color-primary-lighter: #e9f1fe;
--ifm-color-primary-lightest: #ffffff;
- --ifm-background-color: #000000;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
+ --ifm-background-color: #000000;
}
div[class^='announcementBar_'] {
min-height: 2rem;
+ background-color: #2b3336;
+ color: white;
+}
+
+.menu__link {
+ padding: 10px;
+ padding-left: 16px;
+ border-radius: 10px;
+ font-size: 15px;
+}
+
+.menu__list-item-collapsible {
+ border-radius: 10px;
+ font-size: 15px;
+}
+
+code {
+ font-weight: 600;
}
diff --git a/docs/src/pages/cursed-knowledge.tsx b/docs/src/pages/cursed-knowledge.tsx
index 638868bec5324..1e5c724d16678 100644
--- a/docs/src/pages/cursed-knowledge.tsx
+++ b/docs/src/pages/cursed-knowledge.tsx
@@ -1,22 +1,39 @@
import {
+ mdiBug,
mdiCalendarToday,
mdiCrosshairsOff,
+ mdiDatabase,
mdiLeadPencil,
mdiLockOff,
mdiLockOutline,
+ mdiMicrosoftWindows,
+ mdiSecurity,
mdiSpeedometerSlow,
+ mdiTrashCan,
mdiWeb,
mdiWrap,
} from '@mdi/js';
import Layout from '@theme/Layout';
import React from 'react';
-import { Item as TimelineItem, Timeline } from '../components/timeline';
+import { Timeline, Item as TimelineItem } from '../components/timeline';
const withLanguage = (date: Date) => (language: string) => date.toLocaleDateString(language);
type Item = Omit & { date: Date };
const items: Item[] = [
+ {
+ icon: mdiMicrosoftWindows,
+ iconColor: '#357EC7',
+ title: 'Hidden files in Windows are cursed',
+ description:
+ 'Hidden files in Windows cannot be opened with the "w" flag. That, combined with SMB option "hide dot files" leads to a lot of confusion.',
+ link: {
+ url: 'https://github.com/immich-app/immich/pull/12812',
+ text: '#12812',
+ },
+ date: new Date(2024, 8, 20),
+ },
{
icon: mdiWrap,
iconColor: 'gray',
@@ -96,6 +113,51 @@ const items: Item[] = [
link: { url: 'https://github.com/immich-app/immich/pull/6787', text: '#6787' },
date: new Date(2024, 0, 31),
},
+ {
+ icon: mdiBug,
+ iconColor: 'green',
+ title: 'ESM imports are cursed',
+ description:
+ 'Prior to Node.js v20.8 using --experimental-vm-modules in a CommonJS project that imported an ES module that imported a CommonJS modules would create a segfault and crash Node.js',
+ link: {
+ url: 'https://github.com/immich-app/immich/pull/6719',
+ text: '#6179',
+ },
+ date: new Date(2024, 0, 9),
+ },
+ {
+ icon: mdiDatabase,
+ iconColor: 'gray',
+ title: 'PostgreSQL parameters are cursed',
+ description: `PostgresSQL has a limit of ${Number(65535).toLocaleString()} parameters, so bulk inserts can fail with large datasets.`,
+ link: {
+ url: 'https://github.com/immich-app/immich/pull/6034',
+ text: '#6034',
+ },
+ date: new Date(2023, 11, 28),
+ },
+ {
+ icon: mdiSecurity,
+ iconColor: 'gold',
+ title: 'Secure contexts are cursed',
+ description: `Some web features like the clipboard API only work in "secure contexts" (ie. https or localhost)`,
+ link: {
+ url: 'https://github.com/immich-app/immich/issues/2981',
+ text: '#2981',
+ },
+ date: new Date(2023, 5, 26),
+ },
+ {
+ icon: mdiTrashCan,
+ iconColor: 'gray',
+ title: 'TypeORM deletes are cursed',
+ description: `The remove implementation in TypeORM mutates the input, deleting the id property from the original object.`,
+ link: {
+ url: 'https://github.com/typeorm/typeorm/issues/7024#issuecomment-948519328',
+ text: 'typeorm#6034',
+ },
+ date: new Date(2023, 1, 23),
+ },
];
export default function CursedKnowledgePage(): JSX.Element {
diff --git a/docs/src/pages/index.tsx b/docs/src/pages/index.tsx
index a375efb8a8590..a5dbc7aa98c6b 100644
--- a/docs/src/pages/index.tsx
+++ b/docs/src/pages/index.tsx
@@ -2,46 +2,82 @@ import React from 'react';
import Link from '@docusaurus/Link';
import Layout from '@theme/Layout';
import { useColorMode } from '@docusaurus/theme-common';
+import { discordPath } from '@site/src/components/svg-paths';
+import Icon from '@mdi/react';
function HomepageHeader() {
const { isDarkTheme } = useColorMode();
return (
-
+
+
+
+
+
-
-
- Self-hosted photo and
- video management solution
+
+
+ Self-hosted{' '}
+
+ photo and
+ video management{' '}
+
+ solution
+
+
+
+ Easily back up, organize, and manage your photos on your own server. Immich helps you
+ browse, search and organize your photos and videos with ease, without
+ sacrificing your privacy.
-
+
+
Get started
- Demo portal
+ Demo
+
-
- Discord
-
+
+
+ Join our Discord
+
+
+
+
+
+
+
+
+
+
+
Download mobile app
+
+ Download Immich app and start backing up your photos and videos securely to your own server
+