diff --git a/.gitattributes b/.gitattributes
index 2e8a45ca5c3..3d43ff20ed9 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -9,6 +9,9 @@ mobile/lib/**/*.g.dart linguist-generated=true
mobile/lib/**/*.drift.dart -diff -merge
mobile/lib/**/*.drift.dart linguist-generated=true
+mobile/drift_schemas/main/drift_schema_*.json -diff -merge
+mobile/drift_schemas/main/drift_schema_*.json linguist-generated=true
+
open-api/typescript-sdk/fetch-client.ts -diff -merge
open-api/typescript-sdk/fetch-client.ts linguist-generated=true
diff --git a/.github/actions/image-build/action.yml b/.github/actions/image-build/action.yml
deleted file mode 100644
index a4168dcd5a7..00000000000
--- a/.github/actions/image-build/action.yml
+++ /dev/null
@@ -1,118 +0,0 @@
-name: 'Single arch image build'
-description: 'Build single-arch image on platform appropriate runner'
-inputs:
- image:
- description: 'Name of the image to build'
- required: true
- ghcr-token:
- description: 'GitHub Container Registry token'
- required: true
- platform:
- description: 'Platform to build for'
- required: true
- artifact-key-base:
- description: 'Base key for artifact name'
- required: true
- context:
- description: 'Path to build context'
- required: true
- dockerfile:
- description: 'Path to Dockerfile'
- required: true
- build-args:
- description: 'Docker build arguments'
- required: false
-runs:
- using: 'composite'
- steps:
- - name: Prepare
- id: prepare
- shell: bash
- env:
- PLATFORM: ${{ inputs.platform }}
- run: |
- echo "platform-pair=${PLATFORM//\//-}" >> $GITHUB_OUTPUT
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
-
- - name: Login to GitHub Container Registry
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
- if: ${{ !github.event.pull_request.head.repo.fork }}
- with:
- registry: ghcr.io
- username: ${{ github.repository_owner }}
- password: ${{ inputs.ghcr-token }}
-
- - name: Generate cache key suffix
- id: cache-key-suffix
- shell: bash
- env:
- REF: ${{ github.ref_name }}
- run: |
- if [[ "${{ github.event_name }}" == "pull_request" ]]; then
- echo "cache-key-suffix=pr-${{ github.event.number }}" >> $GITHUB_OUTPUT
- else
- SUFFIX=$(echo "${REF}" | sed 's/[^a-zA-Z0-9]/-/g')
- echo "suffix=${SUFFIX}" >> $GITHUB_OUTPUT
- fi
-
- - name: Generate cache target
- id: cache-target
- shell: bash
- env:
- BUILD_ARGS: ${{ inputs.build-args }}
- IMAGE: ${{ inputs.image }}
- SUFFIX: ${{ steps.cache-key-suffix.outputs.suffix }}
- PLATFORM_PAIR: ${{ steps.prepare.outputs.platform-pair }}
- run: |
- HASH=$(sha256sum <<< "${BUILD_ARGS}" | cut -d' ' -f1)
- CACHE_KEY="${PLATFORM_PAIR}-${HASH}"
- echo "cache-key-base=${CACHE_KEY}" >> $GITHUB_OUTPUT
- if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" ]]; then
- # Essentially just ignore the cache output (forks can't write to registry cache)
- echo "cache-to=type=local,dest=/tmp/discard,ignore-error=true" >> $GITHUB_OUTPUT
- else
- echo "cache-to=type=registry,ref=${IMAGE}-build-cache:${CACHE_KEY}-${SUFFIX},mode=max,compression=zstd" >> $GITHUB_OUTPUT
- fi
-
- - name: Generate docker image tags
- id: meta
- uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5
- env:
- DOCKER_METADATA_PR_HEAD_SHA: 'true'
-
- - name: Build and push image
- id: build
- uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
- with:
- context: ${{ inputs.context }}
- file: ${{ inputs.dockerfile }}
- platforms: ${{ inputs.platform }}
- labels: ${{ steps.meta.outputs.labels }}
- cache-to: ${{ steps.cache-target.outputs.cache-to }}
- cache-from: |
- type=registry,ref=${{ inputs.image }}-build-cache:${{ steps.cache-target.outputs.cache-key-base }}-${{ steps.cache-key-suffix.outputs.suffix }}
- type=registry,ref=${{ inputs.image }}-build-cache:${{ steps.cache-target.outputs.cache-key-base }}-main
- outputs: type=image,"name=${{ inputs.image }}",push-by-digest=true,name-canonical=true,push=${{ !github.event.pull_request.head.repo.fork }}
- build-args: |
- BUILD_ID=${{ github.run_id }}
- BUILD_IMAGE=${{ github.event_name == 'release' && github.ref_name || steps.meta.outputs.tags }}
- BUILD_SOURCE_REF=${{ github.ref_name }}
- BUILD_SOURCE_COMMIT=${{ github.sha }}
- ${{ inputs.build-args }}
-
- - name: Export digest
- shell: bash
- run: | # zizmor: ignore[template-injection]
- mkdir -p ${{ runner.temp }}/digests
- digest="${{ steps.build.outputs.digest }}"
- touch "${{ runner.temp }}/digests/${digest#sha256:}"
-
- - name: Upload digest
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- with:
- name: ${{ inputs.artifact-key-base }}-${{ steps.cache-target.outputs.cache-key-base }}
- path: ${{ runner.temp }}/digests/*
- if-no-files-found: error
- retention-days: 1
diff --git a/.github/workflows/build-mobile.yml b/.github/workflows/build-mobile.yml
index 0fcc4f1d7c9..33912d687cb 100644
--- a/.github/workflows/build-mobile.yml
+++ b/.github/workflows/build-mobile.yml
@@ -93,6 +93,10 @@ jobs:
run: make translation
working-directory: ./mobile
+ - name: Generate platform APIs
+ run: make pigeon
+ working-directory: ./mobile
+
- name: Build Android App Bundle
working-directory: ./mobile
env:
diff --git a/.github/workflows/multi-runner-build.yml b/.github/workflows/multi-runner-build.yml
deleted file mode 100644
index f6d7c123552..00000000000
--- a/.github/workflows/multi-runner-build.yml
+++ /dev/null
@@ -1,185 +0,0 @@
-name: 'Multi-runner container image build'
-on:
- workflow_call:
- inputs:
- image:
- description: 'Name of the image'
- type: string
- required: true
- context:
- description: 'Path to build context'
- type: string
- required: true
- dockerfile:
- description: 'Path to Dockerfile'
- type: string
- required: true
- tag-suffix:
- description: 'Suffix to append to the image tag'
- type: string
- default: ''
- dockerhub-push:
- description: 'Push to Docker Hub'
- type: boolean
- default: false
- build-args:
- description: 'Docker build arguments'
- type: string
- required: false
- platforms:
- description: 'Platforms to build for'
- type: string
- runner-mapping:
- description: 'Mapping from platforms to runners'
- type: string
- secrets:
- DOCKERHUB_USERNAME:
- required: false
- DOCKERHUB_TOKEN:
- required: false
-
-env:
- GHCR_IMAGE: ghcr.io/${{ github.repository_owner }}/${{ inputs.image }}
- DOCKERHUB_IMAGE: altran1502/${{ inputs.image }}
-
-jobs:
- matrix:
- name: 'Generate matrix'
- runs-on: ubuntu-latest
- outputs:
- matrix: ${{ steps.matrix.outputs.matrix }}
- key: ${{ steps.artifact-key.outputs.base }}
- steps:
- - name: Generate build matrix
- id: matrix
- shell: bash
- env:
- PLATFORMS: ${{ inputs.platforms || 'linux/amd64,linux/arm64' }}
- RUNNER_MAPPING: ${{ inputs.runner-mapping || '{"linux/amd64":"ubuntu-latest","linux/arm64":"ubuntu-24.04-arm"}' }}
- run: |
- matrix=$(jq -R -c \
- --argjson runner_mapping "${RUNNER_MAPPING}" \
- 'split(",") | map({platform: ., runner: $runner_mapping[.]})' \
- <<< "${PLATFORMS}")
- echo "${matrix}"
- echo "matrix=${matrix}" >> $GITHUB_OUTPUT
-
- - name: Determine artifact key
- id: artifact-key
- shell: bash
- env:
- IMAGE: ${{ inputs.image }}
- SUFFIX: ${{ inputs.tag-suffix }}
- run: |
- if [[ -n "${SUFFIX}" ]]; then
- base="${IMAGE}${SUFFIX}-digests"
- else
- base="${IMAGE}-digests"
- fi
- echo "${base}"
- echo "base=${base}" >> $GITHUB_OUTPUT
-
- build:
- needs: matrix
- runs-on: ${{ matrix.runner }}
- permissions:
- contents: read
- packages: write
- strategy:
- fail-fast: false
- matrix:
- include: ${{ fromJson(needs.matrix.outputs.matrix) }}
- steps:
- - name: Checkout
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- with:
- persist-credentials: false
-
- - uses: ./.github/actions/image-build
- with:
- context: ${{ inputs.context }}
- dockerfile: ${{ inputs.dockerfile }}
- image: ${{ env.GHCR_IMAGE }}
- ghcr-token: ${{ secrets.GITHUB_TOKEN }}
- platform: ${{ matrix.platform }}
- artifact-key-base: ${{ needs.matrix.outputs.key }}
- build-args: ${{ inputs.build-args }}
-
- merge:
- needs: [matrix, build]
- runs-on: ubuntu-latest
- if: ${{ !github.event.pull_request.head.repo.fork }}
- permissions:
- contents: read
- actions: read
- packages: write
- steps:
- - name: Download digests
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
- with:
- path: ${{ runner.temp }}/digests
- pattern: ${{ needs.matrix.outputs.key }}-*
- merge-multiple: true
-
- - name: Login to Docker Hub
- if: ${{ inputs.dockerhub-push }}
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
-
- - name: Login to GHCR
- uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3
- with:
- registry: ghcr.io
- username: ${{ github.repository_owner }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
-
- - name: Generate docker image tags
- id: meta
- uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5
- env:
- DOCKER_METADATA_PR_HEAD_SHA: 'true'
- with:
- flavor: |
- # Disable latest tag
- latest=false
- suffix=${{ inputs.tag-suffix }}
- images: |
- name=${{ env.GHCR_IMAGE }}
- name=${{ env.DOCKERHUB_IMAGE }},enable=${{ inputs.dockerhub-push }}
- tags: |
- # Tag with branch name
- type=ref,event=branch
- # Tag with pr-number
- type=ref,event=pr
- # Tag with long commit sha hash
- type=sha,format=long,prefix=commit-
- # Tag with git tag on release
- type=ref,event=tag
- type=raw,value=release,enable=${{ github.event_name == 'release' }}
-
- - name: Create manifest list and push
- working-directory: ${{ runner.temp }}/digests
- run: |
- # Process annotations
- declare -a ANNOTATIONS=()
- if [[ -n "$DOCKER_METADATA_OUTPUT_JSON" ]]; then
- while IFS= read -r annotation; do
- # Extract key and value by removing the manifest: prefix
- if [[ "$annotation" =~ ^manifest:(.+)=(.+)$ ]]; then
- key="${BASH_REMATCH[1]}"
- value="${BASH_REMATCH[2]}"
- # Use array to properly handle arguments with spaces
- ANNOTATIONS+=(--annotation "index:$key=$value")
- fi
- done < <(jq -r '.annotations[]' <<< "$DOCKER_METADATA_OUTPUT_JSON")
- fi
-
- TAGS=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
- SOURCE_ARGS=$(printf "${GHCR_IMAGE}@sha256:%s " *)
-
- docker buildx imagetools create $TAGS "${ANNOTATIONS[@]}" $SOURCE_ARGS
diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml
index 7cd28228dc2..754c0c38b31 100644
--- a/.github/workflows/static_analysis.yml
+++ b/.github/workflows/static_analysis.yml
@@ -59,13 +59,17 @@ jobs:
working-directory: ./mobile
- name: Generate translation file
- run: make translation; dart format lib/generated/codegen_loader.g.dart
+ run: make translation
working-directory: ./mobile
- name: Run Build Runner
run: make build
working-directory: ./mobile
+ - name: Generate platform API
+ run: make pigeon
+ working-directory: ./mobile
+
- name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-files
diff --git a/cli/package-lock.json b/cli/package-lock.json
index 5373f3cdd15..9464f866630 100644
--- a/cli/package-lock.json
+++ b/cli/package-lock.json
@@ -1370,17 +1370,17 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz",
- "integrity": "sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.0.tgz",
+ "integrity": "sha512-CACyQuqSHt7ma3Ns601xykeBK/rDeZa3w6IS6UtMQbixO5DWy+8TilKkviGDH6jtWCo8FGRKEK5cLLkPvEammQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.32.1",
- "@typescript-eslint/type-utils": "8.32.1",
- "@typescript-eslint/utils": "8.32.1",
- "@typescript-eslint/visitor-keys": "8.32.1",
+ "@typescript-eslint/scope-manager": "8.33.0",
+ "@typescript-eslint/type-utils": "8.33.0",
+ "@typescript-eslint/utils": "8.33.0",
+ "@typescript-eslint/visitor-keys": "8.33.0",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@@ -1394,7 +1394,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+ "@typescript-eslint/parser": "^8.33.0",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
@@ -1410,16 +1410,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz",
- "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.0.tgz",
+ "integrity": "sha512-JaehZvf6m0yqYp34+RVnihBAChkqeH+tqqhS0GuX1qgPpwLvmTPheKEs6OeCK6hVJgXZHJ2vbjnC9j119auStQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.32.1",
- "@typescript-eslint/types": "8.32.1",
- "@typescript-eslint/typescript-estree": "8.32.1",
- "@typescript-eslint/visitor-keys": "8.32.1",
+ "@typescript-eslint/scope-manager": "8.33.0",
+ "@typescript-eslint/types": "8.33.0",
+ "@typescript-eslint/typescript-estree": "8.33.0",
+ "@typescript-eslint/visitor-keys": "8.33.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1434,15 +1434,16 @@
"typescript": ">=4.8.4 <5.9.0"
}
},
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz",
- "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==",
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.0.tgz",
+ "integrity": "sha512-d1hz0u9l6N+u/gcrk6s6gYdl7/+pp8yHheRTqP6X5hVDKALEaTn8WfGiit7G511yueBEL3OpOEpD+3/MBdoN+A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.32.1",
- "@typescript-eslint/visitor-keys": "8.32.1"
+ "@typescript-eslint/tsconfig-utils": "^8.33.0",
+ "@typescript-eslint/types": "^8.33.0",
+ "debug": "^4.3.4"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1452,15 +1453,50 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/@typescript-eslint/type-utils": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz",
- "integrity": "sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==",
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.0.tgz",
+ "integrity": "sha512-LMi/oqrzpqxyO72ltP+dBSP6V0xiUb4saY7WLtxSfiNEBI8m321LLVFU9/QDJxjDQG9/tjSqKz/E3380TEqSTw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "8.32.1",
- "@typescript-eslint/utils": "8.32.1",
+ "@typescript-eslint/types": "8.33.0",
+ "@typescript-eslint/visitor-keys": "8.33.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.0.tgz",
+ "integrity": "sha512-sTkETlbqhEoiFmGr1gsdq5HyVbSOF0145SYDJ/EQmXHtKViCaGvnyLqWFFHtEXoS0J1yU8Wyou2UGmgW88fEug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.0.tgz",
+ "integrity": "sha512-lScnHNCBqL1QayuSrWeqAL5GmqNdVUQAAMTaCwdYEdWfIrSrOGzyLGRCHXcCixa5NK6i5l0AfSO2oBSjCjf4XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "8.33.0",
+ "@typescript-eslint/utils": "8.33.0",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
},
@@ -1477,9 +1513,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.1.tgz",
- "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.0.tgz",
+ "integrity": "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1491,14 +1527,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz",
- "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.0.tgz",
+ "integrity": "sha512-vegY4FQoB6jL97Tu/lWRsAiUUp8qJTqzAmENH2k59SJhw0Th1oszb9Idq/FyyONLuNqT1OADJPXfyUNOR8SzAQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.32.1",
- "@typescript-eslint/visitor-keys": "8.32.1",
+ "@typescript-eslint/project-service": "8.33.0",
+ "@typescript-eslint/tsconfig-utils": "8.33.0",
+ "@typescript-eslint/types": "8.33.0",
+ "@typescript-eslint/visitor-keys": "8.33.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -1544,16 +1582,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.1.tgz",
- "integrity": "sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.0.tgz",
+ "integrity": "sha512-lPFuQaLA9aSNa7D5u2EpRiqdAUhzShwGg/nhpBlc4GR6kcTABttCuyjFs8BcEZ8VWrjCBof/bePhP3Q3fS+Yrw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
- "@typescript-eslint/scope-manager": "8.32.1",
- "@typescript-eslint/types": "8.32.1",
- "@typescript-eslint/typescript-estree": "8.32.1"
+ "@typescript-eslint/scope-manager": "8.33.0",
+ "@typescript-eslint/types": "8.33.0",
+ "@typescript-eslint/typescript-estree": "8.33.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1568,13 +1606,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz",
- "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.0.tgz",
+ "integrity": "sha512-7RW7CMYoskiz5OOGAWjJFxgb7c5UNjTG292gYhWeOAcFmYCtVCSqjqSBj5zMhxbXo2JOW95YYrUWJfU0zrpaGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.32.1",
+ "@typescript-eslint/types": "8.33.0",
"eslint-visitor-keys": "^4.2.0"
},
"engines": {
@@ -2756,9 +2794,9 @@
}
},
"node_modules/globals": {
- "version": "16.1.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-16.1.0.tgz",
- "integrity": "sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==",
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.2.0.tgz",
+ "integrity": "sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4200,15 +4238,15 @@
}
},
"node_modules/typescript-eslint": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.32.1.tgz",
- "integrity": "sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.33.0.tgz",
+ "integrity": "sha512-5YmNhF24ylCsvdNW2oJwMzTbaeO4bg90KeGtMjUw0AGtHksgEPLRTUil+coHwCfiu4QjVJFnjp94DmU6zV7DhQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/eslint-plugin": "8.32.1",
- "@typescript-eslint/parser": "8.32.1",
- "@typescript-eslint/utils": "8.32.1"
+ "@typescript-eslint/eslint-plugin": "8.33.0",
+ "@typescript-eslint/parser": "8.33.0",
+ "@typescript-eslint/utils": "8.33.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
diff --git a/cli/src/commands/asset.ts b/cli/src/commands/asset.ts
index d06b30e984e..edb24e2f671 100644
--- a/cli/src/commands/asset.ts
+++ b/cli/src/commands/asset.ts
@@ -43,6 +43,7 @@ export interface UploadOptionsDto {
concurrency: number;
progress?: boolean;
watch?: boolean;
+ jsonOutput?: boolean;
}
class UploadFile extends File {
@@ -65,6 +66,9 @@ class UploadFile extends File {
const uploadBatch = async (files: string[], options: UploadOptionsDto) => {
const { newFiles, duplicates } = await checkForDuplicates(files, options);
const newAssets = await uploadFiles(newFiles, options);
+ if (options.jsonOutput) {
+ console.log(JSON.stringify({ newFiles, duplicates, newAssets }, undefined, 4));
+ }
await updateAlbums([...newAssets, ...duplicates], options);
await deleteFiles(newFiles, options);
};
diff --git a/cli/src/index.ts b/cli/src/index.ts
index 5da4b50722b..a0392186c09 100644
--- a/cli/src/index.ts
+++ b/cli/src/index.ts
@@ -68,6 +68,11 @@ program
.env('IMMICH_UPLOAD_CONCURRENCY')
.default(4),
)
+ .addOption(
+ new Option('-j, --json-output', 'Output detailed information in json format')
+ .env('IMMICH_JSON_OUTPUT')
+ .default(false),
+ )
.addOption(new Option('--delete', 'Delete local assets after upload').env('IMMICH_DELETE_ASSETS'))
.addOption(new Option('--no-progress', 'Hide progress bars').env('IMMICH_PROGRESS_BAR').default(true))
.addOption(
diff --git a/docs/docs/administration/backup-and-restore.md b/docs/docs/administration/backup-and-restore.md
index 7e55e4e88ff..7b90c3b19ab 100644
--- a/docs/docs/administration/backup-and-restore.md
+++ b/docs/docs/administration/backup-and-restore.md
@@ -219,3 +219,10 @@ When you turn off the storage template engine, it will leave the assets in `UPLO
Do not touch the files inside these folders under any circumstances except taking a backup. Changing or removing an asset can cause untracked and missing files.
You can think of it as App-Which-Must-Not-Be-Named, the only access to viewing, changing and deleting assets is only through the mobile or browser interface.
:::
+
+## Backup ordering
+
+A backup of Immich should contain both the database and the asset files. When backing these up it's possible for them to get out of sync, potentially resulting in broken assets after you restore.
+The best way of dealing with this is to stop the immich-server container while you take a backup. If nothing is changing then the backup will always be in sync.
+
+If stopping the container is not an option, then the recommended order is to back up the database first, and the filesystem second. This way, the worst case scenario is that there are files on the filesystem that the database doesn't know about. If necessary, these can be (re)uploaded manually after a restore. If the backup is done the other way around, with the filesystem first and the database second, it's possible for the restored database to reference files that aren't in the filesystem backup, thus resulting in broken assets.
diff --git a/docs/docs/administration/oauth.md b/docs/docs/administration/oauth.md
index 2dc69909446..b60b5dbb8bf 100644
--- a/docs/docs/administration/oauth.md
+++ b/docs/docs/administration/oauth.md
@@ -93,6 +93,7 @@ The `.well-known/openid-configuration` part of the url is optional and will be a
## Auto Launch
When Auto Launch is enabled, the login page will automatically redirect the user to the OAuth authorization url, to login with OAuth. To access the login screen again, use the browser's back button, or navigate directly to `/auth/login?autoLaunch=0`.
+Auto Launch can also be enabled on a per-request basis by navigating to `/auth/login?authLaunch=1`, this can be useful in situations where Immich is called from e.g. Nextcloud using the _External sites_ app and the _oidc_ app so as to enable users to directly interact with a logged-in instance of Immich.
## Mobile Redirect URI
diff --git a/docs/docs/features/casting.md b/docs/docs/features/casting.md
index cc25e24da76..bca85cb28ce 100644
--- a/docs/docs/features/casting.md
+++ b/docs/docs/features/casting.md
@@ -2,6 +2,14 @@
Immich supports the Google's Cast protocol so that photos and videos can be cast to devices such as a Chromecast and a Nest Hub. This feature is considered experimental and has several important limitations listed below. Currently, this feature is only supported by the web client, support on Android and iOS is planned for the future.
+## Enable Google Cast Support
+
+Google Cast support is disabled by default. The web UI uses Google-provided scripts and must retreive them from Google servers when the page loads. This is a privacy concern for some and is thus opt-in.
+
+You can enable Google Cast support through `Account Settings > Features > Cast > Google Cast`
+
+
+
## Limitations
To use casting with Immich, there are a few prerequisites:
diff --git a/docs/docs/features/command-line-interface.md b/docs/docs/features/command-line-interface.md
index 1ab79ee3f19..436b499e505 100644
--- a/docs/docs/features/command-line-interface.md
+++ b/docs/docs/features/command-line-interface.md
@@ -90,19 +90,22 @@ Usage: immich upload [paths...] [options]
Upload assets
Arguments:
-paths One or more paths to assets to be uploaded
+ paths One or more paths to assets to be uploaded
Options:
--r, --recursive Recursive (default: false, env: IMMICH_RECURSIVE)
--i, --ignore [paths...] Paths to ignore (default: [], env: IMMICH_IGNORE_PATHS)
--h, --skip-hash Don't hash files before upload (default: false, env: IMMICH_SKIP_HASH)
--H, --include-hidden Include hidden folders (default: false, env: IMMICH_INCLUDE_HIDDEN)
--a, --album Automatically create albums based on folder name (default: false, env: IMMICH_AUTO_CREATE_ALBUM)
--A, --album-name Add all assets to specified album (env: IMMICH_ALBUM_NAME)
--n, --dry-run Don't perform any actions, just show what will be done (default: false, env: IMMICH_DRY_RUN)
--c, --concurrency Number of assets to upload at the same time (default: 4, env: IMMICH_UPLOAD_CONCURRENCY)
---delete Delete local assets after upload (env: IMMICH_DELETE_ASSETS)
---help display help for command
+ -r, --recursive Recursive (default: false, env: IMMICH_RECURSIVE)
+ -i, --ignore Pattern to ignore (env: IMMICH_IGNORE_PATHS)
+ -h, --skip-hash Don't hash files before upload (default: false, env: IMMICH_SKIP_HASH)
+ -H, --include-hidden Include hidden folders (default: false, env: IMMICH_INCLUDE_HIDDEN)
+ -a, --album Automatically create albums based on folder name (default: false, env: IMMICH_AUTO_CREATE_ALBUM)
+ -A, --album-name Add all assets to specified album (env: IMMICH_ALBUM_NAME)
+ -n, --dry-run Don't perform any actions, just show what will be done (default: false, env: IMMICH_DRY_RUN)
+ -c, --concurrency Number of assets to upload at the same time (default: 4, env: IMMICH_UPLOAD_CONCURRENCY)
+ -j, --json-output Output detailed information in json format (default: false, env: IMMICH_JSON_OUTPUT)
+ --delete Delete local assets after upload (env: IMMICH_DELETE_ASSETS)
+ --no-progress Hide progress bars (env: IMMICH_PROGRESS_BAR)
+ --watch Watch for changes and upload automatically (default: false, env: IMMICH_WATCH_CHANGES)
+ --help display help for command
```
@@ -172,6 +175,16 @@ By default, hidden files are skipped. If you want to include hidden files, use t
immich upload --include-hidden --recursive directory/
```
+You can use the `--json-output` option to get a json printed which includes
+three keys: `newFiles`, `duplicates` and `newAssets`. Due to some logging
+output you will need to strip the first three lines of output to get the json.
+For example to get a list of files that would be uploaded for further
+processing:
+
+```bash
+immich upload --dry-run . | tail -n +4 | jq .newFiles[]
+```
+
### Obtain the API Key
The API key can be obtained in the user setting panel on the web interface.
diff --git a/docs/docs/features/img/gcast-enable.webp b/docs/docs/features/img/gcast-enable.webp
new file mode 100644
index 00000000000..f128b82e25c
Binary files /dev/null and b/docs/docs/features/img/gcast-enable.webp differ
diff --git a/docs/package-lock.json b/docs/package-lock.json
index 602232da074..ce1ba4cd9d1 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -8,8 +8,8 @@
"name": "documentation",
"version": "0.0.0",
"dependencies": {
- "@docusaurus/core": "~3.7.0",
- "@docusaurus/preset-classic": "~3.7.0",
+ "@docusaurus/core": "~3.8.0",
+ "@docusaurus/preset-classic": "~3.8.0",
"@mdi/js": "^7.3.67",
"@mdi/react": "^1.6.1",
"@mdx-js/react": "^3.0.0",
@@ -27,7 +27,7 @@
"url": "^0.11.0"
},
"devDependencies": {
- "@docusaurus/module-type-aliases": "~3.7.0",
+ "@docusaurus/module-type-aliases": "~3.8.0",
"@docusaurus/tsconfig": "^3.7.0",
"@docusaurus/types": "^3.7.0",
"prettier": "^3.2.4",
@@ -3128,9 +3128,9 @@
}
},
"node_modules/@docusaurus/babel": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.7.0.tgz",
- "integrity": "sha512-0H5uoJLm14S/oKV3Keihxvh8RV+vrid+6Gv+2qhuzbqHanawga8tYnsdpjEyt36ucJjqlby2/Md2ObWjA02UXQ==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.8.0.tgz",
+ "integrity": "sha512-9EJwSgS6TgB8IzGk1L8XddJLhZod8fXT4ULYMx6SKqyCBqCFpVCEjR/hNXXhnmtVM2irDuzYoVLGWv7srG/VOA==",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.25.9",
@@ -3143,8 +3143,8 @@
"@babel/runtime": "^7.25.9",
"@babel/runtime-corejs3": "^7.25.9",
"@babel/traverse": "^7.25.9",
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/utils": "3.7.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
"babel-plugin-dynamic-import-node": "^2.3.3",
"fs-extra": "^11.1.1",
"tslib": "^2.6.0"
@@ -3154,17 +3154,17 @@
}
},
"node_modules/@docusaurus/bundler": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.7.0.tgz",
- "integrity": "sha512-CUUT9VlSGukrCU5ctZucykvgCISivct+cby28wJwCC/fkQFgAHRp/GKv2tx38ZmXb7nacrKzFTcp++f9txUYGg==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.8.0.tgz",
+ "integrity": "sha512-Rq4Z/MSeAHjVzBLirLeMcjLIAQy92pF1OI+2rmt18fSlMARfTGLWRE8Vb+ljQPTOSfJxwDYSzsK6i7XloD2rNA==",
"license": "MIT",
"dependencies": {
"@babel/core": "^7.25.9",
- "@docusaurus/babel": "3.7.0",
- "@docusaurus/cssnano-preset": "3.7.0",
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils": "3.7.0",
+ "@docusaurus/babel": "3.8.0",
+ "@docusaurus/cssnano-preset": "3.8.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
"babel-loader": "^9.2.1",
"clean-css": "^5.3.2",
"copy-webpack-plugin": "^11.0.0",
@@ -3178,7 +3178,6 @@
"postcss": "^8.4.26",
"postcss-loader": "^7.3.3",
"postcss-preset-env": "^10.1.0",
- "react-dev-utils": "^12.0.1",
"terser-webpack-plugin": "^5.3.9",
"tslib": "^2.6.0",
"url-loader": "^4.1.1",
@@ -3198,18 +3197,18 @@
}
},
"node_modules/@docusaurus/core": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.7.0.tgz",
- "integrity": "sha512-b0fUmaL+JbzDIQaamzpAFpTviiaU4cX3Qz8cuo14+HGBCwa0evEK0UYCBFY3n4cLzL8Op1BueeroUD2LYAIHbQ==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.8.0.tgz",
+ "integrity": "sha512-c7u6zFELmSGPEP9WSubhVDjgnpiHgDqMh1qVdCB7rTflh4Jx0msTYmMiO91Ez0KtHj4sIsDsASnjwfJ2IZp3Vw==",
"license": "MIT",
"dependencies": {
- "@docusaurus/babel": "3.7.0",
- "@docusaurus/bundler": "3.7.0",
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/mdx-loader": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-common": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/babel": "3.8.0",
+ "@docusaurus/bundler": "3.8.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/mdx-loader": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-common": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"boxen": "^6.2.1",
"chalk": "^4.1.2",
"chokidar": "^3.5.3",
@@ -3217,19 +3216,19 @@
"combine-promises": "^1.1.0",
"commander": "^5.1.0",
"core-js": "^3.31.1",
- "del": "^6.1.1",
"detect-port": "^1.5.1",
"escape-html": "^1.0.3",
"eta": "^2.2.0",
"eval": "^0.1.8",
+ "execa": "5.1.1",
"fs-extra": "^11.1.1",
"html-tags": "^3.3.1",
"html-webpack-plugin": "^5.6.0",
"leven": "^3.1.0",
"lodash": "^4.17.21",
+ "open": "^8.4.0",
"p-map": "^4.0.0",
"prompts": "^2.4.2",
- "react-dev-utils": "^12.0.1",
"react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
"react-loadable": "npm:@docusaurus/react-loadable@6.0.0",
"react-loadable-ssr-addon-v5-slorber": "^1.0.1",
@@ -3238,7 +3237,7 @@
"react-router-dom": "^5.3.4",
"semver": "^7.5.4",
"serve-handler": "^6.1.6",
- "shelljs": "^0.8.5",
+ "tinypool": "^1.0.2",
"tslib": "^2.6.0",
"update-notifier": "^6.0.2",
"webpack": "^5.95.0",
@@ -3259,9 +3258,9 @@
}
},
"node_modules/@docusaurus/cssnano-preset": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.7.0.tgz",
- "integrity": "sha512-X9GYgruZBSOozg4w4dzv9uOz8oK/EpPVQXkp0MM6Tsgp/nRIU9hJzJ0Pxg1aRa3xCeEQTOimZHcocQFlLwYajQ==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.8.0.tgz",
+ "integrity": "sha512-UJ4hAS2T0R4WNy+phwVff2Q0L5+RXW9cwlH6AEphHR5qw3m/yacfWcSK7ort2pMMbDn8uGrD38BTm4oLkuuNoQ==",
"license": "MIT",
"dependencies": {
"cssnano-preset-advanced": "^6.1.2",
@@ -3274,9 +3273,9 @@
}
},
"node_modules/@docusaurus/logger": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.7.0.tgz",
- "integrity": "sha512-z7g62X7bYxCYmeNNuO9jmzxLQG95q9QxINCwpboVcNff3SJiHJbGrarxxOVMVmAh1MsrSfxWkVGv4P41ktnFsA==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.8.0.tgz",
+ "integrity": "sha512-7eEMaFIam5Q+v8XwGqF/n0ZoCld4hV4eCCgQkfcN9Mq5inoZa6PHHW9Wu6lmgzoK5Kx3keEeABcO2SxwraoPDQ==",
"license": "MIT",
"dependencies": {
"chalk": "^4.1.2",
@@ -3287,21 +3286,21 @@
}
},
"node_modules/@docusaurus/mdx-loader": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.7.0.tgz",
- "integrity": "sha512-OFBG6oMjZzc78/U3WNPSHs2W9ZJ723ewAcvVJaqS0VgyeUfmzUV8f1sv+iUHA0DtwiR5T5FjOxj6nzEE8LY6VA==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.8.0.tgz",
+ "integrity": "sha512-mDPSzssRnpjSdCGuv7z2EIAnPS1MHuZGTaRLwPn4oQwszu4afjWZ/60sfKjTnjBjI8Vl4OgJl2vMmfmiNDX4Ng==",
"license": "MIT",
"dependencies": {
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"@mdx-js/mdx": "^3.0.0",
"@slorber/remark-comment": "^1.0.0",
"escape-html": "^1.0.3",
"estree-util-value-to-estree": "^3.0.1",
"file-loader": "^6.2.0",
"fs-extra": "^11.1.1",
- "image-size": "^1.0.2",
+ "image-size": "^2.0.2",
"mdast-util-mdx": "^3.0.0",
"mdast-util-to-string": "^4.0.0",
"rehype-raw": "^7.0.0",
@@ -3326,17 +3325,17 @@
}
},
"node_modules/@docusaurus/module-type-aliases": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.7.0.tgz",
- "integrity": "sha512-g7WdPqDNaqA60CmBrr0cORTrsOit77hbsTj7xE2l71YhBn79sxdm7WMK7wfhcaafkbpIh7jv5ef5TOpf1Xv9Lg==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.8.0.tgz",
+ "integrity": "sha512-/uMb4Ipt5J/QnD13MpnoC/A4EYAe6DKNWqTWLlGrqsPJwJv73vSwkA25xnYunwfqWk0FlUQfGv/Swdh5eCCg7g==",
"license": "MIT",
"dependencies": {
- "@docusaurus/types": "3.7.0",
+ "@docusaurus/types": "3.8.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"@types/react-router-config": "*",
"@types/react-router-dom": "*",
- "react-helmet-async": "npm:@slorber/react-helmet-async@*",
+ "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0",
"react-loadable": "npm:@docusaurus/react-loadable@6.0.0"
},
"peerDependencies": {
@@ -3345,24 +3344,24 @@
}
},
"node_modules/@docusaurus/plugin-content-blog": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.7.0.tgz",
- "integrity": "sha512-EFLgEz6tGHYWdPU0rK8tSscZwx+AsyuBW/r+tNig2kbccHYGUJmZtYN38GjAa3Fda4NU+6wqUO5kTXQSRBQD3g==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.8.0.tgz",
+ "integrity": "sha512-0SlOTd9R55WEr1GgIXu+hhTT0hzARYx3zIScA5IzpdekZQesI/hKEa5LPHBd415fLkWMjdD59TaW/3qQKpJ0Lg==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/mdx-loader": "3.7.0",
- "@docusaurus/theme-common": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-common": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/mdx-loader": "3.8.0",
+ "@docusaurus/theme-common": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-common": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"cheerio": "1.0.0-rc.12",
"feed": "^4.2.2",
"fs-extra": "^11.1.1",
"lodash": "^4.17.21",
- "reading-time": "^1.5.0",
+ "schema-dts": "^1.1.2",
"srcset": "^4.0.0",
"tslib": "^2.6.0",
"unist-util-visit": "^5.0.0",
@@ -3379,25 +3378,26 @@
}
},
"node_modules/@docusaurus/plugin-content-docs": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.7.0.tgz",
- "integrity": "sha512-GXg5V7kC9FZE4FkUZA8oo/NrlRb06UwuICzI6tcbzj0+TVgjq/mpUXXzSgKzMS82YByi4dY2Q808njcBCyy6tQ==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.8.0.tgz",
+ "integrity": "sha512-fRDMFLbUN6eVRXcjP8s3Y7HpAt9pzPYh1F/7KKXOCxvJhjjCtbon4VJW0WndEPInVz4t8QUXn5QZkU2tGVCE2g==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/mdx-loader": "3.7.0",
- "@docusaurus/module-type-aliases": "3.7.0",
- "@docusaurus/theme-common": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-common": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/mdx-loader": "3.8.0",
+ "@docusaurus/module-type-aliases": "3.8.0",
+ "@docusaurus/theme-common": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-common": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"@types/react-router-config": "^5.0.7",
"combine-promises": "^1.1.0",
"fs-extra": "^11.1.1",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
+ "schema-dts": "^1.1.2",
"tslib": "^2.6.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1"
@@ -3411,16 +3411,16 @@
}
},
"node_modules/@docusaurus/plugin-content-pages": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.7.0.tgz",
- "integrity": "sha512-YJSU3tjIJf032/Aeao8SZjFOrXJbz/FACMveSMjLyMH4itQyZ2XgUIzt4y+1ISvvk5zrW4DABVT2awTCqBkx0Q==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.8.0.tgz",
+ "integrity": "sha512-39EDx2y1GA0Pxfion5tQZLNJxL4gq6susd1xzetVBjVIQtwpCdyloOfQBAgX0FylqQxfJrYqL0DIUuq7rd7uBw==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/mdx-loader": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/mdx-loader": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"fs-extra": "^11.1.1",
"tslib": "^2.6.0",
"webpack": "^5.88.1"
@@ -3433,17 +3433,32 @@
"react-dom": "^18.0.0 || ^19.0.0"
}
},
- "node_modules/@docusaurus/plugin-debug": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.7.0.tgz",
- "integrity": "sha512-Qgg+IjG/z4svtbCNyTocjIwvNTNEwgRjSXXSJkKVG0oWoH0eX/HAPiu+TS1HBwRPQV+tTYPWLrUypYFepfujZA==",
+ "node_modules/@docusaurus/plugin-css-cascade-layers": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.8.0.tgz",
+ "integrity": "sha512-/VBTNymPIxQB8oA3ZQ4GFFRYdH4ZxDRRBECxyjRyv486mfUPXfcdk+im4S5mKWa6EK2JzBz95IH/Wu0qQgJ5yQ==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
+ "tslib": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=18.0"
+ }
+ },
+ "node_modules/@docusaurus/plugin-debug": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.8.0.tgz",
+ "integrity": "sha512-teonJvJsDB9o2OnG6ifbhblg/PXzZvpUKHFgD8dOL1UJ58u0lk8o0ZOkvaYEBa9nDgqzoWrRk9w+e3qaG2mOhQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
"fs-extra": "^11.1.1",
- "react-json-view-lite": "^1.2.0",
+ "react-json-view-lite": "^2.3.0",
"tslib": "^2.6.0"
},
"engines": {
@@ -3455,14 +3470,14 @@
}
},
"node_modules/@docusaurus/plugin-google-analytics": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.7.0.tgz",
- "integrity": "sha512-otIqiRV/jka6Snjf+AqB360XCeSv7lQC+DKYW+EUZf6XbuE8utz5PeUQ8VuOcD8Bk5zvT1MC4JKcd5zPfDuMWA==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.8.0.tgz",
+ "integrity": "sha512-aKKa7Q8+3xRSRESipNvlFgNp3FNPELKhuo48Cg/svQbGNwidSHbZT03JqbW4cBaQnyyVchO1ttk+kJ5VC9Gx0w==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"tslib": "^2.6.0"
},
"engines": {
@@ -3474,14 +3489,14 @@
}
},
"node_modules/@docusaurus/plugin-google-gtag": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.7.0.tgz",
- "integrity": "sha512-M3vrMct1tY65ModbyeDaMoA+fNJTSPe5qmchhAbtqhDD/iALri0g9LrEpIOwNaoLmm6lO88sfBUADQrSRSGSWA==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.8.0.tgz",
+ "integrity": "sha512-ugQYMGF4BjbAW/JIBtVcp+9eZEgT9HRdvdcDudl5rywNPBA0lct+lXMG3r17s02rrhInMpjMahN3Yc9Cb3H5/g==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"@types/gtag.js": "^0.0.12",
"tslib": "^2.6.0"
},
@@ -3494,14 +3509,14 @@
}
},
"node_modules/@docusaurus/plugin-google-tag-manager": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.7.0.tgz",
- "integrity": "sha512-X8U78nb8eiMiPNg3jb9zDIVuuo/rE1LjGDGu+5m5CX4UBZzjMy+klOY2fNya6x8ACyE/L3K2erO1ErheP55W/w==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.8.0.tgz",
+ "integrity": "sha512-9juRWxbwZD3SV02Jd9QB6yeN7eu+7T4zB0bvJLcVQwi+am51wAxn2CwbdL0YCCX+9OfiXbADE8D8Q65Hbopu/w==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"tslib": "^2.6.0"
},
"engines": {
@@ -3513,17 +3528,17 @@
}
},
"node_modules/@docusaurus/plugin-sitemap": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.7.0.tgz",
- "integrity": "sha512-bTRT9YLZ/8I/wYWKMQke18+PF9MV8Qub34Sku6aw/vlZ/U+kuEuRpQ8bTcNOjaTSfYsWkK4tTwDMHK2p5S86cA==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.8.0.tgz",
+ "integrity": "sha512-fGpOIyJvNiuAb90nSJ2Gfy/hUOaDu6826e5w5UxPmbpCIc7KlBHNAZ5g4L4ZuHhc4hdfq4mzVBsQSnne+8Ze1g==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-common": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-common": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"fs-extra": "^11.1.1",
"sitemap": "^7.1.1",
"tslib": "^2.6.0"
@@ -3537,15 +3552,15 @@
}
},
"node_modules/@docusaurus/plugin-svgr": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.7.0.tgz",
- "integrity": "sha512-HByXIZTbc4GV5VAUkZ2DXtXv1Qdlnpk3IpuImwSnEzCDBkUMYcec5282hPjn6skZqB25M1TYCmWS91UbhBGxQg==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.8.0.tgz",
+ "integrity": "sha512-kEDyry+4OMz6BWLG/lEqrNsL/w818bywK70N1gytViw4m9iAmoxCUT7Ri9Dgs7xUdzCHJ3OujolEmD88Wy44OA==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"@svgr/core": "8.1.0",
"@svgr/webpack": "^8.1.0",
"tslib": "^2.6.0",
@@ -3560,25 +3575,26 @@
}
},
"node_modules/@docusaurus/preset-classic": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.7.0.tgz",
- "integrity": "sha512-nPHj8AxDLAaQXs+O6+BwILFuhiWbjfQWrdw2tifOClQoNfuXDjfjogee6zfx6NGHWqshR23LrcN115DmkHC91Q==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.8.0.tgz",
+ "integrity": "sha512-qOu6tQDOWv+rpTlKu+eJATCJVGnABpRCPuqf7LbEaQ1mNY//N/P8cHQwkpAU+aweQfarcZ0XfwCqRHJfjeSV/g==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/plugin-content-blog": "3.7.0",
- "@docusaurus/plugin-content-docs": "3.7.0",
- "@docusaurus/plugin-content-pages": "3.7.0",
- "@docusaurus/plugin-debug": "3.7.0",
- "@docusaurus/plugin-google-analytics": "3.7.0",
- "@docusaurus/plugin-google-gtag": "3.7.0",
- "@docusaurus/plugin-google-tag-manager": "3.7.0",
- "@docusaurus/plugin-sitemap": "3.7.0",
- "@docusaurus/plugin-svgr": "3.7.0",
- "@docusaurus/theme-classic": "3.7.0",
- "@docusaurus/theme-common": "3.7.0",
- "@docusaurus/theme-search-algolia": "3.7.0",
- "@docusaurus/types": "3.7.0"
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/plugin-content-blog": "3.8.0",
+ "@docusaurus/plugin-content-docs": "3.8.0",
+ "@docusaurus/plugin-content-pages": "3.8.0",
+ "@docusaurus/plugin-css-cascade-layers": "3.8.0",
+ "@docusaurus/plugin-debug": "3.8.0",
+ "@docusaurus/plugin-google-analytics": "3.8.0",
+ "@docusaurus/plugin-google-gtag": "3.8.0",
+ "@docusaurus/plugin-google-tag-manager": "3.8.0",
+ "@docusaurus/plugin-sitemap": "3.8.0",
+ "@docusaurus/plugin-svgr": "3.8.0",
+ "@docusaurus/theme-classic": "3.8.0",
+ "@docusaurus/theme-common": "3.8.0",
+ "@docusaurus/theme-search-algolia": "3.8.0",
+ "@docusaurus/types": "3.8.0"
},
"engines": {
"node": ">=18.0"
@@ -3589,24 +3605,24 @@
}
},
"node_modules/@docusaurus/theme-classic": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.7.0.tgz",
- "integrity": "sha512-MnLxG39WcvLCl4eUzHr0gNcpHQfWoGqzADCly54aqCofQX6UozOS9Th4RK3ARbM9m7zIRv3qbhggI53dQtx/hQ==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.8.0.tgz",
+ "integrity": "sha512-nQWFiD5ZjoT76OaELt2n33P3WVuuCz8Dt5KFRP2fCBo2r9JCLsp2GJjZpnaG24LZ5/arRjv4VqWKgpK0/YLt7g==",
"license": "MIT",
"dependencies": {
- "@docusaurus/core": "3.7.0",
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/mdx-loader": "3.7.0",
- "@docusaurus/module-type-aliases": "3.7.0",
- "@docusaurus/plugin-content-blog": "3.7.0",
- "@docusaurus/plugin-content-docs": "3.7.0",
- "@docusaurus/plugin-content-pages": "3.7.0",
- "@docusaurus/theme-common": "3.7.0",
- "@docusaurus/theme-translations": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-common": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/mdx-loader": "3.8.0",
+ "@docusaurus/module-type-aliases": "3.8.0",
+ "@docusaurus/plugin-content-blog": "3.8.0",
+ "@docusaurus/plugin-content-docs": "3.8.0",
+ "@docusaurus/plugin-content-pages": "3.8.0",
+ "@docusaurus/theme-common": "3.8.0",
+ "@docusaurus/theme-translations": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-common": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"copy-text-to-clipboard": "^3.2.0",
@@ -3630,15 +3646,15 @@
}
},
"node_modules/@docusaurus/theme-common": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.7.0.tgz",
- "integrity": "sha512-8eJ5X0y+gWDsURZnBfH0WabdNm8XMCXHv8ENy/3Z/oQKwaB/EHt5lP9VsTDTf36lKEp0V6DjzjFyFIB+CetL0A==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.8.0.tgz",
+ "integrity": "sha512-YqV2vAWpXGLA+A3PMLrOMtqgTHJLDcT+1Caa6RF7N4/IWgrevy5diY8oIHFkXR/eybjcrFFjUPrHif8gSGs3Tw==",
"license": "MIT",
"dependencies": {
- "@docusaurus/mdx-loader": "3.7.0",
- "@docusaurus/module-type-aliases": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-common": "3.7.0",
+ "@docusaurus/mdx-loader": "3.8.0",
+ "@docusaurus/module-type-aliases": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-common": "3.8.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"@types/react-router-config": "*",
@@ -3658,19 +3674,19 @@
}
},
"node_modules/@docusaurus/theme-search-algolia": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.7.0.tgz",
- "integrity": "sha512-Al/j5OdzwRU1m3falm+sYy9AaB93S1XF1Lgk9Yc6amp80dNxJVplQdQTR4cYdzkGtuQqbzUA8+kaoYYO0RbK6g==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.8.0.tgz",
+ "integrity": "sha512-GBZ5UOcPgiu6nUw153+0+PNWvFKweSnvKIL6Rp04H9olKb475jfKjAwCCtju5D2xs5qXHvCMvzWOg5o9f6DtuQ==",
"license": "MIT",
"dependencies": {
- "@docsearch/react": "^3.8.1",
- "@docusaurus/core": "3.7.0",
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/plugin-content-docs": "3.7.0",
- "@docusaurus/theme-common": "3.7.0",
- "@docusaurus/theme-translations": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-validation": "3.7.0",
+ "@docsearch/react": "^3.9.0",
+ "@docusaurus/core": "3.8.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/plugin-content-docs": "3.8.0",
+ "@docusaurus/theme-common": "3.8.0",
+ "@docusaurus/theme-translations": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-validation": "3.8.0",
"algoliasearch": "^5.17.1",
"algoliasearch-helper": "^3.22.6",
"clsx": "^2.0.0",
@@ -3689,9 +3705,9 @@
}
},
"node_modules/@docusaurus/theme-translations": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.7.0.tgz",
- "integrity": "sha512-Ewq3bEraWDmienM6eaNK7fx+/lHMtGDHQyd1O+4+3EsDxxUmrzPkV7Ct3nBWTuE0MsoZr3yNwQVKjllzCMuU3g==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.8.0.tgz",
+ "integrity": "sha512-1DTy/snHicgkCkryWq54fZvsAglTdjTx4qjOXgqnXJ+DIty1B+aPQrAVUu8LiM+6BiILfmNxYsxhKTj+BS3PZg==",
"license": "MIT",
"dependencies": {
"fs-extra": "^11.1.1",
@@ -3702,16 +3718,16 @@
}
},
"node_modules/@docusaurus/tsconfig": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.7.0.tgz",
- "integrity": "sha512-vRsyj3yUZCjscgfgcFYjIsTcAru/4h4YH2/XAE8Rs7wWdnng98PgWKvP5ovVc4rmRpRg2WChVW0uOy2xHDvDBQ==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.8.0.tgz",
+ "integrity": "sha512-utLl48nNjSYBoq47RKukZ9fPLEX3nJWThzrujb0ndQQ1jc/gh4RhTRaAqItH9nImnsgGKmLMnyoMBpfGmoop+w==",
"dev": true,
"license": "MIT"
},
"node_modules/@docusaurus/types": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.7.0.tgz",
- "integrity": "sha512-kOmZg5RRqJfH31m+6ZpnwVbkqMJrPOG5t0IOl4i/+3ruXyNfWzZ0lVtVrD0u4ONc/0NOsS9sWYaxxWNkH1LdLQ==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.8.0.tgz",
+ "integrity": "sha512-RDEClpwNxZq02c+JlaKLWoS13qwWhjcNsi2wG1UpzmEnuti/z1Wx4SGpqbUqRPNSd8QWWePR8Cb7DvG0VN/TtA==",
"license": "MIT",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
@@ -3744,15 +3760,16 @@
}
},
"node_modules/@docusaurus/utils": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.7.0.tgz",
- "integrity": "sha512-e7zcB6TPnVzyUaHMJyLSArKa2AG3h9+4CfvKXKKWNx6hRs+p0a+u7HHTJBgo6KW2m+vqDnuIHK4X+bhmoghAFA==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.8.0.tgz",
+ "integrity": "sha512-2wvtG28ALCN/A1WCSLxPASFBFzXCnP0YKCAFIPcvEb6imNu1wg7ni/Svcp71b3Z2FaOFFIv4Hq+j4gD7gA0yfQ==",
"license": "MIT",
"dependencies": {
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/types": "3.7.0",
- "@docusaurus/utils-common": "3.7.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/types": "3.8.0",
+ "@docusaurus/utils-common": "3.8.0",
"escape-string-regexp": "^4.0.0",
+ "execa": "5.1.1",
"file-loader": "^6.2.0",
"fs-extra": "^11.1.1",
"github-slugger": "^1.5.0",
@@ -3762,9 +3779,9 @@
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"micromatch": "^4.0.5",
+ "p-queue": "^6.6.2",
"prompts": "^2.4.2",
"resolve-pathname": "^3.0.0",
- "shelljs": "^0.8.5",
"tslib": "^2.6.0",
"url-loader": "^4.1.1",
"utility-types": "^3.10.0",
@@ -3775,12 +3792,12 @@
}
},
"node_modules/@docusaurus/utils-common": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.7.0.tgz",
- "integrity": "sha512-IZeyIfCfXy0Mevj6bWNg7DG7B8G+S6o6JVpddikZtWyxJguiQ7JYr0SIZ0qWd8pGNuMyVwriWmbWqMnK7Y5PwA==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.8.0.tgz",
+ "integrity": "sha512-3TGF+wVTGgQ3pAc9+5jVchES4uXUAhAt9pwv7uws4mVOxL4alvU3ue/EZ+R4XuGk94pDy7CNXjRXpPjlfZXQfw==",
"license": "MIT",
"dependencies": {
- "@docusaurus/types": "3.7.0",
+ "@docusaurus/types": "3.8.0",
"tslib": "^2.6.0"
},
"engines": {
@@ -3788,14 +3805,14 @@
}
},
"node_modules/@docusaurus/utils-validation": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.7.0.tgz",
- "integrity": "sha512-w8eiKk8mRdN+bNfeZqC4nyFoxNyI1/VExMKAzD9tqpJfLLbsa46Wfn5wcKH761g9WkKh36RtFV49iL9lh1DYBA==",
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.8.0.tgz",
+ "integrity": "sha512-MrnEbkigr54HkdFeg8e4FKc4EF+E9dlVwsY3XQZsNkbv3MKZnbHQ5LsNJDIKDROFe8PBf5C4qCAg5TPBpsjrjg==",
"license": "MIT",
"dependencies": {
- "@docusaurus/logger": "3.7.0",
- "@docusaurus/utils": "3.7.0",
- "@docusaurus/utils-common": "3.7.0",
+ "@docusaurus/logger": "3.8.0",
+ "@docusaurus/utils": "3.8.0",
+ "@docusaurus/utils-common": "3.8.0",
"fs-extra": "^11.2.0",
"joi": "^17.9.2",
"js-yaml": "^4.1.0",
@@ -4757,12 +4774,6 @@
"@types/node": "*"
}
},
- "node_modules/@types/parse-json": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
- "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
- "license": "MIT"
- },
"node_modules/@types/parse5": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz",
@@ -5437,15 +5448,6 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
- "node_modules/at-least-node": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
- "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
- "license": "ISC",
- "engines": {
- "node": ">= 4.0.0"
- }
- },
"node_modules/autocomplete.js": {
"version": "0.37.1",
"resolved": "https://registry.npmjs.org/autocomplete.js/-/autocomplete.js-0.37.1.tgz",
@@ -7369,28 +7371,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/del": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz",
- "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==",
- "license": "MIT",
- "dependencies": {
- "globby": "^11.0.1",
- "graceful-fs": "^4.2.4",
- "is-glob": "^4.0.1",
- "is-path-cwd": "^2.2.0",
- "is-path-inside": "^3.0.2",
- "p-map": "^4.0.0",
- "rimraf": "^3.0.2",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -7463,38 +7443,6 @@
"node": ">= 4.0.0"
}
},
- "node_modules/detect-port-alt": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz",
- "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==",
- "license": "MIT",
- "dependencies": {
- "address": "^1.0.1",
- "debug": "^2.6.0"
- },
- "bin": {
- "detect": "bin/detect-port",
- "detect-port": "bin/detect-port"
- },
- "engines": {
- "node": ">= 4.2.1"
- }
- },
- "node_modules/detect-port-alt/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/detect-port-alt/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
"node_modules/devlop": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
@@ -8685,15 +8633,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/filesize": {
- "version": "8.0.7",
- "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz",
- "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">= 0.4.0"
- }
- },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -8834,134 +8773,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/fork-ts-checker-webpack-plugin": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz",
- "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.8.3",
- "@types/json-schema": "^7.0.5",
- "chalk": "^4.1.0",
- "chokidar": "^3.4.2",
- "cosmiconfig": "^6.0.0",
- "deepmerge": "^4.2.2",
- "fs-extra": "^9.0.0",
- "glob": "^7.1.6",
- "memfs": "^3.1.2",
- "minimatch": "^3.0.4",
- "schema-utils": "2.7.0",
- "semver": "^7.3.2",
- "tapable": "^1.0.0"
- },
- "engines": {
- "node": ">=10",
- "yarn": ">=1.0.0"
- },
- "peerDependencies": {
- "eslint": ">= 6",
- "typescript": ">= 2.7",
- "vue-template-compiler": "*",
- "webpack": ">= 4"
- },
- "peerDependenciesMeta": {
- "eslint": {
- "optional": true
- },
- "vue-template-compiler": {
- "optional": true
- }
- }
- },
- "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "license": "MIT",
- "peerDependencies": {
- "ajv": "^6.9.1"
- }
- },
- "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
- "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
- "license": "MIT",
- "dependencies": {
- "@types/parse-json": "^4.0.0",
- "import-fresh": "^3.1.0",
- "parse-json": "^5.0.0",
- "path-type": "^4.0.0",
- "yaml": "^1.7.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
- "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
- "license": "MIT",
- "dependencies": {
- "at-least-node": "^1.0.0",
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "license": "MIT"
- },
- "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
- "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
- "license": "MIT",
- "dependencies": {
- "@types/json-schema": "^7.0.4",
- "ajv": "^6.12.2",
- "ajv-keywords": "^3.4.1"
- },
- "engines": {
- "node": ">= 8.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
- "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
- "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/form-data": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
@@ -9281,44 +9092,6 @@
"node": ">=10"
}
},
- "node_modules/global-modules": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
- "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
- "license": "MIT",
- "dependencies": {
- "global-prefix": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/global-prefix": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
- "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
- "license": "MIT",
- "dependencies": {
- "ini": "^1.3.5",
- "kind-of": "^6.0.2",
- "which": "^1.3.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/global-prefix/node_modules/which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "which": "bin/which"
- }
- },
"node_modules/globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@@ -10644,13 +10417,10 @@
}
},
"node_modules/image-size": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
- "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz",
+ "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==",
"license": "MIT",
- "dependencies": {
- "queue": "6.0.2"
- },
"bin": {
"image-size": "bin/image-size.js"
},
@@ -10994,15 +10764,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-path-cwd": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
- "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/is-path-inside": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
@@ -11045,15 +10806,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-root": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz",
- "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -14650,6 +14402,15 @@
"node": ">=12.20"
}
},
+ "node_modules/p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/p-limit": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
@@ -14695,6 +14456,22 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-queue": {
+ "version": "6.6.2",
+ "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz",
+ "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==",
+ "license": "MIT",
+ "dependencies": {
+ "eventemitter3": "^4.0.4",
+ "p-timeout": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/p-retry": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
@@ -14708,13 +14485,16 @@
"node": ">=8"
}
},
- "node_modules/p-try": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "node_modules/p-timeout": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
+ "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
"license": "MIT",
+ "dependencies": {
+ "p-finally": "^1.0.0"
+ },
"engines": {
- "node": ">=6"
+ "node": ">=8"
}
},
"node_modules/package-json": {
@@ -15012,83 +14792,10 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/pkg-up": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
- "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
- "license": "MIT",
- "dependencies": {
- "find-up": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/pkg-up/node_modules/find-up": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
- "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
- "license": "MIT",
- "dependencies": {
- "locate-path": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/pkg-up/node_modules/locate-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
- "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
- "license": "MIT",
- "dependencies": {
- "p-locate": "^3.0.0",
- "path-exists": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/pkg-up/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "license": "MIT",
- "dependencies": {
- "p-try": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/pkg-up/node_modules/p-locate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
- "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
- "license": "MIT",
- "dependencies": {
- "p-limit": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/pkg-up/node_modules/path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/postcss": {
- "version": "8.5.3",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
- "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+ "version": "8.5.4",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz",
+ "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==",
"funding": [
{
"type": "opencollective",
@@ -15105,7 +14812,7 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.8",
+ "nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
@@ -16894,15 +16601,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/queue": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
- "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
- "license": "MIT",
- "dependencies": {
- "inherits": "~2.0.3"
- }
- },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -17094,132 +16792,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/react-dev-utils": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
- "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.16.0",
- "address": "^1.1.2",
- "browserslist": "^4.18.1",
- "chalk": "^4.1.2",
- "cross-spawn": "^7.0.3",
- "detect-port-alt": "^1.1.6",
- "escape-string-regexp": "^4.0.0",
- "filesize": "^8.0.6",
- "find-up": "^5.0.0",
- "fork-ts-checker-webpack-plugin": "^6.5.0",
- "global-modules": "^2.0.0",
- "globby": "^11.0.4",
- "gzip-size": "^6.0.0",
- "immer": "^9.0.7",
- "is-root": "^2.1.0",
- "loader-utils": "^3.2.0",
- "open": "^8.4.0",
- "pkg-up": "^3.1.0",
- "prompts": "^2.4.2",
- "react-error-overlay": "^6.0.11",
- "recursive-readdir": "^2.2.2",
- "shell-quote": "^1.7.3",
- "strip-ansi": "^6.0.1",
- "text-table": "^0.2.0"
- },
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/react-dev-utils/node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "license": "MIT",
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/react-dev-utils/node_modules/loader-utils": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz",
- "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==",
- "license": "MIT",
- "engines": {
- "node": ">= 12.13.0"
- }
- },
- "node_modules/react-dev-utils/node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "license": "MIT",
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/react-dev-utils/node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "license": "MIT",
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/react-dev-utils/node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "license": "MIT",
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/react-dev-utils/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/react-dev-utils/node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
@@ -17233,12 +16805,6 @@
"react": "^18.3.1"
}
},
- "node_modules/react-error-overlay": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.1.0.tgz",
- "integrity": "sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ==",
- "license": "MIT"
- },
"node_modules/react-fast-compare": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
@@ -17270,15 +16836,15 @@
"license": "MIT"
},
"node_modules/react-json-view-lite": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz",
- "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-2.4.1.tgz",
+ "integrity": "sha512-fwFYknRIBxjbFm0kBDrzgBy1xa5tDg2LyXXBepC5f1b+MY3BUClMCsvanMPn089JbV1Eg3nZcrp0VCuH43aXnA==",
"license": "MIT",
"engines": {
- "node": ">=14"
+ "node": ">=18"
},
"peerDependencies": {
- "react": "^16.13.1 || ^17.0.0 || ^18.0.0"
+ "react": "^18.0.0 || ^19.0.0"
}
},
"node_modules/react-loadable": {
@@ -17433,12 +16999,6 @@
"node": ">=8.10.0"
}
},
- "node_modules/reading-time": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz",
- "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==",
- "license": "MIT"
- },
"node_modules/rechoir": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
@@ -17514,18 +17074,6 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/recursive-readdir": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz",
- "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==",
- "license": "MIT",
- "dependencies": {
- "minimatch": "^3.0.5"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
@@ -18208,6 +17756,12 @@
"loose-envify": "^1.1.0"
}
},
+ "node_modules/schema-dts": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz",
+ "integrity": "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==",
+ "license": "Apache-2.0"
+ },
"node_modules/schema-utils": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
@@ -19472,12 +19026,6 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT"
},
- "node_modules/text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
- "license": "MIT"
- },
"node_modules/thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
@@ -19517,6 +19065,15 @@
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==",
"license": "MIT"
},
+ "node_modules/tinypool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.0.tgz",
+ "integrity": "sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ }
+ },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -19686,6 +19243,7 @@
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "devOptional": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
diff --git a/docs/package.json b/docs/package.json
index e13e85ecb33..2cc81f1b2c1 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -16,8 +16,8 @@
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
- "@docusaurus/core": "~3.7.0",
- "@docusaurus/preset-classic": "~3.7.0",
+ "@docusaurus/core": "~3.8.0",
+ "@docusaurus/preset-classic": "~3.8.0",
"@mdi/js": "^7.3.67",
"@mdi/react": "^1.6.1",
"@mdx-js/react": "^3.0.0",
@@ -35,7 +35,7 @@
"url": "^0.11.0"
},
"devDependencies": {
- "@docusaurus/module-type-aliases": "~3.7.0",
+ "@docusaurus/module-type-aliases": "~3.8.0",
"@docusaurus/tsconfig": "^3.7.0",
"@docusaurus/types": "^3.7.0",
"prettier": "^3.2.4",
diff --git a/docs/src/pages/cursed-knowledge.tsx b/docs/src/pages/cursed-knowledge.tsx
index 6a0981a5967..534d8e95d04 100644
--- a/docs/src/pages/cursed-knowledge.tsx
+++ b/docs/src/pages/cursed-knowledge.tsx
@@ -33,7 +33,7 @@ const items: Item[] = [
url: 'https://github.com/immich-app/immich/pull/17974',
text: '#17974',
},
- date: new Date(2025, 5, 5),
+ date: new Date(2025, 4, 5),
},
{
icon: mdiMicrosoftWindows,
diff --git a/e2e/package-lock.json b/e2e/package-lock.json
index 343295c60d7..6d837d67ed4 100644
--- a/e2e/package-lock.json
+++ b/e2e/package-lock.json
@@ -1709,17 +1709,17 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz",
- "integrity": "sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.0.tgz",
+ "integrity": "sha512-CACyQuqSHt7ma3Ns601xykeBK/rDeZa3w6IS6UtMQbixO5DWy+8TilKkviGDH6jtWCo8FGRKEK5cLLkPvEammQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.32.1",
- "@typescript-eslint/type-utils": "8.32.1",
- "@typescript-eslint/utils": "8.32.1",
- "@typescript-eslint/visitor-keys": "8.32.1",
+ "@typescript-eslint/scope-manager": "8.33.0",
+ "@typescript-eslint/type-utils": "8.33.0",
+ "@typescript-eslint/utils": "8.33.0",
+ "@typescript-eslint/visitor-keys": "8.33.0",
"graphemer": "^1.4.0",
"ignore": "^7.0.0",
"natural-compare": "^1.4.0",
@@ -1733,7 +1733,7 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+ "@typescript-eslint/parser": "^8.33.0",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
@@ -1749,16 +1749,16 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz",
- "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.0.tgz",
+ "integrity": "sha512-JaehZvf6m0yqYp34+RVnihBAChkqeH+tqqhS0GuX1qgPpwLvmTPheKEs6OeCK6hVJgXZHJ2vbjnC9j119auStQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/scope-manager": "8.32.1",
- "@typescript-eslint/types": "8.32.1",
- "@typescript-eslint/typescript-estree": "8.32.1",
- "@typescript-eslint/visitor-keys": "8.32.1",
+ "@typescript-eslint/scope-manager": "8.33.0",
+ "@typescript-eslint/types": "8.33.0",
+ "@typescript-eslint/typescript-estree": "8.33.0",
+ "@typescript-eslint/visitor-keys": "8.33.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1773,15 +1773,16 @@
"typescript": ">=4.8.4 <5.9.0"
}
},
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz",
- "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==",
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.0.tgz",
+ "integrity": "sha512-d1hz0u9l6N+u/gcrk6s6gYdl7/+pp8yHheRTqP6X5hVDKALEaTn8WfGiit7G511yueBEL3OpOEpD+3/MBdoN+A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.32.1",
- "@typescript-eslint/visitor-keys": "8.32.1"
+ "@typescript-eslint/tsconfig-utils": "^8.33.0",
+ "@typescript-eslint/types": "^8.33.0",
+ "debug": "^4.3.4"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1791,15 +1792,50 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/@typescript-eslint/type-utils": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz",
- "integrity": "sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==",
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.0.tgz",
+ "integrity": "sha512-LMi/oqrzpqxyO72ltP+dBSP6V0xiUb4saY7WLtxSfiNEBI8m321LLVFU9/QDJxjDQG9/tjSqKz/E3380TEqSTw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "8.32.1",
- "@typescript-eslint/utils": "8.32.1",
+ "@typescript-eslint/types": "8.33.0",
+ "@typescript-eslint/visitor-keys": "8.33.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.0.tgz",
+ "integrity": "sha512-sTkETlbqhEoiFmGr1gsdq5HyVbSOF0145SYDJ/EQmXHtKViCaGvnyLqWFFHtEXoS0J1yU8Wyou2UGmgW88fEug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.0.tgz",
+ "integrity": "sha512-lScnHNCBqL1QayuSrWeqAL5GmqNdVUQAAMTaCwdYEdWfIrSrOGzyLGRCHXcCixa5NK6i5l0AfSO2oBSjCjf4XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "8.33.0",
+ "@typescript-eslint/utils": "8.33.0",
"debug": "^4.3.4",
"ts-api-utils": "^2.1.0"
},
@@ -1816,9 +1852,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.1.tgz",
- "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.0.tgz",
+ "integrity": "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1830,14 +1866,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz",
- "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.0.tgz",
+ "integrity": "sha512-vegY4FQoB6jL97Tu/lWRsAiUUp8qJTqzAmENH2k59SJhw0Th1oszb9Idq/FyyONLuNqT1OADJPXfyUNOR8SzAQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.32.1",
- "@typescript-eslint/visitor-keys": "8.32.1",
+ "@typescript-eslint/project-service": "8.33.0",
+ "@typescript-eslint/tsconfig-utils": "8.33.0",
+ "@typescript-eslint/types": "8.33.0",
+ "@typescript-eslint/visitor-keys": "8.33.0",
"debug": "^4.3.4",
"fast-glob": "^3.3.2",
"is-glob": "^4.0.3",
@@ -1883,16 +1921,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.1.tgz",
- "integrity": "sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.0.tgz",
+ "integrity": "sha512-lPFuQaLA9aSNa7D5u2EpRiqdAUhzShwGg/nhpBlc4GR6kcTABttCuyjFs8BcEZ8VWrjCBof/bePhP3Q3fS+Yrw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.7.0",
- "@typescript-eslint/scope-manager": "8.32.1",
- "@typescript-eslint/types": "8.32.1",
- "@typescript-eslint/typescript-estree": "8.32.1"
+ "@typescript-eslint/scope-manager": "8.33.0",
+ "@typescript-eslint/types": "8.33.0",
+ "@typescript-eslint/typescript-estree": "8.33.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -1907,13 +1945,13 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz",
- "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.0.tgz",
+ "integrity": "sha512-7RW7CMYoskiz5OOGAWjJFxgb7c5UNjTG292gYhWeOAcFmYCtVCSqjqSBj5zMhxbXo2JOW95YYrUWJfU0zrpaGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "8.32.1",
+ "@typescript-eslint/types": "8.33.0",
"eslint-visitor-keys": "^4.2.0"
},
"engines": {
@@ -3834,9 +3872,9 @@
}
},
"node_modules/globals": {
- "version": "16.1.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-16.1.0.tgz",
- "integrity": "sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==",
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.2.0.tgz",
+ "integrity": "sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -6779,15 +6817,15 @@
}
},
"node_modules/typescript-eslint": {
- "version": "8.32.1",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.32.1.tgz",
- "integrity": "sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==",
+ "version": "8.33.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.33.0.tgz",
+ "integrity": "sha512-5YmNhF24ylCsvdNW2oJwMzTbaeO4bg90KeGtMjUw0AGtHksgEPLRTUil+coHwCfiu4QjVJFnjp94DmU6zV7DhQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/eslint-plugin": "8.32.1",
- "@typescript-eslint/parser": "8.32.1",
- "@typescript-eslint/utils": "8.32.1"
+ "@typescript-eslint/eslint-plugin": "8.33.0",
+ "@typescript-eslint/parser": "8.33.0",
+ "@typescript-eslint/utils": "8.33.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
diff --git a/e2e/src/api/specs/album.e2e-spec.ts b/e2e/src/api/specs/album.e2e-spec.ts
index 65a94122fa9..eedf70dc58e 100644
--- a/e2e/src/api/specs/album.e2e-spec.ts
+++ b/e2e/src/api/specs/album.e2e-spec.ts
@@ -428,6 +428,15 @@ describe('/albums', () => {
order: AssetOrder.Desc,
});
});
+
+ it('should not be able to share album with owner', async () => {
+ const { status, body } = await request(app)
+ .post('/albums')
+ .send({ albumName: 'New album', albumUsers: [{ role: AlbumUserRole.Editor, userId: user1.userId }] })
+ .set('Authorization', `Bearer ${user1.accessToken}`);
+ expect(status).toBe(400);
+ expect(body).toEqual(errorDto.badRequest('Cannot share album with owner'));
+ });
});
describe('PUT /albums/:id/assets', () => {
diff --git a/e2e/src/responses.ts b/e2e/src/responses.ts
index 0148f2e1e93..bb6d17a2483 100644
--- a/e2e/src/responses.ts
+++ b/e2e/src/responses.ts
@@ -103,6 +103,7 @@ export const loginResponseDto = {
accessToken: expect.any(String),
name: 'Immich Admin',
isAdmin: true,
+ isOnboarded: false,
profileImagePath: '',
shouldChangePassword: true,
userEmail: 'admin@immich.cloud',
diff --git a/e2e/src/web/specs/auth.e2e-spec.ts b/e2e/src/web/specs/auth.e2e-spec.ts
index 74bee64e0a9..0fde9a6ec64 100644
--- a/e2e/src/web/specs/auth.e2e-spec.ts
+++ b/e2e/src/web/specs/auth.e2e-spec.ts
@@ -33,7 +33,9 @@ test.describe('Registration', () => {
// onboarding
await expect(page).toHaveURL('/auth/onboarding');
await page.getByRole('button', { name: 'Theme' }).click();
- await page.getByRole('button', { name: 'Privacy' }).click();
+ await page.getByRole('button', { name: 'Language' }).click();
+ await page.getByRole('button', { name: 'Server Privacy' }).click();
+ await page.getByRole('button', { name: 'User Privacy' }).click();
await page.getByRole('button', { name: 'Storage Template' }).click();
await page.getByRole('button', { name: 'Done' }).click();
@@ -77,6 +79,13 @@ test.describe('Registration', () => {
await page.getByLabel('Password').fill('new-password');
await page.getByRole('button', { name: 'Login' }).click();
+ // onboarding
+ await expect(page).toHaveURL('/auth/onboarding');
+ await page.getByRole('button', { name: 'Theme' }).click();
+ await page.getByRole('button', { name: 'Language' }).click();
+ await page.getByRole('button', { name: 'User Privacy' }).click();
+ await page.getByRole('button', { name: 'Done' }).click();
+
// success
await expect(page).toHaveURL(/\/photos/);
});
diff --git a/i18n/en.json b/i18n/en.json
index 56e38cf8166..a25d62e94c8 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -26,7 +26,6 @@
"add_to_album": "Add to album",
"add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}",
- "add_to_locked_folder": "Add to locked folder",
"add_to_shared_album": "Add to shared album",
"add_url": "Add URL",
"added_to_archive": "Added to archive",
@@ -44,9 +43,7 @@
"backup_database_enable_description": "Enable database dumps",
"backup_keep_last_amount": "Amount of previous dumps to keep",
"backup_settings": "Database Dump Settings",
- "backup_settings_description": "Manage database dump settings. Note: These jobs are not monitored and you will not be notified of failure.",
- "check_all": "Check All",
- "cleanup": "Cleanup",
+ "backup_settings_description": "Manage database dump settings.",
"cleared_jobs": "Cleared jobs for: {job}",
"config_set_by_file": "Config is currently set by a config file",
"confirm_delete_library": "Are you sure you want to delete {library} library?",
@@ -62,14 +59,12 @@
"disable_login": "Disable login",
"duplicate_detection_job_description": "Run machine learning on assets to detect similar images. Relies on Smart Search",
"exclusion_pattern_description": "Exclusion patterns lets you ignore files and folders when scanning your library. This is useful if you have folders that contain files you don't want to import, such as RAW files.",
- "external_library_created_at": "External library (created on {date})",
"external_library_management": "External Library Management",
"face_detection": "Face detection",
"face_detection_description": "Detect the faces in assets using machine learning. For videos, only the thumbnail is considered. \"Refresh\" (re-)processes all assets. \"Reset\" additionally clears all current face data. \"Missing\" queues assets that haven't been processed yet. Detected faces will be queued for Facial Recognition after Face Detection is complete, grouping them into existing or new people.",
"facial_recognition_job_description": "Group detected faces into people. This step runs after Face Detection is complete. \"Reset\" (re-)clusters all faces. \"Missing\" queues faces that don't have a person assigned.",
"failed_job_command": "Command {command} failed for job: {job}",
"force_delete_user_warning": "WARNING: This will immediately remove the user and all assets. This cannot be undone and the files cannot be recovered.",
- "forcing_refresh_library_files": "Forcing refresh of all library files",
"image_format": "Format",
"image_format_description": "WebP produces smaller files than JPEG, but is slower to encode.",
"image_fullsize_description": "Full-size image with stripped metadata, used when zoomed in",
@@ -210,8 +205,6 @@
"oauth_storage_quota_default_description": "Quota in GiB to be used when no claim is provided (Enter 0 for unlimited quota).",
"oauth_timeout": "Request Timeout",
"oauth_timeout_description": "Timeout for requests in milliseconds",
- "offline_paths": "Offline Paths",
- "offline_paths_description": "These results may be due to manual deletion of files that are not part of an external library.",
"password_enable_description": "Login with email and password",
"password_settings": "Password Login",
"password_settings_description": "Manage password login settings",
@@ -221,9 +214,6 @@
"refreshing_all_libraries": "Refreshing all libraries",
"registration": "Admin Registration",
"registration_description": "Since you are the first user on the system, you will be assigned as the Admin and are responsible for administrative tasks, and additional users will be created by you.",
- "repair_all": "Repair All",
- "repair_matched_items": "Matched {count, plural, one {# item} other {# items}}",
- "repaired_items": "Repaired {count, plural, one {# item} other {# items}}",
"require_password_change_on_login": "Require user to change password on first login",
"reset_settings_to_default": "Reset settings to default",
"reset_settings_to_recent_saved": "Reset settings to the recent saved settings",
@@ -264,7 +254,6 @@
"template_email_invite_album": "Invite Album Template",
"template_email_preview": "Preview",
"template_email_settings": "Email Templates",
- "template_email_settings_description": "Manage custom email notification templates",
"template_email_update_album": "Update Album Template",
"template_email_welcome": "Welcome email template",
"template_settings": "Notification Templates",
@@ -273,7 +262,6 @@
"theme_custom_css_settings_description": "Cascading Style Sheets allow the design of Immich to be customized.",
"theme_settings": "Theme Settings",
"theme_settings_description": "Manage customization of the Immich web interface",
- "these_files_matched_by_checksum": "These files are matched by their checksums",
"thumbnail_generation_job": "Generate Thumbnails",
"thumbnail_generation_job_description": "Generate large, small and blurred thumbnails for each asset, as well as thumbnails for each person",
"transcoding_acceleration_api": "Acceleration API",
@@ -341,8 +329,6 @@
"trash_number_of_days_description": "Number of days to keep the assets in trash before permanently removing them",
"trash_settings": "Trash Settings",
"trash_settings_description": "Manage trash settings",
- "untracked_files": "Untracked Files",
- "untracked_files_description": "These files are not tracked by the application. They can be the results of failed moves, interrupted uploads, or left behind due to a bug",
"user_cleanup_job": "User cleanup",
"user_delete_delay": "{user}'s account and assets will be scheduled for permanent deletion in {delay, plural, one {# day} other {# days}}.",
"user_delete_delay_settings": "Delete delay",
@@ -401,10 +387,6 @@
"album_remove_user": "Remove user?",
"album_remove_user_confirmation": "Are you sure you want to remove {user}?",
"album_share_no_users": "Looks like you have shared this album with all users or you don't have any user to share with.",
- "album_thumbnail_card_item": "1 item",
- "album_thumbnail_card_items": "{count} items",
- "album_thumbnail_card_shared": " · Shared",
- "album_thumbnail_shared_by": "Shared by {user}",
"album_updated": "Album updated",
"album_updated_setting_description": "Receive an email notification when a shared album has new assets",
"album_user_left": "Left {album}",
@@ -495,6 +477,7 @@
"authorized_devices": "Authorized Devices",
"automatic_endpoint_switching_subtitle": "Connect locally over designated Wi-Fi when available and use alternative connections elsewhere",
"automatic_endpoint_switching_title": "Automatic URL switching",
+ "autoplay_slideshow": "Autoplay slideshow",
"back": "Back",
"back_close_deselect": "Back, close, or deselect",
"background_location_permission": "Background location permission",
@@ -576,21 +559,17 @@
"bulk_keep_duplicates_confirmation": "Are you sure you want to keep {count, plural, one {# duplicate asset} other {# duplicate assets}}? This will resolve all duplicate groups without deleting anything.",
"bulk_trash_duplicates_confirmation": "Are you sure you want to bulk trash {count, plural, one {# duplicate asset} other {# duplicate assets}}? This will keep the largest asset of each group and trash all other duplicates.",
"buy": "Purchase Immich",
- "cache_settings_album_thumbnails": "Library page thumbnails ({count} assets)",
"cache_settings_clear_cache_button": "Clear cache",
"cache_settings_clear_cache_button_title": "Clears the app's cache. This will significantly impact the app's performance until the cache has rebuilt.",
"cache_settings_duplicated_assets_clear_button": "CLEAR",
"cache_settings_duplicated_assets_subtitle": "Photos and videos that are black listed by the app",
"cache_settings_duplicated_assets_title": "Duplicated Assets ({count})",
- "cache_settings_image_cache_size": "Image cache size ({count} assets)",
"cache_settings_statistics_album": "Library thumbnails",
- "cache_settings_statistics_assets": "{count} assets ({size})",
"cache_settings_statistics_full": "Full images",
"cache_settings_statistics_shared": "Shared album thumbnails",
"cache_settings_statistics_thumbnail": "Thumbnails",
"cache_settings_statistics_title": "Cache usage",
"cache_settings_subtitle": "Control the caching behaviour of the Immich mobile application",
- "cache_settings_thumbnail_size": "Thumbnail cache size ({count} assets)",
"cache_settings_tile_subtitle": "Control the local storage behaviour",
"cache_settings_tile_title": "Local Storage",
"cache_settings_title": "Caching Settings",
@@ -604,6 +583,7 @@
"cannot_undo_this_action": "You cannot undo this action!",
"cannot_update_the_description": "Cannot update the description",
"cast": "Cast",
+ "cast_description": "Configure available cast destinations",
"change_date": "Change date",
"change_description": "Change description",
"change_display_order": "Change display order",
@@ -621,7 +601,6 @@
"change_pin_code": "Change PIN code",
"change_your_password": "Change your password",
"changed_visibility_successfully": "Changed visibility successfully",
- "check_all": "Check All",
"check_corrupt_asset_backup": "Check for corrupt asset backups",
"check_corrupt_asset_backup_button": "Perform check",
"check_corrupt_asset_backup_description": "Run this check only over Wi-Fi and once all assets have been backed-up. The procedure might take a few minutes.",
@@ -667,7 +646,6 @@
"contain": "Contain",
"context": "Context",
"continue": "Continue",
- "control_bottom_app_bar_album_info_shared": "{count} items · Shared",
"control_bottom_app_bar_create_new_album": "Create new album",
"control_bottom_app_bar_delete_from_immich": "Delete from Immich",
"control_bottom_app_bar_delete_from_local": "Delete from device",
@@ -778,7 +756,6 @@
"download_enqueue": "Download enqueued",
"download_error": "Download Error",
"download_failed": "Download failed",
- "download_filename": "file: {filename}",
"download_finished": "Download finished",
"download_include_embedded_motion_videos": "Embedded videos",
"download_include_embedded_motion_videos_description": "Include videos embedded in motion photos as a separate file",
@@ -854,7 +831,6 @@
"cant_get_number_of_comments": "Can't get number of comments",
"cant_search_people": "Can't search people",
"cant_search_places": "Can't search places",
- "cleared_jobs": "Cleared jobs for: {job}",
"error_adding_assets_to_album": "Error adding assets to album",
"error_adding_users_to_album": "Error adding users to album",
"error_deleting_shared_user": "Error deleting shared user",
@@ -863,7 +839,6 @@
"error_removing_assets_from_album": "Error removing assets from album, check console for more details",
"error_selecting_all_assets": "Error selecting all assets",
"exclusion_pattern_already_exists": "This exclusion pattern already exists.",
- "failed_job_command": "Command {command} failed for job: {job}",
"failed_to_create_album": "Failed to create album",
"failed_to_create_shared_link": "Failed to create shared link",
"failed_to_edit_shared_link": "Failed to edit shared link",
@@ -882,7 +857,6 @@
"paths_validation_failed": "{paths, plural, one {# path} other {# paths}} failed validation",
"profile_picture_transparent_pixels": "Profile pictures cannot have transparent pixels. Please zoom in and/or move the image.",
"quota_higher_than_disk_size": "You set a quota higher than the disk size",
- "repair_unable_to_check_items": "Unable to check {count, select, one {item} other {items}}",
"unable_to_add_album_users": "Unable to add users to album",
"unable_to_add_assets_to_shared_link": "Unable to add assets to shared link",
"unable_to_add_comment": "Unable to add comment",
@@ -901,7 +875,6 @@
"unable_to_change_visibility": "Unable to change the visibility for {count, plural, one {# person} other {# people}}",
"unable_to_complete_oauth_login": "Unable to complete OAuth login",
"unable_to_connect": "Unable to connect",
- "unable_to_connect_to_server": "Unable to connect to server",
"unable_to_copy_to_clipboard": "Cannot copy to clipboard, make sure you are accessing the page through https",
"unable_to_create_admin_account": "Unable to create admin account",
"unable_to_create_api_key": "Unable to create a new API Key",
@@ -925,14 +898,9 @@
"unable_to_hide_person": "Unable to hide person",
"unable_to_link_motion_video": "Unable to link motion video",
"unable_to_link_oauth_account": "Unable to link OAuth account",
- "unable_to_load_album": "Unable to load album",
- "unable_to_load_asset_activity": "Unable to load asset activity",
- "unable_to_load_items": "Unable to load items",
- "unable_to_load_liked_status": "Unable to load liked status",
"unable_to_log_out_all_devices": "Unable to log out all devices",
"unable_to_log_out_device": "Unable to log out device",
"unable_to_login_with_oauth": "Unable to login with OAuth",
- "unable_to_move_to_locked_folder": "Unable to move to locked folder",
"unable_to_play_video": "Unable to play video",
"unable_to_reassign_assets_existing_person": "Unable to reassign assets to {name, select, null {an existing person} other {{name}}}",
"unable_to_reassign_assets_new_person": "Unable to reassign assets to a new person",
@@ -940,11 +908,9 @@
"unable_to_remove_album_users": "Unable to remove users from album",
"unable_to_remove_api_key": "Unable to remove API Key",
"unable_to_remove_assets_from_shared_link": "Unable to remove assets from shared link",
- "unable_to_remove_deleted_assets": "Unable to remove offline files",
"unable_to_remove_library": "Unable to remove library",
"unable_to_remove_partner": "Unable to remove partner",
"unable_to_remove_reaction": "Unable to remove reaction",
- "unable_to_repair_items": "Unable to repair items",
"unable_to_reset_password": "Unable to reset password",
"unable_to_reset_pin_code": "Unable to reset PIN code",
"unable_to_resolve_duplicate": "Unable to resolve duplicate",
@@ -1027,6 +993,8 @@
"folders": "Folders",
"folders_feature_description": "Browsing the folder view for the photos and videos on the file system",
"forward": "Forward",
+ "gcast_enabled": "Google Cast",
+ "gcast_enabled_description": "This feature loads external resources from Google in order to work.",
"general": "General",
"get_help": "Get Help",
"get_wifiname_error": "Could not get Wi-Fi name. Make sure you have granted the necessary permissions and are connected to a Wi-Fi network",
@@ -1115,6 +1083,12 @@
"invalid_date_format": "Invalid date format",
"invite_people": "Invite People",
"invite_to_album": "Invite to album",
+ "ios_debug_info_fetch_ran_at": "Fetch ran {dateTime}",
+ "ios_debug_info_last_sync_at": "Last sync {dateTime}",
+ "ios_debug_info_no_processes_queued": "No background processes queued",
+ "ios_debug_info_no_sync_yet": "No background sync job has run yet",
+ "ios_debug_info_processes_queued": "{count, plural, one {{count} background process queued} other {{count} background processes queued}}",
+ "ios_debug_info_processing_ran_at": "Processing ran {dateTime}",
"items_count": "{count, plural, one {# item} other {# items}}",
"jobs": "Jobs",
"keep": "Keep",
@@ -1123,6 +1097,9 @@
"kept_this_deleted_others": "Kept this asset and deleted {count, plural, one {# asset} other {# assets}}",
"keyboard_shortcuts": "Keyboard shortcuts",
"language": "Language",
+ "language_no_results_subtitle": "Try adjusting your search term",
+ "language_no_results_title": "No languages found",
+ "language_search_hint": "Search languages...",
"language_setting_description": "Select your preferred language",
"last_seen": "Last seen",
"latest_version": "Latest Version",
@@ -1158,7 +1135,7 @@
"location_picker_longitude_error": "Enter a valid longitude",
"location_picker_longitude_hint": "Enter your longitude here",
"lock": "Lock",
- "locked_folder": "Locked folder",
+ "locked_folder": "Locked Folder",
"log_out": "Log out",
"log_out_all_devices": "Log Out All Devices",
"logged_out_all_devices": "Logged out all devices",
@@ -1316,15 +1293,15 @@
"oauth": "OAuth",
"official_immich_resources": "Official Immich Resources",
"offline": "Offline",
- "offline_paths": "Offline paths",
- "offline_paths_description": "These results may be due to manual deletion of files that are not part of an external library.",
"ok": "Ok",
"oldest_first": "Oldest first",
"on_this_device": "On this device",
"onboarding": "Onboarding",
- "onboarding_privacy_description": "The following (optional) features rely on external services, and can be disabled at any time in the administration settings.",
+ "onboarding_locale_description": "Select your preferred language. You can change this later in your settings.",
+ "onboarding_privacy_description": "The following (optional) features rely on external services, and can be disabled at any time in settings.",
+ "onboarding_server_welcome_description": "Let's get your instance set up with some common settings.",
"onboarding_theme_description": "Choose a color theme for your instance. You can change this later in your settings.",
- "onboarding_welcome_description": "Let's get your instance set up with some common settings.",
+ "onboarding_user_welcome_description": "Let's get you started!",
"onboarding_welcome_user": "Welcome, {user}",
"online": "Online",
"only_favorites": "Only favorites",
@@ -1636,6 +1613,7 @@
"server_info_box_server_url": "Server URL",
"server_offline": "Server Offline",
"server_online": "Server Online",
+ "server_privacy": "Server Privacy",
"server_stats": "Server Stats",
"server_version": "Server Version",
"set": "Set",
@@ -1653,7 +1631,6 @@
"setting_image_viewer_title": "Images",
"setting_languages_apply": "Apply",
"setting_languages_subtitle": "Change the app's language",
- "setting_languages_title": "Languages",
"setting_notifications_notify_failures_grace_period": "Notify background backup failures: {duration}",
"setting_notifications_notify_hours": "{count} hours",
"setting_notifications_notify_immediately": "immediately",
@@ -1880,8 +1857,6 @@
"unselect_all_duplicates": "Unselect all duplicates",
"unstack": "Un-stack",
"unstacked_assets_count": "Un-stacked {count, plural, one {# asset} other {# assets}}",
- "untracked_files": "Untracked files",
- "untracked_files_decription": "These files are not tracked by the application. They can be the results of failed moves, interrupted uploads, or left behind due to a bug",
"up_next": "Up next",
"updated_at": "Updated",
"updated_password": "Updated password",
@@ -1909,6 +1884,7 @@
"user_liked": "{user} liked {type, select, photo {this photo} video {this video} asset {this asset} other {it}}",
"user_pin_code_settings": "PIN Code",
"user_pin_code_settings_description": "Manage your PIN code",
+ "user_privacy": "User Privacy",
"user_purchase_settings": "Purchase",
"user_purchase_settings_description": "Manage your purchase",
"user_role_set": "Set {user} as {role}",
@@ -1924,11 +1900,6 @@
"version": "Version",
"version_announcement_closing": "Your friend, Alex",
"version_announcement_message": "Hi there! A new version of Immich is available. Please take some time to read the release notes to ensure your setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your Immich instance automatically.",
- "version_announcement_overlay_release_notes": "release notes",
- "version_announcement_overlay_text_1": "Hi friend, there is a new release of",
- "version_announcement_overlay_text_2": "please take your time to visit the ",
- "version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.",
- "version_announcement_overlay_title": "New Server Version Available 🎉",
"version_history": "Version History",
"version_history_item": "Installed {version} on {date}",
"video": "Video",
diff --git a/mobile/analysis_options.yaml b/mobile/analysis_options.yaml
index 854f852e3cc..dc81c10dece 100644
--- a/mobile/analysis_options.yaml
+++ b/mobile/analysis_options.yaml
@@ -55,6 +55,7 @@ custom_lint:
restrict: package:photo_manager
allowed:
# required / wanted
+ - 'lib/infrastructure/repositories/album_media.repository.dart'
- 'lib/repositories/{album,asset,file}_media.repository.dart'
# acceptable exceptions for the time being
- lib/entities/asset.entity.dart # to provide local AssetEntity for now
diff --git a/mobile/android/app/build.gradle b/mobile/android/app/build.gradle
index 0ec511d9f12..7455ae99a25 100644
--- a/mobile/android/app/build.gradle
+++ b/mobile/android/app/build.gradle
@@ -1,103 +1,106 @@
plugins {
- id "com.android.application"
- id "kotlin-android"
- id "dev.flutter.flutter-gradle-plugin"
- id 'com.google.devtools.ksp'
+ id "com.android.application"
+ id "kotlin-android"
+ id "dev.flutter.flutter-gradle-plugin"
+ id 'com.google.devtools.ksp'
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
- localPropertiesFile.withInputStream { localProperties.load(it) }
+ localPropertiesFile.withInputStream { localProperties.load(it) }
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
- flutterVersionCode = '1'
+ flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
- flutterVersionName = '1.0'
+ flutterVersionName = '1.0'
}
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
- keystorePropertiesFile.withInputStream { keystoreProperties.load(it) }
+ keystorePropertiesFile.withInputStream { keystoreProperties.load(it) }
}
android {
- compileSdkVersion 35
+ compileSdkVersion 35
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_17
- targetCompatibility JavaVersion.VERSION_17
- coreLibraryDesugaringEnabled true
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ coreLibraryDesugaringEnabled true
+ }
+
+ kotlinOptions {
+ jvmTarget = '17'
+ }
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ defaultConfig {
+ applicationId "app.alextran.immich"
+ minSdkVersion 26
+ targetSdkVersion 35
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ }
+
+ signingConfigs {
+ release {
+ def keyAliasVal = System.getenv("ALIAS")
+ def keyPasswordVal = System.getenv("ANDROID_KEY_PASSWORD")
+ def storePasswordVal = System.getenv("ANDROID_STORE_PASSWORD")
+
+ keyAlias keyAliasVal ? keyAliasVal : keystoreProperties['keyAlias']
+ keyPassword keyPasswordVal ? keyPasswordVal : keystoreProperties['keyPassword']
+ storeFile file("../key.jks") ? file("../key.jks") : file(keystoreProperties['storeFile'])
+ storePassword storePasswordVal ? storePasswordVal : keystoreProperties['storePassword']
+ }
+ }
+
+ buildTypes {
+ debug {
+ applicationIdSuffix '.debug'
+ versionNameSuffix '-DEBUG'
}
- kotlinOptions {
- jvmTarget = '17'
+ release {
+ signingConfig signingConfigs.release
}
-
- sourceSets {
- main.java.srcDirs += 'src/main/kotlin'
- }
-
- defaultConfig {
- applicationId "app.alextran.immich"
- minSdkVersion 26
- targetSdkVersion 35
- versionCode flutterVersionCode.toInteger()
- versionName flutterVersionName
- }
-
- signingConfigs {
- release {
- def keyAliasVal = System.getenv("ALIAS")
- def keyPasswordVal = System.getenv("ANDROID_KEY_PASSWORD")
- def storePasswordVal = System.getenv("ANDROID_STORE_PASSWORD")
-
- keyAlias keyAliasVal ? keyAliasVal : keystoreProperties['keyAlias']
- keyPassword keyPasswordVal ? keyPasswordVal : keystoreProperties['keyPassword']
- storeFile file("../key.jks") ? file("../key.jks") : file(keystoreProperties['storeFile'])
- storePassword storePasswordVal ? storePasswordVal : keystoreProperties['storePassword']
- }
- }
-
- buildTypes {
- debug {
- applicationIdSuffix '.debug'
- versionNameSuffix '-DEBUG'
- }
-
- release {
- signingConfig signingConfigs.release
- }
- }
- namespace 'app.alextran.immich'
+ }
+ namespace 'app.alextran.immich'
}
flutter {
- source '../..'
+ source '../..'
}
dependencies {
- def kotlin_version = '2.0.20'
- def kotlin_coroutines_version = '1.9.0'
- def work_version = '2.9.1'
- def concurrent_version = '1.2.0'
- def guava_version = '33.3.1-android'
- def glide_version = '4.16.0'
+ def kotlin_version = '2.0.20'
+ def kotlin_coroutines_version = '1.9.0'
+ def work_version = '2.9.1'
+ def concurrent_version = '1.2.0'
+ def guava_version = '33.3.1-android'
+ def glide_version = '4.16.0'
+ def serialization_version = '1.8.1'
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
- implementation "androidx.work:work-runtime-ktx:$work_version"
- implementation "androidx.concurrent:concurrent-futures:$concurrent_version"
- implementation "com.google.guava:guava:$guava_version"
- implementation "com.github.bumptech.glide:glide:$glide_version"
- ksp "com.github.bumptech.glide:ksp:$glide_version"
- coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.2'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
+ implementation "androidx.work:work-runtime-ktx:$work_version"
+ implementation "androidx.concurrent:concurrent-futures:$concurrent_version"
+ implementation "com.google.guava:guava:$guava_version"
+ implementation "com.github.bumptech.glide:glide:$glide_version"
+ implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$serialization_version"
+
+ ksp "com.github.bumptech.glide:ksp:$glide_version"
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.2'
}
// This is uncommented in F-Droid build script
diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt
index c1e5152d28b..f9c4ee2a1ff 100644
--- a/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt
+++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt
@@ -1,6 +1,11 @@
package app.alextran.immich
+import android.os.Build
+import android.os.ext.SdkExtensions
import androidx.annotation.NonNull
+import app.alextran.immich.sync.NativeSyncApi
+import app.alextran.immich.sync.NativeSyncApiImpl26
+import app.alextran.immich.sync.NativeSyncApiImpl30
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
@@ -10,5 +15,13 @@ class MainActivity : FlutterFragmentActivity() {
flutterEngine.plugins.add(BackgroundServicePlugin())
flutterEngine.plugins.add(HttpSSLOptionsPlugin())
// No need to set up method channel here as it's now handled in the plugin
+
+ val nativeSyncApiImpl =
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R || SdkExtensions.getExtensionVersion(Build.VERSION_CODES.R) < 1) {
+ NativeSyncApiImpl26(this)
+ } else {
+ NativeSyncApiImpl30(this)
+ }
+ NativeSyncApi.setUp(flutterEngine.dartExecutor.binaryMessenger, nativeSyncApiImpl)
}
}
diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt
new file mode 100644
index 00000000000..f4dbda730b0
--- /dev/null
+++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt
@@ -0,0 +1,393 @@
+// Autogenerated from Pigeon (v25.3.2), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
+
+package app.alextran.immich.sync
+
+import android.util.Log
+import io.flutter.plugin.common.BasicMessageChannel
+import io.flutter.plugin.common.BinaryMessenger
+import io.flutter.plugin.common.EventChannel
+import io.flutter.plugin.common.MessageCodec
+import io.flutter.plugin.common.StandardMethodCodec
+import io.flutter.plugin.common.StandardMessageCodec
+import java.io.ByteArrayOutputStream
+import java.nio.ByteBuffer
+private object MessagesPigeonUtils {
+
+ fun wrapResult(result: Any?): List {
+ return listOf(result)
+ }
+
+ fun wrapError(exception: Throwable): List {
+ return if (exception is FlutterError) {
+ listOf(
+ exception.code,
+ exception.message,
+ exception.details
+ )
+ } else {
+ listOf(
+ exception.javaClass.simpleName,
+ exception.toString(),
+ "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
+ )
+ }
+ }
+ fun deepEquals(a: Any?, b: Any?): Boolean {
+ if (a is ByteArray && b is ByteArray) {
+ return a.contentEquals(b)
+ }
+ if (a is IntArray && b is IntArray) {
+ return a.contentEquals(b)
+ }
+ if (a is LongArray && b is LongArray) {
+ return a.contentEquals(b)
+ }
+ if (a is DoubleArray && b is DoubleArray) {
+ return a.contentEquals(b)
+ }
+ if (a is Array<*> && b is Array<*>) {
+ return a.size == b.size &&
+ a.indices.all{ deepEquals(a[it], b[it]) }
+ }
+ if (a is List<*> && b is List<*>) {
+ return a.size == b.size &&
+ a.indices.all{ deepEquals(a[it], b[it]) }
+ }
+ if (a is Map<*, *> && b is Map<*, *>) {
+ return a.size == b.size && a.all {
+ (b as Map).containsKey(it.key) &&
+ deepEquals(it.value, b[it.key])
+ }
+ }
+ return a == b
+ }
+
+}
+
+/**
+ * Error class for passing custom error details to Flutter via a thrown PlatformException.
+ * @property code The error code.
+ * @property message The error message.
+ * @property details The error details. Must be a datatype supported by the api codec.
+ */
+class FlutterError (
+ val code: String,
+ override val message: String? = null,
+ val details: Any? = null
+) : Throwable()
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class PlatformAsset (
+ val id: String,
+ val name: String,
+ val type: Long,
+ val createdAt: Long? = null,
+ val updatedAt: Long? = null,
+ val durationInSeconds: Long
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): PlatformAsset {
+ val id = pigeonVar_list[0] as String
+ val name = pigeonVar_list[1] as String
+ val type = pigeonVar_list[2] as Long
+ val createdAt = pigeonVar_list[3] as Long?
+ val updatedAt = pigeonVar_list[4] as Long?
+ val durationInSeconds = pigeonVar_list[5] as Long
+ return PlatformAsset(id, name, type, createdAt, updatedAt, durationInSeconds)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ id,
+ name,
+ type,
+ createdAt,
+ updatedAt,
+ durationInSeconds,
+ )
+ }
+ override fun equals(other: Any?): Boolean {
+ if (other !is PlatformAsset) {
+ return false
+ }
+ if (this === other) {
+ return true
+ }
+ return MessagesPigeonUtils.deepEquals(toList(), other.toList()) }
+
+ override fun hashCode(): Int = toList().hashCode()
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class PlatformAlbum (
+ val id: String,
+ val name: String,
+ val updatedAt: Long? = null,
+ val isCloud: Boolean,
+ val assetCount: Long
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): PlatformAlbum {
+ val id = pigeonVar_list[0] as String
+ val name = pigeonVar_list[1] as String
+ val updatedAt = pigeonVar_list[2] as Long?
+ val isCloud = pigeonVar_list[3] as Boolean
+ val assetCount = pigeonVar_list[4] as Long
+ return PlatformAlbum(id, name, updatedAt, isCloud, assetCount)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ id,
+ name,
+ updatedAt,
+ isCloud,
+ assetCount,
+ )
+ }
+ override fun equals(other: Any?): Boolean {
+ if (other !is PlatformAlbum) {
+ return false
+ }
+ if (this === other) {
+ return true
+ }
+ return MessagesPigeonUtils.deepEquals(toList(), other.toList()) }
+
+ override fun hashCode(): Int = toList().hashCode()
+}
+
+/** Generated class from Pigeon that represents data sent in messages. */
+data class SyncDelta (
+ val hasChanges: Boolean,
+ val updates: List,
+ val deletes: List,
+ val assetAlbums: Map>
+)
+ {
+ companion object {
+ fun fromList(pigeonVar_list: List): SyncDelta {
+ val hasChanges = pigeonVar_list[0] as Boolean
+ val updates = pigeonVar_list[1] as List
+ val deletes = pigeonVar_list[2] as List
+ val assetAlbums = pigeonVar_list[3] as Map>
+ return SyncDelta(hasChanges, updates, deletes, assetAlbums)
+ }
+ }
+ fun toList(): List {
+ return listOf(
+ hasChanges,
+ updates,
+ deletes,
+ assetAlbums,
+ )
+ }
+ override fun equals(other: Any?): Boolean {
+ if (other !is SyncDelta) {
+ return false
+ }
+ if (this === other) {
+ return true
+ }
+ return MessagesPigeonUtils.deepEquals(toList(), other.toList()) }
+
+ override fun hashCode(): Int = toList().hashCode()
+}
+private open class MessagesPigeonCodec : StandardMessageCodec() {
+ override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
+ return when (type) {
+ 129.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformAsset.fromList(it)
+ }
+ }
+ 130.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ PlatformAlbum.fromList(it)
+ }
+ }
+ 131.toByte() -> {
+ return (readValue(buffer) as? List)?.let {
+ SyncDelta.fromList(it)
+ }
+ }
+ else -> super.readValueOfType(type, buffer)
+ }
+ }
+ override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
+ when (value) {
+ is PlatformAsset -> {
+ stream.write(129)
+ writeValue(stream, value.toList())
+ }
+ is PlatformAlbum -> {
+ stream.write(130)
+ writeValue(stream, value.toList())
+ }
+ is SyncDelta -> {
+ stream.write(131)
+ writeValue(stream, value.toList())
+ }
+ else -> super.writeValue(stream, value)
+ }
+ }
+}
+
+/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
+interface NativeSyncApi {
+ fun shouldFullSync(): Boolean
+ fun getMediaChanges(): SyncDelta
+ fun checkpointSync()
+ fun clearSyncCheckpoint()
+ fun getAssetIdsForAlbum(albumId: String): List
+ fun getAlbums(): List
+ fun getAssetsCountSince(albumId: String, timestamp: Long): Long
+ fun getAssetsForAlbum(albumId: String, updatedTimeCond: Long?): List
+
+ companion object {
+ /** The codec used by NativeSyncApi. */
+ val codec: MessageCodec by lazy {
+ MessagesPigeonCodec()
+ }
+ /** Sets up an instance of `NativeSyncApi` to handle messages through the `binaryMessenger`. */
+ @JvmOverloads
+ fun setUp(binaryMessenger: BinaryMessenger, api: NativeSyncApi?, messageChannelSuffix: String = "") {
+ val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
+ val taskQueue = binaryMessenger.makeBackgroundTaskQueue()
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.shouldFullSync$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ listOf(api.shouldFullSync())
+ } catch (exception: Throwable) {
+ MessagesPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getMediaChanges$separatedMessageChannelSuffix", codec, taskQueue)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ listOf(api.getMediaChanges())
+ } catch (exception: Throwable) {
+ MessagesPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.checkpointSync$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.checkpointSync()
+ listOf(null)
+ } catch (exception: Throwable) {
+ MessagesPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.clearSyncCheckpoint$separatedMessageChannelSuffix", codec)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ api.clearSyncCheckpoint()
+ listOf(null)
+ } catch (exception: Throwable) {
+ MessagesPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getAssetIdsForAlbum$separatedMessageChannelSuffix", codec, taskQueue)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val albumIdArg = args[0] as String
+ val wrapped: List = try {
+ listOf(api.getAssetIdsForAlbum(albumIdArg))
+ } catch (exception: Throwable) {
+ MessagesPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getAlbums$separatedMessageChannelSuffix", codec, taskQueue)
+ if (api != null) {
+ channel.setMessageHandler { _, reply ->
+ val wrapped: List = try {
+ listOf(api.getAlbums())
+ } catch (exception: Throwable) {
+ MessagesPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getAssetsCountSince$separatedMessageChannelSuffix", codec, taskQueue)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val albumIdArg = args[0] as String
+ val timestampArg = args[1] as Long
+ val wrapped: List = try {
+ listOf(api.getAssetsCountSince(albumIdArg, timestampArg))
+ } catch (exception: Throwable) {
+ MessagesPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ run {
+ val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getAssetsForAlbum$separatedMessageChannelSuffix", codec, taskQueue)
+ if (api != null) {
+ channel.setMessageHandler { message, reply ->
+ val args = message as List
+ val albumIdArg = args[0] as String
+ val updatedTimeCondArg = args[1] as Long?
+ val wrapped: List = try {
+ listOf(api.getAssetsForAlbum(albumIdArg, updatedTimeCondArg))
+ } catch (exception: Throwable) {
+ MessagesPigeonUtils.wrapError(exception)
+ }
+ reply.reply(wrapped)
+ }
+ } else {
+ channel.setMessageHandler(null)
+ }
+ }
+ }
+ }
+}
diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImpl26.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImpl26.kt
new file mode 100644
index 00000000000..5deacc30db1
--- /dev/null
+++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImpl26.kt
@@ -0,0 +1,24 @@
+package app.alextran.immich.sync
+
+import android.content.Context
+
+
+class NativeSyncApiImpl26(context: Context) : NativeSyncApiImplBase(context), NativeSyncApi {
+ override fun shouldFullSync(): Boolean {
+ return true
+ }
+
+ // No-op for Android 10 and below
+ override fun checkpointSync() {
+ // Cannot throw exception as this is called from the Dart side
+ // during the full sync process as well
+ }
+
+ override fun clearSyncCheckpoint() {
+ // No-op for Android 10 and below
+ }
+
+ override fun getMediaChanges(): SyncDelta {
+ throw IllegalStateException("Method not supported on this Android version.")
+ }
+}
diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImpl30.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImpl30.kt
new file mode 100644
index 00000000000..052032e143a
--- /dev/null
+++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/sync/MessagesImpl30.kt
@@ -0,0 +1,89 @@
+package app.alextran.immich.sync
+
+import android.content.Context
+import android.os.Build
+import android.provider.MediaStore
+import androidx.annotation.RequiresApi
+import androidx.annotation.RequiresExtension
+import kotlinx.serialization.json.Json
+
+@RequiresApi(Build.VERSION_CODES.Q)
+@RequiresExtension(extension = Build.VERSION_CODES.R, version = 1)
+class NativeSyncApiImpl30(context: Context) : NativeSyncApiImplBase(context), NativeSyncApi {
+ private val ctx: Context = context.applicationContext
+ private val prefs = ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE)
+
+ companion object {
+ const val SHARED_PREF_NAME = "Immich::MediaManager"
+ const val SHARED_PREF_MEDIA_STORE_VERSION_KEY = "MediaStore::getVersion"
+ const val SHARED_PREF_MEDIA_STORE_GEN_KEY = "MediaStore::getGeneration"
+ }
+
+ private fun getSavedGenerationMap(): Map {
+ return prefs.getString(SHARED_PREF_MEDIA_STORE_GEN_KEY, null)?.let {
+ Json.decodeFromString