Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6a4f48204d | |||
| 9cd0871178 | |||
| dbbefde98d | |||
| 5407a28533 | |||
| f5edc87e4d | |||
| bf16b61d43 | |||
| 8c882b54cd | |||
| 2d7c333c8c | |||
| 7c821dd205 | |||
| 703361da1a | |||
| fa5aeaf539 | |||
| 5f3a42a132 | |||
| 9d85272c2b | |||
| d2575d8f00 | |||
| f0a4c945bd | |||
| a3766b879e | |||
| 1a190c33a0 | |||
| 17a63e37b2 | |||
| bf1f8da884 | |||
| 2271984dbd | |||
| b40963ec52 | |||
| 735f8d661e | |||
| 8794c84e9d | |||
| cef19eed97 | |||
| 90c607c1a6 | |||
| 52b650093d | |||
| fe4c49c8e3 | |||
| 4cad23aaa3 | |||
| feba590de7 | |||
| 64f0333306 | |||
| 758bcd1e97 | |||
| fb21950ad8 | |||
| 758449e9f0 | |||
| d7d4d22fe0 | |||
| 03948a69e2 | |||
| 61b8eb85b5 |
@@ -56,10 +56,10 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3.3.0
|
uses: docker/setup-qemu-action@v3.4.0
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.8.0
|
uses: docker/setup-buildx-action@v3.9.0
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
@@ -88,7 +88,7 @@ jobs:
|
|||||||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||||
|
|
||||||
- name: Build and push image
|
- name: Build and push image
|
||||||
uses: docker/build-push-action@v6.12.0
|
uses: docker/build-push-action@v6.13.0
|
||||||
with:
|
with:
|
||||||
file: cli/Dockerfile
|
file: cli/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ jobs:
|
|||||||
TAG_NEW=${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
|
TAG_NEW=${{ github.event.number == 0 && github.ref_name || format('pr-{0}', github.event.number) }}${{ matrix.suffix }}
|
||||||
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_NEW $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
docker buildx imagetools create -t $REGISTRY_NAME/$REPOSITORY:$TAG_NEW $REGISTRY_NAME/$REPOSITORY:$TAG_OLD
|
||||||
|
|
||||||
|
|
||||||
build_and_push_ml:
|
build_and_push_ml:
|
||||||
name: Build and Push ML
|
name: Build and Push ML
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
@@ -122,10 +121,10 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3.3.0
|
uses: docker/setup-qemu-action@v3.4.0
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.8.0
|
uses: docker/setup-buildx-action@v3.9.0
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
# Only push to Docker Hub when making a release
|
# Only push to Docker Hub when making a release
|
||||||
@@ -174,7 +173,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Build and push image
|
- name: Build and push image
|
||||||
uses: docker/build-push-action@v6.12.0
|
uses: docker/build-push-action@v6.13.0
|
||||||
with:
|
with:
|
||||||
context: ${{ env.context }}
|
context: ${{ env.context }}
|
||||||
file: ${{ env.file }}
|
file: ${{ env.file }}
|
||||||
@@ -195,33 +194,38 @@ jobs:
|
|||||||
|
|
||||||
build_and_push_server:
|
build_and_push_server:
|
||||||
name: Build and Push Server
|
name: Build and Push Server
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.runner }}
|
||||||
needs: pre-job
|
needs: pre-job
|
||||||
if: ${{ needs.pre-job.outputs.should_run_server == 'true' }}
|
if: ${{ needs.pre-job.outputs.should_run_server == 'true' }}
|
||||||
env:
|
env:
|
||||||
image: immich-server
|
image: immich-server
|
||||||
context: .
|
context: .
|
||||||
file: server/Dockerfile
|
file: server/Dockerfile
|
||||||
|
GHCR_REPO: ghcr.io/${{ github.repository_owner }}/immich-server
|
||||||
|
DOCKER_REPO: altran1502/immich-server
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- platforms: linux/amd64,linux/arm64
|
- platform: linux/amd64
|
||||||
device: cpu
|
runner: ubuntu-latest
|
||||||
|
- platform: linux/arm64
|
||||||
|
runner: ubuntu-24.04-arm
|
||||||
steps:
|
steps:
|
||||||
|
- name: Prepare
|
||||||
|
run: |
|
||||||
|
platform=${{ matrix.platform }}
|
||||||
|
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v3.3.0
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3.8.0
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
# Only push to Docker Hub when making a release
|
|
||||||
if: ${{ github.event_name == 'release' }}
|
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
@@ -235,16 +239,81 @@ jobs:
|
|||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push image
|
||||||
|
id: build
|
||||||
|
uses: docker/build-push-action@v6.13.0
|
||||||
|
with:
|
||||||
|
context: ${{ env.context }}
|
||||||
|
file: ${{ env.file }}
|
||||||
|
platforms: ${{ matrix.platform }}
|
||||||
|
# Skip pushing when PR from a fork
|
||||||
|
push: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
|
labels: ${{ steps.metadata.outputs.labels }}
|
||||||
|
outputs: type=image,"name=${{ env.GHCR_REPO }},${{ env.DOCKER_REPO }}",push-by-digest=true,name-canonical=true,push=true
|
||||||
|
build-args: |
|
||||||
|
DEVICE=cpu
|
||||||
|
BUILD_ID=${{ github.run_id }}
|
||||||
|
BUILD_IMAGE=${{ github.event_name == 'release' && github.ref_name || steps.metadata.outputs.tags }}
|
||||||
|
BUILD_SOURCE_REF=${{ github.ref_name }}
|
||||||
|
BUILD_SOURCE_COMMIT=${{ github.sha }}
|
||||||
|
|
||||||
|
- name: Export digest
|
||||||
|
run: |
|
||||||
|
mkdir -p ${{ runner.temp }}/digests
|
||||||
|
digest="${{ steps.build.outputs.digest }}"
|
||||||
|
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||||
|
|
||||||
|
- name: Upload digest
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: digests-${{ env.PLATFORM_PAIR }}
|
||||||
|
path: ${{ runner.temp }}/digests/*
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
merge_server:
|
||||||
|
name: Merge & Push Server
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ needs.pre-job.outputs.should_run_server == 'true' && !github.event.pull_request.head.repo.fork }}
|
||||||
|
env:
|
||||||
|
GHCR_REPO: ghcr.io/${{ github.repository_owner }}/immich-server
|
||||||
|
DOCKER_REPO: altran1502/immich-server
|
||||||
|
needs:
|
||||||
|
- build_and_push_server
|
||||||
|
steps:
|
||||||
|
- name: Download digests
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: ${{ runner.temp }}/digests
|
||||||
|
pattern: digests-*
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Login to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Generate docker image tags
|
- name: Generate docker image tags
|
||||||
id: metadata
|
id: meta
|
||||||
uses: docker/metadata-action@v5
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
flavor: |
|
flavor: |
|
||||||
# Disable latest tag
|
# Disable latest tag
|
||||||
latest=false
|
latest=false
|
||||||
images: |
|
images: |
|
||||||
name=ghcr.io/${{ github.repository_owner }}/${{env.image}}
|
name=${{ env.GHCR_REPO }}
|
||||||
name=altran1502/${{env.image}},enable=${{ github.event_name == 'release' }}
|
name=${{ env.DOCKER_REPO }},enable=${{ github.event_name == 'release' }}
|
||||||
tags: |
|
tags: |
|
||||||
# Tag with branch name
|
# Tag with branch name
|
||||||
type=ref,event=branch,suffix=${{ matrix.suffix }}
|
type=ref,event=branch,suffix=${{ matrix.suffix }}
|
||||||
@@ -254,38 +323,16 @@ jobs:
|
|||||||
type=ref,event=tag,suffix=${{ matrix.suffix }}
|
type=ref,event=tag,suffix=${{ matrix.suffix }}
|
||||||
type=raw,value=release,enable=${{ github.event_name == 'release' }},suffix=${{ matrix.suffix }}
|
type=raw,value=release,enable=${{ github.event_name == 'release' }},suffix=${{ matrix.suffix }}
|
||||||
|
|
||||||
- name: Determine build cache output
|
- name: Create manifest list and push
|
||||||
id: cache-target
|
working-directory: ${{ runner.temp }}/digests
|
||||||
run: |
|
run: |
|
||||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||||
# Essentially just ignore the cache output (PR can't write to registry cache)
|
$(printf '${{ env.GHCR_REPO }}@sha256:%s ' *) \
|
||||||
echo "cache-to=type=local,dest=/tmp/discard,ignore-error=true" >> $GITHUB_OUTPUT
|
$(printf '${{ env.DOCKER_REPO }}@sha256:%s ' *)
|
||||||
else
|
|
||||||
echo "cache-to=type=registry,mode=max,ref=ghcr.io/${{ github.repository_owner }}/immich-build-cache:${{ env.image }}" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Build and push image
|
|
||||||
uses: docker/build-push-action@v6.12.0
|
|
||||||
with:
|
|
||||||
context: ${{ env.context }}
|
|
||||||
file: ${{ env.file }}
|
|
||||||
platforms: ${{ matrix.platforms }}
|
|
||||||
# Skip pushing when PR from a fork
|
|
||||||
push: ${{ !github.event.pull_request.head.repo.fork }}
|
|
||||||
cache-from: type=registry,ref=ghcr.io/${{ github.repository_owner }}/immich-build-cache:${{env.image}}
|
|
||||||
cache-to: ${{ steps.cache-target.outputs.cache-to }}
|
|
||||||
tags: ${{ steps.metadata.outputs.tags }}
|
|
||||||
labels: ${{ steps.metadata.outputs.labels }}
|
|
||||||
build-args: |
|
|
||||||
DEVICE=${{ matrix.device }}
|
|
||||||
BUILD_ID=${{ github.run_id }}
|
|
||||||
BUILD_IMAGE=${{ github.event_name == 'release' && github.ref_name || steps.metadata.outputs.tags }}
|
|
||||||
BUILD_SOURCE_REF=${{ github.ref_name }}
|
|
||||||
BUILD_SOURCE_COMMIT=${{ github.sha }}
|
|
||||||
|
|
||||||
success-check-server:
|
success-check-server:
|
||||||
name: Docker Build & Push Server Success
|
name: Docker Build & Push Server Success
|
||||||
needs: [build_and_push_server, retag_server]
|
needs: [merge_server, retag_server]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: always()
|
if: always()
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
name: Preview comment
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [labeled]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
comment-status:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.event.label.name == 'preview' }}
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: mshick/add-pr-comment@v2
|
||||||
|
with:
|
||||||
|
message-id: "preview-status"
|
||||||
|
message: "Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.cloud/"
|
||||||
Generated
+136
-132
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.48",
|
"version": "2.2.50",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.48",
|
"version": "2.2.50",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"@types/cli-progress": "^3.11.0",
|
"@types/cli-progress": "^3.11.0",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/mock-fs": "^4.13.1",
|
"@types/mock-fs": "^4.13.1",
|
||||||
"@types/node": "^22.10.9",
|
"@types/node": "^22.13.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
||||||
"@typescript-eslint/parser": "^8.15.0",
|
"@typescript-eslint/parser": "^8.15.0",
|
||||||
"@vitest/coverage-v8": "^3.0.0",
|
"@vitest/coverage-v8": "^3.0.0",
|
||||||
@@ -52,14 +52,14 @@
|
|||||||
},
|
},
|
||||||
"../open-api/typescript-sdk": {
|
"../open-api/typescript-sdk": {
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.125.7",
|
"version": "1.126.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oazapfts/runtime": "^1.0.2"
|
"@oazapfts/runtime": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.10.9",
|
"@types/node": "^22.13.1",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -881,9 +881,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/js": {
|
"node_modules/@eslint/js": {
|
||||||
"version": "9.18.0",
|
"version": "9.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz",
|
||||||
"integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==",
|
"integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1482,9 +1482,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.10.9",
|
"version": "22.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
|
||||||
"integrity": "sha512-Ir6hwgsKyNESl/gLOcEz3krR4CBGgliDqBQ2ma4wIhEx0w+xnoeTq3tdrNw15kU3SxogDjOgv9sqdtLW8mIHaw==",
|
"integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1498,21 +1498,21 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "8.20.0",
|
"version": "8.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz",
|
||||||
"integrity": "sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==",
|
"integrity": "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.10.0",
|
||||||
"@typescript-eslint/scope-manager": "8.20.0",
|
"@typescript-eslint/scope-manager": "8.23.0",
|
||||||
"@typescript-eslint/type-utils": "8.20.0",
|
"@typescript-eslint/type-utils": "8.23.0",
|
||||||
"@typescript-eslint/utils": "8.20.0",
|
"@typescript-eslint/utils": "8.23.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.20.0",
|
"@typescript-eslint/visitor-keys": "8.23.0",
|
||||||
"graphemer": "^1.4.0",
|
"graphemer": "^1.4.0",
|
||||||
"ignore": "^5.3.1",
|
"ignore": "^5.3.1",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"ts-api-utils": "^2.0.0"
|
"ts-api-utils": "^2.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -1528,16 +1528,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "8.20.0",
|
"version": "8.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.23.0.tgz",
|
||||||
"integrity": "sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g==",
|
"integrity": "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.20.0",
|
"@typescript-eslint/scope-manager": "8.23.0",
|
||||||
"@typescript-eslint/types": "8.20.0",
|
"@typescript-eslint/types": "8.23.0",
|
||||||
"@typescript-eslint/typescript-estree": "8.20.0",
|
"@typescript-eslint/typescript-estree": "8.23.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.20.0",
|
"@typescript-eslint/visitor-keys": "8.23.0",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1553,14 +1553,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "8.20.0",
|
"version": "8.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz",
|
||||||
"integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==",
|
"integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.20.0",
|
"@typescript-eslint/types": "8.23.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.20.0"
|
"@typescript-eslint/visitor-keys": "8.23.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -1571,16 +1571,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "8.20.0",
|
"version": "8.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz",
|
||||||
"integrity": "sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA==",
|
"integrity": "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/typescript-estree": "8.20.0",
|
"@typescript-eslint/typescript-estree": "8.23.0",
|
||||||
"@typescript-eslint/utils": "8.20.0",
|
"@typescript-eslint/utils": "8.23.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"ts-api-utils": "^2.0.0"
|
"ts-api-utils": "^2.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -1595,9 +1595,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "8.20.0",
|
"version": "8.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz",
|
||||||
"integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==",
|
"integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1609,20 +1609,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "8.20.0",
|
"version": "8.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz",
|
||||||
"integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==",
|
"integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.20.0",
|
"@typescript-eslint/types": "8.23.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.20.0",
|
"@typescript-eslint/visitor-keys": "8.23.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
"minimatch": "^9.0.4",
|
"minimatch": "^9.0.4",
|
||||||
"semver": "^7.6.0",
|
"semver": "^7.6.0",
|
||||||
"ts-api-utils": "^2.0.0"
|
"ts-api-utils": "^2.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -1636,16 +1636,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "8.20.0",
|
"version": "8.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz",
|
||||||
"integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==",
|
"integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.4.0",
|
"@eslint-community/eslint-utils": "^4.4.0",
|
||||||
"@typescript-eslint/scope-manager": "8.20.0",
|
"@typescript-eslint/scope-manager": "8.23.0",
|
||||||
"@typescript-eslint/types": "8.20.0",
|
"@typescript-eslint/types": "8.23.0",
|
||||||
"@typescript-eslint/typescript-estree": "8.20.0"
|
"@typescript-eslint/typescript-estree": "8.23.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -1660,13 +1660,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "8.20.0",
|
"version": "8.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz",
|
||||||
"integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==",
|
"integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.20.0",
|
"@typescript-eslint/types": "8.23.0",
|
||||||
"eslint-visitor-keys": "^4.2.0"
|
"eslint-visitor-keys": "^4.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1691,9 +1691,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/coverage-v8": {
|
"node_modules/@vitest/coverage-v8": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.5.tgz",
|
||||||
"integrity": "sha512-uVbJ/xhImdNtzPnLyxCZJMTeTIYdgcC2nWtBBBpR1H6z0w8m7D+9/zrDIx2nNxgMg9r+X8+RY2qVpUDeW2b3nw==",
|
"integrity": "sha512-zOOWIsj5fHh3jjGwQg+P+J1FW3s4jBu1Zqga0qW60yutsBtqEqNEJKWYh7cYn1yGD+1bdPsPdC/eL4eVK56xMg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1714,8 +1714,8 @@
|
|||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@vitest/browser": "3.0.3",
|
"@vitest/browser": "3.0.5",
|
||||||
"vitest": "3.0.3"
|
"vitest": "3.0.5"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@vitest/browser": {
|
"@vitest/browser": {
|
||||||
@@ -1724,14 +1724,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/expect": {
|
"node_modules/@vitest/expect": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.5.tgz",
|
||||||
"integrity": "sha512-SbRCHU4qr91xguu+dH3RUdI5dC86zm8aZWydbp961aIR7G8OYNN6ZiayFuf9WAngRbFOfdrLHCGgXTj3GtoMRQ==",
|
"integrity": "sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/spy": "3.0.3",
|
"@vitest/spy": "3.0.5",
|
||||||
"@vitest/utils": "3.0.3",
|
"@vitest/utils": "3.0.5",
|
||||||
"chai": "^5.1.2",
|
"chai": "^5.1.2",
|
||||||
"tinyrainbow": "^2.0.0"
|
"tinyrainbow": "^2.0.0"
|
||||||
},
|
},
|
||||||
@@ -1740,13 +1740,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/mocker": {
|
"node_modules/@vitest/mocker": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.5.tgz",
|
||||||
"integrity": "sha512-XT2XBc4AN9UdaxJAeIlcSZ0ILi/GzmG5G8XSly4gaiqIvPV3HMTSIDZWJVX6QRJ0PX1m+W8Cy0K9ByXNb/bPIA==",
|
"integrity": "sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/spy": "3.0.3",
|
"@vitest/spy": "3.0.5",
|
||||||
"estree-walker": "^3.0.3",
|
"estree-walker": "^3.0.3",
|
||||||
"magic-string": "^0.30.17"
|
"magic-string": "^0.30.17"
|
||||||
},
|
},
|
||||||
@@ -1767,9 +1767,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/pretty-format": {
|
"node_modules/@vitest/pretty-format": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.5.tgz",
|
||||||
"integrity": "sha512-gCrM9F7STYdsDoNjGgYXKPq4SkSxwwIU5nkaQvdUxiQ0EcNlez+PdKOVIsUJvh9P9IeIFmjn4IIREWblOBpP2Q==",
|
"integrity": "sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1780,38 +1780,38 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/runner": {
|
"node_modules/@vitest/runner": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.5.tgz",
|
||||||
"integrity": "sha512-Rgi2kOAk5ZxWZlwPguRJFOBmWs6uvvyAAR9k3MvjRvYrG7xYvKChZcmnnpJCS98311CBDMqsW9MzzRFsj2gX3g==",
|
"integrity": "sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/utils": "3.0.3",
|
"@vitest/utils": "3.0.5",
|
||||||
"pathe": "^2.0.1"
|
"pathe": "^2.0.2"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/snapshot": {
|
"node_modules/@vitest/snapshot": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.5.tgz",
|
||||||
"integrity": "sha512-kNRcHlI4txBGztuJfPEJ68VezlPAXLRT1u5UCx219TU3kOG2DplNxhWLwDf2h6emwmTPogzLnGVwP6epDaJN6Q==",
|
"integrity": "sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/pretty-format": "3.0.3",
|
"@vitest/pretty-format": "3.0.5",
|
||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
"pathe": "^2.0.1"
|
"pathe": "^2.0.2"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/spy": {
|
"node_modules/@vitest/spy": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.5.tgz",
|
||||||
"integrity": "sha512-7/dgux8ZBbF7lEIKNnEqQlyRaER9nkAL9eTmdKJkDO3hS8p59ATGwKOCUDHcBLKr7h/oi/6hP+7djQk8049T2A==",
|
"integrity": "sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1822,13 +1822,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vitest/utils": {
|
"node_modules/@vitest/utils": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.5.tgz",
|
||||||
"integrity": "sha512-f+s8CvyzPtMFY1eZKkIHGhPsQgYo5qCm6O8KZoim9qm1/jT64qBgGpO5tHscNH6BzRHM+edLNOP+3vO8+8pE/A==",
|
"integrity": "sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/pretty-format": "3.0.3",
|
"@vitest/pretty-format": "3.0.5",
|
||||||
"loupe": "^3.1.2",
|
"loupe": "^3.1.2",
|
||||||
"tinyrainbow": "^2.0.0"
|
"tinyrainbow": "^2.0.0"
|
||||||
},
|
},
|
||||||
@@ -2334,9 +2334,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "9.18.0",
|
"version": "9.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz",
|
||||||
"integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==",
|
"integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -2345,7 +2345,7 @@
|
|||||||
"@eslint/config-array": "^0.19.0",
|
"@eslint/config-array": "^0.19.0",
|
||||||
"@eslint/core": "^0.10.0",
|
"@eslint/core": "^0.10.0",
|
||||||
"@eslint/eslintrc": "^3.2.0",
|
"@eslint/eslintrc": "^3.2.0",
|
||||||
"@eslint/js": "9.18.0",
|
"@eslint/js": "9.19.0",
|
||||||
"@eslint/plugin-kit": "^0.2.5",
|
"@eslint/plugin-kit": "^0.2.5",
|
||||||
"@humanfs/node": "^0.16.6",
|
"@humanfs/node": "^0.16.6",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
@@ -2407,9 +2407,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-prettier": {
|
"node_modules/eslint-plugin-prettier": {
|
||||||
"version": "5.2.2",
|
"version": "5.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.3.tgz",
|
||||||
"integrity": "sha512-1yI3/hf35wmlq66C8yOyrujQnel+v5l1Vop5Cl2I6ylyNTT1JbuUUnV3/41PzwTzcyDp/oF0jWE3HXvcH5AQOQ==",
|
"integrity": "sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -2685,9 +2685,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/fastq": {
|
"node_modules/fastq": {
|
||||||
"version": "1.18.0",
|
"version": "1.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
|
||||||
"integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==",
|
"integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"reusify": "^1.0.4"
|
"reusify": "^1.0.4"
|
||||||
@@ -3180,9 +3180,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/loupe": {
|
"node_modules/loupe": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz",
|
||||||
"integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==",
|
"integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -3285,9 +3285,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mock-fs": {
|
"node_modules/mock-fs": {
|
||||||
"version": "5.4.1",
|
"version": "5.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-5.5.0.tgz",
|
||||||
"integrity": "sha512-sz/Q8K1gXXXHR+qr0GZg2ysxCRr323kuN10O7CtQjraJsFDJ4SJ+0I5MzALz7aRp9lHk8Cc/YdsT95h9Ka1aFw==",
|
"integrity": "sha512-d/P1M/RacgM3dB0sJ8rjeRNXxtapkPCUnMGmIN0ixJ16F/E4GUZCvWcSGfWGz8eaXYvn1s9baUwNjI4LOPEjiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -4166,9 +4166,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ts-api-utils": {
|
"node_modules/ts-api-utils": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz",
|
||||||
"integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==",
|
"integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -4288,15 +4288,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "6.0.11",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz",
|
||||||
"integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==",
|
"integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.24.2",
|
"esbuild": "^0.24.2",
|
||||||
"postcss": "^8.4.49",
|
"postcss": "^8.5.1",
|
||||||
"rollup": "^4.23.0"
|
"rollup": "^4.30.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"vite": "bin/vite.js"
|
"vite": "bin/vite.js"
|
||||||
@@ -4360,16 +4360,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite-node": {
|
"node_modules/vite-node": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.5.tgz",
|
||||||
"integrity": "sha512-0sQcwhwAEw/UJGojbhOrnq3HtiZ3tC7BzpAa0lx3QaTX0S3YX70iGcik25UBdB96pmdwjyY2uyKNYruxCDmiEg==",
|
"integrity": "sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cac": "^6.7.14",
|
"cac": "^6.7.14",
|
||||||
"debug": "^4.4.0",
|
"debug": "^4.4.0",
|
||||||
"es-module-lexer": "^1.6.0",
|
"es-module-lexer": "^1.6.0",
|
||||||
"pathe": "^2.0.1",
|
"pathe": "^2.0.2",
|
||||||
"vite": "^5.0.0 || ^6.0.0"
|
"vite": "^5.0.0 || ^6.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -4403,31 +4403,31 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vitest": {
|
"node_modules/vitest": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.5.tgz",
|
||||||
"integrity": "sha512-dWdwTFUW9rcnL0LyF2F+IfvNQWB0w9DERySCk8VMG75F8k25C7LsZoh6XfCjPvcR8Nb+Lqi9JKr6vnzH7HSrpQ==",
|
"integrity": "sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vitest/expect": "3.0.3",
|
"@vitest/expect": "3.0.5",
|
||||||
"@vitest/mocker": "3.0.3",
|
"@vitest/mocker": "3.0.5",
|
||||||
"@vitest/pretty-format": "^3.0.3",
|
"@vitest/pretty-format": "^3.0.5",
|
||||||
"@vitest/runner": "3.0.3",
|
"@vitest/runner": "3.0.5",
|
||||||
"@vitest/snapshot": "3.0.3",
|
"@vitest/snapshot": "3.0.5",
|
||||||
"@vitest/spy": "3.0.3",
|
"@vitest/spy": "3.0.5",
|
||||||
"@vitest/utils": "3.0.3",
|
"@vitest/utils": "3.0.5",
|
||||||
"chai": "^5.1.2",
|
"chai": "^5.1.2",
|
||||||
"debug": "^4.4.0",
|
"debug": "^4.4.0",
|
||||||
"expect-type": "^1.1.0",
|
"expect-type": "^1.1.0",
|
||||||
"magic-string": "^0.30.17",
|
"magic-string": "^0.30.17",
|
||||||
"pathe": "^2.0.1",
|
"pathe": "^2.0.2",
|
||||||
"std-env": "^3.8.0",
|
"std-env": "^3.8.0",
|
||||||
"tinybench": "^2.9.0",
|
"tinybench": "^2.9.0",
|
||||||
"tinyexec": "^0.3.2",
|
"tinyexec": "^0.3.2",
|
||||||
"tinypool": "^1.0.2",
|
"tinypool": "^1.0.2",
|
||||||
"tinyrainbow": "^2.0.0",
|
"tinyrainbow": "^2.0.0",
|
||||||
"vite": "^5.0.0 || ^6.0.0",
|
"vite": "^5.0.0 || ^6.0.0",
|
||||||
"vite-node": "3.0.3",
|
"vite-node": "3.0.5",
|
||||||
"why-is-node-running": "^2.3.0"
|
"why-is-node-running": "^2.3.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -4441,9 +4441,10 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@edge-runtime/vm": "*",
|
"@edge-runtime/vm": "*",
|
||||||
|
"@types/debug": "^4.1.12",
|
||||||
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
|
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
|
||||||
"@vitest/browser": "3.0.3",
|
"@vitest/browser": "3.0.5",
|
||||||
"@vitest/ui": "3.0.3",
|
"@vitest/ui": "3.0.5",
|
||||||
"happy-dom": "*",
|
"happy-dom": "*",
|
||||||
"jsdom": "*"
|
"jsdom": "*"
|
||||||
},
|
},
|
||||||
@@ -4451,6 +4452,9 @@
|
|||||||
"@edge-runtime/vm": {
|
"@edge-runtime/vm": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
"@types/debug": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/cli",
|
"name": "@immich/cli",
|
||||||
"version": "2.2.48",
|
"version": "2.2.50",
|
||||||
"description": "Command Line Interface (CLI) for Immich",
|
"description": "Command Line Interface (CLI) for Immich",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"exports": "./dist/index.js",
|
"exports": "./dist/index.js",
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"@types/cli-progress": "^3.11.0",
|
"@types/cli-progress": "^3.11.0",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/mock-fs": "^4.13.1",
|
"@types/mock-fs": "^4.13.1",
|
||||||
"@types/node": "^22.10.9",
|
"@types/node": "^22.13.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
"@typescript-eslint/eslint-plugin": "^8.15.0",
|
||||||
"@typescript-eslint/parser": "^8.15.0",
|
"@typescript-eslint/parser": "^8.15.0",
|
||||||
"@vitest/coverage-v8": "^3.0.0",
|
"@vitest/coverage-v8": "^3.0.0",
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ services:
|
|||||||
command: ['./run.sh', '-disable-reporting']
|
command: ['./run.sh', '-disable-reporting']
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
image: grafana/grafana:11.5.0-ubuntu@sha256:3c9e2b202eb933a22da5f2b5a22c98a665493f603b452263d9d6f242a87f60d7
|
image: grafana/grafana:11.5.1-ubuntu@sha256:9a4ab78cec1a2ec7d1ca5dfd5aacec6412706a1bc9e971fc7184e2f6696a63f5
|
||||||
volumes:
|
volumes:
|
||||||
- grafana-data:/var/lib/grafana
|
- grafana-data:/var/lib/grafana
|
||||||
|
|
||||||
|
|||||||
@@ -77,9 +77,7 @@ docker start immich_postgres # Start Postgres server
|
|||||||
sleep 10 # Wait for Postgres server to start up
|
sleep 10 # Wait for Postgres server to start up
|
||||||
docker exec -it immich_postgres bash # Enter the Docker shell and run the following command
|
docker exec -it immich_postgres bash # Enter the Docker shell and run the following command
|
||||||
# Check the database user if you deviated from the default. If your backup ends in `.gz`, replace `cat` with `gunzip`
|
# Check the database user if you deviated from the default. If your backup ends in `.gz`, replace `cat` with `gunzip`
|
||||||
cat < "/dump.sql" \
|
cat < "/dump.sql" | sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" | psql --dbname=postgres --username=<DB_USERNAME>
|
||||||
| sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" \
|
|
||||||
| psql --dbname=postgres --username=<DB_USERNAME> # Restore Backup
|
|
||||||
exit # Exit the Docker shell
|
exit # Exit the Docker shell
|
||||||
docker compose up -d # Start remainder of Immich apps
|
docker compose up -d # Start remainder of Immich apps
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export default function VersionSwitcher(): JSX.Element {
|
|||||||
mobile={windowSize === 'mobile'}
|
mobile={windowSize === 'mobile'}
|
||||||
items={versions.map(({ label, url }) => ({
|
items={versions.map(({ label, url }) => ({
|
||||||
label,
|
label,
|
||||||
to: url + location.pathname,
|
to: url + location.pathname + location.hash,
|
||||||
target: '_self',
|
target: '_self',
|
||||||
}))}
|
}))}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ function HomepageHeader() {
|
|||||||
|
|
||||||
<Link
|
<Link
|
||||||
className="flex place-items-center place-content-center py-3 px-8 border bg-immich-primary/10 dark:bg-gray-300 rounded-xl hover:no-underline text-immich-primary dark:text-immich-dark-bg font-bold uppercase"
|
className="flex place-items-center place-content-center py-3 px-8 border bg-immich-primary/10 dark:bg-gray-300 rounded-xl hover:no-underline text-immich-primary dark:text-immich-dark-bg font-bold uppercase"
|
||||||
to="https://demo.immich.app/"
|
to="https://immich.store"
|
||||||
>
|
>
|
||||||
Buy Merch
|
Buy Merch
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
Vendored
+8
@@ -1,4 +1,12 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"label": "v1.126.1",
|
||||||
|
"url": "https://v1.126.1.archive.immich.app"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "v1.126.0",
|
||||||
|
"url": "https://v1.126.0.archive.immich.app"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "v1.125.7",
|
"label": "v1.125.7",
|
||||||
"url": "https://v1.125.7.archive.immich.app"
|
"url": "https://v1.125.7.archive.immich.app"
|
||||||
|
|||||||
Generated
+448
-362
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "immich-e2e",
|
"name": "immich-e2e",
|
||||||
"version": "1.125.7",
|
"version": "1.126.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"@immich/sdk": "file:../open-api/typescript-sdk",
|
"@immich/sdk": "file:../open-api/typescript-sdk",
|
||||||
"@playwright/test": "^1.44.1",
|
"@playwright/test": "^1.44.1",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
"@types/node": "^22.10.9",
|
"@types/node": "^22.13.1",
|
||||||
"@types/oidc-provider": "^8.5.1",
|
"@types/oidc-provider": "^8.5.1",
|
||||||
"@types/pg": "^8.11.0",
|
"@types/pg": "^8.11.0",
|
||||||
"@types/pngjs": "^6.0.4",
|
"@types/pngjs": "^6.0.4",
|
||||||
|
|||||||
@@ -298,6 +298,7 @@ describe('/libraries', () => {
|
|||||||
expect(status).toBe(204);
|
expect(status).toBe(204);
|
||||||
|
|
||||||
await utils.waitForQueueFinish(admin.accessToken, 'library');
|
await utils.waitForQueueFinish(admin.accessToken, 'library');
|
||||||
|
await utils.waitForQueueFinish(admin.accessToken, 'metadataExtraction');
|
||||||
|
|
||||||
const { assets } = await utils.searchAssets(admin.accessToken, {
|
const { assets } = await utils.searchAssets(admin.accessToken, {
|
||||||
originalPath: `${testAssetDirInternal}/temp/directoryA/assetA.png`,
|
originalPath: `${testAssetDirInternal}/temp/directoryA/assetA.png`,
|
||||||
|
|||||||
@@ -150,6 +150,30 @@ describe('/shared-links', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should filter on albumId', async () => {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.get(`/shared-links?albumId=${album.id}`)
|
||||||
|
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||||
|
|
||||||
|
expect(status).toBe(200);
|
||||||
|
expect(body).toHaveLength(2);
|
||||||
|
expect(body).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({ id: linkWithAlbum.id }),
|
||||||
|
expect.objectContaining({ id: linkWithPassword.id }),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find 0 albums', async () => {
|
||||||
|
const { status, body } = await request(app)
|
||||||
|
.get(`/shared-links?albumId=${uuidDto.notFound}`)
|
||||||
|
.set('Authorization', `Bearer ${user1.accessToken}`);
|
||||||
|
|
||||||
|
expect(status).toBe(200);
|
||||||
|
expect(body).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
it('should not get shared links created by other users', async () => {
|
it('should not get shared links created by other users', async () => {
|
||||||
const { status, body } = await request(app)
|
const { status, body } = await request(app)
|
||||||
.get('/shared-links')
|
.get('/shared-links')
|
||||||
|
|||||||
@@ -602,6 +602,8 @@
|
|||||||
"enable": "Enable",
|
"enable": "Enable",
|
||||||
"enabled": "Enabled",
|
"enabled": "Enabled",
|
||||||
"end_date": "End date",
|
"end_date": "End date",
|
||||||
|
"rotate_left": "Rotate left",
|
||||||
|
"rotate_right": "Rotate right",
|
||||||
"error": "Error",
|
"error": "Error",
|
||||||
"error_loading_image": "Error loading image",
|
"error_loading_image": "Error loading image",
|
||||||
"error_title": "Error - Something went wrong",
|
"error_title": "Error - Something went wrong",
|
||||||
@@ -644,6 +646,7 @@
|
|||||||
"quota_higher_than_disk_size": "You set a quota higher than the disk size",
|
"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}}",
|
"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_album_users": "Unable to add users to album",
|
||||||
|
"unable_to_rotate_image": "Unable to rotate image",
|
||||||
"unable_to_add_assets_to_shared_link": "Unable to add assets to shared link",
|
"unable_to_add_assets_to_shared_link": "Unable to add assets to shared link",
|
||||||
"unable_to_add_comment": "Unable to add comment",
|
"unable_to_add_comment": "Unable to add comment",
|
||||||
"unable_to_add_exclusion_pattern": "Unable to add exclusion pattern",
|
"unable_to_add_exclusion_pattern": "Unable to add exclusion pattern",
|
||||||
|
|||||||
+437
-437
@@ -312,157 +312,157 @@
|
|||||||
"admin_password": "رمز عبور مدیر",
|
"admin_password": "رمز عبور مدیر",
|
||||||
"administration": "مدیریت",
|
"administration": "مدیریت",
|
||||||
"advanced": "پیشرفته",
|
"advanced": "پیشرفته",
|
||||||
"album_added": "",
|
"album_added": "آلبوم اضافه شد",
|
||||||
"album_added_notification_setting_description": "",
|
"album_added_notification_setting_description": "",
|
||||||
"album_cover_updated": "",
|
"album_cover_updated": "جلد آلبوم بهروزرسانی شد",
|
||||||
"album_info_updated": "",
|
"album_info_updated": "اطلاعات آلبوم بهروزرسانی شد",
|
||||||
"album_name": "",
|
"album_name": "نام آلبوم",
|
||||||
"album_options": "",
|
"album_options": "گزینههای آلبوم",
|
||||||
"album_updated": "",
|
"album_updated": "آلبوم بهروزرسانی شد",
|
||||||
"album_updated_setting_description": "",
|
"album_updated_setting_description": "",
|
||||||
"albums": "",
|
"albums": "آلبومها",
|
||||||
"albums_count": "",
|
"albums_count": "",
|
||||||
"all": "",
|
"all": "همه",
|
||||||
"all_people": "",
|
"all_people": "همه افراد",
|
||||||
"allow_dark_mode": "",
|
"allow_dark_mode": "اجازه دادن به حالت تاریک",
|
||||||
"allow_edits": "",
|
"allow_edits": "اجازه ویرایش",
|
||||||
"api_key": "",
|
"api_key": "کلید API",
|
||||||
"api_keys": "",
|
"api_keys": "کلیدهای API",
|
||||||
"app_settings": "",
|
"app_settings": "تنظیمات برنامه",
|
||||||
"appears_in": "",
|
"appears_in": "ظاهر میشود در",
|
||||||
"archive": "",
|
"archive": "بایگانی",
|
||||||
"archive_or_unarchive_photo": "",
|
"archive_or_unarchive_photo": "",
|
||||||
"archive_size": "",
|
"archive_size": "اندازه بایگانی",
|
||||||
"archive_size_description": "",
|
"archive_size_description": "",
|
||||||
"asset_offline": "",
|
"asset_offline": "محتوا آفلاین",
|
||||||
"assets": "",
|
"assets": "محتواها",
|
||||||
"authorized_devices": "",
|
"authorized_devices": "دستگاههای مجاز",
|
||||||
"back": "",
|
"back": "بازگشت",
|
||||||
"backward": "",
|
"backward": "عقب",
|
||||||
"blurred_background": "",
|
"blurred_background": "پسزمینه محو",
|
||||||
"bulk_delete_duplicates_confirmation": "",
|
"bulk_delete_duplicates_confirmation": "",
|
||||||
"bulk_keep_duplicates_confirmation": "",
|
"bulk_keep_duplicates_confirmation": "",
|
||||||
"bulk_trash_duplicates_confirmation": "",
|
"bulk_trash_duplicates_confirmation": "",
|
||||||
"camera": "",
|
"camera": "دوربین",
|
||||||
"camera_brand": "",
|
"camera_brand": "برند دوربین",
|
||||||
"camera_model": "",
|
"camera_model": "مدل دوربین",
|
||||||
"cancel": "",
|
"cancel": "لغو",
|
||||||
"cancel_search": "",
|
"cancel_search": "لغو جستجو",
|
||||||
"cannot_merge_people": "",
|
"cannot_merge_people": "نمیتوان افراد را ادغام کرد",
|
||||||
"cannot_update_the_description": "",
|
"cannot_update_the_description": "نمیتوان توضیحات را بهروزرسانی کرد",
|
||||||
"change_date": "",
|
"change_date": "تغییر تاریخ",
|
||||||
"change_expiration_time": "",
|
"change_expiration_time": "تغییر زمان انقضا",
|
||||||
"change_location": "",
|
"change_location": "تغییر مکان",
|
||||||
"change_name": "",
|
"change_name": "تغییر نام",
|
||||||
"change_name_successfully": "",
|
"change_name_successfully": "نام با موفقیت تغییر یافت",
|
||||||
"change_password": "",
|
"change_password": "تغییر رمز عبور",
|
||||||
"change_your_password": "",
|
"change_your_password": "رمز عبور خود را تغییر دهید",
|
||||||
"changed_visibility_successfully": "",
|
"changed_visibility_successfully": "",
|
||||||
"check_all": "",
|
"check_all": "انتخاب همه",
|
||||||
"check_logs": "",
|
"check_logs": "بررسی لاگها",
|
||||||
"choose_matching_people_to_merge": "",
|
"choose_matching_people_to_merge": "",
|
||||||
"city": "",
|
"city": "شهر",
|
||||||
"clear": "",
|
"clear": "پاک کردن",
|
||||||
"clear_all": "",
|
"clear_all": "پاک کردن همه",
|
||||||
"clear_message": "",
|
"clear_message": "پاک کردن پیام",
|
||||||
"clear_value": "",
|
"clear_value": "پاک کردن مقدار",
|
||||||
"close": "",
|
"close": "بستن",
|
||||||
"collapse_all": "",
|
"collapse_all": "جمع کردن همه",
|
||||||
"color_theme": "",
|
"color_theme": "تم رنگ",
|
||||||
"comment_options": "",
|
"comment_options": "گزینههای نظر",
|
||||||
"comments_are_disabled": "",
|
"comments_are_disabled": "نظرات غیرفعال هستند",
|
||||||
"confirm": "",
|
"confirm": "تأیید",
|
||||||
"confirm_admin_password": "",
|
"confirm_admin_password": "تأیید رمز عبور مدیر",
|
||||||
"confirm_delete_shared_link": "",
|
"confirm_delete_shared_link": "",
|
||||||
"confirm_password": "",
|
"confirm_password": "تأیید رمز عبور",
|
||||||
"contain": "",
|
"contain": "شامل",
|
||||||
"context": "",
|
"context": "زمینه",
|
||||||
"continue": "",
|
"continue": "ادامه",
|
||||||
"copied_image_to_clipboard": "",
|
"copied_image_to_clipboard": "تصویر به کلیپبورد کپی شد.",
|
||||||
"copied_to_clipboard": "",
|
"copied_to_clipboard": "به کلیپبورد کپی شد!",
|
||||||
"copy_error": "",
|
"copy_error": "خطا در کپی",
|
||||||
"copy_file_path": "",
|
"copy_file_path": "کپی مسیر فایل",
|
||||||
"copy_image": "",
|
"copy_image": "کپی تصویر",
|
||||||
"copy_link": "",
|
"copy_link": "کپی لینک",
|
||||||
"copy_link_to_clipboard": "",
|
"copy_link_to_clipboard": "کپی لینک به کلیپبورد",
|
||||||
"copy_password": "",
|
"copy_password": "کپی رمز عبور",
|
||||||
"copy_to_clipboard": "",
|
"copy_to_clipboard": "کپی به کلیپبورد",
|
||||||
"country": "",
|
"country": "کشور",
|
||||||
"cover": "",
|
"cover": "جلد",
|
||||||
"covers": "",
|
"covers": "جلدها",
|
||||||
"create": "",
|
"create": "ایجاد",
|
||||||
"create_album": "",
|
"create_album": "ایجاد آلبوم",
|
||||||
"create_library": "",
|
"create_library": "ایجاد کتابخانه",
|
||||||
"create_link": "",
|
"create_link": "ایجاد لینک",
|
||||||
"create_link_to_share": "",
|
"create_link_to_share": "ایجاد لینک برای اشتراکگذاری",
|
||||||
"create_new_person": "",
|
"create_new_person": "ایجاد فرد جدید",
|
||||||
"create_new_user": "",
|
"create_new_user": "ایجاد کاربر جدید",
|
||||||
"create_user": "",
|
"create_user": "ایجاد کاربر",
|
||||||
"created": "",
|
"created": "ایجاد شد",
|
||||||
"current_device": "",
|
"current_device": "دستگاه فعلی",
|
||||||
"custom_locale": "",
|
"custom_locale": "",
|
||||||
"custom_locale_description": "",
|
"custom_locale_description": "",
|
||||||
"dark": "",
|
"dark": "تاریک",
|
||||||
"date_after": "",
|
"date_after": "تاریخ پس از",
|
||||||
"date_and_time": "",
|
"date_and_time": "تاریخ و زمان",
|
||||||
"date_before": "",
|
"date_before": "تاریخ قبل از",
|
||||||
"date_range": "",
|
"date_range": "بازه زمانی",
|
||||||
"day": "",
|
"day": "روز",
|
||||||
"deduplicate_all": "",
|
"deduplicate_all": "حذف تکراریها به صورت کامل",
|
||||||
"default_locale": "",
|
"default_locale": "",
|
||||||
"default_locale_description": "",
|
"default_locale_description": "",
|
||||||
"delete": "",
|
"delete": "حذف",
|
||||||
"delete_album": "",
|
"delete_album": "حذف آلبوم",
|
||||||
"delete_api_key_prompt": "",
|
"delete_api_key_prompt": "",
|
||||||
"delete_duplicates_confirmation": "",
|
"delete_duplicates_confirmation": "",
|
||||||
"delete_key": "",
|
"delete_key": "حذف کلید",
|
||||||
"delete_library": "",
|
"delete_library": "حذف کتابخانه",
|
||||||
"delete_link": "",
|
"delete_link": "حذف لینک",
|
||||||
"delete_shared_link": "",
|
"delete_shared_link": "حذف لینک اشتراکی",
|
||||||
"delete_user": "",
|
"delete_user": "حذف کاربر",
|
||||||
"deleted_shared_link": "",
|
"deleted_shared_link": "لینک اشتراکی حذف شد",
|
||||||
"description": "",
|
"description": "توضیحات",
|
||||||
"details": "",
|
"details": "جزئیات",
|
||||||
"direction": "",
|
"direction": "جهت",
|
||||||
"disabled": "",
|
"disabled": "غیرفعال",
|
||||||
"disallow_edits": "",
|
"disallow_edits": "عدم اجازه ویرایش",
|
||||||
"discover": "",
|
"discover": "کشف کردن",
|
||||||
"dismiss_all_errors": "",
|
"dismiss_all_errors": "رد تمام خطاها",
|
||||||
"dismiss_error": "",
|
"dismiss_error": "رد خطا",
|
||||||
"display_options": "",
|
"display_options": "گزینههای نمایش",
|
||||||
"display_order": "",
|
"display_order": "ترتیب نمایش",
|
||||||
"display_original_photos": "",
|
"display_original_photos": "نمایش عکسهای اصلی",
|
||||||
"display_original_photos_setting_description": "",
|
"display_original_photos_setting_description": "",
|
||||||
"done": "",
|
"done": "انجام شد",
|
||||||
"download": "",
|
"download": "دانلود",
|
||||||
"download_settings": "",
|
"download_settings": "تنظیمات دانلود",
|
||||||
"download_settings_description": "",
|
"download_settings_description": "مدیریت تنظیمات مرتبط با دانلود محتوا",
|
||||||
"downloading": "",
|
"downloading": "در حال دانلود",
|
||||||
"duplicates": "",
|
"duplicates": "تکراریها",
|
||||||
"duplicates_description": "",
|
"duplicates_description": "",
|
||||||
"duration": "",
|
"duration": "مدت زمان",
|
||||||
"edit_album": "",
|
"edit_album": "ویرایش آلبوم",
|
||||||
"edit_avatar": "",
|
"edit_avatar": "ویرایش آواتار",
|
||||||
"edit_date": "",
|
"edit_date": "ویرایش تاریخ",
|
||||||
"edit_date_and_time": "",
|
"edit_date_and_time": "ویرایش تاریخ و زمان",
|
||||||
"edit_exclusion_pattern": "",
|
"edit_exclusion_pattern": "ویرایش الگوی استثناء",
|
||||||
"edit_faces": "",
|
"edit_faces": "ویرایش چهرهها",
|
||||||
"edit_import_path": "",
|
"edit_import_path": "",
|
||||||
"edit_import_paths": "",
|
"edit_import_paths": "",
|
||||||
"edit_key": "",
|
"edit_key": "ویرایش کلید",
|
||||||
"edit_link": "",
|
"edit_link": "ویرایش لینک",
|
||||||
"edit_location": "",
|
"edit_location": "ویرایش مکان",
|
||||||
"edit_name": "",
|
"edit_name": "ویرایش نام",
|
||||||
"edit_people": "",
|
"edit_people": "ویرایش افراد",
|
||||||
"edit_title": "",
|
"edit_title": "ویرایش عنوان",
|
||||||
"edit_user": "",
|
"edit_user": "ویرایش کاربر",
|
||||||
"edited": "",
|
"edited": "ویرایش شد",
|
||||||
"editor": "",
|
"editor": "ویرایشگر",
|
||||||
"email": "",
|
"email": "ایمیل",
|
||||||
"empty_trash": "",
|
"empty_trash": "خالی کردن سطل زباله",
|
||||||
"end_date": "",
|
"end_date": "تاریخ پایان",
|
||||||
"error": "",
|
"error": "خطا",
|
||||||
"error_loading_image": "",
|
"error_loading_image": "خطا در بارگذاری تصویر",
|
||||||
"errors": {
|
"errors": {
|
||||||
"exclusion_pattern_already_exists": "",
|
"exclusion_pattern_already_exists": "",
|
||||||
"import_path_already_exists": "",
|
"import_path_already_exists": "",
|
||||||
@@ -530,400 +530,400 @@
|
|||||||
"unable_to_update_timeline_display_status": "",
|
"unable_to_update_timeline_display_status": "",
|
||||||
"unable_to_update_user": ""
|
"unable_to_update_user": ""
|
||||||
},
|
},
|
||||||
"exit_slideshow": "",
|
"exit_slideshow": "خروج از نمایش اسلاید",
|
||||||
"expand_all": "",
|
"expand_all": "باز کردن همه",
|
||||||
"expire_after": "",
|
"expire_after": "منقضی شدن بعد از",
|
||||||
"expired": "",
|
"expired": "منقضی شده",
|
||||||
"explore": "",
|
"explore": "کاوش کردن",
|
||||||
"export": "",
|
"export": "صادر کردن",
|
||||||
"export_as_json": "",
|
"export_as_json": "صادر کردن بهصورت JSON",
|
||||||
"extension": "",
|
"extension": "پسوند",
|
||||||
"external": "",
|
"external": "خارجی",
|
||||||
"external_libraries": "",
|
"external_libraries": "کتابخانههای خارجی",
|
||||||
"favorite": "",
|
"favorite": "علاقهمندی",
|
||||||
"favorite_or_unfavorite_photo": "",
|
"favorite_or_unfavorite_photo": "",
|
||||||
"favorites": "",
|
"favorites": "علاقهمندیها",
|
||||||
"feature_photo_updated": "",
|
"feature_photo_updated": "",
|
||||||
"file_name": "",
|
"file_name": "نام فایل",
|
||||||
"file_name_or_extension": "",
|
"file_name_or_extension": "نام فایل یا پسوند",
|
||||||
"filename": "",
|
"filename": "نام فایل",
|
||||||
"filetype": "",
|
"filetype": "نوع فایل",
|
||||||
"filter_people": "",
|
"filter_people": "فیلتر افراد",
|
||||||
"find_them_fast": "",
|
"find_them_fast": "",
|
||||||
"fix_incorrect_match": "",
|
"fix_incorrect_match": "رفع تطابق نادرست",
|
||||||
"forward": "",
|
"forward": "جلو",
|
||||||
"general": "",
|
"general": "عمومی",
|
||||||
"get_help": "",
|
"get_help": "دریافت کمک",
|
||||||
"getting_started": "",
|
"getting_started": "شروع به کار",
|
||||||
"go_back": "",
|
"go_back": "بازگشت",
|
||||||
"go_to_search": "",
|
"go_to_search": "رفتن به جستجو",
|
||||||
"group_albums_by": "",
|
"group_albums_by": "گروهبندی آلبومها براساس...",
|
||||||
"has_quota": "",
|
"has_quota": "دارای سهمیه",
|
||||||
"hide_gallery": "",
|
"hide_gallery": "پنهان کردن گالری",
|
||||||
"hide_password": "",
|
"hide_password": "پنهان کردن رمز عبور",
|
||||||
"hide_person": "",
|
"hide_person": "پنهان کردن فرد",
|
||||||
"host": "",
|
"host": "میزبان",
|
||||||
"hour": "",
|
"hour": "ساعت",
|
||||||
"image": "",
|
"image": "تصویر",
|
||||||
"immich_logo": "",
|
"immich_logo": "لوگوی Immich",
|
||||||
"immich_web_interface": "",
|
"immich_web_interface": "رابط وب Immich",
|
||||||
"import_from_json": "",
|
"import_from_json": "وارد کردن از JSON",
|
||||||
"import_path": "",
|
"import_path": "مسیر وارد کردن",
|
||||||
"in_albums": "",
|
"in_albums": "",
|
||||||
"in_archive": "",
|
"in_archive": "در بایگانی",
|
||||||
"include_archived": "",
|
"include_archived": "شامل بایگانی شدهها",
|
||||||
"include_shared_albums": "",
|
"include_shared_albums": "شامل آلبومهای اشتراکی",
|
||||||
"include_shared_partner_assets": "",
|
"include_shared_partner_assets": "",
|
||||||
"individual_share": "",
|
"individual_share": "اشتراک فردی",
|
||||||
"info": "",
|
"info": "اطلاعات",
|
||||||
"interval": {
|
"interval": {
|
||||||
"day_at_onepm": "",
|
"day_at_onepm": "",
|
||||||
"hours": "",
|
"hours": "",
|
||||||
"night_at_midnight": "",
|
"night_at_midnight": "",
|
||||||
"night_at_twoam": ""
|
"night_at_twoam": ""
|
||||||
},
|
},
|
||||||
"invite_people": "",
|
"invite_people": "دعوت افراد",
|
||||||
"invite_to_album": "",
|
"invite_to_album": "دعوت به آلبوم",
|
||||||
"jobs": "",
|
"jobs": "وظایف",
|
||||||
"keep": "",
|
"keep": "نگه داشتن",
|
||||||
"keep_all": "",
|
"keep_all": "نگه داشتن همه",
|
||||||
"keyboard_shortcuts": "",
|
"keyboard_shortcuts": "میانبرهای صفحهکلید",
|
||||||
"language": "",
|
"language": "زبان",
|
||||||
"language_setting_description": "",
|
"language_setting_description": "انتخاب زبان دلخواه شما",
|
||||||
"last_seen": "",
|
"last_seen": "آخرین مشاهده",
|
||||||
"leave": "",
|
"leave": "ترک کردن",
|
||||||
"let_others_respond": "",
|
"let_others_respond": "اجازه به دیگران برای پاسخگویی",
|
||||||
"level": "",
|
"level": "سطح",
|
||||||
"library": "",
|
"library": "کتابخانه",
|
||||||
"library_options": "",
|
"library_options": "گزینههای کتابخانه",
|
||||||
"light": "",
|
"light": "روشن",
|
||||||
"link_options": "",
|
"link_options": "گزینههای لینک",
|
||||||
"link_to_oauth": "",
|
"link_to_oauth": "اتصال به OAuth",
|
||||||
"linked_oauth_account": "",
|
"linked_oauth_account": "حساب OAuth متصل شده",
|
||||||
"list": "",
|
"list": "لیست",
|
||||||
"loading": "",
|
"loading": "در حال بارگذاری",
|
||||||
"loading_search_results_failed": "",
|
"loading_search_results_failed": "بارگذاری نتایج جستجو ناموفق بود",
|
||||||
"log_out": "",
|
"log_out": "خروج از سیستم",
|
||||||
"log_out_all_devices": "",
|
"log_out_all_devices": "خروج از همه دستگاهها",
|
||||||
"login_has_been_disabled": "",
|
"login_has_been_disabled": "ورود غیرفعال شده است.",
|
||||||
"look": "",
|
"look": "نگاه کردن",
|
||||||
"loop_videos": "",
|
"loop_videos": "پخش مداوم ویدئوها",
|
||||||
"loop_videos_description": "",
|
"loop_videos_description": "",
|
||||||
"make": "",
|
"make": "ساختن",
|
||||||
"manage_shared_links": "",
|
"manage_shared_links": "مدیریت لینکهای اشتراکی",
|
||||||
"manage_sharing_with_partners": "",
|
"manage_sharing_with_partners": "",
|
||||||
"manage_the_app_settings": "",
|
"manage_the_app_settings": "مدیریت تنظیمات برنامه",
|
||||||
"manage_your_account": "",
|
"manage_your_account": "مدیریت حساب کاربری شما",
|
||||||
"manage_your_api_keys": "",
|
"manage_your_api_keys": "مدیریت کلیدهای API شما",
|
||||||
"manage_your_devices": "",
|
"manage_your_devices": "مدیریت دستگاههای متصل",
|
||||||
"manage_your_oauth_connection": "",
|
"manage_your_oauth_connection": "مدیریت اتصال OAuth شما",
|
||||||
"map": "",
|
"map": "نقشه",
|
||||||
"map_marker_with_image": "",
|
"map_marker_with_image": "",
|
||||||
"map_settings": "",
|
"map_settings": "تنظیمات نقشه",
|
||||||
"matches": "",
|
"matches": "تطابقها",
|
||||||
"media_type": "",
|
"media_type": "نوع رسانه",
|
||||||
"memories": "",
|
"memories": "خاطرات",
|
||||||
"memories_setting_description": "",
|
"memories_setting_description": "",
|
||||||
"memory": "",
|
"memory": "خاطره",
|
||||||
"menu": "",
|
"menu": "منو",
|
||||||
"merge": "",
|
"merge": "ادغام",
|
||||||
"merge_people": "",
|
"merge_people": "ادغام افراد",
|
||||||
"merge_people_limit": "",
|
"merge_people_limit": "",
|
||||||
"merge_people_prompt": "",
|
"merge_people_prompt": "",
|
||||||
"merge_people_successfully": "",
|
"merge_people_successfully": "ادغام افراد با موفقیت انجام شد",
|
||||||
"minimize": "",
|
"minimize": "کوچک کردن",
|
||||||
"minute": "",
|
"minute": "دقیقه",
|
||||||
"missing": "",
|
"missing": "گمشده",
|
||||||
"model": "",
|
"model": "مدل",
|
||||||
"month": "",
|
"month": "ماه",
|
||||||
"more": "",
|
"more": "بیشتر",
|
||||||
"moved_to_trash": "",
|
"moved_to_trash": "به سطل زباله منتقل شد",
|
||||||
"my_albums": "",
|
"my_albums": "آلبومهای من",
|
||||||
"name": "",
|
"name": "نام",
|
||||||
"name_or_nickname": "",
|
"name_or_nickname": "نام یا لقب",
|
||||||
"never": "",
|
"never": "هرگز",
|
||||||
"new_api_key": "",
|
"new_api_key": "کلید API جدید",
|
||||||
"new_password": "",
|
"new_password": "رمز عبور جدید",
|
||||||
"new_person": "",
|
"new_person": "فرد جدید",
|
||||||
"new_user_created": "",
|
"new_user_created": "کاربر جدید ایجاد شد",
|
||||||
"newest_first": "",
|
"newest_first": "جدیدترین ابتدا",
|
||||||
"next": "",
|
"next": "بعدی",
|
||||||
"next_memory": "",
|
"next_memory": "خاطره بعدی",
|
||||||
"no": "",
|
"no": "خیر",
|
||||||
"no_albums_message": "",
|
"no_albums_message": "",
|
||||||
"no_archived_assets_message": "",
|
"no_archived_assets_message": "",
|
||||||
"no_assets_message": "",
|
"no_assets_message": "",
|
||||||
"no_duplicates_found": "",
|
"no_duplicates_found": "هیچ تکراری یافت نشد.",
|
||||||
"no_exif_info_available": "",
|
"no_exif_info_available": "اطلاعات EXIF موجود نیست",
|
||||||
"no_explore_results_message": "",
|
"no_explore_results_message": "",
|
||||||
"no_favorites_message": "",
|
"no_favorites_message": "",
|
||||||
"no_libraries_message": "",
|
"no_libraries_message": "",
|
||||||
"no_name": "",
|
"no_name": "بدون نام",
|
||||||
"no_places": "",
|
"no_places": "مکانی یافت نشد",
|
||||||
"no_results": "",
|
"no_results": "نتیجهای یافت نشد",
|
||||||
"no_shared_albums_message": "",
|
"no_shared_albums_message": "",
|
||||||
"not_in_any_album": "",
|
"not_in_any_album": "در هیچ آلبومی نیست",
|
||||||
"note_apply_storage_label_to_previously_uploaded assets": "",
|
"note_apply_storage_label_to_previously_uploaded assets": "",
|
||||||
"note_unlimited_quota": "",
|
"note_unlimited_quota": "",
|
||||||
"notes": "",
|
"notes": "یادداشتها",
|
||||||
"notification_toggle_setting_description": "",
|
"notification_toggle_setting_description": "اعلانهای ایمیلی را فعال کنید",
|
||||||
"notifications": "",
|
"notifications": "اعلانها",
|
||||||
"notifications_setting_description": "",
|
"notifications_setting_description": "مدیریت اعلانها",
|
||||||
"oauth": "",
|
"oauth": "OAuth",
|
||||||
"offline": "",
|
"offline": "آفلاین",
|
||||||
"offline_paths": "",
|
"offline_paths": "مسیرهای آفلاین",
|
||||||
"offline_paths_description": "",
|
"offline_paths_description": "",
|
||||||
"ok": "",
|
"ok": "تأیید",
|
||||||
"oldest_first": "",
|
"oldest_first": "قدیمیترین ابتدا",
|
||||||
"online": "",
|
"online": "آنلاین",
|
||||||
"only_favorites": "",
|
"only_favorites": "فقط علاقهمندیها",
|
||||||
"open_the_search_filters": "",
|
"open_the_search_filters": "باز کردن فیلترهای جستجو",
|
||||||
"options": "",
|
"options": "گزینهها",
|
||||||
"organize_your_library": "",
|
"organize_your_library": "کتابخانه خود را سازماندهی کنید",
|
||||||
"other": "",
|
"other": "دیگر",
|
||||||
"other_devices": "",
|
"other_devices": "دستگاههای دیگر",
|
||||||
"other_variables": "",
|
"other_variables": "متغیرهای دیگر",
|
||||||
"owned": "",
|
"owned": "مالکیت",
|
||||||
"owner": "",
|
"owner": "مالک",
|
||||||
"partner": "",
|
"partner": "شریک",
|
||||||
"partner_can_access": "",
|
"partner_can_access": "{partner} میتواند دسترسی داشته باشد",
|
||||||
"partner_can_access_assets": "",
|
"partner_can_access_assets": "",
|
||||||
"partner_can_access_location": "",
|
"partner_can_access_location": "مکانهایی که عکسهای شما گرفته شدهاند",
|
||||||
"partner_sharing": "",
|
"partner_sharing": "اشتراکگذاری با شریک",
|
||||||
"partners": "",
|
"partners": "شرکا",
|
||||||
"password": "",
|
"password": "رمز عبور",
|
||||||
"password_does_not_match": "",
|
"password_does_not_match": "رمز عبور مطابقت ندارد",
|
||||||
"password_required": "",
|
"password_required": "رمز عبور مورد نیاز است",
|
||||||
"password_reset_success": "",
|
"password_reset_success": "بازنشانی رمز عبور موفقیتآمیز بود",
|
||||||
"past_durations": {
|
"past_durations": {
|
||||||
"days": "",
|
"days": "",
|
||||||
"hours": "",
|
"hours": "",
|
||||||
"years": ""
|
"years": ""
|
||||||
},
|
},
|
||||||
"path": "",
|
"path": "مسیر",
|
||||||
"pattern": "",
|
"pattern": "الگو",
|
||||||
"pause": "",
|
"pause": "توقف",
|
||||||
"pause_memories": "",
|
"pause_memories": "توقف خاطرات",
|
||||||
"paused": "",
|
"paused": "متوقف شده",
|
||||||
"pending": "",
|
"pending": "در انتظار",
|
||||||
"people": "",
|
"people": "افراد",
|
||||||
"people_sidebar_description": "",
|
"people_sidebar_description": "",
|
||||||
"permanent_deletion_warning": "",
|
"permanent_deletion_warning": "هشدار حذف دائمی",
|
||||||
"permanent_deletion_warning_setting_description": "",
|
"permanent_deletion_warning_setting_description": "نمایش هشدار هنگام حذف دائمی محتواها",
|
||||||
"permanently_delete": "",
|
"permanently_delete": "حذف دائمی",
|
||||||
"permanently_deleted_asset": "",
|
"permanently_deleted_asset": "محتوای حذف شده دائمی",
|
||||||
"person": "",
|
"person": "فرد",
|
||||||
"photos": "",
|
"photos": "عکسها",
|
||||||
"photos_count": "",
|
"photos_count": "",
|
||||||
"photos_from_previous_years": "",
|
"photos_from_previous_years": "عکسهای سالهای گذشته",
|
||||||
"pick_a_location": "",
|
"pick_a_location": "یک مکان انتخاب کنید",
|
||||||
"place": "",
|
"place": "مکان",
|
||||||
"places": "",
|
"places": "مکانها",
|
||||||
"play": "",
|
"play": "پخش",
|
||||||
"play_memories": "",
|
"play_memories": "پخش خاطرات",
|
||||||
"play_motion_photo": "",
|
"play_motion_photo": "پخش عکس متحرک",
|
||||||
"play_or_pause_video": "",
|
"play_or_pause_video": "پخش یا توقف ویدیو",
|
||||||
"port": "",
|
"port": "پورت",
|
||||||
"preset": "",
|
"preset": "پیشفرض",
|
||||||
"preview": "",
|
"preview": "پیشنمایش",
|
||||||
"previous": "",
|
"previous": "قبلی",
|
||||||
"previous_memory": "",
|
"previous_memory": "خاطره قبلی",
|
||||||
"previous_or_next_photo": "",
|
"previous_or_next_photo": "عکس قبلی یا بعدی",
|
||||||
"primary": "",
|
"primary": "اصلی",
|
||||||
"profile_picture_set": "",
|
"profile_picture_set": "تصویر پروفایل تنظیم شد.",
|
||||||
"public_share": "",
|
"public_share": "اشتراک عمومی",
|
||||||
"reaction_options": "",
|
"reaction_options": "گزینههای واکنش",
|
||||||
"read_changelog": "",
|
"read_changelog": "مطالعه تغییرات نسخه",
|
||||||
"recent": "",
|
"recent": "اخیر",
|
||||||
"recent_searches": "",
|
"recent_searches": "جستجوهای اخیر",
|
||||||
"refresh": "",
|
"refresh": "تازه سازی",
|
||||||
"refreshed": "",
|
"refreshed": "تازه سازی شد",
|
||||||
"refreshes_every_file": "",
|
"refreshes_every_file": "",
|
||||||
"remove": "",
|
"remove": "حذف",
|
||||||
"remove_deleted_assets": "",
|
"remove_deleted_assets": "حذف محتواهای حذفشده",
|
||||||
"remove_from_album": "",
|
"remove_from_album": "حذف از آلبوم",
|
||||||
"remove_from_favorites": "",
|
"remove_from_favorites": "حذف از علاقهمندیها",
|
||||||
"remove_from_shared_link": "",
|
"remove_from_shared_link": "",
|
||||||
"removed_api_key": "",
|
"removed_api_key": "",
|
||||||
"rename": "",
|
"rename": "تغییر نام",
|
||||||
"repair": "",
|
"repair": "تعمیر",
|
||||||
"repair_no_results_message": "",
|
"repair_no_results_message": "",
|
||||||
"replace_with_upload": "",
|
"replace_with_upload": "جایگزینی با آپلود",
|
||||||
"require_password": "",
|
"require_password": "",
|
||||||
"require_user_to_change_password_on_first_login": "",
|
"require_user_to_change_password_on_first_login": "",
|
||||||
"reset": "",
|
"reset": "بازنشانی",
|
||||||
"reset_password": "",
|
"reset_password": "بازنشانی رمز عبور",
|
||||||
"reset_people_visibility": "",
|
"reset_people_visibility": "",
|
||||||
"resolved_all_duplicates": "",
|
"resolved_all_duplicates": "",
|
||||||
"restore": "",
|
"restore": "بازیابی",
|
||||||
"restore_all": "",
|
"restore_all": "بازیابی همه",
|
||||||
"restore_user": "",
|
"restore_user": "بازیابی کاربر",
|
||||||
"resume": "",
|
"resume": "ادامه",
|
||||||
"retry_upload": "",
|
"retry_upload": "",
|
||||||
"review_duplicates": "",
|
"review_duplicates": "بررسی تکراریها",
|
||||||
"role": "",
|
"role": "نقش",
|
||||||
"save": "",
|
"save": "ذخیره",
|
||||||
"saved_api_key": "",
|
"saved_api_key": "",
|
||||||
"saved_profile": "",
|
"saved_profile": "پروفایل ذخیره شد",
|
||||||
"saved_settings": "",
|
"saved_settings": "تنظیمات ذخیره شد",
|
||||||
"say_something": "",
|
"say_something": "چیزی بگویید",
|
||||||
"scan_all_libraries": "",
|
"scan_all_libraries": "اسکن همه کتابخانهها",
|
||||||
"scan_settings": "",
|
"scan_settings": "تنظیمات اسکن",
|
||||||
"scanning_for_album": "",
|
"scanning_for_album": "",
|
||||||
"search": "",
|
"search": "جستجو",
|
||||||
"search_albums": "",
|
"search_albums": "جستجوی آلبومها",
|
||||||
"search_by_context": "",
|
"search_by_context": "جستجو براساس زمینه",
|
||||||
"search_camera_make": "",
|
"search_camera_make": "جستجوی برند دوربین...",
|
||||||
"search_camera_model": "",
|
"search_camera_model": "جستجوی مدل دوربین...",
|
||||||
"search_city": "",
|
"search_city": "جستجوی شهر...",
|
||||||
"search_country": "",
|
"search_country": "جستجوی کشور...",
|
||||||
"search_for_existing_person": "",
|
"search_for_existing_person": "جستجوی فرد موجود",
|
||||||
"search_people": "",
|
"search_people": "جستجوی افراد",
|
||||||
"search_places": "",
|
"search_places": "جستجوی مکانها",
|
||||||
"search_state": "",
|
"search_state": "جستجوی ایالت...",
|
||||||
"search_timezone": "",
|
"search_timezone": "جستجوی منطقه زمانی...",
|
||||||
"search_type": "",
|
"search_type": "نوع جستجو",
|
||||||
"search_your_photos": "",
|
"search_your_photos": "",
|
||||||
"searching_locales": "",
|
"searching_locales": "",
|
||||||
"second": "",
|
"second": "ثانیه",
|
||||||
"select_album_cover": "",
|
"select_album_cover": "انتخاب جلد آلبوم",
|
||||||
"select_all": "",
|
"select_all": "انتخاب همه",
|
||||||
"select_avatar_color": "",
|
"select_avatar_color": "انتخاب رنگ آواتار",
|
||||||
"select_face": "",
|
"select_face": "انتخاب چهره",
|
||||||
"select_featured_photo": "",
|
"select_featured_photo": "انتخاب عکس ویژه",
|
||||||
"select_keep_all": "",
|
"select_keep_all": "انتخاب نگهداری همه",
|
||||||
"select_library_owner": "",
|
"select_library_owner": "انتخاب مالک کتابخانه",
|
||||||
"select_new_face": "",
|
"select_new_face": "انتخاب چهره جدید",
|
||||||
"select_photos": "",
|
"select_photos": "انتخاب عکسها",
|
||||||
"select_trash_all": "",
|
"select_trash_all": "",
|
||||||
"selected": "",
|
"selected": "انتخاب شده",
|
||||||
"send_message": "",
|
"send_message": "ارسال پیام",
|
||||||
"send_welcome_email": "",
|
"send_welcome_email": "ارسال ایمیل خوشآمدگویی",
|
||||||
"server_stats": "",
|
"server_stats": "آمار سرور",
|
||||||
"set": "",
|
"set": "تنظیم",
|
||||||
"set_as_album_cover": "",
|
"set_as_album_cover": "",
|
||||||
"set_as_profile_picture": "",
|
"set_as_profile_picture": "",
|
||||||
"set_date_of_birth": "",
|
"set_date_of_birth": "تنظیم تاریخ تولد",
|
||||||
"set_profile_picture": "",
|
"set_profile_picture": "تنظیم تصویر پروفایل",
|
||||||
"set_slideshow_to_fullscreen": "",
|
"set_slideshow_to_fullscreen": "",
|
||||||
"settings": "",
|
"settings": "تنظیمات",
|
||||||
"settings_saved": "",
|
"settings_saved": "تنظیمات ذخیره شد",
|
||||||
"share": "",
|
"share": "اشتراکگذاری",
|
||||||
"shared": "",
|
"shared": "مشترک",
|
||||||
"shared_by": "",
|
"shared_by": "مشترک توسط",
|
||||||
"shared_by_you": "",
|
"shared_by_you": "",
|
||||||
"shared_from_partner": "",
|
"shared_from_partner": "عکسها از {partner}",
|
||||||
"shared_links": "",
|
"shared_links": "لینکهای اشتراکی",
|
||||||
"shared_photos_and_videos_count": "",
|
"shared_photos_and_videos_count": "",
|
||||||
"shared_with_partner": "",
|
"shared_with_partner": "مشترک با {partner}",
|
||||||
"sharing": "",
|
"sharing": "اشتراکگذاری",
|
||||||
"sharing_sidebar_description": "",
|
"sharing_sidebar_description": "",
|
||||||
"show_album_options": "",
|
"show_album_options": "نمایش گزینههای آلبوم",
|
||||||
"show_and_hide_people": "",
|
"show_and_hide_people": "",
|
||||||
"show_file_location": "",
|
"show_file_location": "نمایش مسیر فایل",
|
||||||
"show_gallery": "",
|
"show_gallery": "نمایش گالری",
|
||||||
"show_hidden_people": "",
|
"show_hidden_people": "نمایش افراد پنهان",
|
||||||
"show_in_timeline": "",
|
"show_in_timeline": "",
|
||||||
"show_in_timeline_setting_description": "",
|
"show_in_timeline_setting_description": "",
|
||||||
"show_keyboard_shortcuts": "",
|
"show_keyboard_shortcuts": "",
|
||||||
"show_metadata": "",
|
"show_metadata": "نمایش اطلاعات متا",
|
||||||
"show_or_hide_info": "",
|
"show_or_hide_info": "",
|
||||||
"show_password": "",
|
"show_password": "نمایش رمز عبور",
|
||||||
"show_person_options": "",
|
"show_person_options": "",
|
||||||
"show_progress_bar": "",
|
"show_progress_bar": "نمایش نوار پیشرفت",
|
||||||
"show_search_options": "",
|
"show_search_options": "نمایش گزینههای جستجو",
|
||||||
"shuffle": "",
|
"shuffle": "تصادفی",
|
||||||
"sign_out": "",
|
"sign_out": "خروج",
|
||||||
"sign_up": "",
|
"sign_up": "ثبتنام",
|
||||||
"size": "",
|
"size": "اندازه",
|
||||||
"skip_to_content": "",
|
"skip_to_content": "رفتن به محتوا",
|
||||||
"slideshow": "",
|
"slideshow": "نمایش اسلاید",
|
||||||
"slideshow_settings": "",
|
"slideshow_settings": "تنظیمات نمایش اسلاید",
|
||||||
"sort_albums_by": "",
|
"sort_albums_by": "",
|
||||||
"stack": "",
|
"stack": "پشته",
|
||||||
"stack_selected_photos": "",
|
"stack_selected_photos": "",
|
||||||
"stacktrace": "",
|
"stacktrace": "",
|
||||||
"start": "",
|
"start": "شروع",
|
||||||
"start_date": "",
|
"start_date": "تاریخ شروع",
|
||||||
"state": "",
|
"state": "ایالت",
|
||||||
"status": "",
|
"status": "وضعیت",
|
||||||
"stop_motion_photo": "",
|
"stop_motion_photo": "توقف عکس متحرک",
|
||||||
"stop_photo_sharing": "",
|
"stop_photo_sharing": "",
|
||||||
"stop_photo_sharing_description": "",
|
"stop_photo_sharing_description": "",
|
||||||
"stop_sharing_photos_with_user": "",
|
"stop_sharing_photos_with_user": "",
|
||||||
"storage": "",
|
"storage": "فضای ذخیرهسازی",
|
||||||
"storage_label": "",
|
"storage_label": "برچسب فضای ذخیرهسازی",
|
||||||
"storage_usage": "",
|
"storage_usage": "",
|
||||||
"submit": "",
|
"submit": "ارسال",
|
||||||
"suggestions": "",
|
"suggestions": "پیشنهادات",
|
||||||
"sunrise_on_the_beach": "",
|
"sunrise_on_the_beach": "",
|
||||||
"swap_merge_direction": "",
|
"swap_merge_direction": "تغییر جهت ادغام",
|
||||||
"sync": "",
|
"sync": "همگامسازی",
|
||||||
"template": "",
|
"template": "الگو",
|
||||||
"theme": "",
|
"theme": "تم",
|
||||||
"theme_selection": "",
|
"theme_selection": "انتخاب تم",
|
||||||
"theme_selection_description": "",
|
"theme_selection_description": "",
|
||||||
"time_based_memories": "",
|
"time_based_memories": "",
|
||||||
"timezone": "",
|
"timezone": "منطقه زمانی",
|
||||||
"to_archive": "",
|
"to_archive": "بایگانی",
|
||||||
"to_favorite": "",
|
"to_favorite": "به علاقهمندیها",
|
||||||
"to_trash": "",
|
"to_trash": "",
|
||||||
"toggle_settings": "",
|
"toggle_settings": "تغییر تنظیمات",
|
||||||
"toggle_theme": "",
|
"toggle_theme": "تغییر تم تاریک",
|
||||||
"total_usage": "",
|
"total_usage": "استفاده کلی",
|
||||||
"trash": "",
|
"trash": "سطل زباله",
|
||||||
"trash_all": "",
|
"trash_all": "",
|
||||||
"trash_count": "",
|
"trash_count": "",
|
||||||
"trash_no_results_message": "",
|
"trash_no_results_message": "",
|
||||||
"trashed_items_will_be_permanently_deleted_after": "",
|
"trashed_items_will_be_permanently_deleted_after": "",
|
||||||
"type": "",
|
"type": "نوع",
|
||||||
"unarchive": "",
|
"unarchive": "",
|
||||||
"unfavorite": "",
|
"unfavorite": "حذف از علاقهمندیها",
|
||||||
"unhide_person": "",
|
"unhide_person": "آشکار کردن فرد",
|
||||||
"unknown": "",
|
"unknown": "ناشناخته",
|
||||||
"unknown_year": "",
|
"unknown_year": "سال نامشخص",
|
||||||
"unlimited": "",
|
"unlimited": "نامحدود",
|
||||||
"unlink_oauth": "",
|
"unlink_oauth": "لغو اتصال OAuth",
|
||||||
"unlinked_oauth_account": "",
|
"unlinked_oauth_account": "",
|
||||||
"unnamed_album": "",
|
"unnamed_album": "آلبوم بدون نام",
|
||||||
"unnamed_share": "",
|
"unnamed_share": "اشتراک بدون نام",
|
||||||
"unselect_all": "",
|
"unselect_all": "لغو انتخاب همه",
|
||||||
"unstack": "",
|
"unstack": "",
|
||||||
"untracked_files": "",
|
"untracked_files": "",
|
||||||
"untracked_files_decription": "",
|
"untracked_files_decription": "",
|
||||||
"up_next": "",
|
"up_next": "مورد بعدی",
|
||||||
"updated_password": "",
|
"updated_password": "",
|
||||||
"upload": "",
|
"upload": "آپلود",
|
||||||
"upload_concurrency": "",
|
"upload_concurrency": "تعداد آپلود همزمان",
|
||||||
"url": "",
|
"url": "آدرس",
|
||||||
"usage": "",
|
"usage": "استفاده",
|
||||||
"user": "",
|
"user": "کاربر",
|
||||||
"user_id": "",
|
"user_id": "شناسه کاربر",
|
||||||
"user_usage_detail": "",
|
"user_usage_detail": "جزئیات استفاده کاربر",
|
||||||
"username": "",
|
"username": "نام کاربری",
|
||||||
"users": "",
|
"users": "کاربران",
|
||||||
"utilities": "",
|
"utilities": "ابزارها",
|
||||||
"validate": "",
|
"validate": "اعتبارسنجی",
|
||||||
"variables": "",
|
"variables": "متغیرها",
|
||||||
"version": "",
|
"version": "نسخه",
|
||||||
"version_announcement_message": "",
|
"version_announcement_message": "",
|
||||||
"video": "",
|
"video": "ویدیو",
|
||||||
"video_hover_setting": "",
|
"video_hover_setting": "",
|
||||||
"video_hover_setting_description": "",
|
"video_hover_setting_description": "",
|
||||||
"videos": "",
|
"videos": "ویدیوها",
|
||||||
"videos_count": "",
|
"videos_count": "",
|
||||||
"view": "",
|
"view": "مشاهده",
|
||||||
"view_all": "",
|
"view_all": "مشاهده همه",
|
||||||
"view_all_users": "",
|
"view_all_users": "مشاهده همه کاربران",
|
||||||
"view_links": "",
|
"view_links": "مشاهده لینکها",
|
||||||
"view_next_asset": "",
|
"view_next_asset": "مشاهده محتوای بعدی",
|
||||||
"view_previous_asset": "",
|
"view_previous_asset": "مشاهده محتوای قبلی",
|
||||||
"waiting": "",
|
"waiting": "در انتظار",
|
||||||
"week": "",
|
"week": "هفته",
|
||||||
"welcome": "",
|
"welcome": "خوش آمدید",
|
||||||
"welcome_to_immich": "",
|
"welcome_to_immich": "",
|
||||||
"year": "",
|
"year": "سال",
|
||||||
"yes": "",
|
"yes": "بله",
|
||||||
"you_dont_have_any_shared_links": "",
|
"you_dont_have_any_shared_links": "",
|
||||||
"zoom_image": "بزرگنمایی تصویر"
|
"zoom_image": "بزرگنمایی تصویر"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
ARG DEVICE=cpu
|
ARG DEVICE=cpu
|
||||||
|
|
||||||
FROM python:3.11-bookworm@sha256:adb581d8ed80edd03efd4dcad66db115b9ce8de8522b01720b9f3e6146f0884c AS builder-cpu
|
FROM python:3.11-bookworm@sha256:14b4620f59a90f163dfa6bd252b68743f9a41d494a9fde935f9d7669d98094bb AS builder-cpu
|
||||||
|
|
||||||
FROM builder-cpu AS builder-openvino
|
FROM builder-cpu AS builder-openvino
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ RUN python3 -m venv /opt/venv
|
|||||||
COPY poetry.lock pyproject.toml ./
|
COPY poetry.lock pyproject.toml ./
|
||||||
RUN poetry install --sync --no-interaction --no-ansi --no-root --with ${DEVICE} --without dev
|
RUN poetry install --sync --no-interaction --no-ansi --no-root --with ${DEVICE} --without dev
|
||||||
|
|
||||||
FROM python:3.11-slim-bookworm@sha256:6ed5bff4d7d377e2a27d9285553b8c21cfccc4f00881de1b24c9bc8d90016e82 AS prod-cpu
|
FROM python:3.11-slim-bookworm@sha256:42420f737ba91d509fc60d5ed65ed0492678a90c561e1fa08786ae8ba8b52eda AS prod-cpu
|
||||||
|
|
||||||
FROM prod-cpu AS prod-openvino
|
FROM prod-cpu AS prod-openvino
|
||||||
|
|
||||||
|
|||||||
Generated
+156
-158
@@ -758,23 +758,23 @@ test = ["pytest (>=6)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastapi"
|
name = "fastapi"
|
||||||
version = "0.115.6"
|
version = "0.115.8"
|
||||||
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "fastapi-0.115.6-py3-none-any.whl", hash = "sha256:e9240b29e36fa8f4bb7290316988e90c381e5092e0cbe84e7818cc3713bcf305"},
|
{file = "fastapi-0.115.8-py3-none-any.whl", hash = "sha256:753a96dd7e036b34eeef8babdfcfe3f28ff79648f86551eb36bfc1b0bf4a8cbf"},
|
||||||
{file = "fastapi-0.115.6.tar.gz", hash = "sha256:9ec46f7addc14ea472958a96aae5b5de65f39721a46aaf5705c480d9a8b76654"},
|
{file = "fastapi-0.115.8.tar.gz", hash = "sha256:0ce9111231720190473e222cdf0f07f7206ad7e53ea02beb1d2dc36e2f0741e9"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
|
pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
|
||||||
starlette = ">=0.40.0,<0.42.0"
|
starlette = ">=0.40.0,<0.46.0"
|
||||||
typing-extensions = ">=4.8.0"
|
typing-extensions = ">=4.8.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
|
all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
|
||||||
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"]
|
standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filelock"
|
name = "filelock"
|
||||||
@@ -1331,13 +1331,13 @@ zstd = ["zstandard (>=0.18.0)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "huggingface-hub"
|
name = "huggingface-hub"
|
||||||
version = "0.27.1"
|
version = "0.28.1"
|
||||||
description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub"
|
description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8.0"
|
python-versions = ">=3.8.0"
|
||||||
files = [
|
files = [
|
||||||
{file = "huggingface_hub-0.27.1-py3-none-any.whl", hash = "sha256:1c5155ca7d60b60c2e2fc38cbb3ffb7f7c3adf48f824015b219af9061771daec"},
|
{file = "huggingface_hub-0.28.1-py3-none-any.whl", hash = "sha256:aa6b9a3ffdae939b72c464dbb0d7f99f56e649b55c3d52406f49e0a5a620c0a7"},
|
||||||
{file = "huggingface_hub-0.27.1.tar.gz", hash = "sha256:c004463ca870283909d715d20f066ebd6968c2207dae9393fdffb3c1d4d8f98b"},
|
{file = "huggingface_hub-0.28.1.tar.gz", hash = "sha256:893471090c98e3b6efbdfdacafe4052b20b84d59866fb6f54c33d9af18c303ae"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -1350,13 +1350,13 @@ tqdm = ">=4.42.1"
|
|||||||
typing-extensions = ">=3.7.4.3"
|
typing-extensions = ">=3.7.4.3"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.9.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||||
cli = ["InquirerPy (==0.3.4)"]
|
cli = ["InquirerPy (==0.3.4)"]
|
||||||
dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.9.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
|
||||||
fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"]
|
fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"]
|
||||||
hf-transfer = ["hf-transfer (>=0.1.4)"]
|
hf-transfer = ["hf-transfer (>=0.1.4)"]
|
||||||
inference = ["aiohttp"]
|
inference = ["aiohttp"]
|
||||||
quality = ["libcst (==1.4.0)", "mypy (==1.5.1)", "ruff (>=0.5.0)"]
|
quality = ["libcst (==1.4.0)", "mypy (==1.5.1)", "ruff (>=0.9.0)"]
|
||||||
tensorflow = ["graphviz", "pydot", "tensorflow"]
|
tensorflow = ["graphviz", "pydot", "tensorflow"]
|
||||||
tensorflow-testing = ["keras (<3.0)", "tensorflow"]
|
tensorflow-testing = ["keras (<3.0)", "tensorflow"]
|
||||||
testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"]
|
testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"]
|
||||||
@@ -1625,13 +1625,13 @@ test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "locust"
|
name = "locust"
|
||||||
version = "2.32.6"
|
version = "2.32.9"
|
||||||
description = "Developer-friendly load testing framework"
|
description = "Developer-friendly load testing framework"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "locust-2.32.6-py3-none-any.whl", hash = "sha256:d5c0e4f73134415d250087034431cf3ea42ca695d3dee7f10812287cacb6c4ef"},
|
{file = "locust-2.32.9-py3-none-any.whl", hash = "sha256:d9447c26d2bbaec5a0ace7cadefa1a31820ed392234257b309965a43d5e8d26f"},
|
||||||
{file = "locust-2.32.6.tar.gz", hash = "sha256:6600cc308398e724764aacc56ccddf6cfcd0127c4c92dedd5c4979dd37ef5b15"},
|
{file = "locust-2.32.9.tar.gz", hash = "sha256:4c297afa5cdc3de15dfa79279576e5f33c1d69dd70006b51d079dcbd212201cc"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -1649,8 +1649,8 @@ psutil = ">=5.9.1"
|
|||||||
pywin32 = {version = "*", markers = "sys_platform == \"win32\""}
|
pywin32 = {version = "*", markers = "sys_platform == \"win32\""}
|
||||||
pyzmq = ">=25.0.0"
|
pyzmq = ">=25.0.0"
|
||||||
requests = [
|
requests = [
|
||||||
{version = ">=2.32.2", markers = "python_full_version > \"3.11.0\""},
|
|
||||||
{version = ">=2.26.0", markers = "python_full_version <= \"3.11.0\""},
|
{version = ">=2.26.0", markers = "python_full_version <= \"3.11.0\""},
|
||||||
|
{version = ">=2.32.2", markers = "python_full_version > \"3.11.0\""},
|
||||||
]
|
]
|
||||||
setuptools = ">=70.0.0"
|
setuptools = ">=70.0.0"
|
||||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||||
@@ -1893,49 +1893,43 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
version = "1.14.1"
|
version = "1.15.0"
|
||||||
description = "Optional static typing for Python"
|
description = "Optional static typing for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"},
|
{file = "mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13"},
|
||||||
{file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"},
|
{file = "mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559"},
|
||||||
{file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"},
|
{file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b"},
|
||||||
{file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"},
|
{file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3"},
|
||||||
{file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"},
|
{file = "mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b"},
|
||||||
{file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"},
|
{file = "mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828"},
|
||||||
{file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"},
|
{file = "mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f"},
|
||||||
{file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"},
|
{file = "mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5"},
|
||||||
{file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"},
|
{file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e"},
|
||||||
{file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"},
|
{file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c"},
|
||||||
{file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"},
|
{file = "mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f"},
|
||||||
{file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"},
|
{file = "mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f"},
|
||||||
{file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"},
|
{file = "mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd"},
|
||||||
{file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"},
|
{file = "mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f"},
|
||||||
{file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"},
|
{file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464"},
|
||||||
{file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"},
|
{file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee"},
|
||||||
{file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"},
|
{file = "mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e"},
|
||||||
{file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"},
|
{file = "mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22"},
|
||||||
{file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"},
|
{file = "mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445"},
|
||||||
{file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"},
|
{file = "mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d"},
|
||||||
{file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"},
|
{file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5"},
|
||||||
{file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"},
|
{file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036"},
|
||||||
{file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"},
|
{file = "mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357"},
|
||||||
{file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"},
|
{file = "mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf"},
|
||||||
{file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"},
|
{file = "mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078"},
|
||||||
{file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"},
|
{file = "mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba"},
|
||||||
{file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"},
|
{file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5"},
|
||||||
{file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"},
|
{file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b"},
|
||||||
{file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"},
|
{file = "mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2"},
|
||||||
{file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"},
|
{file = "mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980"},
|
||||||
{file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"},
|
{file = "mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e"},
|
||||||
{file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"},
|
{file = "mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43"},
|
||||||
{file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"},
|
|
||||||
{file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"},
|
|
||||||
{file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"},
|
|
||||||
{file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"},
|
|
||||||
{file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"},
|
|
||||||
{file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -2181,94 +2175,98 @@ files = [
|
|||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
numpy = [
|
numpy = [
|
||||||
{version = ">=1.26.0", markers = "python_version >= \"3.12\""},
|
|
||||||
{version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""},
|
{version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""},
|
||||||
{version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""},
|
{version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""},
|
||||||
{version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""},
|
{version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""},
|
||||||
|
{version = ">=1.26.0", markers = "python_version >= \"3.12\""},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orjson"
|
name = "orjson"
|
||||||
version = "3.10.14"
|
version = "3.10.15"
|
||||||
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "orjson-3.10.14-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:849ea7845a55f09965826e816cdc7689d6cf74fe9223d79d758c714af955bcb6"},
|
{file = "orjson-3.10.15-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:552c883d03ad185f720d0c09583ebde257e41b9521b74ff40e08b7dec4559c04"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5947b139dfa33f72eecc63f17e45230a97e741942955a6c9e650069305eb73d"},
|
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:616e3e8d438d02e4854f70bfdc03a6bcdb697358dbaa6bcd19cbe24d24ece1f8"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cde6d76910d3179dae70f164466692f4ea36da124d6fb1a61399ca589e81d69a"},
|
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c2c79fa308e6edb0ffab0a31fd75a7841bf2a79a20ef08a3c6e3b26814c8ca8"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6dfbaeb7afa77ca608a50e2770a0461177b63a99520d4928e27591b142c74b1"},
|
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cb85490aa6bf98abd20607ab5c8324c0acb48d6da7863a51be48505646c814"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa45e489ef80f28ff0e5ba0a72812b8cfc7c1ef8b46a694723807d1b07c89ebb"},
|
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:763dadac05e4e9d2bc14938a45a2d0560549561287d41c465d3c58aec818b164"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5007abfdbb1d866e2aa8990bd1c465f0f6da71d19e695fc278282be12cffa5"},
|
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a330b9b4734f09a623f74a7490db713695e13b67c959713b78369f26b3dee6bf"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1b49e2af011c84c3f2d541bb5cd1e3c7c2df672223e7e3ea608f09cf295e5f8a"},
|
{file = "orjson-3.10.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a61a4622b7ff861f019974f73d8165be1bd9a0855e1cad18ee167acacabeb061"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:164ac155109226b3a2606ee6dda899ccfbe6e7e18b5bdc3fbc00f79cc074157d"},
|
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:acd271247691574416b3228db667b84775c497b245fa275c6ab90dc1ffbbd2b3"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6b1225024cf0ef5d15934b5ffe9baf860fe8bc68a796513f5ea4f5056de30bca"},
|
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4759b109c37f635aa5c5cc93a1b26927bfde24b254bcc0e1149a9fada253d2d"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d6546e8073dc382e60fcae4a001a5a1bc46da5eab4a4878acc2d12072d6166d5"},
|
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e992fd5cfb8b9f00bfad2fd7a05a4299db2bbe92e6440d9dd2fab27655b3182"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9f1d2942605c894162252d6259b0121bf1cb493071a1ea8cb35d79cb3e6ac5bc"},
|
{file = "orjson-3.10.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f95fb363d79366af56c3f26b71df40b9a583b07bbaaf5b317407c4d58497852e"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-win32.whl", hash = "sha256:397083806abd51cf2b3bbbf6c347575374d160331a2d33c5823e22249ad3118b"},
|
{file = "orjson-3.10.15-cp310-cp310-win32.whl", hash = "sha256:f9875f5fea7492da8ec2444839dcc439b0ef298978f311103d0b7dfd775898ab"},
|
||||||
{file = "orjson-3.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:fa18f949d3183a8d468367056be989666ac2bef3a72eece0bade9cdb733b3c28"},
|
{file = "orjson-3.10.15-cp310-cp310-win_amd64.whl", hash = "sha256:17085a6aa91e1cd70ca8533989a18b5433e15d29c574582f76f821737c8d5806"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f506fd666dd1ecd15a832bebc66c4df45c1902fd47526292836c339f7ba665a9"},
|
{file = "orjson-3.10.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c4cc83960ab79a4031f3119cc4b1a1c627a3dc09df125b27c4201dff2af7eaa6"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efe5fd254cfb0eeee13b8ef7ecb20f5d5a56ddda8a587f3852ab2cedfefdb5f6"},
|
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddbeef2481d895ab8be5185f2432c334d6dec1f5d1933a9c83014d188e102cef"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ddc8c866d7467f5ee2991397d2ea94bcf60d0048bdd8ca555740b56f9042725"},
|
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9e590a0477b23ecd5b0ac865b1b907b01b3c5535f5e8a8f6ab0e503efb896334"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af8e42ae4363773658b8d578d56dedffb4f05ceeb4d1d4dd3fb504950b45526"},
|
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6be38bd103d2fd9bdfa31c2720b23b5d47c6796bcb1d1b598e3924441b4298d"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84dd83110503bc10e94322bf3ffab8bc49150176b49b4984dc1cce4c0a993bf9"},
|
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff4f6edb1578960ed628a3b998fa54d78d9bb3e2eb2cfc5c2a09732431c678d0"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36f5bfc0399cd4811bf10ec7a759c7ab0cd18080956af8ee138097d5b5296a95"},
|
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0482b21d0462eddd67e7fce10b89e0b6ac56570424662b685a0d6fccf581e13"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:868943660fb2a1e6b6b965b74430c16a79320b665b28dd4511d15ad5038d37d5"},
|
{file = "orjson-3.10.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bb5cc3527036ae3d98b65e37b7986a918955f85332c1ee07f9d3f82f3a6899b5"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33449c67195969b1a677533dee9d76e006001213a24501333624623e13c7cc8e"},
|
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d569c1c462912acdd119ccbf719cf7102ea2c67dd03b99edcb1a3048651ac96b"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4c9f60f9fb0b5be66e416dcd8c9d94c3eabff3801d875bdb1f8ffc12cf86905"},
|
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1e6d33efab6b71d67f22bf2962895d3dc6f82a6273a965fab762e64fa90dc399"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0de4d6315cfdbd9ec803b945c23b3a68207fd47cbe43626036d97e8e9561a436"},
|
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c33be3795e299f565681d69852ac8c1bc5c84863c0b0030b2b3468843be90388"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83adda3db595cb1a7e2237029b3249c85afbe5c747d26b41b802e7482cb3933e"},
|
{file = "orjson-3.10.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eea80037b9fae5339b214f59308ef0589fc06dc870578b7cce6d71eb2096764c"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-win32.whl", hash = "sha256:998019ef74a4997a9d741b1473533cdb8faa31373afc9849b35129b4b8ec048d"},
|
{file = "orjson-3.10.15-cp311-cp311-win32.whl", hash = "sha256:d5ac11b659fd798228a7adba3e37c010e0152b78b1982897020a8e019a94882e"},
|
||||||
{file = "orjson-3.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:9d034abdd36f0f0f2240f91492684e5043d46f290525d1117712d5b8137784eb"},
|
{file = "orjson-3.10.15-cp311-cp311-win_amd64.whl", hash = "sha256:cf45e0214c593660339ef63e875f32ddd5aa3b4adc15e662cdb80dc49e194f8e"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2ad4b7e367efba6dc3f119c9a0fcd41908b7ec0399a696f3cdea7ec477441b09"},
|
{file = "orjson-3.10.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d11c0714fc85bfcf36ada1179400862da3288fc785c30e8297844c867d7505a"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f496286fc85e93ce0f71cc84fc1c42de2decf1bf494094e188e27a53694777a7"},
|
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba5a1e85d554e3897fa9fe6fbcff2ed32d55008973ec9a2b992bd9a65d2352d"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c7f189bbfcded40e41a6969c1068ba305850ba016665be71a217918931416fbf"},
|
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7723ad949a0ea502df656948ddd8b392780a5beaa4c3b5f97e525191b102fff0"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cc8204f0b75606869c707da331058ddf085de29558b516fc43c73ee5ee2aadb"},
|
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6fd9bc64421e9fe9bd88039e7ce8e58d4fead67ca88e3a4014b143cec7684fd4"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deaa2899dff7f03ab667e2ec25842d233e2a6a9e333efa484dfe666403f3501c"},
|
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dadba0e7b6594216c214ef7894c4bd5f08d7c0135f4dd0145600be4fbcc16767"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1c3ea52642c9714dc6e56de8a451a066f6d2707d273e07fe8a9cc1ba073813d"},
|
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48f59114fe318f33bbaee8ebeda696d8ccc94c9e90bc27dbe72153094e26f41"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d3f9ed72e7458ded9a1fb1b4d4ed4c4fdbaf82030ce3f9274b4dc1bff7ace2b"},
|
{file = "orjson-3.10.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:035fb83585e0f15e076759b6fedaf0abb460d1765b6a36f48018a52858443514"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:07520685d408a2aba514c17ccc16199ff2934f9f9e28501e676c557f454a37fe"},
|
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d13b7fe322d75bf84464b075eafd8e7dd9eae05649aa2a5354cfa32f43c59f17"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:76344269b550ea01488d19a2a369ab572c1ac4449a72e9f6ac0d70eb1cbfb953"},
|
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7066b74f9f259849629e0d04db6609db4cf5b973248f455ba5d3bd58a4daaa5b"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e2979d0f2959990620f7e62da6cd954e4620ee815539bc57a8ae46e2dacf90e3"},
|
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88dc3f65a026bd3175eb157fea994fca6ac7c4c8579fc5a86fc2114ad05705b7"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03f61ca3674555adcb1aa717b9fc87ae936aa7a63f6aba90a474a88701278780"},
|
{file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b342567e5465bd99faa559507fe45e33fc76b9fb868a63f1642c6bc0735ad02a"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-win32.whl", hash = "sha256:d5075c54edf1d6ad81d4c6523ce54a748ba1208b542e54b97d8a882ecd810fd1"},
|
{file = "orjson-3.10.15-cp312-cp312-win32.whl", hash = "sha256:0a4f27ea5617828e6b58922fdbec67b0aa4bb844e2d363b9244c47fa2180e665"},
|
||||||
{file = "orjson-3.10.14-cp312-cp312-win_amd64.whl", hash = "sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406"},
|
{file = "orjson-3.10.15-cp312-cp312-win_amd64.whl", hash = "sha256:ef5b87e7aa9545ddadd2309efe6824bd3dd64ac101c15dae0f2f597911d46eaa"},
|
||||||
{file = "orjson-3.10.14-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:0905ca08a10f7e0e0c97d11359609300eb1437490a7f32bbaa349de757e2e0c7"},
|
{file = "orjson-3.10.15-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:bae0e6ec2b7ba6895198cd981b7cca95d1487d0147c8ed751e5632ad16f031a6"},
|
||||||
{file = "orjson-3.10.14-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92d13292249f9f2a3e418cbc307a9fbbef043c65f4bd8ba1eb620bc2aaba3d15"},
|
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f93ce145b2db1252dd86af37d4165b6faa83072b46e3995ecc95d4b2301b725a"},
|
||||||
{file = "orjson-3.10.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90937664e776ad316d64251e2fa2ad69265e4443067668e4727074fe39676414"},
|
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c203f6f969210128af3acae0ef9ea6aab9782939f45f6fe02d05958fe761ef9"},
|
||||||
{file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9ed3d26c4cb4f6babaf791aa46a029265850e80ec2a566581f5c2ee1a14df4f1"},
|
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8918719572d662e18b8af66aef699d8c21072e54b6c82a3f8f6404c1f5ccd5e0"},
|
||||||
{file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:56ee546c2bbe9599aba78169f99d1dc33301853e897dbaf642d654248280dc6e"},
|
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f71eae9651465dff70aa80db92586ad5b92df46a9373ee55252109bb6b703307"},
|
||||||
{file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:901e826cb2f1bdc1fcef3ef59adf0c451e8f7c0b5deb26c1a933fb66fb505eae"},
|
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e117eb299a35f2634e25ed120c37c641398826c2f5a3d3cc39f5993b96171b9e"},
|
||||||
{file = "orjson-3.10.14-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:26336c0d4b2d44636e1e1e6ed1002f03c6aae4a8a9329561c8883f135e9ff010"},
|
{file = "orjson-3.10.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13242f12d295e83c2955756a574ddd6741c81e5b99f2bef8ed8d53e47a01e4b7"},
|
||||||
{file = "orjson-3.10.14-cp313-cp313-win32.whl", hash = "sha256:e2bc525e335a8545c4e48f84dd0328bc46158c9aaeb8a1c2276546e94540ea3d"},
|
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7946922ada8f3e0b7b958cc3eb22cfcf6c0df83d1fe5521b4a100103e3fa84c8"},
|
||||||
{file = "orjson-3.10.14-cp313-cp313-win_amd64.whl", hash = "sha256:eca04dfd792cedad53dc9a917da1a522486255360cb4e77619343a20d9f35364"},
|
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b7155eb1623347f0f22c38c9abdd738b287e39b9982e1da227503387b81b34ca"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9a0fba3b8a587a54c18585f077dcab6dd251c170d85cfa4d063d5746cd595a0f"},
|
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:208beedfa807c922da4e81061dafa9c8489c6328934ca2a562efa707e049e561"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:175abf3d20e737fec47261d278f95031736a49d7832a09ab684026528c4d96db"},
|
{file = "orjson-3.10.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eca81f83b1b8c07449e1d6ff7074e82e3fd6777e588f1a6632127f286a968825"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29ca1a93e035d570e8b791b6c0feddd403c6a5388bfe870bf2aa6bba1b9d9b8e"},
|
{file = "orjson-3.10.15-cp313-cp313-win32.whl", hash = "sha256:c03cd6eea1bd3b949d0d007c8d57049aa2b39bd49f58b4b2af571a5d3833d890"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f77202c80e8ab5a1d1e9faf642343bee5aaf332061e1ada4e9147dbd9eb00c46"},
|
{file = "orjson-3.10.15-cp313-cp313-win_amd64.whl", hash = "sha256:fd56a26a04f6ba5fb2045b0acc487a63162a958ed837648c5781e1fe3316cfbf"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e2ec73b7099b6a29b40a62e08a23b936423bd35529f8f55c42e27acccde7954"},
|
{file = "orjson-3.10.15-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5e8afd6200e12771467a1a44e5ad780614b86abb4b11862ec54861a82d677746"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2d1679df9f9cd9504f8dff24555c1eaabba8aad7f5914f28dab99e3c2552c9d"},
|
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da9a18c500f19273e9e104cca8c1f0b40a6470bcccfc33afcc088045d0bf5ea6"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:691ab9a13834310a263664313e4f747ceb93662d14a8bdf20eb97d27ed488f16"},
|
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb00b7bfbdf5d34a13180e4805d76b4567025da19a197645ca746fc2fb536586"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b11ed82054fce82fb74cea33247d825d05ad6a4015ecfc02af5fbce442fbf361"},
|
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33aedc3d903378e257047fee506f11e0833146ca3e57a1a1fb0ddb789876c1e1"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:e70a1d62b8288677d48f3bea66c21586a5f999c64ecd3878edb7393e8d1b548d"},
|
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0099ae6aed5eb1fc84c9eb72b95505a3df4267e6962eb93cdd5af03be71c98"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:16642f10c1ca5611251bd835de9914a4b03095e28a34c8ba6a5500b5074338bd"},
|
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c864a80a2d467d7786274fce0e4f93ef2a7ca4ff31f7fc5634225aaa4e9e98c"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3871bad546aa66c155e3f36f99c459780c2a392d502a64e23fb96d9abf338511"},
|
{file = "orjson-3.10.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c25774c9e88a3e0013d7d1a6c8056926b607a61edd423b50eb5c88fd7f2823ae"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-win32.whl", hash = "sha256:0293a88815e9bb5c90af4045f81ed364d982f955d12052d989d844d6c4e50945"},
|
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e78c211d0074e783d824ce7bb85bf459f93a233eb67a5b5003498232ddfb0e8a"},
|
||||||
{file = "orjson-3.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:6169d3868b190d6b21adc8e61f64e3db30f50559dfbdef34a1cd6c738d409dfc"},
|
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:43e17289ffdbbac8f39243916c893d2ae41a2ea1a9cbb060a56a4d75286351ae"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:06d4ec218b1ec1467d8d64da4e123b4794c781b536203c309ca0f52819a16c03"},
|
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:781d54657063f361e89714293c095f506c533582ee40a426cb6489c48a637b81"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:962c2ec0dcaf22b76dee9831fdf0c4a33d4bf9a257a2bc5d4adc00d5c8ad9034"},
|
{file = "orjson-3.10.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6875210307d36c94873f553786a808af2788e362bd0cf4c8e66d976791e7b528"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:21d3be4132f71ef1360385770474f29ea1538a242eef72ac4934fe142800e37f"},
|
{file = "orjson-3.10.15-cp38-cp38-win32.whl", hash = "sha256:305b38b2b8f8083cc3d618927d7f424349afce5975b316d33075ef0f73576b60"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c28ed60597c149a9e3f5ad6dd9cebaee6fb2f0e3f2d159a4a2b9b862d4748860"},
|
{file = "orjson-3.10.15-cp38-cp38-win_amd64.whl", hash = "sha256:5dd9ef1639878cc3efffed349543cbf9372bdbd79f478615a1c633fe4e4180d1"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e947f70167fe18469f2023644e91ab3d24f9aed69a5e1c78e2c81b9cea553fb"},
|
{file = "orjson-3.10.15-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ffe19f3e8d68111e8644d4f4e267a069ca427926855582ff01fc012496d19969"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64410696c97a35af2432dea7bdc4ce32416458159430ef1b4beb79fd30093ad6"},
|
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d433bf32a363823863a96561a555227c18a522a8217a6f9400f00ddc70139ae2"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8050a5d81c022561ee29cd2739de5b4445f3c72f39423fde80a63299c1892c52"},
|
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da03392674f59a95d03fa5fb9fe3a160b0511ad84b7a3914699ea5a1b3a38da2"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b49a28e30d3eca86db3fe6f9b7f4152fcacbb4a467953cd1b42b94b479b77956"},
|
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a63bb41559b05360ded9132032239e47983a39b151af1201f07ec9370715c82"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ca041ad20291a65d853a9523744eebc3f5a4b2f7634e99f8fe88320695ddf766"},
|
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3766ac4702f8f795ff3fa067968e806b4344af257011858cc3d6d8721588b53f"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d313a2998b74bb26e9e371851a173a9b9474764916f1fc7971095699b3c6e964"},
|
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a1c73dcc8fadbd7c55802d9aa093b36878d34a3b3222c41052ce6b0fc65f8e8"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7796692136a67b3e301ef9052bde6fe8e7bd5200da766811a3a608ffa62aaff0"},
|
{file = "orjson-3.10.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b299383825eafe642cbab34be762ccff9fd3408d72726a6b2a4506d410a71ab3"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-win32.whl", hash = "sha256:eee4bc767f348fba485ed9dc576ca58b0a9eac237f0e160f7a59bce628ed06b3"},
|
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:abc7abecdbf67a173ef1316036ebbf54ce400ef2300b4e26a7b843bd446c2480"},
|
||||||
{file = "orjson-3.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:96a1c0ee30fb113b3ae3c748fd75ca74a157ff4c58476c47db4d61518962a011"},
|
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:3614ea508d522a621384c1d6639016a5a2e4f027f3e4a1c93a51867615d28829"},
|
||||||
{file = "orjson-3.10.14.tar.gz", hash = "sha256:cf31f6f071a6b8e7aa1ead1fa27b935b48d00fbfa6a28ce856cfff2d5dd68eed"},
|
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:295c70f9dc154307777ba30fe29ff15c1bcc9dfc5c48632f37d20a607e9ba85a"},
|
||||||
|
{file = "orjson-3.10.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:63309e3ff924c62404923c80b9e2048c1f74ba4b615e7584584389ada50ed428"},
|
||||||
|
{file = "orjson-3.10.15-cp39-cp39-win32.whl", hash = "sha256:a2f708c62d026fb5340788ba94a55c23df4e1869fec74be455e0b2f5363b8507"},
|
||||||
|
{file = "orjson-3.10.15-cp39-cp39-win_amd64.whl", hash = "sha256:efcf6c735c3d22ef60c4aa27a5238f1a477df85e9b15f2142f9d669beb2d13fd"},
|
||||||
|
{file = "orjson-3.10.15.tar.gz", hash = "sha256:05ca7fe452a2e9d8d9d706a2984c95b9c2ebc5db417ce0b7a49b91d50642a23e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2498,13 +2496,13 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic"
|
name = "pydantic"
|
||||||
version = "2.10.5"
|
version = "2.10.6"
|
||||||
description = "Data validation using Python type hints"
|
description = "Data validation using Python type hints"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"},
|
{file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"},
|
||||||
{file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"},
|
{file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -2712,13 +2710,13 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytest-asyncio"
|
name = "pytest-asyncio"
|
||||||
version = "0.25.2"
|
version = "0.25.3"
|
||||||
description = "Pytest support for asyncio"
|
description = "Pytest support for asyncio"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
files = [
|
files = [
|
||||||
{file = "pytest_asyncio-0.25.2-py3-none-any.whl", hash = "sha256:0d0bb693f7b99da304a0634afc0a4b19e49d5e0de2d670f38dc4bfa5727c5075"},
|
{file = "pytest_asyncio-0.25.3-py3-none-any.whl", hash = "sha256:9e89518e0f9bd08928f97a3482fdc4e244df17529460bc038291ccaf8f85c7c3"},
|
||||||
{file = "pytest_asyncio-0.25.2.tar.gz", hash = "sha256:3f8ef9a98f45948ea91a0ed3dc4268b5326c0e7bce73892acc654df4262ad45f"},
|
{file = "pytest_asyncio-0.25.3.tar.gz", hash = "sha256:fc1da2cf9f125ada7e710b4ddad05518d4cee187ae9412e9ac9271003497f07a"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -3049,29 +3047,29 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff"
|
name = "ruff"
|
||||||
version = "0.9.2"
|
version = "0.9.6"
|
||||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "ruff-0.9.2-py3-none-linux_armv6l.whl", hash = "sha256:80605a039ba1454d002b32139e4970becf84b5fee3a3c3bf1c2af6f61a784347"},
|
{file = "ruff-0.9.6-py3-none-linux_armv6l.whl", hash = "sha256:2f218f356dd2d995839f1941322ff021c72a492c470f0b26a34f844c29cdf5ba"},
|
||||||
{file = "ruff-0.9.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b9aab82bb20afd5f596527045c01e6ae25a718ff1784cb92947bff1f83068b00"},
|
{file = "ruff-0.9.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b908ff4df65dad7b251c9968a2e4560836d8f5487c2f0cc238321ed951ea0504"},
|
||||||
{file = "ruff-0.9.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fbd337bac1cfa96be615f6efcd4bc4d077edbc127ef30e2b8ba2a27e18c054d4"},
|
{file = "ruff-0.9.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b109c0ad2ececf42e75fa99dc4043ff72a357436bb171900714a9ea581ddef83"},
|
||||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b35259b0cbf8daa22a498018e300b9bb0174c2bbb7bcba593935158a78054d"},
|
{file = "ruff-0.9.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de4367cca3dac99bcbd15c161404e849bb0bfd543664db39232648dc00112dc"},
|
||||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b6a9701d1e371bf41dca22015c3f89769da7576884d2add7317ec1ec8cb9c3c"},
|
{file = "ruff-0.9.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3ee4d7c2c92ddfdaedf0bf31b2b176fa7aa8950efc454628d477394d35638b"},
|
||||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9cc53e68b3c5ae41e8faf83a3b89f4a5d7b2cb666dff4b366bb86ed2a85b481f"},
|
{file = "ruff-0.9.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dc1edd1775270e6aa2386119aea692039781429f0be1e0949ea5884e011aa8e"},
|
||||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8efd9da7a1ee314b910da155ca7e8953094a7c10d0c0a39bfde3fcfd2a015684"},
|
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4a091729086dffa4bd070aa5dab7e39cc6b9d62eb2bef8f3d91172d30d599666"},
|
||||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3292c5a22ea9a5f9a185e2d131dc7f98f8534a32fb6d2ee7b9944569239c648d"},
|
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1bbc6808bf7b15796cef0815e1dfb796fbd383e7dbd4334709642649625e7c5"},
|
||||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a605fdcf6e8b2d39f9436d343d1f0ff70c365a1e681546de0104bef81ce88df"},
|
{file = "ruff-0.9.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:589d1d9f25b5754ff230dce914a174a7c951a85a4e9270613a2b74231fdac2f5"},
|
||||||
{file = "ruff-0.9.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c547f7f256aa366834829a08375c297fa63386cbe5f1459efaf174086b564247"},
|
{file = "ruff-0.9.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc61dd5131742e21103fbbdcad683a8813be0e3c204472d520d9a5021ca8b217"},
|
||||||
{file = "ruff-0.9.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d18bba3d3353ed916e882521bc3e0af403949dbada344c20c16ea78f47af965e"},
|
{file = "ruff-0.9.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5e2d9126161d0357e5c8f30b0bd6168d2c3872372f14481136d13de9937f79b6"},
|
||||||
{file = "ruff-0.9.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b338edc4610142355ccf6b87bd356729b62bf1bc152a2fad5b0c7dc04af77bfe"},
|
{file = "ruff-0.9.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:68660eab1a8e65babb5229a1f97b46e3120923757a68b5413d8561f8a85d4897"},
|
||||||
{file = "ruff-0.9.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:492a5e44ad9b22a0ea98cf72e40305cbdaf27fac0d927f8bc9e1df316dcc96eb"},
|
{file = "ruff-0.9.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c4cae6c4cc7b9b4017c71114115db0445b00a16de3bcde0946273e8392856f08"},
|
||||||
{file = "ruff-0.9.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:af1e9e9fe7b1f767264d26b1075ac4ad831c7db976911fa362d09b2d0356426a"},
|
{file = "ruff-0.9.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19f505b643228b417c1111a2a536424ddde0db4ef9023b9e04a46ed8a1cb4656"},
|
||||||
{file = "ruff-0.9.2-py3-none-win32.whl", hash = "sha256:71cbe22e178c5da20e1514e1e01029c73dc09288a8028a5d3446e6bba87a5145"},
|
{file = "ruff-0.9.6-py3-none-win32.whl", hash = "sha256:194d8402bceef1b31164909540a597e0d913c0e4952015a5b40e28c146121b5d"},
|
||||||
{file = "ruff-0.9.2-py3-none-win_amd64.whl", hash = "sha256:c5e1d6abc798419cf46eed03f54f2e0c3adb1ad4b801119dedf23fcaf69b55b5"},
|
{file = "ruff-0.9.6-py3-none-win_amd64.whl", hash = "sha256:03482d5c09d90d4ee3f40d97578423698ad895c87314c4de39ed2af945633caa"},
|
||||||
{file = "ruff-0.9.2-py3-none-win_arm64.whl", hash = "sha256:a1b63fa24149918f8b37cef2ee6fff81f24f0d74b6f0bdc37bc3e1f2143e41c6"},
|
{file = "ruff-0.9.6-py3-none-win_arm64.whl", hash = "sha256:0e2bb706a2be7ddfea4a4af918562fdc1bcb16df255e5fa595bbd800ce322a5a"},
|
||||||
{file = "ruff-0.9.2.tar.gz", hash = "sha256:b5eceb334d55fae5f316f783437392642ae18e16dcf4f1858d55d3c2a0f8f5d0"},
|
{file = "ruff-0.9.6.tar.gz", hash = "sha256:81761592f72b620ec8fa1068a6fd00e98a5ebee342a3642efd84454f3031dca9"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "machine-learning"
|
name = "machine-learning"
|
||||||
version = "1.125.7"
|
version = "1.126.1"
|
||||||
description = ""
|
description = ""
|
||||||
authors = ["Hau Tran <alex.tran1502@gmail.com>"]
|
authors = ["Hau Tran <alex.tran1502@gmail.com>"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ platform :android do
|
|||||||
task: 'bundle',
|
task: 'bundle',
|
||||||
build_type: 'Release',
|
build_type: 'Release',
|
||||||
properties: {
|
properties: {
|
||||||
"android.injected.version.code" => 182,
|
"android.injected.version.code" => 184,
|
||||||
"android.injected.version.name" => "1.125.7",
|
"android.injected.version.name" => "1.126.1",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
|
||||||
|
|||||||
@@ -541,7 +541,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 190;
|
CURRENT_PROJECT_VERSION = 194;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
@@ -685,7 +685,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 190;
|
CURRENT_PROJECT_VERSION = 194;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
@@ -715,7 +715,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 190;
|
CURRENT_PROJECT_VERSION = 194;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
@@ -748,7 +748,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 190;
|
CURRENT_PROJECT_VERSION = 194;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
@@ -791,7 +791,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 190;
|
CURRENT_PROJECT_VERSION = 194;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
@@ -831,7 +831,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 190;
|
CURRENT_PROJECT_VERSION = 194;
|
||||||
CUSTOM_GROUP_ID = group.app.immich.share;
|
CUSTOM_GROUP_ID = group.app.immich.share;
|
||||||
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
DEVELOPMENT_TEAM = 2F67MQ8R79;
|
||||||
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.125.2</string>
|
<string>1.126.1</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>190</string>
|
<string>194</string>
|
||||||
<key>FLTEnableImpeller</key>
|
<key>FLTEnableImpeller</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ platform :ios do
|
|||||||
desc "iOS Release"
|
desc "iOS Release"
|
||||||
lane :release do
|
lane :release do
|
||||||
increment_version_number(
|
increment_version_number(
|
||||||
version_number: "1.125.7"
|
version_number: "1.126.1"
|
||||||
)
|
)
|
||||||
increment_build_number(
|
increment_build_number(
|
||||||
build_number: latest_testflight_build_number + 1,
|
build_number: latest_testflight_build_number + 1,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ dynamic upgradeDto(dynamic value, String targetType) {
|
|||||||
addDefault(value, 'ratings', RatingsResponse().toJson());
|
addDefault(value, 'ratings', RatingsResponse().toJson());
|
||||||
addDefault(value, 'people', PeopleResponse().toJson());
|
addDefault(value, 'people', PeopleResponse().toJson());
|
||||||
addDefault(value, 'tags', TagsResponse().toJson());
|
addDefault(value, 'tags', TagsResponse().toJson());
|
||||||
|
addDefault(value, 'sharedLinks', SharedLinksResponse().toJson());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ServerConfigDto':
|
case 'ServerConfigDto':
|
||||||
|
|||||||
@@ -59,9 +59,10 @@ class MapBottomSheet extends HookConsumerWidget {
|
|||||||
child: DraggableScrollableSheet(
|
child: DraggableScrollableSheet(
|
||||||
controller: sheetController,
|
controller: sheetController,
|
||||||
minChildSize: sheetMinExtent,
|
minChildSize: sheetMinExtent,
|
||||||
maxChildSize: 0.5,
|
maxChildSize: 0.8,
|
||||||
initialChildSize: sheetMinExtent,
|
initialChildSize: sheetMinExtent,
|
||||||
snap: true,
|
snap: true,
|
||||||
|
snapSizes: [sheetMinExtent, 0.5, 0.8],
|
||||||
shouldCloseOnMinExtent: false,
|
shouldCloseOnMinExtent: false,
|
||||||
builder: (ctx, scrollController) => MapAssetGrid(
|
builder: (ctx, scrollController) => MapAssetGrid(
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
@@ -78,18 +79,23 @@ class MapBottomSheet extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
ValueListenableBuilder(
|
ValueListenableBuilder(
|
||||||
valueListenable: bottomSheetOffset,
|
valueListenable: bottomSheetOffset,
|
||||||
builder: (ctx, value, child) => Positioned(
|
builder: (context, value, child) {
|
||||||
right: 0,
|
return Positioned(
|
||||||
bottom: context.height * (value + 0.02),
|
right: 0,
|
||||||
child: child!,
|
bottom: context.height * (value + 0.02),
|
||||||
),
|
child: AnimatedOpacity(
|
||||||
child: ElevatedButton(
|
opacity: value < 0.8 ? 1 : 0,
|
||||||
onPressed: onZoomToLocation,
|
duration: const Duration(milliseconds: 150),
|
||||||
style: ElevatedButton.styleFrom(
|
child: ElevatedButton(
|
||||||
shape: const CircleBorder(),
|
onPressed: onZoomToLocation,
|
||||||
),
|
style: ElevatedButton.styleFrom(
|
||||||
child: const Icon(Icons.my_location),
|
shape: const CircleBorder(),
|
||||||
),
|
),
|
||||||
|
child: const Icon(Icons.my_location),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
Generated
+1
-1
@@ -3,7 +3,7 @@ Immich API
|
|||||||
|
|
||||||
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
|
||||||
|
|
||||||
- API version: 1.125.7
|
- API version: 1.126.1
|
||||||
- Generator version: 7.8.0
|
- Generator version: 7.8.0
|
||||||
- Build package: org.openapitools.codegen.languages.DartClientCodegen
|
- Build package: org.openapitools.codegen.languages.DartClientCodegen
|
||||||
|
|
||||||
|
|||||||
+13
-3
@@ -127,7 +127,10 @@ class SharedLinksApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Performs an HTTP 'GET /shared-links' operation and returns the [Response].
|
/// Performs an HTTP 'GET /shared-links' operation and returns the [Response].
|
||||||
Future<Response> getAllSharedLinksWithHttpInfo() async {
|
/// Parameters:
|
||||||
|
///
|
||||||
|
/// * [String] albumId:
|
||||||
|
Future<Response> getAllSharedLinksWithHttpInfo({ String? albumId, }) async {
|
||||||
// ignore: prefer_const_declarations
|
// ignore: prefer_const_declarations
|
||||||
final path = r'/shared-links';
|
final path = r'/shared-links';
|
||||||
|
|
||||||
@@ -138,6 +141,10 @@ class SharedLinksApi {
|
|||||||
final headerParams = <String, String>{};
|
final headerParams = <String, String>{};
|
||||||
final formParams = <String, String>{};
|
final formParams = <String, String>{};
|
||||||
|
|
||||||
|
if (albumId != null) {
|
||||||
|
queryParams.addAll(_queryParams('', 'albumId', albumId));
|
||||||
|
}
|
||||||
|
|
||||||
const contentTypes = <String>[];
|
const contentTypes = <String>[];
|
||||||
|
|
||||||
|
|
||||||
@@ -152,8 +159,11 @@ class SharedLinksApi {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<SharedLinkResponseDto>?> getAllSharedLinks() async {
|
/// Parameters:
|
||||||
final response = await getAllSharedLinksWithHttpInfo();
|
///
|
||||||
|
/// * [String] albumId:
|
||||||
|
Future<List<SharedLinkResponseDto>?> getAllSharedLinks({ String? albumId, }) async {
|
||||||
|
final response = await getAllSharedLinksWithHttpInfo( albumId: albumId, );
|
||||||
if (response.statusCode >= HttpStatus.badRequest) {
|
if (response.statusCode >= HttpStatus.badRequest) {
|
||||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||||
}
|
}
|
||||||
|
|||||||
+104
-1
@@ -20,6 +20,7 @@ class AssetBulkUpdateDto {
|
|||||||
this.isFavorite,
|
this.isFavorite,
|
||||||
this.latitude,
|
this.latitude,
|
||||||
this.longitude,
|
this.longitude,
|
||||||
|
this.orientation,
|
||||||
this.rating,
|
this.rating,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -67,6 +68,8 @@ class AssetBulkUpdateDto {
|
|||||||
///
|
///
|
||||||
num? longitude;
|
num? longitude;
|
||||||
|
|
||||||
|
AssetBulkUpdateDtoOrientationEnum? orientation;
|
||||||
|
|
||||||
/// Minimum value: -1
|
/// Minimum value: -1
|
||||||
/// Maximum value: 5
|
/// Maximum value: 5
|
||||||
///
|
///
|
||||||
@@ -86,6 +89,7 @@ class AssetBulkUpdateDto {
|
|||||||
other.isFavorite == isFavorite &&
|
other.isFavorite == isFavorite &&
|
||||||
other.latitude == latitude &&
|
other.latitude == latitude &&
|
||||||
other.longitude == longitude &&
|
other.longitude == longitude &&
|
||||||
|
other.orientation == orientation &&
|
||||||
other.rating == rating;
|
other.rating == rating;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -98,10 +102,11 @@ class AssetBulkUpdateDto {
|
|||||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||||
(latitude == null ? 0 : latitude!.hashCode) +
|
(latitude == null ? 0 : latitude!.hashCode) +
|
||||||
(longitude == null ? 0 : longitude!.hashCode) +
|
(longitude == null ? 0 : longitude!.hashCode) +
|
||||||
|
(orientation == null ? 0 : orientation!.hashCode) +
|
||||||
(rating == null ? 0 : rating!.hashCode);
|
(rating == null ? 0 : rating!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'AssetBulkUpdateDto[dateTimeOriginal=$dateTimeOriginal, duplicateId=$duplicateId, ids=$ids, isArchived=$isArchived, isFavorite=$isFavorite, latitude=$latitude, longitude=$longitude, rating=$rating]';
|
String toString() => 'AssetBulkUpdateDto[dateTimeOriginal=$dateTimeOriginal, duplicateId=$duplicateId, ids=$ids, isArchived=$isArchived, isFavorite=$isFavorite, latitude=$latitude, longitude=$longitude, orientation=$orientation, rating=$rating]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@@ -136,6 +141,11 @@ class AssetBulkUpdateDto {
|
|||||||
} else {
|
} else {
|
||||||
// json[r'longitude'] = null;
|
// json[r'longitude'] = null;
|
||||||
}
|
}
|
||||||
|
if (this.orientation != null) {
|
||||||
|
json[r'orientation'] = this.orientation;
|
||||||
|
} else {
|
||||||
|
// json[r'orientation'] = null;
|
||||||
|
}
|
||||||
if (this.rating != null) {
|
if (this.rating != null) {
|
||||||
json[r'rating'] = this.rating;
|
json[r'rating'] = this.rating;
|
||||||
} else {
|
} else {
|
||||||
@@ -162,6 +172,7 @@ class AssetBulkUpdateDto {
|
|||||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||||
latitude: num.parse('${json[r'latitude']}'),
|
latitude: num.parse('${json[r'latitude']}'),
|
||||||
longitude: num.parse('${json[r'longitude']}'),
|
longitude: num.parse('${json[r'longitude']}'),
|
||||||
|
orientation: AssetBulkUpdateDtoOrientationEnum.fromJson(json[r'orientation']),
|
||||||
rating: num.parse('${json[r'rating']}'),
|
rating: num.parse('${json[r'rating']}'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -214,3 +225,95 @@ class AssetBulkUpdateDto {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AssetBulkUpdateDtoOrientationEnum {
|
||||||
|
/// Instantiate a new enum with the provided [value].
|
||||||
|
const AssetBulkUpdateDtoOrientationEnum._(this.value);
|
||||||
|
|
||||||
|
/// The underlying value of this enum member.
|
||||||
|
final int value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => value.toString();
|
||||||
|
|
||||||
|
int toJson() => value;
|
||||||
|
|
||||||
|
static const number1 = AssetBulkUpdateDtoOrientationEnum._(1);
|
||||||
|
static const number2 = AssetBulkUpdateDtoOrientationEnum._(2);
|
||||||
|
static const number3 = AssetBulkUpdateDtoOrientationEnum._(3);
|
||||||
|
static const number4 = AssetBulkUpdateDtoOrientationEnum._(4);
|
||||||
|
static const number5 = AssetBulkUpdateDtoOrientationEnum._(5);
|
||||||
|
static const number6 = AssetBulkUpdateDtoOrientationEnum._(6);
|
||||||
|
static const number7 = AssetBulkUpdateDtoOrientationEnum._(7);
|
||||||
|
static const number8 = AssetBulkUpdateDtoOrientationEnum._(8);
|
||||||
|
|
||||||
|
/// List of all possible values in this [enum][AssetBulkUpdateDtoOrientationEnum].
|
||||||
|
static const values = <AssetBulkUpdateDtoOrientationEnum>[
|
||||||
|
number1,
|
||||||
|
number2,
|
||||||
|
number3,
|
||||||
|
number4,
|
||||||
|
number5,
|
||||||
|
number6,
|
||||||
|
number7,
|
||||||
|
number8,
|
||||||
|
];
|
||||||
|
|
||||||
|
static AssetBulkUpdateDtoOrientationEnum? fromJson(dynamic value) => AssetBulkUpdateDtoOrientationEnumTypeTransformer().decode(value);
|
||||||
|
|
||||||
|
static List<AssetBulkUpdateDtoOrientationEnum> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <AssetBulkUpdateDtoOrientationEnum>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = AssetBulkUpdateDtoOrientationEnum.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transformation class that can [encode] an instance of [AssetBulkUpdateDtoOrientationEnum] to int,
|
||||||
|
/// and [decode] dynamic data back to [AssetBulkUpdateDtoOrientationEnum].
|
||||||
|
class AssetBulkUpdateDtoOrientationEnumTypeTransformer {
|
||||||
|
factory AssetBulkUpdateDtoOrientationEnumTypeTransformer() => _instance ??= const AssetBulkUpdateDtoOrientationEnumTypeTransformer._();
|
||||||
|
|
||||||
|
const AssetBulkUpdateDtoOrientationEnumTypeTransformer._();
|
||||||
|
|
||||||
|
int encode(AssetBulkUpdateDtoOrientationEnum data) => data.value;
|
||||||
|
|
||||||
|
/// Decodes a [dynamic value][data] to a AssetBulkUpdateDtoOrientationEnum.
|
||||||
|
///
|
||||||
|
/// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully,
|
||||||
|
/// then null is returned. However, if [allowNull] is false and the [dynamic value][data]
|
||||||
|
/// cannot be decoded successfully, then an [UnimplementedError] is thrown.
|
||||||
|
///
|
||||||
|
/// The [allowNull] is very handy when an API changes and a new enum value is added or removed,
|
||||||
|
/// and users are still using an old app with the old code.
|
||||||
|
AssetBulkUpdateDtoOrientationEnum? decode(dynamic data, {bool allowNull = true}) {
|
||||||
|
if (data != null) {
|
||||||
|
switch (data) {
|
||||||
|
case 1: return AssetBulkUpdateDtoOrientationEnum.number1;
|
||||||
|
case 2: return AssetBulkUpdateDtoOrientationEnum.number2;
|
||||||
|
case 3: return AssetBulkUpdateDtoOrientationEnum.number3;
|
||||||
|
case 4: return AssetBulkUpdateDtoOrientationEnum.number4;
|
||||||
|
case 5: return AssetBulkUpdateDtoOrientationEnum.number5;
|
||||||
|
case 6: return AssetBulkUpdateDtoOrientationEnum.number6;
|
||||||
|
case 7: return AssetBulkUpdateDtoOrientationEnum.number7;
|
||||||
|
case 8: return AssetBulkUpdateDtoOrientationEnum.number8;
|
||||||
|
default:
|
||||||
|
if (!allowNull) {
|
||||||
|
throw ArgumentError('Unknown enum value to decode: $data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Singleton [AssetBulkUpdateDtoOrientationEnumTypeTransformer] instance.
|
||||||
|
static AssetBulkUpdateDtoOrientationEnumTypeTransformer? _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+104
-1
@@ -20,6 +20,7 @@ class UpdateAssetDto {
|
|||||||
this.latitude,
|
this.latitude,
|
||||||
this.livePhotoVideoId,
|
this.livePhotoVideoId,
|
||||||
this.longitude,
|
this.longitude,
|
||||||
|
this.orientation,
|
||||||
this.rating,
|
this.rating,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -73,6 +74,8 @@ class UpdateAssetDto {
|
|||||||
///
|
///
|
||||||
num? longitude;
|
num? longitude;
|
||||||
|
|
||||||
|
UpdateAssetDtoOrientationEnum? orientation;
|
||||||
|
|
||||||
/// Minimum value: -1
|
/// Minimum value: -1
|
||||||
/// Maximum value: 5
|
/// Maximum value: 5
|
||||||
///
|
///
|
||||||
@@ -92,6 +95,7 @@ class UpdateAssetDto {
|
|||||||
other.latitude == latitude &&
|
other.latitude == latitude &&
|
||||||
other.livePhotoVideoId == livePhotoVideoId &&
|
other.livePhotoVideoId == livePhotoVideoId &&
|
||||||
other.longitude == longitude &&
|
other.longitude == longitude &&
|
||||||
|
other.orientation == orientation &&
|
||||||
other.rating == rating;
|
other.rating == rating;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -104,10 +108,11 @@ class UpdateAssetDto {
|
|||||||
(latitude == null ? 0 : latitude!.hashCode) +
|
(latitude == null ? 0 : latitude!.hashCode) +
|
||||||
(livePhotoVideoId == null ? 0 : livePhotoVideoId!.hashCode) +
|
(livePhotoVideoId == null ? 0 : livePhotoVideoId!.hashCode) +
|
||||||
(longitude == null ? 0 : longitude!.hashCode) +
|
(longitude == null ? 0 : longitude!.hashCode) +
|
||||||
|
(orientation == null ? 0 : orientation!.hashCode) +
|
||||||
(rating == null ? 0 : rating!.hashCode);
|
(rating == null ? 0 : rating!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'UpdateAssetDto[dateTimeOriginal=$dateTimeOriginal, description=$description, isArchived=$isArchived, isFavorite=$isFavorite, latitude=$latitude, livePhotoVideoId=$livePhotoVideoId, longitude=$longitude, rating=$rating]';
|
String toString() => 'UpdateAssetDto[dateTimeOriginal=$dateTimeOriginal, description=$description, isArchived=$isArchived, isFavorite=$isFavorite, latitude=$latitude, livePhotoVideoId=$livePhotoVideoId, longitude=$longitude, orientation=$orientation, rating=$rating]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@@ -146,6 +151,11 @@ class UpdateAssetDto {
|
|||||||
} else {
|
} else {
|
||||||
// json[r'longitude'] = null;
|
// json[r'longitude'] = null;
|
||||||
}
|
}
|
||||||
|
if (this.orientation != null) {
|
||||||
|
json[r'orientation'] = this.orientation;
|
||||||
|
} else {
|
||||||
|
// json[r'orientation'] = null;
|
||||||
|
}
|
||||||
if (this.rating != null) {
|
if (this.rating != null) {
|
||||||
json[r'rating'] = this.rating;
|
json[r'rating'] = this.rating;
|
||||||
} else {
|
} else {
|
||||||
@@ -170,6 +180,7 @@ class UpdateAssetDto {
|
|||||||
latitude: num.parse('${json[r'latitude']}'),
|
latitude: num.parse('${json[r'latitude']}'),
|
||||||
livePhotoVideoId: mapValueOfType<String>(json, r'livePhotoVideoId'),
|
livePhotoVideoId: mapValueOfType<String>(json, r'livePhotoVideoId'),
|
||||||
longitude: num.parse('${json[r'longitude']}'),
|
longitude: num.parse('${json[r'longitude']}'),
|
||||||
|
orientation: UpdateAssetDtoOrientationEnum.fromJson(json[r'orientation']),
|
||||||
rating: num.parse('${json[r'rating']}'),
|
rating: num.parse('${json[r'rating']}'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -221,3 +232,95 @@ class UpdateAssetDto {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateAssetDtoOrientationEnum {
|
||||||
|
/// Instantiate a new enum with the provided [value].
|
||||||
|
const UpdateAssetDtoOrientationEnum._(this.value);
|
||||||
|
|
||||||
|
/// The underlying value of this enum member.
|
||||||
|
final int value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => value.toString();
|
||||||
|
|
||||||
|
int toJson() => value;
|
||||||
|
|
||||||
|
static const number1 = UpdateAssetDtoOrientationEnum._(1);
|
||||||
|
static const number2 = UpdateAssetDtoOrientationEnum._(2);
|
||||||
|
static const number3 = UpdateAssetDtoOrientationEnum._(3);
|
||||||
|
static const number4 = UpdateAssetDtoOrientationEnum._(4);
|
||||||
|
static const number5 = UpdateAssetDtoOrientationEnum._(5);
|
||||||
|
static const number6 = UpdateAssetDtoOrientationEnum._(6);
|
||||||
|
static const number7 = UpdateAssetDtoOrientationEnum._(7);
|
||||||
|
static const number8 = UpdateAssetDtoOrientationEnum._(8);
|
||||||
|
|
||||||
|
/// List of all possible values in this [enum][UpdateAssetDtoOrientationEnum].
|
||||||
|
static const values = <UpdateAssetDtoOrientationEnum>[
|
||||||
|
number1,
|
||||||
|
number2,
|
||||||
|
number3,
|
||||||
|
number4,
|
||||||
|
number5,
|
||||||
|
number6,
|
||||||
|
number7,
|
||||||
|
number8,
|
||||||
|
];
|
||||||
|
|
||||||
|
static UpdateAssetDtoOrientationEnum? fromJson(dynamic value) => UpdateAssetDtoOrientationEnumTypeTransformer().decode(value);
|
||||||
|
|
||||||
|
static List<UpdateAssetDtoOrientationEnum> listFromJson(dynamic json, {bool growable = false,}) {
|
||||||
|
final result = <UpdateAssetDtoOrientationEnum>[];
|
||||||
|
if (json is List && json.isNotEmpty) {
|
||||||
|
for (final row in json) {
|
||||||
|
final value = UpdateAssetDtoOrientationEnum.fromJson(row);
|
||||||
|
if (value != null) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toList(growable: growable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Transformation class that can [encode] an instance of [UpdateAssetDtoOrientationEnum] to int,
|
||||||
|
/// and [decode] dynamic data back to [UpdateAssetDtoOrientationEnum].
|
||||||
|
class UpdateAssetDtoOrientationEnumTypeTransformer {
|
||||||
|
factory UpdateAssetDtoOrientationEnumTypeTransformer() => _instance ??= const UpdateAssetDtoOrientationEnumTypeTransformer._();
|
||||||
|
|
||||||
|
const UpdateAssetDtoOrientationEnumTypeTransformer._();
|
||||||
|
|
||||||
|
int encode(UpdateAssetDtoOrientationEnum data) => data.value;
|
||||||
|
|
||||||
|
/// Decodes a [dynamic value][data] to a UpdateAssetDtoOrientationEnum.
|
||||||
|
///
|
||||||
|
/// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully,
|
||||||
|
/// then null is returned. However, if [allowNull] is false and the [dynamic value][data]
|
||||||
|
/// cannot be decoded successfully, then an [UnimplementedError] is thrown.
|
||||||
|
///
|
||||||
|
/// The [allowNull] is very handy when an API changes and a new enum value is added or removed,
|
||||||
|
/// and users are still using an old app with the old code.
|
||||||
|
UpdateAssetDtoOrientationEnum? decode(dynamic data, {bool allowNull = true}) {
|
||||||
|
if (data != null) {
|
||||||
|
switch (data) {
|
||||||
|
case 1: return UpdateAssetDtoOrientationEnum.number1;
|
||||||
|
case 2: return UpdateAssetDtoOrientationEnum.number2;
|
||||||
|
case 3: return UpdateAssetDtoOrientationEnum.number3;
|
||||||
|
case 4: return UpdateAssetDtoOrientationEnum.number4;
|
||||||
|
case 5: return UpdateAssetDtoOrientationEnum.number5;
|
||||||
|
case 6: return UpdateAssetDtoOrientationEnum.number6;
|
||||||
|
case 7: return UpdateAssetDtoOrientationEnum.number7;
|
||||||
|
case 8: return UpdateAssetDtoOrientationEnum.number8;
|
||||||
|
default:
|
||||||
|
if (!allowNull) {
|
||||||
|
throw ArgumentError('Unknown enum value to decode: $data');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Singleton [UpdateAssetDtoOrientationEnumTypeTransformer] instance.
|
||||||
|
static UpdateAssetDtoOrientationEnumTypeTransformer? _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ name: immich_mobile
|
|||||||
description: Immich - selfhosted backup media file on mobile phone
|
description: Immich - selfhosted backup media file on mobile phone
|
||||||
|
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
version: 1.125.7+182
|
version: 1.126.1+184
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.3.0 <4.0.0'
|
sdk: '>=3.3.0 <4.0.0'
|
||||||
|
|||||||
@@ -5230,7 +5230,17 @@
|
|||||||
"/shared-links": {
|
"/shared-links": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "getAllSharedLinks",
|
"operationId": "getAllSharedLinks",
|
||||||
"parameters": [],
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "albumId",
|
||||||
|
"required": false,
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"format": "uuid",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"content": {
|
"content": {
|
||||||
@@ -7458,7 +7468,7 @@
|
|||||||
"info": {
|
"info": {
|
||||||
"title": "Immich",
|
"title": "Immich",
|
||||||
"description": "Immich API",
|
"description": "Immich API",
|
||||||
"version": "1.125.7",
|
"version": "1.126.1",
|
||||||
"contact": {}
|
"contact": {}
|
||||||
},
|
},
|
||||||
"tags": [],
|
"tags": [],
|
||||||
@@ -7953,6 +7963,21 @@
|
|||||||
"longitude": {
|
"longitude": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
|
"orientation": {
|
||||||
|
"enum": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"maximum": 8,
|
||||||
|
"minimum": 1,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"rating": {
|
"rating": {
|
||||||
"maximum": 5,
|
"maximum": 5,
|
||||||
"minimum": -1,
|
"minimum": -1,
|
||||||
@@ -12870,6 +12895,21 @@
|
|||||||
"longitude": {
|
"longitude": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
|
"orientation": {
|
||||||
|
"enum": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"maximum": 8,
|
||||||
|
"minimum": 1,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"rating": {
|
"rating": {
|
||||||
"maximum": 5,
|
"maximum": 5,
|
||||||
"minimum": -1,
|
"minimum": -1,
|
||||||
|
|||||||
+6
-6
@@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.125.7",
|
"version": "1.126.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.125.7",
|
"version": "1.126.1",
|
||||||
"license": "GNU Affero General Public License version 3",
|
"license": "GNU Affero General Public License version 3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oazapfts/runtime": "^1.0.2"
|
"@oazapfts/runtime": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.10.9",
|
"@types/node": "^22.13.1",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -22,9 +22,9 @@
|
|||||||
"integrity": "sha512-8tKiYffhwTGHSHYGnZ3oneLGCjX0po/XAXQ5Ng9fqKkvIdl/xz8+Vh8i+6xjzZqvZ2pLVpUcuSfnvNI/x67L0g=="
|
"integrity": "sha512-8tKiYffhwTGHSHYGnZ3oneLGCjX0po/XAXQ5Ng9fqKkvIdl/xz8+Vh8i+6xjzZqvZ2pLVpUcuSfnvNI/x67L0g=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.10.9",
|
"version": "22.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
|
||||||
"integrity": "sha512-Ir6hwgsKyNESl/gLOcEz3krR4CBGgliDqBQ2ma4wIhEx0w+xnoeTq3tdrNw15kU3SxogDjOgv9sqdtLW8mIHaw==",
|
"integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@immich/sdk",
|
"name": "@immich/sdk",
|
||||||
"version": "1.125.7",
|
"version": "1.126.1",
|
||||||
"description": "Auto-generated TypeScript SDK for the Immich API",
|
"description": "Auto-generated TypeScript SDK for the Immich API",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./build/index.js",
|
"main": "./build/index.js",
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
"@oazapfts/runtime": "^1.0.2"
|
"@oazapfts/runtime": "^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.10.9",
|
"@types/node": "^22.13.1",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Immich
|
* Immich
|
||||||
* 1.125.7
|
* 1.126.1
|
||||||
* DO NOT MODIFY - This file has been generated using oazapfts.
|
* DO NOT MODIFY - This file has been generated using oazapfts.
|
||||||
* See https://www.npmjs.com/package/oazapfts
|
* See https://www.npmjs.com/package/oazapfts
|
||||||
*/
|
*/
|
||||||
@@ -391,6 +391,7 @@ export type AssetBulkUpdateDto = {
|
|||||||
isFavorite?: boolean;
|
isFavorite?: boolean;
|
||||||
latitude?: number;
|
latitude?: number;
|
||||||
longitude?: number;
|
longitude?: number;
|
||||||
|
orientation?: Orientation;
|
||||||
rating?: number;
|
rating?: number;
|
||||||
};
|
};
|
||||||
export type AssetBulkUploadCheckItem = {
|
export type AssetBulkUploadCheckItem = {
|
||||||
@@ -439,6 +440,7 @@ export type UpdateAssetDto = {
|
|||||||
latitude?: number;
|
latitude?: number;
|
||||||
livePhotoVideoId?: string | null;
|
livePhotoVideoId?: string | null;
|
||||||
longitude?: number;
|
longitude?: number;
|
||||||
|
orientation?: Orientation;
|
||||||
rating?: number;
|
rating?: number;
|
||||||
};
|
};
|
||||||
export type AssetMediaReplaceDto = {
|
export type AssetMediaReplaceDto = {
|
||||||
@@ -2762,11 +2764,15 @@ export function deleteSession({ id }: {
|
|||||||
method: "DELETE"
|
method: "DELETE"
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
export function getAllSharedLinks(opts?: Oazapfts.RequestOpts) {
|
export function getAllSharedLinks({ albumId }: {
|
||||||
|
albumId?: string;
|
||||||
|
}, opts?: Oazapfts.RequestOpts) {
|
||||||
return oazapfts.ok(oazapfts.fetchJson<{
|
return oazapfts.ok(oazapfts.fetchJson<{
|
||||||
status: 200;
|
status: 200;
|
||||||
data: SharedLinkResponseDto[];
|
data: SharedLinkResponseDto[];
|
||||||
}>("/shared-links", {
|
}>(`/shared-links${QS.query(QS.explode({
|
||||||
|
albumId
|
||||||
|
}))}`, {
|
||||||
...opts
|
...opts
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -3477,6 +3483,16 @@ export enum AssetMediaStatus {
|
|||||||
Replaced = "replaced",
|
Replaced = "replaced",
|
||||||
Duplicate = "duplicate"
|
Duplicate = "duplicate"
|
||||||
}
|
}
|
||||||
|
export enum Orientation {
|
||||||
|
$1 = 1,
|
||||||
|
$2 = 2,
|
||||||
|
$3 = 3,
|
||||||
|
$4 = 4,
|
||||||
|
$5 = 5,
|
||||||
|
$6 = 6,
|
||||||
|
$7 = 7,
|
||||||
|
$8 = 8
|
||||||
|
}
|
||||||
export enum Action {
|
export enum Action {
|
||||||
Accept = "accept",
|
Accept = "accept",
|
||||||
Reject = "reject"
|
Reject = "reject"
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
# dev build
|
# dev build
|
||||||
FROM ghcr.io/immich-app/base-server-dev:20250204@sha256:8b203f19f4d5cf4619b60ee5f50d6d4b5ea3745747f5e5170d1b7404ebeb0792 AS dev
|
FROM ghcr.io/immich-app/base-server-dev:20250211@sha256:6ae577a6518e1ccca973db16955f4d79b01cac3ae122759ccb1c17bf6c330ba9 AS dev
|
||||||
|
|
||||||
RUN apt-get install --no-install-recommends -yqq tini
|
RUN apt-get install --no-install-recommends -yqq tini
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
@@ -42,7 +42,7 @@ RUN npm run build
|
|||||||
|
|
||||||
|
|
||||||
# prod build
|
# prod build
|
||||||
FROM ghcr.io/immich-app/base-server-prod:20250204@sha256:2af3da713d5ab3ccca23b216b747557ea6016117e72deac101e35069ccaf9b5e
|
FROM ghcr.io/immich-app/base-server-prod:20250211@sha256:879cfe3d2afd4b7bdb211f694f99b6c0679a8bbd3e96964ad6c878f8471d63ea
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
ENV NODE_ENV=production \
|
ENV NODE_ENV=production \
|
||||||
|
|||||||
Generated
+246
-251
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "immich",
|
"name": "immich",
|
||||||
"version": "1.125.7",
|
"version": "1.126.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "",
|
"author": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
"@nestjs/swagger": "^11.0.2",
|
"@nestjs/swagger": "^11.0.2",
|
||||||
"@nestjs/typeorm": "^11.0.0",
|
"@nestjs/typeorm": "^11.0.0",
|
||||||
"@nestjs/websockets": "^11.0.4",
|
"@nestjs/websockets": "^11.0.4",
|
||||||
"@opentelemetry/auto-instrumentations-node": "^0.55.0",
|
"@opentelemetry/auto-instrumentations-node": "^0.56.0",
|
||||||
"@opentelemetry/context-async-hooks": "^1.24.0",
|
"@opentelemetry/context-async-hooks": "^1.24.0",
|
||||||
"@opentelemetry/exporter-prometheus": "^0.57.0",
|
"@opentelemetry/exporter-prometheus": "^0.57.0",
|
||||||
"@opentelemetry/sdk-node": "^0.57.0",
|
"@opentelemetry/sdk-node": "^0.57.0",
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
"@types/lodash": "^4.14.197",
|
"@types/lodash": "^4.14.197",
|
||||||
"@types/mock-fs": "^4.13.1",
|
"@types/mock-fs": "^4.13.1",
|
||||||
"@types/multer": "^1.4.7",
|
"@types/multer": "^1.4.7",
|
||||||
"@types/node": "^22.10.9",
|
"@types/node": "^22.13.1",
|
||||||
"@types/nodemailer": "^6.4.14",
|
"@types/nodemailer": "^6.4.14",
|
||||||
"@types/picomatch": "^3.0.0",
|
"@types/picomatch": "^3.0.0",
|
||||||
"@types/pngjs": "^6.0.5",
|
"@types/pngjs": "^6.0.5",
|
||||||
|
|||||||
@@ -13,22 +13,23 @@ import { IWorker } from 'src/constants';
|
|||||||
import { controllers } from 'src/controllers';
|
import { controllers } from 'src/controllers';
|
||||||
import { entities } from 'src/entities';
|
import { entities } from 'src/entities';
|
||||||
import { ImmichWorker } from 'src/enum';
|
import { ImmichWorker } from 'src/enum';
|
||||||
import { IEventRepository } from 'src/interfaces/event.interface';
|
|
||||||
import { IJobRepository } from 'src/interfaces/job.interface';
|
|
||||||
import { AuthGuard } from 'src/middleware/auth.guard';
|
import { AuthGuard } from 'src/middleware/auth.guard';
|
||||||
import { ErrorInterceptor } from 'src/middleware/error.interceptor';
|
import { ErrorInterceptor } from 'src/middleware/error.interceptor';
|
||||||
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
|
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
|
||||||
import { GlobalExceptionFilter } from 'src/middleware/global-exception.filter';
|
import { GlobalExceptionFilter } from 'src/middleware/global-exception.filter';
|
||||||
import { LoggingInterceptor } from 'src/middleware/logging.interceptor';
|
import { LoggingInterceptor } from 'src/middleware/logging.interceptor';
|
||||||
import { providers, repositories } from 'src/repositories';
|
import { repositories } from 'src/repositories';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
|
import { EventRepository } from 'src/repositories/event.repository';
|
||||||
|
import { JobRepository } from 'src/repositories/job.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { teardownTelemetry, TelemetryRepository } from 'src/repositories/telemetry.repository';
|
import { teardownTelemetry, TelemetryRepository } from 'src/repositories/telemetry.repository';
|
||||||
import { services } from 'src/services';
|
import { services } from 'src/services';
|
||||||
|
import { AuthService } from 'src/services/auth.service';
|
||||||
import { CliService } from 'src/services/cli.service';
|
import { CliService } from 'src/services/cli.service';
|
||||||
import { DatabaseService } from 'src/services/database.service';
|
import { DatabaseService } from 'src/services/database.service';
|
||||||
|
|
||||||
const common = [...services, ...providers, ...repositories];
|
const common = [...repositories, ...services];
|
||||||
|
|
||||||
const middleware = [
|
const middleware = [
|
||||||
FileUploadInterceptor,
|
FileUploadInterceptor,
|
||||||
@@ -78,21 +79,30 @@ class BaseModule implements OnModuleInit, OnModuleDestroy {
|
|||||||
constructor(
|
constructor(
|
||||||
@Inject(IWorker) private worker: ImmichWorker,
|
@Inject(IWorker) private worker: ImmichWorker,
|
||||||
logger: LoggingRepository,
|
logger: LoggingRepository,
|
||||||
@Inject(IEventRepository) private eventRepository: IEventRepository,
|
private eventRepository: EventRepository,
|
||||||
@Inject(IJobRepository) private jobRepository: IJobRepository,
|
private jobRepository: JobRepository,
|
||||||
private telemetryRepository: TelemetryRepository,
|
private telemetryRepository: TelemetryRepository,
|
||||||
|
private authService: AuthService,
|
||||||
) {
|
) {
|
||||||
logger.setAppName(this.worker);
|
logger.setAppName(this.worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleInit() {
|
async onModuleInit() {
|
||||||
this.telemetryRepository.setup({ repositories: [...providers.map(({ useClass }) => useClass), ...repositories] });
|
this.telemetryRepository.setup({ repositories });
|
||||||
|
|
||||||
this.jobRepository.setup({ services });
|
this.jobRepository.setup({ services });
|
||||||
if (this.worker === ImmichWorker.MICROSERVICES) {
|
if (this.worker === ImmichWorker.MICROSERVICES) {
|
||||||
this.jobRepository.startWorkers();
|
this.jobRepository.startWorkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.eventRepository.setAuthFn(async (client) =>
|
||||||
|
this.authService.authenticate({
|
||||||
|
headers: client.request.headers,
|
||||||
|
queryParams: {},
|
||||||
|
metadata: { adminRoute: false, sharedLinkRoute: false, uri: '/api/socket.io' },
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
this.eventRepository.setup({ services });
|
this.eventRepository.setup({ services });
|
||||||
await this.eventRepository.emit('app.bootstrap');
|
await this.eventRepository.emit('app.bootstrap');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Reflector } from '@nestjs/core';
|
|||||||
import { SchedulerRegistry } from '@nestjs/schedule';
|
import { SchedulerRegistry } from '@nestjs/schedule';
|
||||||
import { Test } from '@nestjs/testing';
|
import { Test } from '@nestjs/testing';
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { ClassConstructor } from 'class-transformer';
|
||||||
import { PostgresJSDialect } from 'kysely-postgres-js';
|
import { PostgresJSDialect } from 'kysely-postgres-js';
|
||||||
import { KyselyModule } from 'nestjs-kysely';
|
import { KyselyModule } from 'nestjs-kysely';
|
||||||
import { OpenTelemetryModule } from 'nestjs-otel';
|
import { OpenTelemetryModule } from 'nestjs-otel';
|
||||||
@@ -13,7 +14,7 @@ import postgres from 'postgres';
|
|||||||
import { format } from 'sql-formatter';
|
import { format } from 'sql-formatter';
|
||||||
import { GENERATE_SQL_KEY, GenerateSqlQueries } from 'src/decorators';
|
import { GENERATE_SQL_KEY, GenerateSqlQueries } from 'src/decorators';
|
||||||
import { entities } from 'src/entities';
|
import { entities } from 'src/entities';
|
||||||
import { providers, repositories } from 'src/repositories';
|
import { repositories } from 'src/repositories';
|
||||||
import { AccessRepository } from 'src/repositories/access.repository';
|
import { AccessRepository } from 'src/repositories/access.repository';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
@@ -45,8 +46,7 @@ export class SqlLogger implements Logger {
|
|||||||
|
|
||||||
const reflector = new Reflector();
|
const reflector = new Reflector();
|
||||||
|
|
||||||
type Repository = (typeof providers)[0]['useClass'];
|
type Repository = ClassConstructor<any>;
|
||||||
type Provider = { provide: any; useClass: Repository };
|
|
||||||
type SqlGeneratorOptions = { targetDir: string };
|
type SqlGeneratorOptions = { targetDir: string };
|
||||||
|
|
||||||
class SqlGenerator {
|
class SqlGenerator {
|
||||||
@@ -59,15 +59,11 @@ class SqlGenerator {
|
|||||||
async run() {
|
async run() {
|
||||||
try {
|
try {
|
||||||
await this.setup();
|
await this.setup();
|
||||||
const targets = [
|
for (const Repository of repositories) {
|
||||||
...providers,
|
if (Repository === LoggingRepository) {
|
||||||
...repositories.map((repository) => ({ provide: repository, useClass: repository as any })),
|
|
||||||
];
|
|
||||||
for (const repository of targets) {
|
|
||||||
if (repository.provide === LoggingRepository) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
await this.process(repository);
|
await this.process(Repository);
|
||||||
}
|
}
|
||||||
await this.write();
|
await this.write();
|
||||||
this.stats();
|
this.stats();
|
||||||
@@ -105,19 +101,19 @@ class SqlGenerator {
|
|||||||
TypeOrmModule.forFeature(entities),
|
TypeOrmModule.forFeature(entities),
|
||||||
OpenTelemetryModule.forRoot(otel),
|
OpenTelemetryModule.forRoot(otel),
|
||||||
],
|
],
|
||||||
providers: [...providers, ...repositories, AuthService, SchedulerRegistry],
|
providers: [...repositories, AuthService, SchedulerRegistry],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
this.app = await moduleFixture.createNestApplication().init();
|
this.app = await moduleFixture.createNestApplication().init();
|
||||||
}
|
}
|
||||||
|
|
||||||
async process({ provide: token, useClass: Repository }: Provider) {
|
async process(Repository: Repository) {
|
||||||
if (!this.app) {
|
if (!this.app) {
|
||||||
throw new Error('Not initialized');
|
throw new Error('Not initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
const data: string[] = [`-- NOTE: This file is auto generated by ./sql-generator`];
|
const data: string[] = [`-- NOTE: This file is auto generated by ./sql-generator`];
|
||||||
const instance = this.app.get<Repository>(token);
|
const instance = this.app.get<Repository>(Repository);
|
||||||
|
|
||||||
// normal repositories
|
// normal repositories
|
||||||
data.push(...(await this.runTargets(instance, `${Repository.name}`)));
|
data.push(...(await this.runTargets(instance, `${Repository.name}`)));
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import {
|
|||||||
CQMode,
|
CQMode,
|
||||||
ImageFormat,
|
ImageFormat,
|
||||||
LogLevel,
|
LogLevel,
|
||||||
|
QueueName,
|
||||||
ToneMapping,
|
ToneMapping,
|
||||||
TranscodeHWAccel,
|
TranscodeHWAccel,
|
||||||
TranscodePolicy,
|
TranscodePolicy,
|
||||||
VideoCodec,
|
VideoCodec,
|
||||||
VideoContainer,
|
VideoContainer,
|
||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
import { ConcurrentQueueName, QueueName } from 'src/interfaces/job.interface';
|
import { ConcurrentQueueName, ImageOptions } from 'src/types';
|
||||||
import { ImageOptions } from 'src/types';
|
|
||||||
|
|
||||||
export interface SystemConfig {
|
export interface SystemConfig {
|
||||||
backup: {
|
backup: {
|
||||||
|
|||||||
+11
-1
@@ -1,7 +1,7 @@
|
|||||||
import { Duration } from 'luxon';
|
import { Duration } from 'luxon';
|
||||||
import { readFileSync } from 'node:fs';
|
import { readFileSync } from 'node:fs';
|
||||||
import { SemVer } from 'semver';
|
import { SemVer } from 'semver';
|
||||||
import { ExifOrientation } from 'src/enum';
|
import { DatabaseExtension, ExifOrientation } from 'src/enum';
|
||||||
|
|
||||||
export const POSTGRES_VERSION_RANGE = '>=14.0.0';
|
export const POSTGRES_VERSION_RANGE = '>=14.0.0';
|
||||||
export const VECTORS_VERSION_RANGE = '>=0.2 <0.4';
|
export const VECTORS_VERSION_RANGE = '>=0.2 <0.4';
|
||||||
@@ -16,6 +16,16 @@ export const LIFECYCLE_EXTENSION = 'x-immich-lifecycle';
|
|||||||
export const DEPRECATED_IN_PREFIX = 'This property was deprecated in ';
|
export const DEPRECATED_IN_PREFIX = 'This property was deprecated in ';
|
||||||
export const ADDED_IN_PREFIX = 'This property was added in ';
|
export const ADDED_IN_PREFIX = 'This property was added in ';
|
||||||
|
|
||||||
|
export const JOBS_ASSET_PAGINATION_SIZE = 1000;
|
||||||
|
export const JOBS_LIBRARY_PAGINATION_SIZE = 10_000;
|
||||||
|
|
||||||
|
export const EXTENSION_NAMES: Record<DatabaseExtension, string> = {
|
||||||
|
cube: 'cube',
|
||||||
|
earthdistance: 'earthdistance',
|
||||||
|
vector: 'pgvector',
|
||||||
|
vectors: 'pgvecto.rs',
|
||||||
|
} as const;
|
||||||
|
|
||||||
export const SALT_ROUNDS = 10;
|
export const SALT_ROUNDS = 10;
|
||||||
|
|
||||||
export const IWorker = 'IWorker';
|
export const IWorker = 'IWorker';
|
||||||
|
|||||||
@@ -35,9 +35,10 @@ import { AuthDto } from 'src/dtos/auth.dto';
|
|||||||
import { ImmichHeader, RouteKey } from 'src/enum';
|
import { ImmichHeader, RouteKey } from 'src/enum';
|
||||||
import { AssetUploadInterceptor } from 'src/middleware/asset-upload.interceptor';
|
import { AssetUploadInterceptor } from 'src/middleware/asset-upload.interceptor';
|
||||||
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
|
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
|
||||||
import { FileUploadInterceptor, UploadFiles, getFiles } from 'src/middleware/file-upload.interceptor';
|
import { FileUploadInterceptor, getFiles } from 'src/middleware/file-upload.interceptor';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { AssetMediaService } from 'src/services/asset-media.service';
|
import { AssetMediaService } from 'src/services/asset-media.service';
|
||||||
|
import { UploadFiles } from 'src/types';
|
||||||
import { sendFile } from 'src/utils/file';
|
import { sendFile } from 'src/utils/file';
|
||||||
import { FileNotEmptyValidator, UUIDParamDto } from 'src/validation';
|
import { FileNotEmptyValidator, UUIDParamDto } from 'src/validation';
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
SharedLinkEditDto,
|
SharedLinkEditDto,
|
||||||
SharedLinkPasswordDto,
|
SharedLinkPasswordDto,
|
||||||
SharedLinkResponseDto,
|
SharedLinkResponseDto,
|
||||||
|
SharedLinkSearchDto,
|
||||||
} from 'src/dtos/shared-link.dto';
|
} from 'src/dtos/shared-link.dto';
|
||||||
import { ImmichCookie, Permission } from 'src/enum';
|
import { ImmichCookie, Permission } from 'src/enum';
|
||||||
import { Auth, Authenticated, GetLoginDetails } from 'src/middleware/auth.guard';
|
import { Auth, Authenticated, GetLoginDetails } from 'src/middleware/auth.guard';
|
||||||
@@ -24,8 +25,8 @@ export class SharedLinkController {
|
|||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@Authenticated({ permission: Permission.SHARED_LINK_READ })
|
@Authenticated({ permission: Permission.SHARED_LINK_READ })
|
||||||
getAllSharedLinks(@Auth() auth: AuthDto): Promise<SharedLinkResponseDto[]> {
|
getAllSharedLinks(@Auth() auth: AuthDto, @Query() dto: SharedLinkSearchDto): Promise<SharedLinkResponseDto[]> {
|
||||||
return this.service.getAll(auth);
|
return this.service.getAll(auth, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('me')
|
@Get('me')
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export class UserController {
|
|||||||
|
|
||||||
@Get('me')
|
@Get('me')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
getMyUser(@Auth() auth: AuthDto): UserAdminResponseDto {
|
getMyUser(@Auth() auth: AuthDto): Promise<UserAdminResponseDto> {
|
||||||
return this.service.getMe(auth);
|
return this.service.getMe(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ export class UserController {
|
|||||||
|
|
||||||
@Get('me/preferences')
|
@Get('me/preferences')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
getMyPreferences(@Auth() auth: AuthDto): UserPreferencesResponseDto {
|
getMyPreferences(@Auth() auth: AuthDto): Promise<UserPreferencesResponseDto> {
|
||||||
return this.service.getMyPreferences(auth);
|
return this.service.getMyPreferences(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ export class UserController {
|
|||||||
|
|
||||||
@Get('me/license')
|
@Get('me/license')
|
||||||
@Authenticated()
|
@Authenticated()
|
||||||
getUserLicense(@Auth() auth: AuthDto): LicenseResponseDto {
|
getUserLicense(@Auth() auth: AuthDto): Promise<LicenseResponseDto> {
|
||||||
return this.service.getLicense(auth);
|
return this.service.getLicense(auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ vitest.mock('src/constants', () => ({
|
|||||||
APP_MEDIA_LOCATION: '/photos',
|
APP_MEDIA_LOCATION: '/photos',
|
||||||
ADDED_IN_PREFIX: 'This property was added in ',
|
ADDED_IN_PREFIX: 'This property was added in ',
|
||||||
DEPRECATED_IN_PREFIX: 'This property was deprecated in ',
|
DEPRECATED_IN_PREFIX: 'This property was deprecated in ',
|
||||||
|
IWorker: 'IWorker',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('StorageCore', () => {
|
describe('StorageCore', () => {
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ import { APP_MEDIA_LOCATION } from 'src/constants';
|
|||||||
import { AssetEntity } from 'src/entities/asset.entity';
|
import { AssetEntity } from 'src/entities/asset.entity';
|
||||||
import { PersonEntity } from 'src/entities/person.entity';
|
import { PersonEntity } from 'src/entities/person.entity';
|
||||||
import { AssetFileType, AssetPathType, ImageFormat, PathType, PersonPathType, StorageFolder } from 'src/enum';
|
import { AssetFileType, AssetPathType, ImageFormat, PathType, PersonPathType, StorageFolder } from 'src/enum';
|
||||||
import { IAssetRepository } from 'src/interfaces/asset.interface';
|
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||||
import { ICryptoRepository } from 'src/interfaces/crypto.interface';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { IMoveRepository } from 'src/interfaces/move.interface';
|
import { CryptoRepository } from 'src/repositories/crypto.repository';
|
||||||
import { IPersonRepository } from 'src/interfaces/person.interface';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { IStorageRepository } from 'src/interfaces/storage.interface';
|
import { MoveRepository } from 'src/repositories/move.repository';
|
||||||
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
|
import { PersonRepository } from 'src/repositories/person.repository';
|
||||||
import { IConfigRepository, ILoggingRepository } from 'src/types';
|
import { StorageRepository } from 'src/repositories/storage.repository';
|
||||||
|
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||||
import { getAssetFiles } from 'src/utils/asset.util';
|
import { getAssetFiles } from 'src/utils/asset.util';
|
||||||
import { getConfig } from 'src/utils/config';
|
import { getConfig } from 'src/utils/config';
|
||||||
|
|
||||||
@@ -32,25 +33,25 @@ let instance: StorageCore | null;
|
|||||||
|
|
||||||
export class StorageCore {
|
export class StorageCore {
|
||||||
private constructor(
|
private constructor(
|
||||||
private assetRepository: IAssetRepository,
|
private assetRepository: AssetRepository,
|
||||||
private configRepository: IConfigRepository,
|
private configRepository: ConfigRepository,
|
||||||
private cryptoRepository: ICryptoRepository,
|
private cryptoRepository: CryptoRepository,
|
||||||
private moveRepository: IMoveRepository,
|
private moveRepository: MoveRepository,
|
||||||
private personRepository: IPersonRepository,
|
private personRepository: PersonRepository,
|
||||||
private storageRepository: IStorageRepository,
|
private storageRepository: StorageRepository,
|
||||||
private systemMetadataRepository: ISystemMetadataRepository,
|
private systemMetadataRepository: SystemMetadataRepository,
|
||||||
private logger: ILoggingRepository,
|
private logger: LoggingRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
static create(
|
static create(
|
||||||
assetRepository: IAssetRepository,
|
assetRepository: AssetRepository,
|
||||||
configRepository: IConfigRepository,
|
configRepository: ConfigRepository,
|
||||||
cryptoRepository: ICryptoRepository,
|
cryptoRepository: CryptoRepository,
|
||||||
moveRepository: IMoveRepository,
|
moveRepository: MoveRepository,
|
||||||
personRepository: IPersonRepository,
|
personRepository: PersonRepository,
|
||||||
storageRepository: IStorageRepository,
|
storageRepository: StorageRepository,
|
||||||
systemMetadataRepository: ISystemMetadataRepository,
|
systemMetadataRepository: SystemMetadataRepository,
|
||||||
logger: ILoggingRepository,
|
logger: LoggingRepository,
|
||||||
) {
|
) {
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
instance = new StorageCore(
|
instance = new StorageCore(
|
||||||
|
|||||||
@@ -1,3 +1,53 @@
|
|||||||
|
import { Permission } from 'src/enum';
|
||||||
|
|
||||||
|
export type AuthUser = {
|
||||||
|
id: string;
|
||||||
|
isAdmin: boolean;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
quotaUsageInBytes: number;
|
||||||
|
quotaSizeInBytes: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AuthApiKey = {
|
||||||
|
id: string;
|
||||||
|
permissions: Permission[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AuthSharedLink = {
|
||||||
|
id: string;
|
||||||
|
expiresAt: Date | null;
|
||||||
|
userId: string;
|
||||||
|
showExif: boolean;
|
||||||
|
allowUpload: boolean;
|
||||||
|
allowDownload: boolean;
|
||||||
|
password: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AuthSession = {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
|
||||||
export const columns = {
|
export const columns = {
|
||||||
|
authUser: [
|
||||||
|
'users.id',
|
||||||
|
'users.name',
|
||||||
|
'users.email',
|
||||||
|
'users.isAdmin',
|
||||||
|
'users.quotaUsageInBytes',
|
||||||
|
'users.quotaSizeInBytes',
|
||||||
|
],
|
||||||
|
authApiKey: ['api_keys.id', 'api_keys.permissions'],
|
||||||
|
authSession: ['sessions.id', 'sessions.updatedAt'],
|
||||||
|
authSharedLink: [
|
||||||
|
'shared_links.id',
|
||||||
|
'shared_links.userId',
|
||||||
|
'shared_links.expiresAt',
|
||||||
|
'shared_links.showExif',
|
||||||
|
'shared_links.allowUpload',
|
||||||
|
'shared_links.allowDownload',
|
||||||
|
'shared_links.password',
|
||||||
|
],
|
||||||
userDto: ['id', 'name', 'email', 'profileImagePath', 'profileChangedAt'],
|
userDto: ['id', 'name', 'email', 'profileImagePath', 'profileChangedAt'],
|
||||||
|
apiKey: ['id', 'name', 'userId', 'createdAt', 'updatedAt', 'permissions'],
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
Vendored
+14
-18
@@ -3,23 +3,19 @@
|
|||||||
* Please do not edit it manually.
|
* Please do not edit it manually.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { ColumnType } from "kysely";
|
import type { ColumnType } from 'kysely';
|
||||||
|
import { Permission } from 'src/enum';
|
||||||
|
|
||||||
export type ArrayType<T> = ArrayTypeImpl<T> extends (infer U)[]
|
export type ArrayType<T> = ArrayTypeImpl<T> extends (infer U)[] ? U[] : ArrayTypeImpl<T>;
|
||||||
? U[]
|
|
||||||
: ArrayTypeImpl<T>;
|
|
||||||
|
|
||||||
export type ArrayTypeImpl<T> = T extends ColumnType<infer S, infer I, infer U>
|
export type ArrayTypeImpl<T> = T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S[], I[], U[]> : T[];
|
||||||
? ColumnType<S[], I[], U[]>
|
|
||||||
: T[];
|
|
||||||
|
|
||||||
export type AssetsStatusEnum = "active" | "deleted" | "trashed";
|
export type AssetsStatusEnum = 'active' | 'deleted' | 'trashed';
|
||||||
|
|
||||||
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
|
export type Generated<T> =
|
||||||
? ColumnType<S, I | undefined, U>
|
T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
|
||||||
: ColumnType<T, T | undefined, T>;
|
|
||||||
|
|
||||||
export type Int8 = ColumnType<string, bigint | number | string, bigint | number | string>;
|
export type Int8 = ColumnType<number>;
|
||||||
|
|
||||||
export type Json = JsonValue;
|
export type Json = JsonValue;
|
||||||
|
|
||||||
@@ -33,7 +29,7 @@ export type JsonPrimitive = boolean | number | string | null;
|
|||||||
|
|
||||||
export type JsonValue = JsonArray | JsonObject | JsonPrimitive;
|
export type JsonValue = JsonArray | JsonObject | JsonPrimitive;
|
||||||
|
|
||||||
export type Sourcetype = "exif" | "machine-learning";
|
export type Sourcetype = 'exif' | 'machine-learning';
|
||||||
|
|
||||||
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
||||||
|
|
||||||
@@ -81,7 +77,7 @@ export interface ApiKeys {
|
|||||||
id: Generated<string>;
|
id: Generated<string>;
|
||||||
key: string;
|
key: string;
|
||||||
name: string;
|
name: string;
|
||||||
permissions: string[];
|
permissions: Permission[];
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
userId: string;
|
userId: string;
|
||||||
}
|
}
|
||||||
@@ -126,8 +122,8 @@ export interface Assets {
|
|||||||
duplicateId: string | null;
|
duplicateId: string | null;
|
||||||
duration: string | null;
|
duration: string | null;
|
||||||
encodedVideoPath: Generated<string | null>;
|
encodedVideoPath: Generated<string | null>;
|
||||||
fileCreatedAt: Timestamp;
|
fileCreatedAt: Timestamp | null;
|
||||||
fileModifiedAt: Timestamp;
|
fileModifiedAt: Timestamp | null;
|
||||||
id: Generated<string>;
|
id: Generated<string>;
|
||||||
isArchived: Generated<boolean>;
|
isArchived: Generated<boolean>;
|
||||||
isExternal: Generated<boolean>;
|
isExternal: Generated<boolean>;
|
||||||
@@ -136,7 +132,7 @@ export interface Assets {
|
|||||||
isVisible: Generated<boolean>;
|
isVisible: Generated<boolean>;
|
||||||
libraryId: string | null;
|
libraryId: string | null;
|
||||||
livePhotoVideoId: string | null;
|
livePhotoVideoId: string | null;
|
||||||
localDateTime: Timestamp;
|
localDateTime: Timestamp | null;
|
||||||
originalFileName: string;
|
originalFileName: string;
|
||||||
originalPath: string;
|
originalPath: string;
|
||||||
ownerId: string;
|
ownerId: string;
|
||||||
@@ -444,6 +440,6 @@ export interface DB {
|
|||||||
typeorm_metadata: TypeormMetadata;
|
typeorm_metadata: TypeormMetadata;
|
||||||
user_metadata: UserMetadata;
|
user_metadata: UserMetadata;
|
||||||
users: Users;
|
users: Users;
|
||||||
"vectors.pg_vector_index_stat": VectorsPgVectorIndexStat;
|
'vectors.pg_vector_index_stat': VectorsPgVectorIndexStat;
|
||||||
version_history: VersionHistory;
|
version_history: VersionHistory;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ import { SetMetadata, applyDecorators } from '@nestjs/common';
|
|||||||
import { ApiExtension, ApiOperation, ApiProperty, ApiTags } from '@nestjs/swagger';
|
import { ApiExtension, ApiOperation, ApiProperty, ApiTags } from '@nestjs/swagger';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { ADDED_IN_PREFIX, DEPRECATED_IN_PREFIX, LIFECYCLE_EXTENSION } from 'src/constants';
|
import { ADDED_IN_PREFIX, DEPRECATED_IN_PREFIX, LIFECYCLE_EXTENSION } from 'src/constants';
|
||||||
import { ImmichWorker, MetadataKey } from 'src/enum';
|
import { ImmichWorker, JobName, MetadataKey, QueueName } from 'src/enum';
|
||||||
import { EmitEvent } from 'src/interfaces/event.interface';
|
import { EmitEvent } from 'src/repositories/event.repository';
|
||||||
import { JobName, QueueName } from 'src/interfaces/job.interface';
|
|
||||||
import { setUnion } from 'src/utils/set';
|
import { setUnion } from 'src/utils/set';
|
||||||
|
|
||||||
// PostgreSQL uses a 16-bit integer to indicate the number of bound parameters. This means that the
|
// PostgreSQL uses a 16-bit integer to indicate the number of bound parameters. This means that the
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import {
|
|||||||
ValidateIf,
|
ValidateIf,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AssetType } from 'src/enum';
|
import { AssetType, ExifOrientation } from 'src/enum';
|
||||||
import { AssetStats } from 'src/interfaces/asset.interface';
|
import { AssetStats } from 'src/repositories/asset.repository';
|
||||||
import { Optional, ValidateBoolean, ValidateUUID } from 'src/validation';
|
import { Optional, ValidateBoolean, ValidateUUID } from 'src/validation';
|
||||||
|
|
||||||
export class DeviceIdDto {
|
export class DeviceIdDto {
|
||||||
@@ -54,6 +54,12 @@ export class UpdateAssetBase {
|
|||||||
@Max(5)
|
@Max(5)
|
||||||
@Min(-1)
|
@Min(-1)
|
||||||
rating?: number;
|
rating?: number;
|
||||||
|
|
||||||
|
@Optional()
|
||||||
|
@Min(1)
|
||||||
|
@Max(8)
|
||||||
|
@ApiProperty({ type: 'integer' })
|
||||||
|
orientation?: ExifOrientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AssetBulkUpdateDto extends UpdateAssetBase {
|
export class AssetBulkUpdateDto extends UpdateAssetBase {
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Transform } from 'class-transformer';
|
import { Transform } from 'class-transformer';
|
||||||
import { IsEmail, IsNotEmpty, IsString, MinLength } from 'class-validator';
|
import { IsEmail, IsNotEmpty, IsString, MinLength } from 'class-validator';
|
||||||
import { SessionEntity } from 'src/entities/session.entity';
|
import { AuthApiKey, AuthSession, AuthSharedLink, AuthUser } from 'src/database';
|
||||||
import { SharedLinkEntity } from 'src/entities/shared-link.entity';
|
|
||||||
import { UserEntity } from 'src/entities/user.entity';
|
import { UserEntity } from 'src/entities/user.entity';
|
||||||
import { ImmichCookie } from 'src/enum';
|
import { ImmichCookie } from 'src/enum';
|
||||||
import { AuthApiKey } from 'src/types';
|
|
||||||
import { toEmail } from 'src/validation';
|
import { toEmail } from 'src/validation';
|
||||||
|
|
||||||
export type CookieResponse = {
|
export type CookieResponse = {
|
||||||
@@ -14,11 +12,11 @@ export type CookieResponse = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class AuthDto {
|
export class AuthDto {
|
||||||
user!: UserEntity;
|
user!: AuthUser;
|
||||||
|
|
||||||
apiKey?: AuthApiKey;
|
apiKey?: AuthApiKey;
|
||||||
sharedLink?: SharedLinkEntity;
|
sharedLink?: AuthSharedLink;
|
||||||
session?: SessionEntity;
|
session?: AuthSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LoginCredentialDto {
|
export class LoginCredentialDto {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsEnum, IsNotEmpty } from 'class-validator';
|
import { IsEnum, IsNotEmpty } from 'class-validator';
|
||||||
import { ManualJobName } from 'src/enum';
|
import { JobCommand, ManualJobName, QueueName } from 'src/enum';
|
||||||
import { JobCommand, QueueName } from 'src/interfaces/job.interface';
|
|
||||||
import { ValidateBoolean } from 'src/validation';
|
import { ValidateBoolean } from 'src/validation';
|
||||||
|
|
||||||
export class JobIdParamDto {
|
export class JobIdParamDto {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsEnum, IsNotEmpty } from 'class-validator';
|
import { IsEnum, IsNotEmpty } from 'class-validator';
|
||||||
import { UserResponseDto } from 'src/dtos/user.dto';
|
import { UserResponseDto } from 'src/dtos/user.dto';
|
||||||
import { PartnerDirection } from 'src/interfaces/partner.interface';
|
import { PartnerDirection } from 'src/repositories/partner.repository';
|
||||||
|
|
||||||
export class UpdatePartnerDto {
|
export class UpdatePartnerDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { SessionEntity } from 'src/entities/session.entity';
|
import { SessionItem } from 'src/types';
|
||||||
|
|
||||||
export class SessionResponseDto {
|
export class SessionResponseDto {
|
||||||
id!: string;
|
id!: string;
|
||||||
@@ -9,7 +9,7 @@ export class SessionResponseDto {
|
|||||||
deviceOS!: string;
|
deviceOS!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mapSession = (entity: SessionEntity, currentId?: string): SessionResponseDto => ({
|
export const mapSession = (entity: SessionItem, currentId?: string): SessionResponseDto => ({
|
||||||
id: entity.id,
|
id: entity.id,
|
||||||
createdAt: entity.createdAt.toISOString(),
|
createdAt: entity.createdAt.toISOString(),
|
||||||
updatedAt: entity.updatedAt.toISOString(),
|
updatedAt: entity.updatedAt.toISOString(),
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ import { SharedLinkEntity } from 'src/entities/shared-link.entity';
|
|||||||
import { SharedLinkType } from 'src/enum';
|
import { SharedLinkType } from 'src/enum';
|
||||||
import { Optional, ValidateBoolean, ValidateDate, ValidateUUID } from 'src/validation';
|
import { Optional, ValidateBoolean, ValidateDate, ValidateUUID } from 'src/validation';
|
||||||
|
|
||||||
|
export class SharedLinkSearchDto {
|
||||||
|
@ValidateUUID({ optional: true })
|
||||||
|
albumId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class SharedLinkCreateDto {
|
export class SharedLinkCreateDto {
|
||||||
@IsEnum(SharedLinkType)
|
@IsEnum(SharedLinkType)
|
||||||
@ApiProperty({ enum: SharedLinkType, enumName: 'SharedLinkType' })
|
@ApiProperty({ enum: SharedLinkType, enumName: 'SharedLinkType' })
|
||||||
|
|||||||
@@ -25,13 +25,14 @@ import {
|
|||||||
Colorspace,
|
Colorspace,
|
||||||
ImageFormat,
|
ImageFormat,
|
||||||
LogLevel,
|
LogLevel,
|
||||||
|
QueueName,
|
||||||
ToneMapping,
|
ToneMapping,
|
||||||
TranscodeHWAccel,
|
TranscodeHWAccel,
|
||||||
TranscodePolicy,
|
TranscodePolicy,
|
||||||
VideoCodec,
|
VideoCodec,
|
||||||
VideoContainer,
|
VideoContainer,
|
||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
import { ConcurrentQueueName, QueueName } from 'src/interfaces/job.interface';
|
import { ConcurrentQueueName } from 'src/types';
|
||||||
import { IsCronExpression, ValidateBoolean } from 'src/validation';
|
import { IsCronExpression, ValidateBoolean } from 'src/validation';
|
||||||
|
|
||||||
const isLibraryScanEnabled = (config: SystemConfigLibraryScanDto) => config.enabled;
|
const isLibraryScanEnabled = (config: SystemConfigLibraryScanDto) => config.enabled;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
import { IsEnum, IsNotEmpty, IsString } from 'class-validator';
|
||||||
import { AssetOrder } from 'src/enum';
|
import { AssetOrder } from 'src/enum';
|
||||||
import { TimeBucketSize } from 'src/interfaces/asset.interface';
|
import { TimeBucketSize } from 'src/repositories/asset.repository';
|
||||||
import { Optional, ValidateBoolean, ValidateUUID } from 'src/validation';
|
import { Optional, ValidateBoolean, ValidateUUID } from 'src/validation';
|
||||||
|
|
||||||
export class TimeBucketDto {
|
export class TimeBucketDto {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export const mapUser = (entity: UserEntity): UserResponseDto => {
|
|||||||
email: entity.email,
|
email: entity.email,
|
||||||
name: entity.name,
|
name: entity.name,
|
||||||
profileImagePath: entity.profileImagePath,
|
profileImagePath: entity.profileImagePath,
|
||||||
avatarColor: getPreferences(entity).avatar.color,
|
avatarColor: getPreferences(entity.email, entity.metadata || []).avatar.color,
|
||||||
profileChangedAt: entity.profileChangedAt,
|
profileChangedAt: entity.profileChangedAt,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import { StackEntity } from 'src/entities/stack.entity';
|
|||||||
import { TagEntity } from 'src/entities/tag.entity';
|
import { TagEntity } from 'src/entities/tag.entity';
|
||||||
import { UserEntity } from 'src/entities/user.entity';
|
import { UserEntity } from 'src/entities/user.entity';
|
||||||
import { AssetFileType, AssetStatus, AssetType } from 'src/enum';
|
import { AssetFileType, AssetStatus, AssetType } from 'src/enum';
|
||||||
import { TimeBucketSize } from 'src/interfaces/asset.interface';
|
import { TimeBucketSize } from 'src/repositories/asset.repository';
|
||||||
import { AssetSearchBuilderOptions } from 'src/interfaces/search.interface';
|
import { AssetSearchBuilderOptions } from 'src/repositories/search.repository';
|
||||||
import { anyUuid, asUuid } from 'src/utils/database';
|
import { anyUuid, asUuid } from 'src/utils/database';
|
||||||
import {
|
import {
|
||||||
Column,
|
Column,
|
||||||
@@ -100,13 +100,13 @@ export class AssetEntity {
|
|||||||
deletedAt!: Date | null;
|
deletedAt!: Date | null;
|
||||||
|
|
||||||
@Index('idx_asset_file_created_at')
|
@Index('idx_asset_file_created_at')
|
||||||
@Column({ type: 'timestamptz' })
|
@Column({ type: 'timestamptz', nullable: true, default: null })
|
||||||
fileCreatedAt!: Date;
|
fileCreatedAt!: Date;
|
||||||
|
|
||||||
@Column({ type: 'timestamptz' })
|
@Column({ type: 'timestamptz', nullable: true, default: null })
|
||||||
localDateTime!: Date;
|
localDateTime!: Date;
|
||||||
|
|
||||||
@Column({ type: 'timestamptz' })
|
@Column({ type: 'timestamptz', nullable: true, default: null })
|
||||||
fileModifiedAt!: Date;
|
fileModifiedAt!: Date;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
@@ -180,6 +180,12 @@ export class AssetEntity {
|
|||||||
duplicateId!: string | null;
|
duplicateId!: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AssetEntityPlaceholder = AssetEntity & {
|
||||||
|
fileCreatedAt: Date | null;
|
||||||
|
fileModifiedAt: Date | null;
|
||||||
|
localDateTime: Date | null;
|
||||||
|
};
|
||||||
|
|
||||||
export function withExif<O>(qb: SelectQueryBuilder<DB, 'assets', O>) {
|
export function withExif<O>(qb: SelectQueryBuilder<DB, 'assets', O>) {
|
||||||
return qb.leftJoin('exif', 'assets.id', 'exif.assetId').select((eb) => eb.fn.toJson(eb.table('exif')).as('exifInfo'));
|
return qb.leftJoin('exif', 'assets.id', 'exif.assetId').select((eb) => eb.fn.toJson(eb.table('exif')).as('exifInfo'));
|
||||||
}
|
}
|
||||||
@@ -419,5 +425,8 @@ export function searchAssetBuilder(kysely: Kysely<DB>, options: AssetSearchBuild
|
|||||||
)
|
)
|
||||||
.$if(!!options.withExif, withExifInner)
|
.$if(!!options.withExif, withExifInner)
|
||||||
.$if(!!(options.withFaces || options.withPeople || options.personIds), (qb) => qb.select(withFacesAndPeople))
|
.$if(!!(options.withFaces || options.withPeople || options.personIds), (qb) => qb.select(withFacesAndPeople))
|
||||||
.$if(!options.withDeleted, (qb) => qb.where('assets.deletedAt', 'is', null));
|
.$if(!options.withDeleted, (qb) => qb.where('assets.deletedAt', 'is', null))
|
||||||
|
.where('assets.fileCreatedAt', 'is not', null)
|
||||||
|
.where('assets.fileModifiedAt', 'is not', null)
|
||||||
|
.where('assets.localDateTime', 'is not', null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,18 @@ import { DeepPartial } from 'src/types';
|
|||||||
import { HumanReadableSize } from 'src/utils/bytes';
|
import { HumanReadableSize } from 'src/utils/bytes';
|
||||||
import { Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
|
import { Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
|
export type UserMetadataItem<T extends keyof UserMetadata = UserMetadataKey> = {
|
||||||
|
key: T;
|
||||||
|
value: UserMetadata[T];
|
||||||
|
};
|
||||||
|
|
||||||
@Entity('user_metadata')
|
@Entity('user_metadata')
|
||||||
export class UserMetadataEntity<T extends keyof UserMetadata = UserMetadataKey> {
|
export class UserMetadataEntity<T extends keyof UserMetadata = UserMetadataKey> implements UserMetadataItem<T> {
|
||||||
@PrimaryColumn({ type: 'uuid' })
|
@PrimaryColumn({ type: 'uuid' })
|
||||||
userId!: string;
|
userId!: string;
|
||||||
|
|
||||||
@ManyToOne(() => UserEntity, (user) => user.metadata, { onUpdate: 'CASCADE', onDelete: 'CASCADE' })
|
@ManyToOne(() => UserEntity, (user) => user.metadata, { onUpdate: 'CASCADE', onDelete: 'CASCADE' })
|
||||||
user!: UserEntity;
|
user?: UserEntity;
|
||||||
|
|
||||||
@PrimaryColumn({ type: 'varchar' })
|
@PrimaryColumn({ type: 'varchar' })
|
||||||
key!: T;
|
key!: T;
|
||||||
|
|||||||
@@ -384,3 +384,156 @@ export enum ExifOrientation {
|
|||||||
MirrorHorizontalRotate90CW = 7,
|
MirrorHorizontalRotate90CW = 7,
|
||||||
Rotate270CW = 8,
|
Rotate270CW = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum DatabaseExtension {
|
||||||
|
CUBE = 'cube',
|
||||||
|
EARTH_DISTANCE = 'earthdistance',
|
||||||
|
VECTOR = 'vector',
|
||||||
|
VECTORS = 'vectors',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum BootstrapEventPriority {
|
||||||
|
// Database service should be initialized before anything else, most other services need database access
|
||||||
|
DatabaseService = -200,
|
||||||
|
// Initialise config after other bootstrap services, stop other services from using config on bootstrap
|
||||||
|
SystemConfig = 100,
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum QueueName {
|
||||||
|
THUMBNAIL_GENERATION = 'thumbnailGeneration',
|
||||||
|
METADATA_EXTRACTION = 'metadataExtraction',
|
||||||
|
VIDEO_CONVERSION = 'videoConversion',
|
||||||
|
FACE_DETECTION = 'faceDetection',
|
||||||
|
FACIAL_RECOGNITION = 'facialRecognition',
|
||||||
|
SMART_SEARCH = 'smartSearch',
|
||||||
|
DUPLICATE_DETECTION = 'duplicateDetection',
|
||||||
|
BACKGROUND_TASK = 'backgroundTask',
|
||||||
|
STORAGE_TEMPLATE_MIGRATION = 'storageTemplateMigration',
|
||||||
|
MIGRATION = 'migration',
|
||||||
|
SEARCH = 'search',
|
||||||
|
SIDECAR = 'sidecar',
|
||||||
|
LIBRARY = 'library',
|
||||||
|
NOTIFICATION = 'notifications',
|
||||||
|
BACKUP_DATABASE = 'backupDatabase',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum JobName {
|
||||||
|
//backups
|
||||||
|
BACKUP_DATABASE = 'database-backup',
|
||||||
|
|
||||||
|
// conversion
|
||||||
|
QUEUE_VIDEO_CONVERSION = 'queue-video-conversion',
|
||||||
|
VIDEO_CONVERSION = 'video-conversion',
|
||||||
|
|
||||||
|
// thumbnails
|
||||||
|
QUEUE_GENERATE_THUMBNAILS = 'queue-generate-thumbnails',
|
||||||
|
GENERATE_THUMBNAILS = 'generate-thumbnails',
|
||||||
|
GENERATE_PERSON_THUMBNAIL = 'generate-person-thumbnail',
|
||||||
|
|
||||||
|
// metadata
|
||||||
|
QUEUE_METADATA_EXTRACTION = 'queue-metadata-extraction',
|
||||||
|
METADATA_EXTRACTION = 'metadata-extraction',
|
||||||
|
LINK_LIVE_PHOTOS = 'link-live-photos',
|
||||||
|
|
||||||
|
// user
|
||||||
|
USER_DELETION = 'user-deletion',
|
||||||
|
USER_DELETE_CHECK = 'user-delete-check',
|
||||||
|
USER_SYNC_USAGE = 'user-sync-usage',
|
||||||
|
|
||||||
|
// asset
|
||||||
|
ASSET_DELETION = 'asset-deletion',
|
||||||
|
ASSET_DELETION_CHECK = 'asset-deletion-check',
|
||||||
|
|
||||||
|
// storage template
|
||||||
|
STORAGE_TEMPLATE_MIGRATION = 'storage-template-migration',
|
||||||
|
STORAGE_TEMPLATE_MIGRATION_SINGLE = 'storage-template-migration-single',
|
||||||
|
|
||||||
|
// tags
|
||||||
|
TAG_CLEANUP = 'tag-cleanup',
|
||||||
|
|
||||||
|
// migration
|
||||||
|
QUEUE_MIGRATION = 'queue-migration',
|
||||||
|
MIGRATE_ASSET = 'migrate-asset',
|
||||||
|
MIGRATE_PERSON = 'migrate-person',
|
||||||
|
|
||||||
|
// facial recognition
|
||||||
|
PERSON_CLEANUP = 'person-cleanup',
|
||||||
|
QUEUE_FACE_DETECTION = 'queue-face-detection',
|
||||||
|
FACE_DETECTION = 'face-detection',
|
||||||
|
QUEUE_FACIAL_RECOGNITION = 'queue-facial-recognition',
|
||||||
|
FACIAL_RECOGNITION = 'facial-recognition',
|
||||||
|
|
||||||
|
// library management
|
||||||
|
LIBRARY_QUEUE_SYNC_FILES = 'library-queue-sync-files',
|
||||||
|
LIBRARY_QUEUE_SYNC_ASSETS = 'library-queue-sync-assets',
|
||||||
|
LIBRARY_SYNC_FILE = 'library-sync-file',
|
||||||
|
LIBRARY_SYNC_ASSET = 'library-sync-asset',
|
||||||
|
LIBRARY_DELETE = 'library-delete',
|
||||||
|
LIBRARY_QUEUE_SYNC_ALL = 'library-queue-sync-all',
|
||||||
|
LIBRARY_QUEUE_CLEANUP = 'library-queue-cleanup',
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
DELETE_FILES = 'delete-files',
|
||||||
|
CLEAN_OLD_AUDIT_LOGS = 'clean-old-audit-logs',
|
||||||
|
CLEAN_OLD_SESSION_TOKENS = 'clean-old-session-tokens',
|
||||||
|
|
||||||
|
// smart search
|
||||||
|
QUEUE_SMART_SEARCH = 'queue-smart-search',
|
||||||
|
SMART_SEARCH = 'smart-search',
|
||||||
|
|
||||||
|
QUEUE_TRASH_EMPTY = 'queue-trash-empty',
|
||||||
|
|
||||||
|
// duplicate detection
|
||||||
|
QUEUE_DUPLICATE_DETECTION = 'queue-duplicate-detection',
|
||||||
|
DUPLICATE_DETECTION = 'duplicate-detection',
|
||||||
|
|
||||||
|
// XMP sidecars
|
||||||
|
QUEUE_SIDECAR = 'queue-sidecar',
|
||||||
|
SIDECAR_DISCOVERY = 'sidecar-discovery',
|
||||||
|
SIDECAR_SYNC = 'sidecar-sync',
|
||||||
|
SIDECAR_WRITE = 'sidecar-write',
|
||||||
|
|
||||||
|
// Notification
|
||||||
|
NOTIFY_SIGNUP = 'notify-signup',
|
||||||
|
NOTIFY_ALBUM_INVITE = 'notify-album-invite',
|
||||||
|
NOTIFY_ALBUM_UPDATE = 'notify-album-update',
|
||||||
|
SEND_EMAIL = 'notification-send-email',
|
||||||
|
|
||||||
|
// Version check
|
||||||
|
VERSION_CHECK = 'version-check',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum JobCommand {
|
||||||
|
START = 'start',
|
||||||
|
PAUSE = 'pause',
|
||||||
|
RESUME = 'resume',
|
||||||
|
EMPTY = 'empty',
|
||||||
|
CLEAR_FAILED = 'clear-failed',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum JobStatus {
|
||||||
|
SUCCESS = 'success',
|
||||||
|
FAILED = 'failed',
|
||||||
|
SKIPPED = 'skipped',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum QueueCleanType {
|
||||||
|
FAILED = 'failed',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum VectorIndex {
|
||||||
|
CLIP = 'clip_index',
|
||||||
|
FACE = 'face_index',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum DatabaseLock {
|
||||||
|
GeodataImport = 100,
|
||||||
|
Migrations = 200,
|
||||||
|
SystemFileMounts = 300,
|
||||||
|
StorageTemplateMigration = 420,
|
||||||
|
VersionHistory = 500,
|
||||||
|
CLIPDimSize = 512,
|
||||||
|
Library = 1337,
|
||||||
|
GetSystemConfig = 69,
|
||||||
|
BackupDatabase = 42,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
import { Insertable, Updateable } from 'kysely';
|
|
||||||
import { Albums } from 'src/db';
|
|
||||||
import { AlbumUserCreateDto } from 'src/dtos/album.dto';
|
|
||||||
import { AlbumEntity } from 'src/entities/album.entity';
|
|
||||||
import { IBulkAsset } from 'src/utils/asset.util';
|
|
||||||
|
|
||||||
export const IAlbumRepository = 'IAlbumRepository';
|
|
||||||
|
|
||||||
export interface AlbumAssetCount {
|
|
||||||
albumId: string;
|
|
||||||
assetCount: number;
|
|
||||||
startDate: Date | null;
|
|
||||||
endDate: Date | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AlbumInfoOptions {
|
|
||||||
withAssets: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAlbumRepository extends IBulkAsset {
|
|
||||||
getById(id: string, options: AlbumInfoOptions): Promise<AlbumEntity | undefined>;
|
|
||||||
getByAssetId(ownerId: string, assetId: string): Promise<AlbumEntity[]>;
|
|
||||||
removeAsset(assetId: string): Promise<void>;
|
|
||||||
getMetadataForIds(ids: string[]): Promise<AlbumAssetCount[]>;
|
|
||||||
getOwned(ownerId: string): Promise<AlbumEntity[]>;
|
|
||||||
getShared(ownerId: string): Promise<AlbumEntity[]>;
|
|
||||||
getNotShared(ownerId: string): Promise<AlbumEntity[]>;
|
|
||||||
restoreAll(userId: string): Promise<void>;
|
|
||||||
softDeleteAll(userId: string): Promise<void>;
|
|
||||||
deleteAll(userId: string): Promise<void>;
|
|
||||||
create(album: Insertable<Albums>, assetIds: string[], albumUsers: AlbumUserCreateDto[]): Promise<AlbumEntity>;
|
|
||||||
update(id: string, album: Updateable<Albums>): Promise<AlbumEntity>;
|
|
||||||
delete(id: string): Promise<void>;
|
|
||||||
updateThumbnails(): Promise<number | undefined>;
|
|
||||||
}
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
import { Insertable, Updateable } from 'kysely';
|
|
||||||
import { AssetFiles, AssetJobStatus, Assets, Exif } from 'src/db';
|
|
||||||
import { AssetEntity } from 'src/entities/asset.entity';
|
|
||||||
import { AssetFileType, AssetOrder, AssetStatus, AssetType } from 'src/enum';
|
|
||||||
import { AssetSearchOptions, SearchExploreItem } from 'src/interfaces/search.interface';
|
|
||||||
import { Paginated, PaginationOptions } from 'src/utils/pagination';
|
|
||||||
|
|
||||||
export type AssetStats = Record<AssetType, number>;
|
|
||||||
|
|
||||||
export interface AssetStatsOptions {
|
|
||||||
isFavorite?: boolean;
|
|
||||||
isArchived?: boolean;
|
|
||||||
isTrashed?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LivePhotoSearchOptions {
|
|
||||||
ownerId: string;
|
|
||||||
libraryId?: string | null;
|
|
||||||
livePhotoCID: string;
|
|
||||||
otherAssetId: string;
|
|
||||||
type: AssetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum WithoutProperty {
|
|
||||||
THUMBNAIL = 'thumbnail',
|
|
||||||
ENCODED_VIDEO = 'encoded-video',
|
|
||||||
EXIF = 'exif',
|
|
||||||
SMART_SEARCH = 'smart-search',
|
|
||||||
DUPLICATE = 'duplicate',
|
|
||||||
FACES = 'faces',
|
|
||||||
SIDECAR = 'sidecar',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum WithProperty {
|
|
||||||
SIDECAR = 'sidecar',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum TimeBucketSize {
|
|
||||||
DAY = 'DAY',
|
|
||||||
MONTH = 'MONTH',
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetBuilderOptions {
|
|
||||||
isArchived?: boolean;
|
|
||||||
isFavorite?: boolean;
|
|
||||||
isTrashed?: boolean;
|
|
||||||
isDuplicate?: boolean;
|
|
||||||
albumId?: string;
|
|
||||||
tagId?: string;
|
|
||||||
personId?: string;
|
|
||||||
userIds?: string[];
|
|
||||||
withStacked?: boolean;
|
|
||||||
exifInfo?: boolean;
|
|
||||||
status?: AssetStatus;
|
|
||||||
assetType?: AssetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TimeBucketOptions extends AssetBuilderOptions {
|
|
||||||
size: TimeBucketSize;
|
|
||||||
order?: AssetOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TimeBucketItem {
|
|
||||||
timeBucket: string;
|
|
||||||
count: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MonthDay {
|
|
||||||
day: number;
|
|
||||||
month: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetExploreFieldOptions {
|
|
||||||
maxFields: number;
|
|
||||||
minAssetsPerField: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetFullSyncOptions {
|
|
||||||
ownerId: string;
|
|
||||||
lastId?: string;
|
|
||||||
updatedUntil: Date;
|
|
||||||
limit: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetDeltaSyncOptions {
|
|
||||||
userIds: string[];
|
|
||||||
updatedAfter: Date;
|
|
||||||
limit: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetUpdateDuplicateOptions {
|
|
||||||
targetDuplicateId: string | null;
|
|
||||||
assetIds: string[];
|
|
||||||
duplicateIds: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UpsertFileOptions {
|
|
||||||
assetId: string;
|
|
||||||
type: AssetFileType;
|
|
||||||
path: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetGetByChecksumOptions {
|
|
||||||
ownerId: string;
|
|
||||||
checksum: Buffer;
|
|
||||||
libraryId?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AssetPathEntity = Pick<AssetEntity, 'id' | 'originalPath' | 'isOffline'>;
|
|
||||||
|
|
||||||
export interface GetByIdsRelations {
|
|
||||||
exifInfo?: boolean;
|
|
||||||
faces?: { person?: boolean };
|
|
||||||
files?: boolean;
|
|
||||||
library?: boolean;
|
|
||||||
owner?: boolean;
|
|
||||||
smartSearch?: boolean;
|
|
||||||
stack?: { assets?: boolean };
|
|
||||||
tags?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DuplicateGroup {
|
|
||||||
duplicateId: string;
|
|
||||||
assets: AssetEntity[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DayOfYearAssets {
|
|
||||||
yearsAgo: number;
|
|
||||||
assets: AssetEntity[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const IAssetRepository = 'IAssetRepository';
|
|
||||||
|
|
||||||
export interface IAssetRepository {
|
|
||||||
create(asset: Insertable<Assets>): Promise<AssetEntity>;
|
|
||||||
getByIds(ids: string[], relations?: GetByIdsRelations): Promise<AssetEntity[]>;
|
|
||||||
getByIdsWithAllRelations(ids: string[]): Promise<AssetEntity[]>;
|
|
||||||
getByDayOfYear(ownerIds: string[], monthDay: MonthDay): Promise<DayOfYearAssets[]>;
|
|
||||||
getByChecksum(options: AssetGetByChecksumOptions): Promise<AssetEntity | undefined>;
|
|
||||||
getByChecksums(userId: string, checksums: Buffer[]): Promise<AssetEntity[]>;
|
|
||||||
getUploadAssetIdByChecksum(ownerId: string, checksum: Buffer): Promise<string | undefined>;
|
|
||||||
getByAlbumId(pagination: PaginationOptions, albumId: string): Paginated<AssetEntity>;
|
|
||||||
getByDeviceIds(ownerId: string, deviceId: string, deviceAssetIds: string[]): Promise<string[]>;
|
|
||||||
getByUserId(pagination: PaginationOptions, userId: string, options?: AssetSearchOptions): Paginated<AssetEntity>;
|
|
||||||
getById(id: string, relations?: GetByIdsRelations): Promise<AssetEntity | undefined>;
|
|
||||||
getWithout(pagination: PaginationOptions, property: WithoutProperty): Paginated<AssetEntity>;
|
|
||||||
getRandom(userIds: string[], count: number): Promise<AssetEntity[]>;
|
|
||||||
getLastUpdatedAssetForAlbumId(albumId: string): Promise<AssetEntity | undefined>;
|
|
||||||
getByLibraryIdAndOriginalPath(libraryId: string, originalPath: string): Promise<AssetEntity | undefined>;
|
|
||||||
deleteAll(ownerId: string): Promise<void>;
|
|
||||||
getAll(pagination: PaginationOptions, options?: AssetSearchOptions): Paginated<AssetEntity>;
|
|
||||||
getAllByDeviceId(userId: string, deviceId: string): Promise<string[]>;
|
|
||||||
getLivePhotoCount(motionId: string): Promise<number>;
|
|
||||||
updateAll(ids: string[], options: Updateable<Assets>): Promise<void>;
|
|
||||||
updateDuplicates(options: AssetUpdateDuplicateOptions): Promise<void>;
|
|
||||||
update(asset: Updateable<Assets> & { id: string }): Promise<AssetEntity>;
|
|
||||||
remove(asset: AssetEntity): Promise<void>;
|
|
||||||
findLivePhotoMatch(options: LivePhotoSearchOptions): Promise<AssetEntity | undefined>;
|
|
||||||
getStatistics(ownerId: string, options: AssetStatsOptions): Promise<AssetStats>;
|
|
||||||
getTimeBuckets(options: TimeBucketOptions): Promise<TimeBucketItem[]>;
|
|
||||||
getTimeBucket(timeBucket: string, options: TimeBucketOptions): Promise<AssetEntity[]>;
|
|
||||||
upsertExif(exif: Insertable<Exif>): Promise<void>;
|
|
||||||
upsertJobStatus(...jobStatus: Insertable<AssetJobStatus>[]): Promise<void>;
|
|
||||||
getAssetIdByCity(userId: string, options: AssetExploreFieldOptions): Promise<SearchExploreItem<string>>;
|
|
||||||
getDuplicates(userId: string): Promise<DuplicateGroup[]>;
|
|
||||||
getAllForUserFullSync(options: AssetFullSyncOptions): Promise<AssetEntity[]>;
|
|
||||||
getChangedDeltaSync(options: AssetDeltaSyncOptions): Promise<AssetEntity[]>;
|
|
||||||
upsertFile(options: Insertable<AssetFiles>): Promise<void>;
|
|
||||||
upsertFiles(options: Insertable<AssetFiles>[]): Promise<void>;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
export const ICryptoRepository = 'ICryptoRepository';
|
|
||||||
|
|
||||||
export interface ICryptoRepository {
|
|
||||||
randomBytes(size: number): Buffer;
|
|
||||||
randomUUID(): string;
|
|
||||||
hashFile(filePath: string | Buffer): Promise<Buffer>;
|
|
||||||
hashSha256(data: string): string;
|
|
||||||
verifySha256(data: string, encrypted: string, publicKey: string): boolean;
|
|
||||||
hashSha1(data: string | Buffer): Buffer;
|
|
||||||
hashBcrypt(data: string | Buffer, saltOrRounds: string | number): Promise<string>;
|
|
||||||
compareBcrypt(data: string | Buffer, encrypted: string): boolean;
|
|
||||||
newPassword(bytes: number): string;
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
export enum DatabaseExtension {
|
|
||||||
CUBE = 'cube',
|
|
||||||
EARTH_DISTANCE = 'earthdistance',
|
|
||||||
VECTOR = 'vector',
|
|
||||||
VECTORS = 'vectors',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type VectorExtension = DatabaseExtension.VECTOR | DatabaseExtension.VECTORS;
|
|
||||||
|
|
||||||
export type DatabaseConnectionURL = {
|
|
||||||
connectionType: 'url';
|
|
||||||
url: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DatabaseConnectionParts = {
|
|
||||||
connectionType: 'parts';
|
|
||||||
host: string;
|
|
||||||
port: number;
|
|
||||||
username: string;
|
|
||||||
password: string;
|
|
||||||
database: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DatabaseConnectionParams = DatabaseConnectionURL | DatabaseConnectionParts;
|
|
||||||
|
|
||||||
export enum VectorIndex {
|
|
||||||
CLIP = 'clip_index',
|
|
||||||
FACE = 'face_index',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum DatabaseLock {
|
|
||||||
GeodataImport = 100,
|
|
||||||
Migrations = 200,
|
|
||||||
SystemFileMounts = 300,
|
|
||||||
StorageTemplateMigration = 420,
|
|
||||||
VersionHistory = 500,
|
|
||||||
CLIPDimSize = 512,
|
|
||||||
Library = 1337,
|
|
||||||
GetSystemConfig = 69,
|
|
||||||
BackupDatabase = 42,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const EXTENSION_NAMES: Record<DatabaseExtension, string> = {
|
|
||||||
cube: 'cube',
|
|
||||||
earthdistance: 'earthdistance',
|
|
||||||
vector: 'pgvector',
|
|
||||||
vectors: 'pgvecto.rs',
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export interface ExtensionVersion {
|
|
||||||
availableVersion: string | null;
|
|
||||||
installedVersion: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VectorUpdateResult {
|
|
||||||
restartRequired: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const IDatabaseRepository = 'IDatabaseRepository';
|
|
||||||
|
|
||||||
export interface IDatabaseRepository {
|
|
||||||
init(): void;
|
|
||||||
reconnect(): Promise<boolean>;
|
|
||||||
shutdown(): Promise<void>;
|
|
||||||
getExtensionVersion(extension: DatabaseExtension): Promise<ExtensionVersion>;
|
|
||||||
getExtensionVersionRange(extension: VectorExtension): string;
|
|
||||||
getPostgresVersion(): Promise<string>;
|
|
||||||
getPostgresVersionRange(): string;
|
|
||||||
createExtension(extension: DatabaseExtension): Promise<void>;
|
|
||||||
updateVectorExtension(extension: VectorExtension, version?: string): Promise<VectorUpdateResult>;
|
|
||||||
reindex(index: VectorIndex): Promise<void>;
|
|
||||||
shouldReindex(name: VectorIndex): Promise<boolean>;
|
|
||||||
runMigrations(options?: { transaction?: 'all' | 'none' | 'each' }): Promise<void>;
|
|
||||||
withLock<R>(lock: DatabaseLock, callback: () => Promise<R>): Promise<R>;
|
|
||||||
tryLock(lock: DatabaseLock): Promise<boolean>;
|
|
||||||
isBusy(lock: DatabaseLock): boolean;
|
|
||||||
wait(lock: DatabaseLock): Promise<void>;
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
import { ClassConstructor } from 'class-transformer';
|
|
||||||
import { SystemConfig } from 'src/config';
|
|
||||||
import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
|
||||||
import { ReleaseNotification, ServerVersionResponseDto } from 'src/dtos/server.dto';
|
|
||||||
import { JobItem, QueueName } from 'src/interfaces/job.interface';
|
|
||||||
|
|
||||||
export const IEventRepository = 'IEventRepository';
|
|
||||||
|
|
||||||
type EventMap = {
|
|
||||||
// app events
|
|
||||||
'app.bootstrap': [];
|
|
||||||
'app.shutdown': [];
|
|
||||||
|
|
||||||
'config.init': [{ newConfig: SystemConfig }];
|
|
||||||
// config events
|
|
||||||
'config.update': [
|
|
||||||
{
|
|
||||||
newConfig: SystemConfig;
|
|
||||||
oldConfig: SystemConfig;
|
|
||||||
},
|
|
||||||
];
|
|
||||||
'config.validate': [{ newConfig: SystemConfig; oldConfig: SystemConfig }];
|
|
||||||
|
|
||||||
// album events
|
|
||||||
'album.update': [{ id: string; recipientIds: string[] }];
|
|
||||||
'album.invite': [{ id: string; userId: string }];
|
|
||||||
|
|
||||||
// asset events
|
|
||||||
'asset.tag': [{ assetId: string }];
|
|
||||||
'asset.untag': [{ assetId: string }];
|
|
||||||
'asset.hide': [{ assetId: string; userId: string }];
|
|
||||||
'asset.show': [{ assetId: string; userId: string }];
|
|
||||||
'asset.trash': [{ assetId: string; userId: string }];
|
|
||||||
'asset.delete': [{ assetId: string; userId: string }];
|
|
||||||
|
|
||||||
// asset bulk events
|
|
||||||
'assets.trash': [{ assetIds: string[]; userId: string }];
|
|
||||||
'assets.delete': [{ assetIds: string[]; userId: string }];
|
|
||||||
'assets.restore': [{ assetIds: string[]; userId: string }];
|
|
||||||
|
|
||||||
'job.start': [QueueName, JobItem];
|
|
||||||
|
|
||||||
// session events
|
|
||||||
'session.delete': [{ sessionId: string }];
|
|
||||||
|
|
||||||
// stack events
|
|
||||||
'stack.create': [{ stackId: string; userId: string }];
|
|
||||||
'stack.update': [{ stackId: string; userId: string }];
|
|
||||||
'stack.delete': [{ stackId: string; userId: string }];
|
|
||||||
|
|
||||||
// stack bulk events
|
|
||||||
'stacks.delete': [{ stackIds: string[]; userId: string }];
|
|
||||||
|
|
||||||
// user events
|
|
||||||
'user.signup': [{ notify: boolean; id: string; tempPassword?: string }];
|
|
||||||
|
|
||||||
// websocket events
|
|
||||||
'websocket.connect': [{ userId: string }];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const serverEvents = ['config.update'] as const;
|
|
||||||
export type ServerEvents = (typeof serverEvents)[number];
|
|
||||||
|
|
||||||
export type EmitEvent = keyof EventMap;
|
|
||||||
export type EmitHandler<T extends EmitEvent> = (...args: ArgsOf<T>) => Promise<void> | void;
|
|
||||||
export type ArgOf<T extends EmitEvent> = EventMap[T][0];
|
|
||||||
export type ArgsOf<T extends EmitEvent> = EventMap[T];
|
|
||||||
|
|
||||||
export interface ClientEventMap {
|
|
||||||
on_upload_success: [AssetResponseDto];
|
|
||||||
on_user_delete: [string];
|
|
||||||
on_asset_delete: [string];
|
|
||||||
on_asset_trash: [string[]];
|
|
||||||
on_asset_update: [AssetResponseDto];
|
|
||||||
on_asset_hidden: [string];
|
|
||||||
on_asset_restore: [string[]];
|
|
||||||
on_asset_stack_update: string[];
|
|
||||||
on_person_thumbnail: [string];
|
|
||||||
on_server_version: [ServerVersionResponseDto];
|
|
||||||
on_config_update: [];
|
|
||||||
on_new_release: [ReleaseNotification];
|
|
||||||
on_session_delete: [string];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EventItem<T extends EmitEvent> = {
|
|
||||||
event: T;
|
|
||||||
handler: EmitHandler<T>;
|
|
||||||
server: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum BootstrapEventPriority {
|
|
||||||
// Database service should be initialized before anything else, most other services need database access
|
|
||||||
DatabaseService = -200,
|
|
||||||
// Initialise config after other bootstrap services, stop other services from using config on bootstrap
|
|
||||||
SystemConfig = 100,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IEventRepository {
|
|
||||||
setup(options: { services: ClassConstructor<unknown>[] }): void;
|
|
||||||
emit<T extends keyof EventMap>(event: T, ...args: ArgsOf<T>): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send to connected clients for a specific user
|
|
||||||
*/
|
|
||||||
clientSend<E extends keyof ClientEventMap>(event: E, room: string, ...data: ClientEventMap[E]): void;
|
|
||||||
/**
|
|
||||||
* Send to all connected clients
|
|
||||||
*/
|
|
||||||
clientBroadcast<E extends keyof ClientEventMap>(event: E, ...data: ClientEventMap[E]): void;
|
|
||||||
/**
|
|
||||||
* Send to all connected servers
|
|
||||||
*/
|
|
||||||
serverSend<T extends ServerEvents>(event: T, ...args: ArgsOf<T>): void;
|
|
||||||
}
|
|
||||||
@@ -1,328 +0,0 @@
|
|||||||
import { ClassConstructor } from 'class-transformer';
|
|
||||||
import { EmailImageAttachment } from 'src/repositories/notification.repository';
|
|
||||||
|
|
||||||
export enum QueueName {
|
|
||||||
THUMBNAIL_GENERATION = 'thumbnailGeneration',
|
|
||||||
METADATA_EXTRACTION = 'metadataExtraction',
|
|
||||||
VIDEO_CONVERSION = 'videoConversion',
|
|
||||||
FACE_DETECTION = 'faceDetection',
|
|
||||||
FACIAL_RECOGNITION = 'facialRecognition',
|
|
||||||
SMART_SEARCH = 'smartSearch',
|
|
||||||
DUPLICATE_DETECTION = 'duplicateDetection',
|
|
||||||
BACKGROUND_TASK = 'backgroundTask',
|
|
||||||
STORAGE_TEMPLATE_MIGRATION = 'storageTemplateMigration',
|
|
||||||
MIGRATION = 'migration',
|
|
||||||
SEARCH = 'search',
|
|
||||||
SIDECAR = 'sidecar',
|
|
||||||
LIBRARY = 'library',
|
|
||||||
NOTIFICATION = 'notifications',
|
|
||||||
BACKUP_DATABASE = 'backupDatabase',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ConcurrentQueueName = Exclude<
|
|
||||||
QueueName,
|
|
||||||
| QueueName.STORAGE_TEMPLATE_MIGRATION
|
|
||||||
| QueueName.FACIAL_RECOGNITION
|
|
||||||
| QueueName.DUPLICATE_DETECTION
|
|
||||||
| QueueName.BACKUP_DATABASE
|
|
||||||
>;
|
|
||||||
|
|
||||||
export enum JobCommand {
|
|
||||||
START = 'start',
|
|
||||||
PAUSE = 'pause',
|
|
||||||
RESUME = 'resume',
|
|
||||||
EMPTY = 'empty',
|
|
||||||
CLEAR_FAILED = 'clear-failed',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum JobName {
|
|
||||||
//backups
|
|
||||||
BACKUP_DATABASE = 'database-backup',
|
|
||||||
|
|
||||||
// conversion
|
|
||||||
QUEUE_VIDEO_CONVERSION = 'queue-video-conversion',
|
|
||||||
VIDEO_CONVERSION = 'video-conversion',
|
|
||||||
|
|
||||||
// thumbnails
|
|
||||||
QUEUE_GENERATE_THUMBNAILS = 'queue-generate-thumbnails',
|
|
||||||
GENERATE_THUMBNAILS = 'generate-thumbnails',
|
|
||||||
GENERATE_PERSON_THUMBNAIL = 'generate-person-thumbnail',
|
|
||||||
|
|
||||||
// metadata
|
|
||||||
QUEUE_METADATA_EXTRACTION = 'queue-metadata-extraction',
|
|
||||||
METADATA_EXTRACTION = 'metadata-extraction',
|
|
||||||
LINK_LIVE_PHOTOS = 'link-live-photos',
|
|
||||||
|
|
||||||
// user
|
|
||||||
USER_DELETION = 'user-deletion',
|
|
||||||
USER_DELETE_CHECK = 'user-delete-check',
|
|
||||||
USER_SYNC_USAGE = 'user-sync-usage',
|
|
||||||
|
|
||||||
// asset
|
|
||||||
ASSET_DELETION = 'asset-deletion',
|
|
||||||
ASSET_DELETION_CHECK = 'asset-deletion-check',
|
|
||||||
|
|
||||||
// storage template
|
|
||||||
STORAGE_TEMPLATE_MIGRATION = 'storage-template-migration',
|
|
||||||
STORAGE_TEMPLATE_MIGRATION_SINGLE = 'storage-template-migration-single',
|
|
||||||
|
|
||||||
// tags
|
|
||||||
TAG_CLEANUP = 'tag-cleanup',
|
|
||||||
|
|
||||||
// migration
|
|
||||||
QUEUE_MIGRATION = 'queue-migration',
|
|
||||||
MIGRATE_ASSET = 'migrate-asset',
|
|
||||||
MIGRATE_PERSON = 'migrate-person',
|
|
||||||
|
|
||||||
// facial recognition
|
|
||||||
PERSON_CLEANUP = 'person-cleanup',
|
|
||||||
QUEUE_FACE_DETECTION = 'queue-face-detection',
|
|
||||||
FACE_DETECTION = 'face-detection',
|
|
||||||
QUEUE_FACIAL_RECOGNITION = 'queue-facial-recognition',
|
|
||||||
FACIAL_RECOGNITION = 'facial-recognition',
|
|
||||||
|
|
||||||
// library management
|
|
||||||
LIBRARY_QUEUE_SYNC_FILES = 'library-queue-sync-files',
|
|
||||||
LIBRARY_QUEUE_SYNC_ASSETS = 'library-queue-sync-assets',
|
|
||||||
LIBRARY_SYNC_FILE = 'library-sync-file',
|
|
||||||
LIBRARY_SYNC_ASSET = 'library-sync-asset',
|
|
||||||
LIBRARY_DELETE = 'library-delete',
|
|
||||||
LIBRARY_QUEUE_SYNC_ALL = 'library-queue-sync-all',
|
|
||||||
LIBRARY_QUEUE_CLEANUP = 'library-queue-cleanup',
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
DELETE_FILES = 'delete-files',
|
|
||||||
CLEAN_OLD_AUDIT_LOGS = 'clean-old-audit-logs',
|
|
||||||
CLEAN_OLD_SESSION_TOKENS = 'clean-old-session-tokens',
|
|
||||||
|
|
||||||
// smart search
|
|
||||||
QUEUE_SMART_SEARCH = 'queue-smart-search',
|
|
||||||
SMART_SEARCH = 'smart-search',
|
|
||||||
|
|
||||||
QUEUE_TRASH_EMPTY = 'queue-trash-empty',
|
|
||||||
|
|
||||||
// duplicate detection
|
|
||||||
QUEUE_DUPLICATE_DETECTION = 'queue-duplicate-detection',
|
|
||||||
DUPLICATE_DETECTION = 'duplicate-detection',
|
|
||||||
|
|
||||||
// XMP sidecars
|
|
||||||
QUEUE_SIDECAR = 'queue-sidecar',
|
|
||||||
SIDECAR_DISCOVERY = 'sidecar-discovery',
|
|
||||||
SIDECAR_SYNC = 'sidecar-sync',
|
|
||||||
SIDECAR_WRITE = 'sidecar-write',
|
|
||||||
|
|
||||||
// Notification
|
|
||||||
NOTIFY_SIGNUP = 'notify-signup',
|
|
||||||
NOTIFY_ALBUM_INVITE = 'notify-album-invite',
|
|
||||||
NOTIFY_ALBUM_UPDATE = 'notify-album-update',
|
|
||||||
SEND_EMAIL = 'notification-send-email',
|
|
||||||
|
|
||||||
// Version check
|
|
||||||
VERSION_CHECK = 'version-check',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const JOBS_ASSET_PAGINATION_SIZE = 1000;
|
|
||||||
export const JOBS_LIBRARY_PAGINATION_SIZE = 10_000;
|
|
||||||
|
|
||||||
export interface IBaseJob {
|
|
||||||
force?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IDelayedJob extends IBaseJob {
|
|
||||||
/** The minimum time to wait to execute this job, in milliseconds. */
|
|
||||||
delay?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IEntityJob extends IBaseJob {
|
|
||||||
id: string;
|
|
||||||
source?: 'upload' | 'sidecar-write' | 'copy';
|
|
||||||
notify?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAssetDeleteJob extends IEntityJob {
|
|
||||||
deleteOnDisk: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ILibraryFileJob extends IEntityJob {
|
|
||||||
assetPath: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ILibraryAssetJob extends IEntityJob {
|
|
||||||
importPaths: string[];
|
|
||||||
exclusionPatterns: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IBulkEntityJob extends IBaseJob {
|
|
||||||
ids: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IDeleteFilesJob extends IBaseJob {
|
|
||||||
files: Array<string | null | undefined>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ISidecarWriteJob extends IEntityJob {
|
|
||||||
description?: string;
|
|
||||||
dateTimeOriginal?: string;
|
|
||||||
latitude?: number;
|
|
||||||
longitude?: number;
|
|
||||||
rating?: number;
|
|
||||||
tags?: true;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IDeferrableJob extends IEntityJob {
|
|
||||||
deferred?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INightlyJob extends IBaseJob {
|
|
||||||
nightly?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IEmailJob {
|
|
||||||
to: string;
|
|
||||||
subject: string;
|
|
||||||
html: string;
|
|
||||||
text: string;
|
|
||||||
imageAttachments?: EmailImageAttachment[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INotifySignupJob extends IEntityJob {
|
|
||||||
tempPassword?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INotifyAlbumInviteJob extends IEntityJob {
|
|
||||||
recipientId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INotifyAlbumUpdateJob extends IEntityJob, IDelayedJob {
|
|
||||||
recipientIds: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface JobCounts {
|
|
||||||
active: number;
|
|
||||||
completed: number;
|
|
||||||
failed: number;
|
|
||||||
delayed: number;
|
|
||||||
waiting: number;
|
|
||||||
paused: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface QueueStatus {
|
|
||||||
isActive: boolean;
|
|
||||||
isPaused: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum QueueCleanType {
|
|
||||||
FAILED = 'failed',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type JobItem =
|
|
||||||
// Backups
|
|
||||||
| { name: JobName.BACKUP_DATABASE; data?: IBaseJob }
|
|
||||||
|
|
||||||
// Transcoding
|
|
||||||
| { name: JobName.QUEUE_VIDEO_CONVERSION; data: IBaseJob }
|
|
||||||
| { name: JobName.VIDEO_CONVERSION; data: IEntityJob }
|
|
||||||
|
|
||||||
// Thumbnails
|
|
||||||
| { name: JobName.QUEUE_GENERATE_THUMBNAILS; data: IBaseJob }
|
|
||||||
| { name: JobName.GENERATE_THUMBNAILS; data: IEntityJob }
|
|
||||||
|
|
||||||
// User
|
|
||||||
| { name: JobName.USER_DELETE_CHECK; data?: IBaseJob }
|
|
||||||
| { name: JobName.USER_DELETION; data: IEntityJob }
|
|
||||||
| { name: JobName.USER_SYNC_USAGE; data?: IBaseJob }
|
|
||||||
|
|
||||||
// Storage Template
|
|
||||||
| { name: JobName.STORAGE_TEMPLATE_MIGRATION; data?: IBaseJob }
|
|
||||||
| { name: JobName.STORAGE_TEMPLATE_MIGRATION_SINGLE; data: IEntityJob }
|
|
||||||
|
|
||||||
// Migration
|
|
||||||
| { name: JobName.QUEUE_MIGRATION; data?: IBaseJob }
|
|
||||||
| { name: JobName.MIGRATE_ASSET; data: IEntityJob }
|
|
||||||
| { name: JobName.MIGRATE_PERSON; data: IEntityJob }
|
|
||||||
|
|
||||||
// Metadata Extraction
|
|
||||||
| { name: JobName.QUEUE_METADATA_EXTRACTION; data: IBaseJob }
|
|
||||||
| { name: JobName.METADATA_EXTRACTION; data: IEntityJob }
|
|
||||||
| { name: JobName.LINK_LIVE_PHOTOS; data: IEntityJob }
|
|
||||||
// Sidecar Scanning
|
|
||||||
| { name: JobName.QUEUE_SIDECAR; data: IBaseJob }
|
|
||||||
| { name: JobName.SIDECAR_DISCOVERY; data: IEntityJob }
|
|
||||||
| { name: JobName.SIDECAR_SYNC; data: IEntityJob }
|
|
||||||
| { name: JobName.SIDECAR_WRITE; data: ISidecarWriteJob }
|
|
||||||
|
|
||||||
// Facial Recognition
|
|
||||||
| { name: JobName.QUEUE_FACE_DETECTION; data: IBaseJob }
|
|
||||||
| { name: JobName.FACE_DETECTION; data: IEntityJob }
|
|
||||||
| { name: JobName.QUEUE_FACIAL_RECOGNITION; data: INightlyJob }
|
|
||||||
| { name: JobName.FACIAL_RECOGNITION; data: IDeferrableJob }
|
|
||||||
| { name: JobName.GENERATE_PERSON_THUMBNAIL; data: IEntityJob }
|
|
||||||
|
|
||||||
// Smart Search
|
|
||||||
| { name: JobName.QUEUE_SMART_SEARCH; data: IBaseJob }
|
|
||||||
| { name: JobName.SMART_SEARCH; data: IEntityJob }
|
|
||||||
| { name: JobName.QUEUE_TRASH_EMPTY; data?: IBaseJob }
|
|
||||||
|
|
||||||
// Duplicate Detection
|
|
||||||
| { name: JobName.QUEUE_DUPLICATE_DETECTION; data: IBaseJob }
|
|
||||||
| { name: JobName.DUPLICATE_DETECTION; data: IEntityJob }
|
|
||||||
|
|
||||||
// Filesystem
|
|
||||||
| { name: JobName.DELETE_FILES; data: IDeleteFilesJob }
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
| { name: JobName.CLEAN_OLD_AUDIT_LOGS; data?: IBaseJob }
|
|
||||||
| { name: JobName.CLEAN_OLD_SESSION_TOKENS; data?: IBaseJob }
|
|
||||||
|
|
||||||
// Tags
|
|
||||||
| { name: JobName.TAG_CLEANUP; data?: IBaseJob }
|
|
||||||
|
|
||||||
// Asset Deletion
|
|
||||||
| { name: JobName.PERSON_CLEANUP; data?: IBaseJob }
|
|
||||||
| { name: JobName.ASSET_DELETION; data: IAssetDeleteJob }
|
|
||||||
| { name: JobName.ASSET_DELETION_CHECK; data?: IBaseJob }
|
|
||||||
|
|
||||||
// Library Management
|
|
||||||
| { name: JobName.LIBRARY_SYNC_FILE; data: ILibraryFileJob }
|
|
||||||
| { name: JobName.LIBRARY_QUEUE_SYNC_FILES; data: IEntityJob }
|
|
||||||
| { name: JobName.LIBRARY_QUEUE_SYNC_ASSETS; data: IEntityJob }
|
|
||||||
| { name: JobName.LIBRARY_SYNC_ASSET; data: ILibraryAssetJob }
|
|
||||||
| { name: JobName.LIBRARY_DELETE; data: IEntityJob }
|
|
||||||
| { name: JobName.LIBRARY_QUEUE_SYNC_ALL; data?: IBaseJob }
|
|
||||||
| { name: JobName.LIBRARY_QUEUE_CLEANUP; data: IBaseJob }
|
|
||||||
|
|
||||||
// Notification
|
|
||||||
| { name: JobName.SEND_EMAIL; data: IEmailJob }
|
|
||||||
| { name: JobName.NOTIFY_ALBUM_INVITE; data: INotifyAlbumInviteJob }
|
|
||||||
| { name: JobName.NOTIFY_ALBUM_UPDATE; data: INotifyAlbumUpdateJob }
|
|
||||||
| { name: JobName.NOTIFY_SIGNUP; data: INotifySignupJob }
|
|
||||||
|
|
||||||
// Version check
|
|
||||||
| { name: JobName.VERSION_CHECK; data: IBaseJob };
|
|
||||||
|
|
||||||
export enum JobStatus {
|
|
||||||
SUCCESS = 'success',
|
|
||||||
FAILED = 'failed',
|
|
||||||
SKIPPED = 'skipped',
|
|
||||||
}
|
|
||||||
export type Jobs = { [K in JobItem['name']]: (JobItem & { name: K })['data'] };
|
|
||||||
export type JobOf<T extends JobName> = Jobs[T];
|
|
||||||
|
|
||||||
export const IJobRepository = 'IJobRepository';
|
|
||||||
|
|
||||||
export interface IJobRepository {
|
|
||||||
setup(options: { services: ClassConstructor<unknown>[] }): void;
|
|
||||||
startWorkers(): void;
|
|
||||||
run(job: JobItem): Promise<JobStatus>;
|
|
||||||
setConcurrency(queueName: QueueName, concurrency: number): void;
|
|
||||||
queue(item: JobItem): Promise<void>;
|
|
||||||
queueAll(items: JobItem[]): Promise<void>;
|
|
||||||
pause(name: QueueName): Promise<void>;
|
|
||||||
resume(name: QueueName): Promise<void>;
|
|
||||||
empty(name: QueueName): Promise<void>;
|
|
||||||
clear(name: QueueName, type: QueueCleanType): Promise<string[]>;
|
|
||||||
getQueueStatus(name: QueueName): Promise<QueueStatus>;
|
|
||||||
getJobCounts(name: QueueName): Promise<JobCounts>;
|
|
||||||
waitForQueueCompletion(...queues: QueueName[]): Promise<void>;
|
|
||||||
removeJob(jobId: string, name: JobName): Promise<IEntityJob | undefined>;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import { Insertable, Updateable } from 'kysely';
|
|
||||||
import { Libraries } from 'src/db';
|
|
||||||
import { LibraryStatsResponseDto } from 'src/dtos/library.dto';
|
|
||||||
import { LibraryEntity } from 'src/entities/library.entity';
|
|
||||||
|
|
||||||
export const ILibraryRepository = 'ILibraryRepository';
|
|
||||||
|
|
||||||
export interface ILibraryRepository {
|
|
||||||
getAll(withDeleted?: boolean): Promise<LibraryEntity[]>;
|
|
||||||
getAllDeleted(): Promise<LibraryEntity[]>;
|
|
||||||
get(id: string, withDeleted?: boolean): Promise<LibraryEntity | undefined>;
|
|
||||||
create(library: Insertable<Libraries>): Promise<LibraryEntity>;
|
|
||||||
delete(id: string): Promise<void>;
|
|
||||||
softDelete(id: string): Promise<void>;
|
|
||||||
update(id: string, library: Updateable<Libraries>): Promise<LibraryEntity>;
|
|
||||||
getStatistics(id: string): Promise<LibraryStatsResponseDto | undefined>;
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
export const IMachineLearningRepository = 'IMachineLearningRepository';
|
|
||||||
|
|
||||||
export interface BoundingBox {
|
|
||||||
x1: number;
|
|
||||||
y1: number;
|
|
||||||
x2: number;
|
|
||||||
y2: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ModelTask {
|
|
||||||
FACIAL_RECOGNITION = 'facial-recognition',
|
|
||||||
SEARCH = 'clip',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ModelType {
|
|
||||||
DETECTION = 'detection',
|
|
||||||
PIPELINE = 'pipeline',
|
|
||||||
RECOGNITION = 'recognition',
|
|
||||||
TEXTUAL = 'textual',
|
|
||||||
VISUAL = 'visual',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ModelPayload = { imagePath: string } | { text: string };
|
|
||||||
|
|
||||||
type ModelOptions = { modelName: string };
|
|
||||||
|
|
||||||
export type FaceDetectionOptions = ModelOptions & { minScore: number };
|
|
||||||
|
|
||||||
type VisualResponse = { imageHeight: number; imageWidth: number };
|
|
||||||
export type ClipVisualRequest = { [ModelTask.SEARCH]: { [ModelType.VISUAL]: ModelOptions } };
|
|
||||||
export type ClipVisualResponse = { [ModelTask.SEARCH]: string } & VisualResponse;
|
|
||||||
|
|
||||||
export type ClipTextualRequest = { [ModelTask.SEARCH]: { [ModelType.TEXTUAL]: ModelOptions } };
|
|
||||||
export type ClipTextualResponse = { [ModelTask.SEARCH]: string };
|
|
||||||
|
|
||||||
export type FacialRecognitionRequest = {
|
|
||||||
[ModelTask.FACIAL_RECOGNITION]: {
|
|
||||||
[ModelType.DETECTION]: ModelOptions & { options: { minScore: number } };
|
|
||||||
[ModelType.RECOGNITION]: ModelOptions;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface Face {
|
|
||||||
boundingBox: BoundingBox;
|
|
||||||
embedding: string;
|
|
||||||
score: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type FacialRecognitionResponse = { [ModelTask.FACIAL_RECOGNITION]: Face[] } & VisualResponse;
|
|
||||||
export type DetectedFaces = { faces: Face[] } & VisualResponse;
|
|
||||||
export type MachineLearningRequest = ClipVisualRequest | ClipTextualRequest | FacialRecognitionRequest;
|
|
||||||
|
|
||||||
export interface IMachineLearningRepository {
|
|
||||||
encodeImage(urls: string[], imagePath: string, config: ModelOptions): Promise<string>;
|
|
||||||
encodeText(urls: string[], text: string, config: ModelOptions): Promise<string>;
|
|
||||||
detectFaces(urls: string[], imagePath: string, config: FaceDetectionOptions): Promise<DetectedFaces>;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import { Insertable, Updateable } from 'kysely';
|
|
||||||
import { MoveHistory } from 'src/db';
|
|
||||||
import { MoveEntity } from 'src/entities/move.entity';
|
|
||||||
import { PathType } from 'src/enum';
|
|
||||||
|
|
||||||
export const IMoveRepository = 'IMoveRepository';
|
|
||||||
|
|
||||||
export type MoveCreate = Pick<MoveEntity, 'oldPath' | 'newPath' | 'entityId' | 'pathType'> & Partial<MoveEntity>;
|
|
||||||
|
|
||||||
export interface IMoveRepository {
|
|
||||||
create(entity: Insertable<MoveHistory>): Promise<MoveEntity>;
|
|
||||||
getByEntity(entityId: string, pathType: PathType): Promise<MoveEntity | undefined>;
|
|
||||||
update(id: string, entity: Updateable<MoveHistory>): Promise<MoveEntity>;
|
|
||||||
delete(id: string): Promise<MoveEntity>;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { Updateable } from 'kysely';
|
|
||||||
import { Partners } from 'src/db';
|
|
||||||
import { PartnerEntity } from 'src/entities/partner.entity';
|
|
||||||
|
|
||||||
export interface PartnerIds {
|
|
||||||
sharedById: string;
|
|
||||||
sharedWithId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum PartnerDirection {
|
|
||||||
SharedBy = 'shared-by',
|
|
||||||
SharedWith = 'shared-with',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const IPartnerRepository = 'IPartnerRepository';
|
|
||||||
|
|
||||||
export interface IPartnerRepository {
|
|
||||||
getAll(userId: string): Promise<PartnerEntity[]>;
|
|
||||||
get(partner: PartnerIds): Promise<PartnerEntity | undefined>;
|
|
||||||
create(partner: PartnerIds): Promise<PartnerEntity>;
|
|
||||||
remove(partner: PartnerIds): Promise<void>;
|
|
||||||
update(partner: PartnerIds, entity: Updateable<Partners>): Promise<PartnerEntity>;
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
import { Insertable, Selectable, Updateable } from 'kysely';
|
|
||||||
import { AssetFaces, FaceSearch, Person } from 'src/db';
|
|
||||||
import { AssetFaceEntity } from 'src/entities/asset-face.entity';
|
|
||||||
import { PersonEntity } from 'src/entities/person.entity';
|
|
||||||
import { SourceType } from 'src/enum';
|
|
||||||
import { Paginated, PaginationOptions } from 'src/utils/pagination';
|
|
||||||
import { FindOptionsRelations } from 'typeorm';
|
|
||||||
|
|
||||||
export const IPersonRepository = 'IPersonRepository';
|
|
||||||
|
|
||||||
export interface PersonSearchOptions {
|
|
||||||
minimumFaceCount: number;
|
|
||||||
withHidden: boolean;
|
|
||||||
closestFaceAssetId?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PersonNameSearchOptions {
|
|
||||||
withHidden?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PersonNameResponse {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetFaceId {
|
|
||||||
assetId: string;
|
|
||||||
personId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UpdateFacesData {
|
|
||||||
oldPersonId?: string;
|
|
||||||
faceIds?: string[];
|
|
||||||
newPersonId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PersonStatistics {
|
|
||||||
assets: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PeopleStatistics {
|
|
||||||
total: number;
|
|
||||||
hidden: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DeleteFacesOptions {
|
|
||||||
sourceType: SourceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type UnassignFacesOptions = DeleteFacesOptions;
|
|
||||||
|
|
||||||
export type SelectFaceOptions = (keyof Selectable<AssetFaces>)[];
|
|
||||||
|
|
||||||
export interface IPersonRepository {
|
|
||||||
getAll(options?: Partial<PersonEntity>): AsyncIterableIterator<PersonEntity>;
|
|
||||||
getAllForUser(pagination: PaginationOptions, userId: string, options: PersonSearchOptions): Paginated<PersonEntity>;
|
|
||||||
getAllWithoutFaces(): Promise<PersonEntity[]>;
|
|
||||||
getById(personId: string): Promise<PersonEntity | null>;
|
|
||||||
getByName(userId: string, personName: string, options: PersonNameSearchOptions): Promise<PersonEntity[]>;
|
|
||||||
getDistinctNames(userId: string, options: PersonNameSearchOptions): Promise<PersonNameResponse[]>;
|
|
||||||
|
|
||||||
create(person: Insertable<Person>): Promise<PersonEntity>;
|
|
||||||
createAll(people: Insertable<Person>[]): Promise<string[]>;
|
|
||||||
delete(entities: PersonEntity[]): Promise<void>;
|
|
||||||
deleteFaces(options: DeleteFacesOptions): Promise<void>;
|
|
||||||
refreshFaces(
|
|
||||||
facesToAdd: Insertable<AssetFaces>[],
|
|
||||||
faceIdsToRemove: string[],
|
|
||||||
embeddingsToAdd?: Insertable<FaceSearch>[],
|
|
||||||
): Promise<void>;
|
|
||||||
getAllFaces(options?: Partial<AssetFaceEntity>): AsyncIterableIterator<AssetFaceEntity>;
|
|
||||||
getFaceById(id: string): Promise<AssetFaceEntity>;
|
|
||||||
getFaceByIdWithAssets(
|
|
||||||
id: string,
|
|
||||||
relations?: FindOptionsRelations<AssetFaceEntity>,
|
|
||||||
select?: SelectFaceOptions,
|
|
||||||
): Promise<AssetFaceEntity | undefined>;
|
|
||||||
getFaces(assetId: string): Promise<AssetFaceEntity[]>;
|
|
||||||
getFacesByIds(ids: AssetFaceId[]): Promise<AssetFaceEntity[]>;
|
|
||||||
getRandomFace(personId: string): Promise<AssetFaceEntity | undefined>;
|
|
||||||
getStatistics(personId: string): Promise<PersonStatistics>;
|
|
||||||
reassignFace(assetFaceId: string, newPersonId: string): Promise<number>;
|
|
||||||
getNumberOfPeople(userId: string): Promise<PeopleStatistics>;
|
|
||||||
reassignFaces(data: UpdateFacesData): Promise<number>;
|
|
||||||
unassignFaces(options: UnassignFacesOptions): Promise<void>;
|
|
||||||
update(person: Updateable<Person> & { id: string }): Promise<PersonEntity>;
|
|
||||||
updateAll(people: Insertable<Person>[]): Promise<void>;
|
|
||||||
getLatestFaceDate(): Promise<string | undefined>;
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import { ChildProcessWithoutNullStreams, SpawnOptionsWithoutStdio } from 'node:child_process';
|
|
||||||
import { Readable } from 'node:stream';
|
|
||||||
|
|
||||||
export interface ImmichReadStream {
|
|
||||||
stream: Readable;
|
|
||||||
type?: string;
|
|
||||||
length?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ImmichZipStream extends ImmichReadStream {
|
|
||||||
addFile: (inputPath: string, filename: string) => void;
|
|
||||||
finalize: () => Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DiskUsage {
|
|
||||||
available: number;
|
|
||||||
free: number;
|
|
||||||
total: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const IProcessRepository = 'IProcessRepository';
|
|
||||||
|
|
||||||
export interface IProcessRepository {
|
|
||||||
spawn(command: string, args?: readonly string[], options?: SpawnOptionsWithoutStdio): ChildProcessWithoutNullStreams;
|
|
||||||
}
|
|
||||||
@@ -1,213 +0,0 @@
|
|||||||
import { AssetEntity } from 'src/entities/asset.entity';
|
|
||||||
import { GeodataPlacesEntity } from 'src/entities/geodata-places.entity';
|
|
||||||
import { AssetStatus, AssetType } from 'src/enum';
|
|
||||||
import { Paginated } from 'src/utils/pagination';
|
|
||||||
|
|
||||||
export const ISearchRepository = 'ISearchRepository';
|
|
||||||
|
|
||||||
export interface SearchResult<T> {
|
|
||||||
/** total matches */
|
|
||||||
total: number;
|
|
||||||
/** collection size */
|
|
||||||
count: number;
|
|
||||||
/** current page */
|
|
||||||
page: number;
|
|
||||||
/** items for page */
|
|
||||||
items: T[];
|
|
||||||
/** score */
|
|
||||||
distances: number[];
|
|
||||||
facets: SearchFacet[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchFacet {
|
|
||||||
fieldName: string;
|
|
||||||
counts: Array<{
|
|
||||||
count: number;
|
|
||||||
value: string;
|
|
||||||
}>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SearchExploreItemSet<T> = Array<{
|
|
||||||
value: string;
|
|
||||||
data: T;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
export interface SearchExploreItem<T> {
|
|
||||||
fieldName: string;
|
|
||||||
items: SearchExploreItemSet<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchAssetIDOptions {
|
|
||||||
checksum?: Buffer;
|
|
||||||
deviceAssetId?: string;
|
|
||||||
id?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchUserIdOptions {
|
|
||||||
deviceId?: string;
|
|
||||||
libraryId?: string | null;
|
|
||||||
userIds?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SearchIdOptions = SearchAssetIDOptions & SearchUserIdOptions;
|
|
||||||
|
|
||||||
export interface SearchStatusOptions {
|
|
||||||
isArchived?: boolean;
|
|
||||||
isEncoded?: boolean;
|
|
||||||
isFavorite?: boolean;
|
|
||||||
isMotion?: boolean;
|
|
||||||
isOffline?: boolean;
|
|
||||||
isVisible?: boolean;
|
|
||||||
isNotInAlbum?: boolean;
|
|
||||||
type?: AssetType;
|
|
||||||
status?: AssetStatus;
|
|
||||||
withArchived?: boolean;
|
|
||||||
withDeleted?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchOneToOneRelationOptions {
|
|
||||||
withExif?: boolean;
|
|
||||||
withStacked?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchRelationOptions extends SearchOneToOneRelationOptions {
|
|
||||||
withFaces?: boolean;
|
|
||||||
withPeople?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchDateOptions {
|
|
||||||
createdBefore?: Date;
|
|
||||||
createdAfter?: Date;
|
|
||||||
takenBefore?: Date;
|
|
||||||
takenAfter?: Date;
|
|
||||||
trashedBefore?: Date;
|
|
||||||
trashedAfter?: Date;
|
|
||||||
updatedBefore?: Date;
|
|
||||||
updatedAfter?: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchPathOptions {
|
|
||||||
encodedVideoPath?: string;
|
|
||||||
originalFileName?: string;
|
|
||||||
originalPath?: string;
|
|
||||||
previewPath?: string;
|
|
||||||
thumbnailPath?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchExifOptions {
|
|
||||||
city?: string | null;
|
|
||||||
country?: string | null;
|
|
||||||
lensModel?: string | null;
|
|
||||||
make?: string | null;
|
|
||||||
model?: string | null;
|
|
||||||
state?: string | null;
|
|
||||||
description?: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchEmbeddingOptions {
|
|
||||||
embedding: string;
|
|
||||||
userIds: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchPeopleOptions {
|
|
||||||
personIds?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchTagOptions {
|
|
||||||
tagIds?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchOrderOptions {
|
|
||||||
orderDirection?: 'asc' | 'desc';
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchPaginationOptions {
|
|
||||||
page: number;
|
|
||||||
size: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
type BaseAssetSearchOptions = SearchDateOptions &
|
|
||||||
SearchIdOptions &
|
|
||||||
SearchExifOptions &
|
|
||||||
SearchOrderOptions &
|
|
||||||
SearchPathOptions &
|
|
||||||
SearchStatusOptions &
|
|
||||||
SearchUserIdOptions &
|
|
||||||
SearchPeopleOptions &
|
|
||||||
SearchTagOptions;
|
|
||||||
|
|
||||||
export type AssetSearchOptions = BaseAssetSearchOptions & SearchRelationOptions;
|
|
||||||
|
|
||||||
export type AssetSearchOneToOneRelationOptions = BaseAssetSearchOptions & SearchOneToOneRelationOptions;
|
|
||||||
|
|
||||||
export type AssetSearchBuilderOptions = Omit<AssetSearchOptions, 'orderDirection'>;
|
|
||||||
|
|
||||||
export type SmartSearchOptions = SearchDateOptions &
|
|
||||||
SearchEmbeddingOptions &
|
|
||||||
SearchExifOptions &
|
|
||||||
SearchOneToOneRelationOptions &
|
|
||||||
SearchStatusOptions &
|
|
||||||
SearchUserIdOptions &
|
|
||||||
SearchPeopleOptions &
|
|
||||||
SearchTagOptions;
|
|
||||||
|
|
||||||
export interface FaceEmbeddingSearch extends SearchEmbeddingOptions {
|
|
||||||
hasPerson?: boolean;
|
|
||||||
numResults: number;
|
|
||||||
maxDistance: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetDuplicateSearch {
|
|
||||||
assetId: string;
|
|
||||||
embedding: string;
|
|
||||||
maxDistance: number;
|
|
||||||
type: AssetType;
|
|
||||||
userIds: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FaceSearchResult {
|
|
||||||
distance: number;
|
|
||||||
id: string;
|
|
||||||
personId: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetDuplicateResult {
|
|
||||||
assetId: string;
|
|
||||||
duplicateId: string | null;
|
|
||||||
distance: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GetStatesOptions {
|
|
||||||
country?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GetCitiesOptions extends GetStatesOptions {
|
|
||||||
state?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GetCameraModelsOptions {
|
|
||||||
make?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GetCameraMakesOptions {
|
|
||||||
model?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ISearchRepository {
|
|
||||||
searchMetadata(pagination: SearchPaginationOptions, options: AssetSearchOptions): Paginated<AssetEntity>;
|
|
||||||
searchSmart(pagination: SearchPaginationOptions, options: SmartSearchOptions): Paginated<AssetEntity>;
|
|
||||||
searchDuplicates(options: AssetDuplicateSearch): Promise<AssetDuplicateResult[]>;
|
|
||||||
searchFaces(search: FaceEmbeddingSearch): Promise<FaceSearchResult[]>;
|
|
||||||
searchRandom(size: number, options: AssetSearchOptions): Promise<AssetEntity[]>;
|
|
||||||
upsert(assetId: string, embedding: string): Promise<void>;
|
|
||||||
searchPlaces(placeName: string): Promise<GeodataPlacesEntity[]>;
|
|
||||||
getAssetsByCity(userIds: string[]): Promise<AssetEntity[]>;
|
|
||||||
deleteAllSearchEmbeddings(): Promise<void>;
|
|
||||||
getDimensionSize(): Promise<number>;
|
|
||||||
setDimensionSize(dimSize: number): Promise<void>;
|
|
||||||
getCountries(userIds: string[]): Promise<Array<string | null>>;
|
|
||||||
getStates(userIds: string[], options: GetStatesOptions): Promise<Array<string | null>>;
|
|
||||||
getCities(userIds: string[], options: GetCitiesOptions): Promise<Array<string | null>>;
|
|
||||||
getCameraMakes(userIds: string[], options: GetCameraMakesOptions): Promise<Array<string | null>>;
|
|
||||||
getCameraModels(userIds: string[], options: GetCameraModelsOptions): Promise<Array<string | null>>;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import { Insertable, Updateable } from 'kysely';
|
|
||||||
import { Sessions } from 'src/db';
|
|
||||||
import { SessionEntity } from 'src/entities/session.entity';
|
|
||||||
|
|
||||||
export const ISessionRepository = 'ISessionRepository';
|
|
||||||
|
|
||||||
type E = SessionEntity;
|
|
||||||
export type SessionSearchOptions = { updatedBefore: Date };
|
|
||||||
|
|
||||||
export interface ISessionRepository {
|
|
||||||
search(options: SessionSearchOptions): Promise<SessionEntity[]>;
|
|
||||||
create(dto: Insertable<Sessions>): Promise<SessionEntity>;
|
|
||||||
update(id: string, dto: Updateable<Sessions>): Promise<SessionEntity>;
|
|
||||||
delete(id: string): Promise<void>;
|
|
||||||
getByToken(token: string): Promise<E | undefined>;
|
|
||||||
getByUserId(userId: string): Promise<E[]>;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import { Insertable, Updateable } from 'kysely';
|
|
||||||
import { SharedLinks } from 'src/db';
|
|
||||||
import { SharedLinkEntity } from 'src/entities/shared-link.entity';
|
|
||||||
|
|
||||||
export const ISharedLinkRepository = 'ISharedLinkRepository';
|
|
||||||
|
|
||||||
export interface ISharedLinkRepository {
|
|
||||||
getAll(userId: string): Promise<SharedLinkEntity[]>;
|
|
||||||
get(userId: string, id: string): Promise<SharedLinkEntity | undefined>;
|
|
||||||
getByKey(key: Buffer): Promise<SharedLinkEntity | undefined>;
|
|
||||||
create(entity: Insertable<SharedLinks> & { assetIds?: string[] }): Promise<SharedLinkEntity>;
|
|
||||||
update(entity: Updateable<SharedLinks> & { id: string; assetIds?: string[] }): Promise<SharedLinkEntity>;
|
|
||||||
remove(entity: SharedLinkEntity): Promise<void>;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { Updateable } from 'kysely';
|
|
||||||
import { StackEntity } from 'src/entities/stack.entity';
|
|
||||||
|
|
||||||
export const IStackRepository = 'IStackRepository';
|
|
||||||
|
|
||||||
export interface StackSearch {
|
|
||||||
ownerId: string;
|
|
||||||
primaryAssetId?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IStackRepository {
|
|
||||||
search(query: StackSearch): Promise<StackEntity[]>;
|
|
||||||
create(stack: { ownerId: string; assetIds: string[] }): Promise<StackEntity>;
|
|
||||||
update(id: string, entity: Updateable<StackEntity>): Promise<StackEntity>;
|
|
||||||
delete(id: string): Promise<void>;
|
|
||||||
deleteAll(ids: string[]): Promise<void>;
|
|
||||||
getById(id: string): Promise<StackEntity | undefined>;
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
import { WatchOptions } from 'chokidar';
|
|
||||||
import { Stats } from 'node:fs';
|
|
||||||
import { FileReadOptions } from 'node:fs/promises';
|
|
||||||
import { Readable, Writable } from 'node:stream';
|
|
||||||
import { CrawlOptionsDto, WalkOptionsDto } from 'src/dtos/library.dto';
|
|
||||||
|
|
||||||
export interface ImmichReadStream {
|
|
||||||
stream: Readable;
|
|
||||||
type?: string;
|
|
||||||
length?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ImmichZipStream extends ImmichReadStream {
|
|
||||||
addFile: (inputPath: string, filename: string) => void;
|
|
||||||
finalize: () => Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DiskUsage {
|
|
||||||
available: number;
|
|
||||||
free: number;
|
|
||||||
total: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const IStorageRepository = 'IStorageRepository';
|
|
||||||
|
|
||||||
export interface WatchEvents {
|
|
||||||
onReady(): void;
|
|
||||||
onAdd(path: string): void;
|
|
||||||
onChange(path: string): void;
|
|
||||||
onUnlink(path: string): void;
|
|
||||||
onError(error: Error): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IStorageRepository {
|
|
||||||
createZipStream(): ImmichZipStream;
|
|
||||||
createReadStream(filepath: string, mimeType?: string | null): Promise<ImmichReadStream>;
|
|
||||||
readFile(filepath: string, options?: FileReadOptions<Buffer>): Promise<Buffer>;
|
|
||||||
createFile(filepath: string, buffer: Buffer): Promise<void>;
|
|
||||||
createWriteStream(filepath: string): Writable;
|
|
||||||
createOrOverwriteFile(filepath: string, buffer: Buffer): Promise<void>;
|
|
||||||
overwriteFile(filepath: string, buffer: Buffer): Promise<void>;
|
|
||||||
realpath(filepath: string): Promise<string>;
|
|
||||||
unlink(filepath: string): Promise<void>;
|
|
||||||
unlinkDir(folder: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;
|
|
||||||
removeEmptyDirs(folder: string, self?: boolean): Promise<void>;
|
|
||||||
checkFileExists(filepath: string, mode?: number): Promise<boolean>;
|
|
||||||
mkdirSync(filepath: string): void;
|
|
||||||
checkDiskUsage(folder: string): Promise<DiskUsage>;
|
|
||||||
readdir(folder: string): Promise<string[]>;
|
|
||||||
stat(filepath: string): Promise<Stats>;
|
|
||||||
crawl(options: CrawlOptionsDto): Promise<string[]>;
|
|
||||||
walk(options: WalkOptionsDto): AsyncGenerator<string[]>;
|
|
||||||
copyFile(source: string, target: string): Promise<void>;
|
|
||||||
rename(source: string, target: string): Promise<void>;
|
|
||||||
watch(paths: string[], options: WatchOptions, events: Partial<WatchEvents>): () => Promise<void>;
|
|
||||||
utimes(filepath: string, atime: Date, mtime: Date): Promise<void>;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import { SystemMetadata } from 'src/entities/system-metadata.entity';
|
|
||||||
|
|
||||||
export const ISystemMetadataRepository = 'ISystemMetadataRepository';
|
|
||||||
|
|
||||||
export interface ISystemMetadataRepository {
|
|
||||||
get<T extends keyof SystemMetadata>(key: T): Promise<SystemMetadata[T] | null>;
|
|
||||||
set<T extends keyof SystemMetadata>(key: T, value: SystemMetadata[T]): Promise<void>;
|
|
||||||
delete<T extends keyof SystemMetadata>(key: T): Promise<void>;
|
|
||||||
readFile(filename: string): Promise<string>;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import { TagEntity } from 'src/entities/tag.entity';
|
|
||||||
import { IBulkAsset } from 'src/utils/asset.util';
|
|
||||||
|
|
||||||
export const ITagRepository = 'ITagRepository';
|
|
||||||
|
|
||||||
export type AssetTagItem = { assetId: string; tagId: string };
|
|
||||||
|
|
||||||
export interface ITagRepository extends IBulkAsset {
|
|
||||||
getAll(userId: string): Promise<TagEntity[]>;
|
|
||||||
getByValue(userId: string, value: string): Promise<TagEntity | null>;
|
|
||||||
upsertValue(request: { userId: string; value: string; parent?: TagEntity }): Promise<TagEntity>;
|
|
||||||
|
|
||||||
create(tag: Partial<TagEntity>): Promise<TagEntity>;
|
|
||||||
get(id: string): Promise<TagEntity | null>;
|
|
||||||
update(tag: { id: string } & Partial<TagEntity>): Promise<TagEntity>;
|
|
||||||
delete(id: string): Promise<void>;
|
|
||||||
|
|
||||||
upsertAssetTags({ assetId, tagIds }: { assetId: string; tagIds: string[] }): Promise<void>;
|
|
||||||
upsertAssetIds(items: AssetTagItem[]): Promise<AssetTagItem[]>;
|
|
||||||
deleteEmptyTags(): Promise<void>;
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
import { Insertable, Updateable } from 'kysely';
|
|
||||||
import { Users } from 'src/db';
|
|
||||||
import { UserMetadata } from 'src/entities/user-metadata.entity';
|
|
||||||
import { UserEntity } from 'src/entities/user.entity';
|
|
||||||
|
|
||||||
export interface UserListFilter {
|
|
||||||
withDeleted?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserStatsQueryResponse {
|
|
||||||
userId: string;
|
|
||||||
userName: string;
|
|
||||||
photos: number;
|
|
||||||
videos: number;
|
|
||||||
usage: number;
|
|
||||||
usagePhotos: number;
|
|
||||||
usageVideos: number;
|
|
||||||
quotaSizeInBytes: number | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserFindOptions {
|
|
||||||
withDeleted?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const IUserRepository = 'IUserRepository';
|
|
||||||
|
|
||||||
export interface IUserRepository {
|
|
||||||
get(id: string, options: UserFindOptions): Promise<UserEntity | undefined>;
|
|
||||||
getAdmin(): Promise<UserEntity | undefined>;
|
|
||||||
hasAdmin(): Promise<boolean>;
|
|
||||||
getByEmail(email: string, withPassword?: boolean): Promise<UserEntity | undefined>;
|
|
||||||
getByStorageLabel(storageLabel: string): Promise<UserEntity | undefined>;
|
|
||||||
getByOAuthId(oauthId: string): Promise<UserEntity | undefined>;
|
|
||||||
getDeletedUsers(): Promise<UserEntity[]>;
|
|
||||||
getList(filter?: UserListFilter): Promise<UserEntity[]>;
|
|
||||||
getUserStats(): Promise<UserStatsQueryResponse[]>;
|
|
||||||
create(user: Insertable<Users>): Promise<UserEntity>;
|
|
||||||
update(id: string, user: Updateable<Users>): Promise<UserEntity>;
|
|
||||||
restore(id: string): Promise<UserEntity>;
|
|
||||||
upsertMetadata<T extends keyof UserMetadata>(id: string, item: { key: T; value: UserMetadata[T] }): Promise<void>;
|
|
||||||
deleteMetadata<T extends keyof UserMetadata>(id: string, key: T): Promise<void>;
|
|
||||||
delete(user: UserEntity, hard?: boolean): Promise<UserEntity>;
|
|
||||||
updateUsage(id: string, delta: number): Promise<void>;
|
|
||||||
syncUsage(id?: string): Promise<void>;
|
|
||||||
}
|
|
||||||
@@ -10,14 +10,10 @@ import { UploadFieldName } from 'src/dtos/asset-media.dto';
|
|||||||
import { RouteKey } from 'src/enum';
|
import { RouteKey } from 'src/enum';
|
||||||
import { AuthRequest } from 'src/middleware/auth.guard';
|
import { AuthRequest } from 'src/middleware/auth.guard';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { AssetMediaService, UploadFile } from 'src/services/asset-media.service';
|
import { AssetMediaService } from 'src/services/asset-media.service';
|
||||||
|
import { ImmichFile, UploadFile, UploadFiles } from 'src/types';
|
||||||
import { asRequest, mapToUploadFile } from 'src/utils/asset.util';
|
import { asRequest, mapToUploadFile } from 'src/utils/asset.util';
|
||||||
|
|
||||||
export interface UploadFiles {
|
|
||||||
assetData: ImmichFile[];
|
|
||||||
sidecarData: ImmichFile[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getFile(files: UploadFiles, property: 'assetData' | 'sidecarData') {
|
export function getFile(files: UploadFiles, property: 'assetData' | 'sidecarData') {
|
||||||
const file = files[property]?.[0];
|
const file = files[property]?.[0];
|
||||||
return file ? mapToUploadFile(file) : file;
|
return file ? mapToUploadFile(file) : file;
|
||||||
@@ -30,12 +26,6 @@ export function getFiles(files: UploadFiles) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ImmichFile extends Express.Multer.File {
|
|
||||||
/** sha1 hash of file */
|
|
||||||
uuid: string;
|
|
||||||
checksum: Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
type DiskStorageCallback = (error: Error | null, result: string) => void;
|
type DiskStorageCallback = (error: Error | null, result: string) => void;
|
||||||
|
|
||||||
type ImmichMulterFile = Express.Multer.File & { uuid: string };
|
type ImmichMulterFile = Express.Multer.File & { uuid: string };
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DatabaseExtension } from 'src/interfaces/database.interface';
|
import { DatabaseExtension } from 'src/enum';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DatabaseExtension } from 'src/interfaces/database.interface';
|
import { DatabaseExtension } from 'src/enum';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { DatabaseExtension } from 'src/interfaces/database.interface';
|
import { DatabaseExtension } from 'src/enum';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class NullableDates1737845696644 implements MigrationInterface {
|
||||||
|
name = 'NullableDates1737845696644'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "assets" ALTER COLUMN "fileCreatedAt" DROP NOT NULL`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "assets" ALTER COLUMN "localDateTime" DROP NOT NULL`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "assets" ALTER COLUMN "fileModifiedAt" DROP NOT NULL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "assets" ALTER COLUMN "fileModifiedAt" SET NOT NULL`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "assets" ALTER COLUMN "localDateTime" SET NOT NULL`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "assets" ALTER COLUMN "fileCreatedAt" SET NOT NULL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -43,3 +43,6 @@ where
|
|||||||
and "activity"."albumId" = $2
|
and "activity"."albumId" = $2
|
||||||
and "activity"."isLiked" = $3
|
and "activity"."isLiked" = $3
|
||||||
and "assets"."deletedAt" is null
|
and "assets"."deletedAt" is null
|
||||||
|
and "assets"."fileCreatedAt" is not null
|
||||||
|
and "assets"."fileModifiedAt" is not null
|
||||||
|
and "assets"."localDateTime" is not null
|
||||||
|
|||||||
@@ -3,29 +3,28 @@
|
|||||||
-- ApiKeyRepository.getKey
|
-- ApiKeyRepository.getKey
|
||||||
select
|
select
|
||||||
"api_keys"."id",
|
"api_keys"."id",
|
||||||
"api_keys"."key",
|
|
||||||
"api_keys"."userId",
|
|
||||||
"api_keys"."permissions",
|
"api_keys"."permissions",
|
||||||
to_json("user") as "user"
|
(
|
||||||
from
|
|
||||||
"api_keys"
|
|
||||||
inner join lateral (
|
|
||||||
select
|
select
|
||||||
"users".*,
|
to_json(obj)
|
||||||
|
from
|
||||||
(
|
(
|
||||||
select
|
select
|
||||||
array_agg("user_metadata") as "metadata"
|
"users"."id",
|
||||||
|
"users"."name",
|
||||||
|
"users"."email",
|
||||||
|
"users"."isAdmin",
|
||||||
|
"users"."quotaUsageInBytes",
|
||||||
|
"users"."quotaSizeInBytes"
|
||||||
from
|
from
|
||||||
"user_metadata"
|
"users"
|
||||||
where
|
where
|
||||||
"users"."id" = "user_metadata"."userId"
|
"users"."id" = "api_keys"."userId"
|
||||||
) as "metadata"
|
and "users"."deletedAt" is null
|
||||||
from
|
) as obj
|
||||||
"users"
|
) as "user"
|
||||||
where
|
from
|
||||||
"users"."id" = "api_keys"."userId"
|
"api_keys"
|
||||||
and "users"."deletedAt" is null
|
|
||||||
) as "user" on true
|
|
||||||
where
|
where
|
||||||
"api_keys"."key" = $1
|
"api_keys"."key" = $1
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,9 @@ where
|
|||||||
"ownerId" = $1::uuid
|
"ownerId" = $1::uuid
|
||||||
and "deviceId" = $2
|
and "deviceId" = $2
|
||||||
and "isVisible" = $3
|
and "isVisible" = $3
|
||||||
|
and "assets"."fileCreatedAt" is not null
|
||||||
|
and "assets"."fileModifiedAt" is not null
|
||||||
|
and "assets"."localDateTime" is not null
|
||||||
and "deletedAt" is null
|
and "deletedAt" is null
|
||||||
|
|
||||||
-- AssetRepository.getLivePhotoCount
|
-- AssetRepository.getLivePhotoCount
|
||||||
@@ -260,6 +263,9 @@ with
|
|||||||
where
|
where
|
||||||
"assets"."deletedAt" is null
|
"assets"."deletedAt" is null
|
||||||
and "assets"."isVisible" = $2
|
and "assets"."isVisible" = $2
|
||||||
|
and "assets"."fileCreatedAt" is not null
|
||||||
|
and "assets"."fileModifiedAt" is not null
|
||||||
|
and "assets"."localDateTime" is not null
|
||||||
)
|
)
|
||||||
select
|
select
|
||||||
"timeBucket",
|
"timeBucket",
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ where
|
|||||||
and "assets"."isFavorite" = $4
|
and "assets"."isFavorite" = $4
|
||||||
and "assets"."isArchived" = $5
|
and "assets"."isArchived" = $5
|
||||||
and "assets"."deletedAt" is null
|
and "assets"."deletedAt" is null
|
||||||
|
and "assets"."fileCreatedAt" is not null
|
||||||
|
and "assets"."fileModifiedAt" is not null
|
||||||
|
and "assets"."localDateTime" is not null
|
||||||
order by
|
order by
|
||||||
"assets"."fileCreatedAt" desc
|
"assets"."fileCreatedAt" desc
|
||||||
limit
|
limit
|
||||||
@@ -34,6 +37,9 @@ offset
|
|||||||
and "assets"."isFavorite" = $4
|
and "assets"."isFavorite" = $4
|
||||||
and "assets"."isArchived" = $5
|
and "assets"."isArchived" = $5
|
||||||
and "assets"."deletedAt" is null
|
and "assets"."deletedAt" is null
|
||||||
|
and "assets"."fileCreatedAt" is not null
|
||||||
|
and "assets"."fileModifiedAt" is not null
|
||||||
|
and "assets"."localDateTime" is not null
|
||||||
and "assets"."id" < $6
|
and "assets"."id" < $6
|
||||||
order by
|
order by
|
||||||
random()
|
random()
|
||||||
@@ -54,6 +60,9 @@ union all
|
|||||||
and "assets"."isFavorite" = $11
|
and "assets"."isFavorite" = $11
|
||||||
and "assets"."isArchived" = $12
|
and "assets"."isArchived" = $12
|
||||||
and "assets"."deletedAt" is null
|
and "assets"."deletedAt" is null
|
||||||
|
and "assets"."fileCreatedAt" is not null
|
||||||
|
and "assets"."fileModifiedAt" is not null
|
||||||
|
and "assets"."localDateTime" is not null
|
||||||
and "assets"."id" > $13
|
and "assets"."id" > $13
|
||||||
order by
|
order by
|
||||||
random()
|
random()
|
||||||
@@ -77,6 +86,9 @@ where
|
|||||||
and "assets"."isFavorite" = $4
|
and "assets"."isFavorite" = $4
|
||||||
and "assets"."isArchived" = $5
|
and "assets"."isArchived" = $5
|
||||||
and "assets"."deletedAt" is null
|
and "assets"."deletedAt" is null
|
||||||
|
and "assets"."fileCreatedAt" is not null
|
||||||
|
and "assets"."fileModifiedAt" is not null
|
||||||
|
and "assets"."localDateTime" is not null
|
||||||
order by
|
order by
|
||||||
smart_search.embedding <=> $6
|
smart_search.embedding <=> $6
|
||||||
limit
|
limit
|
||||||
|
|||||||
@@ -10,41 +10,29 @@ where
|
|||||||
|
|
||||||
-- SessionRepository.getByToken
|
-- SessionRepository.getByToken
|
||||||
select
|
select
|
||||||
"sessions".*,
|
"sessions"."id",
|
||||||
to_json("user") as "user"
|
"sessions"."updatedAt",
|
||||||
from
|
(
|
||||||
"sessions"
|
|
||||||
inner join lateral (
|
|
||||||
select
|
select
|
||||||
"id",
|
to_json(obj)
|
||||||
"email",
|
from
|
||||||
"createdAt",
|
|
||||||
"profileImagePath",
|
|
||||||
"isAdmin",
|
|
||||||
"shouldChangePassword",
|
|
||||||
"deletedAt",
|
|
||||||
"oauthId",
|
|
||||||
"updatedAt",
|
|
||||||
"storageLabel",
|
|
||||||
"name",
|
|
||||||
"quotaSizeInBytes",
|
|
||||||
"quotaUsageInBytes",
|
|
||||||
"status",
|
|
||||||
"profileChangedAt",
|
|
||||||
(
|
(
|
||||||
select
|
select
|
||||||
array_agg("user_metadata") as "metadata"
|
"users"."id",
|
||||||
|
"users"."name",
|
||||||
|
"users"."email",
|
||||||
|
"users"."isAdmin",
|
||||||
|
"users"."quotaUsageInBytes",
|
||||||
|
"users"."quotaSizeInBytes"
|
||||||
from
|
from
|
||||||
"user_metadata"
|
"users"
|
||||||
where
|
where
|
||||||
"users"."id" = "user_metadata"."userId"
|
"users"."id" = "sessions"."userId"
|
||||||
) as "metadata"
|
and "users"."deletedAt" is null
|
||||||
from
|
) as obj
|
||||||
"users"
|
) as "user"
|
||||||
where
|
from
|
||||||
"users"."id" = "sessions"."userId"
|
"sessions"
|
||||||
and "users"."deletedAt" is null
|
|
||||||
) as "user" on true
|
|
||||||
where
|
where
|
||||||
"sessions"."token" = $1
|
"sessions"."token" = $1
|
||||||
|
|
||||||
|
|||||||
@@ -153,12 +153,19 @@ where
|
|||||||
"shared_links"."type" = $2
|
"shared_links"."type" = $2
|
||||||
or "album"."id" is not null
|
or "album"."id" is not null
|
||||||
)
|
)
|
||||||
|
and "shared_links"."albumId" = $3
|
||||||
order by
|
order by
|
||||||
"shared_links"."createdAt" desc
|
"shared_links"."createdAt" desc
|
||||||
|
|
||||||
-- SharedLinkRepository.getByKey
|
-- SharedLinkRepository.getByKey
|
||||||
select
|
select
|
||||||
"shared_links".*,
|
"shared_links"."id",
|
||||||
|
"shared_links"."userId",
|
||||||
|
"shared_links"."expiresAt",
|
||||||
|
"shared_links"."showExif",
|
||||||
|
"shared_links"."allowUpload",
|
||||||
|
"shared_links"."allowDownload",
|
||||||
|
"shared_links"."password",
|
||||||
(
|
(
|
||||||
select
|
select
|
||||||
to_json(obj)
|
to_json(obj)
|
||||||
@@ -166,20 +173,11 @@ select
|
|||||||
(
|
(
|
||||||
select
|
select
|
||||||
"users"."id",
|
"users"."id",
|
||||||
"users"."email",
|
|
||||||
"users"."createdAt",
|
|
||||||
"users"."profileImagePath",
|
|
||||||
"users"."isAdmin",
|
|
||||||
"users"."shouldChangePassword",
|
|
||||||
"users"."deletedAt",
|
|
||||||
"users"."oauthId",
|
|
||||||
"users"."updatedAt",
|
|
||||||
"users"."storageLabel",
|
|
||||||
"users"."name",
|
"users"."name",
|
||||||
"users"."quotaSizeInBytes",
|
"users"."email",
|
||||||
|
"users"."isAdmin",
|
||||||
"users"."quotaUsageInBytes",
|
"users"."quotaUsageInBytes",
|
||||||
"users"."status",
|
"users"."quotaSizeInBytes"
|
||||||
"users"."profileChangedAt"
|
|
||||||
from
|
from
|
||||||
"users"
|
"users"
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ where
|
|||||||
and "isVisible" = $3
|
and "isVisible" = $3
|
||||||
and "isArchived" = $4
|
and "isArchived" = $4
|
||||||
and "deletedAt" is null
|
and "deletedAt" is null
|
||||||
|
and "fileModifiedAt" is not null
|
||||||
|
and "fileModifiedAt" is not null
|
||||||
|
and "localDateTime" is not null
|
||||||
|
|
||||||
-- ViewRepository.getAssetsByOriginalPath
|
-- ViewRepository.getAssetsByOriginalPath
|
||||||
select
|
select
|
||||||
@@ -23,6 +26,9 @@ where
|
|||||||
and "isVisible" = $2
|
and "isVisible" = $2
|
||||||
and "isArchived" = $3
|
and "isArchived" = $3
|
||||||
and "deletedAt" is null
|
and "deletedAt" is null
|
||||||
|
and "fileModifiedAt" is not null
|
||||||
|
and "fileModifiedAt" is not null
|
||||||
|
and "localDateTime" is not null
|
||||||
and "originalPath" like $4
|
and "originalPath" like $4
|
||||||
and "originalPath" not like $5
|
and "originalPath" not like $5
|
||||||
order by
|
order by
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ export class ActivityRepository {
|
|||||||
.where('activity.albumId', '=', albumId)
|
.where('activity.albumId', '=', albumId)
|
||||||
.where('activity.isLiked', '=', false)
|
.where('activity.isLiked', '=', false)
|
||||||
.where('assets.deletedAt', 'is', null)
|
.where('assets.deletedAt', 'is', null)
|
||||||
|
.where('assets.fileCreatedAt', 'is not', null)
|
||||||
|
.where('assets.fileModifiedAt', 'is not', null)
|
||||||
|
.where('assets.localDateTime', 'is not', null)
|
||||||
.executeTakeFirstOrThrow();
|
.executeTakeFirstOrThrow();
|
||||||
|
|
||||||
return count as number;
|
return count as number;
|
||||||
|
|||||||
@@ -6,7 +6,17 @@ import { Albums, DB } from 'src/db';
|
|||||||
import { Chunked, ChunkedArray, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
import { Chunked, ChunkedArray, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AlbumUserCreateDto } from 'src/dtos/album.dto';
|
import { AlbumUserCreateDto } from 'src/dtos/album.dto';
|
||||||
import { AlbumEntity } from 'src/entities/album.entity';
|
import { AlbumEntity } from 'src/entities/album.entity';
|
||||||
import { AlbumAssetCount, AlbumInfoOptions, IAlbumRepository } from 'src/interfaces/album.interface';
|
|
||||||
|
export interface AlbumAssetCount {
|
||||||
|
albumId: string;
|
||||||
|
assetCount: number;
|
||||||
|
startDate: Date | null;
|
||||||
|
endDate: Date | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AlbumInfoOptions {
|
||||||
|
withAssets: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
const userColumns = [
|
const userColumns = [
|
||||||
'id',
|
'id',
|
||||||
@@ -71,7 +81,7 @@ const withAssets = (eb: ExpressionBuilder<DB, 'albums'>) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AlbumRepository implements IAlbumRepository {
|
export class AlbumRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
|
|
||||||
@GenerateSql({ params: [DummyValue.UUID, { withAssets: true }] })
|
@GenerateSql({ params: [DummyValue.UUID, { withAssets: true }] })
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Insertable, Kysely, Updateable } from 'kysely';
|
import { Insertable, Kysely, Updateable } from 'kysely';
|
||||||
|
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
|
import { columns } from 'src/database';
|
||||||
import { ApiKeys, DB } from 'src/db';
|
import { ApiKeys, DB } from 'src/db';
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { asUuid } from 'src/utils/database';
|
import { asUuid } from 'src/utils/database';
|
||||||
|
|
||||||
const columns = ['id', 'name', 'userId', 'createdAt', 'updatedAt', 'permissions'] as const;
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ApiKeyRepository {
|
export class ApiKeyRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
@@ -33,29 +33,15 @@ export class ApiKeyRepository {
|
|||||||
getKey(hashedToken: string) {
|
getKey(hashedToken: string) {
|
||||||
return this.db
|
return this.db
|
||||||
.selectFrom('api_keys')
|
.selectFrom('api_keys')
|
||||||
.innerJoinLateral(
|
.select((eb) => [
|
||||||
(eb) =>
|
...columns.authApiKey,
|
||||||
|
jsonObjectFrom(
|
||||||
eb
|
eb
|
||||||
.selectFrom('users')
|
.selectFrom('users')
|
||||||
.selectAll('users')
|
.select(columns.authUser)
|
||||||
.select((eb) =>
|
|
||||||
eb
|
|
||||||
.selectFrom('user_metadata')
|
|
||||||
.whereRef('users.id', '=', 'user_metadata.userId')
|
|
||||||
.select((eb) => eb.fn('array_agg', [eb.table('user_metadata')]).as('metadata'))
|
|
||||||
.as('metadata'),
|
|
||||||
)
|
|
||||||
.whereRef('users.id', '=', 'api_keys.userId')
|
.whereRef('users.id', '=', 'api_keys.userId')
|
||||||
.where('users.deletedAt', 'is', null)
|
.where('users.deletedAt', 'is', null),
|
||||||
.as('user'),
|
).as('user'),
|
||||||
(join) => join.onTrue(),
|
|
||||||
)
|
|
||||||
.select((eb) => [
|
|
||||||
'api_keys.id',
|
|
||||||
'api_keys.key',
|
|
||||||
'api_keys.userId',
|
|
||||||
'api_keys.permissions',
|
|
||||||
eb.fn.toJson('user').as('user'),
|
|
||||||
])
|
])
|
||||||
.where('api_keys.key', '=', hashedToken)
|
.where('api_keys.key', '=', hashedToken)
|
||||||
.executeTakeFirst();
|
.executeTakeFirst();
|
||||||
@@ -65,7 +51,7 @@ export class ApiKeyRepository {
|
|||||||
getById(userId: string, id: string) {
|
getById(userId: string, id: string) {
|
||||||
return this.db
|
return this.db
|
||||||
.selectFrom('api_keys')
|
.selectFrom('api_keys')
|
||||||
.select(columns)
|
.select(columns.apiKey)
|
||||||
.where('id', '=', asUuid(id))
|
.where('id', '=', asUuid(id))
|
||||||
.where('userId', '=', userId)
|
.where('userId', '=', userId)
|
||||||
.executeTakeFirst();
|
.executeTakeFirst();
|
||||||
@@ -75,7 +61,7 @@ export class ApiKeyRepository {
|
|||||||
getByUserId(userId: string) {
|
getByUserId(userId: string) {
|
||||||
return this.db
|
return this.db
|
||||||
.selectFrom('api_keys')
|
.selectFrom('api_keys')
|
||||||
.select(columns)
|
.select(columns.apiKey)
|
||||||
.where('userId', '=', userId)
|
.where('userId', '=', userId)
|
||||||
.orderBy('createdAt', 'desc')
|
.orderBy('createdAt', 'desc')
|
||||||
.execute();
|
.execute();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { AssetFiles, AssetJobStatus, Assets, DB, Exif } from 'src/db';
|
|||||||
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
|
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
AssetEntity,
|
AssetEntity,
|
||||||
|
AssetEntityPlaceholder,
|
||||||
hasPeople,
|
hasPeople,
|
||||||
searchAssetBuilder,
|
searchAssetBuilder,
|
||||||
truncatedDate,
|
truncatedDate,
|
||||||
@@ -21,34 +22,138 @@ import {
|
|||||||
withTagId,
|
withTagId,
|
||||||
withTags,
|
withTags,
|
||||||
} from 'src/entities/asset.entity';
|
} from 'src/entities/asset.entity';
|
||||||
import { AssetFileType, AssetStatus, AssetType } from 'src/enum';
|
import { AssetFileType, AssetOrder, AssetStatus, AssetType } from 'src/enum';
|
||||||
import {
|
|
||||||
AssetDeltaSyncOptions,
|
|
||||||
AssetExploreFieldOptions,
|
|
||||||
AssetFullSyncOptions,
|
|
||||||
AssetGetByChecksumOptions,
|
|
||||||
AssetStats,
|
|
||||||
AssetStatsOptions,
|
|
||||||
AssetUpdateDuplicateOptions,
|
|
||||||
DayOfYearAssets,
|
|
||||||
DuplicateGroup,
|
|
||||||
GetByIdsRelations,
|
|
||||||
IAssetRepository,
|
|
||||||
LivePhotoSearchOptions,
|
|
||||||
MonthDay,
|
|
||||||
TimeBucketItem,
|
|
||||||
TimeBucketOptions,
|
|
||||||
TimeBucketSize,
|
|
||||||
WithProperty,
|
|
||||||
WithoutProperty,
|
|
||||||
} from 'src/interfaces/asset.interface';
|
|
||||||
import { AssetSearchOptions, SearchExploreItem, SearchExploreItemSet } from 'src/interfaces/search.interface';
|
|
||||||
import { MapMarker, MapMarkerSearchOptions } from 'src/repositories/map.repository';
|
import { MapMarker, MapMarkerSearchOptions } from 'src/repositories/map.repository';
|
||||||
|
import { AssetSearchOptions, SearchExploreItem, SearchExploreItemSet } from 'src/repositories/search.repository';
|
||||||
import { anyUuid, asUuid, mapUpsertColumns } from 'src/utils/database';
|
import { anyUuid, asUuid, mapUpsertColumns } from 'src/utils/database';
|
||||||
import { Paginated, PaginationOptions, paginationHelper } from 'src/utils/pagination';
|
import { Paginated, PaginationOptions, paginationHelper } from 'src/utils/pagination';
|
||||||
|
|
||||||
|
export type AssetStats = Record<AssetType, number>;
|
||||||
|
|
||||||
|
export interface AssetStatsOptions {
|
||||||
|
isFavorite?: boolean;
|
||||||
|
isArchived?: boolean;
|
||||||
|
isTrashed?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LivePhotoSearchOptions {
|
||||||
|
ownerId: string;
|
||||||
|
libraryId?: string | null;
|
||||||
|
livePhotoCID: string;
|
||||||
|
otherAssetId: string;
|
||||||
|
type: AssetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum WithoutProperty {
|
||||||
|
THUMBNAIL = 'thumbnail',
|
||||||
|
ENCODED_VIDEO = 'encoded-video',
|
||||||
|
EXIF = 'exif',
|
||||||
|
SMART_SEARCH = 'smart-search',
|
||||||
|
DUPLICATE = 'duplicate',
|
||||||
|
FACES = 'faces',
|
||||||
|
SIDECAR = 'sidecar',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum WithProperty {
|
||||||
|
SIDECAR = 'sidecar',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum TimeBucketSize {
|
||||||
|
DAY = 'DAY',
|
||||||
|
MONTH = 'MONTH',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AssetBuilderOptions {
|
||||||
|
isArchived?: boolean;
|
||||||
|
isFavorite?: boolean;
|
||||||
|
isTrashed?: boolean;
|
||||||
|
isDuplicate?: boolean;
|
||||||
|
albumId?: string;
|
||||||
|
tagId?: string;
|
||||||
|
personId?: string;
|
||||||
|
userIds?: string[];
|
||||||
|
withStacked?: boolean;
|
||||||
|
exifInfo?: boolean;
|
||||||
|
status?: AssetStatus;
|
||||||
|
assetType?: AssetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TimeBucketOptions extends AssetBuilderOptions {
|
||||||
|
size: TimeBucketSize;
|
||||||
|
order?: AssetOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TimeBucketItem {
|
||||||
|
timeBucket: string;
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MonthDay {
|
||||||
|
day: number;
|
||||||
|
month: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AssetExploreFieldOptions {
|
||||||
|
maxFields: number;
|
||||||
|
minAssetsPerField: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AssetFullSyncOptions {
|
||||||
|
ownerId: string;
|
||||||
|
lastId?: string;
|
||||||
|
updatedUntil: Date;
|
||||||
|
limit: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AssetDeltaSyncOptions {
|
||||||
|
userIds: string[];
|
||||||
|
updatedAfter: Date;
|
||||||
|
limit: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AssetUpdateDuplicateOptions {
|
||||||
|
targetDuplicateId: string | null;
|
||||||
|
assetIds: string[];
|
||||||
|
duplicateIds: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpsertFileOptions {
|
||||||
|
assetId: string;
|
||||||
|
type: AssetFileType;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AssetGetByChecksumOptions {
|
||||||
|
ownerId: string;
|
||||||
|
checksum: Buffer;
|
||||||
|
libraryId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AssetPathEntity = Pick<AssetEntity, 'id' | 'originalPath' | 'isOffline'>;
|
||||||
|
|
||||||
|
export interface GetByIdsRelations {
|
||||||
|
exifInfo?: boolean;
|
||||||
|
faces?: { person?: boolean };
|
||||||
|
files?: boolean;
|
||||||
|
library?: boolean;
|
||||||
|
owner?: boolean;
|
||||||
|
smartSearch?: boolean;
|
||||||
|
stack?: { assets?: boolean };
|
||||||
|
tags?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DuplicateGroup {
|
||||||
|
duplicateId: string;
|
||||||
|
assets: AssetEntity[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DayOfYearAssets {
|
||||||
|
yearsAgo: number;
|
||||||
|
assets: AssetEntity[];
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AssetRepository implements IAssetRepository {
|
export class AssetRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
|
|
||||||
async upsertExif(exif: Insertable<Exif>): Promise<void> {
|
async upsertExif(exif: Insertable<Exif>): Promise<void> {
|
||||||
@@ -79,8 +184,12 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
create(asset: Insertable<Assets>): Promise<AssetEntity> {
|
create(asset: Insertable<Assets>): Promise<AssetEntityPlaceholder> {
|
||||||
return this.db.insertInto('assets').values(asset).returningAll().executeTakeFirst() as any as Promise<AssetEntity>;
|
return this.db
|
||||||
|
.insertInto('assets')
|
||||||
|
.values(asset)
|
||||||
|
.returningAll()
|
||||||
|
.executeTakeFirst() as any as Promise<AssetEntityPlaceholder>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [DummyValue.UUID, { day: 1, month: 1 }] })
|
@GenerateSql({ params: [DummyValue.UUID, { day: 1, month: 1 }] })
|
||||||
@@ -291,6 +400,9 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
.where('ownerId', '=', asUuid(ownerId))
|
.where('ownerId', '=', asUuid(ownerId))
|
||||||
.where('deviceId', '=', deviceId)
|
.where('deviceId', '=', deviceId)
|
||||||
.where('isVisible', '=', true)
|
.where('isVisible', '=', true)
|
||||||
|
.where('assets.fileCreatedAt', 'is not', null)
|
||||||
|
.where('assets.fileModifiedAt', 'is not', null)
|
||||||
|
.where('assets.localDateTime', 'is not', null)
|
||||||
.where('deletedAt', 'is', null)
|
.where('deletedAt', 'is', null)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
@@ -458,7 +570,10 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
.where('job_status.duplicatesDetectedAt', 'is', null)
|
.where('job_status.duplicatesDetectedAt', 'is', null)
|
||||||
.where('job_status.previewAt', 'is not', null)
|
.where('job_status.previewAt', 'is not', null)
|
||||||
.where((eb) => eb.exists(eb.selectFrom('smart_search').where('assetId', '=', eb.ref('assets.id'))))
|
.where((eb) => eb.exists(eb.selectFrom('smart_search').where('assetId', '=', eb.ref('assets.id'))))
|
||||||
.where('assets.isVisible', '=', true),
|
.where('assets.isVisible', '=', true)
|
||||||
|
.where('assets.fileCreatedAt', 'is not', null)
|
||||||
|
.where('assets.fileModifiedAt', 'is not', null)
|
||||||
|
.where('assets.localDateTime', 'is not', null),
|
||||||
)
|
)
|
||||||
.$if(property === WithoutProperty.ENCODED_VIDEO, (qb) =>
|
.$if(property === WithoutProperty.ENCODED_VIDEO, (qb) =>
|
||||||
qb
|
qb
|
||||||
@@ -524,7 +639,7 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
.executeTakeFirst() as Promise<AssetEntity | undefined>;
|
.executeTakeFirst() as Promise<AssetEntity | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMapMarkers(ownerIds: string[], options: MapMarkerSearchOptions = {}): Promise<MapMarker[]> {
|
private getMapMarkers(ownerIds: string[], options: MapMarkerSearchOptions = {}): Promise<MapMarker[]> {
|
||||||
const { isArchived, isFavorite, fileCreatedAfter, fileCreatedBefore } = options;
|
const { isArchived, isFavorite, fileCreatedAfter, fileCreatedBefore } = options;
|
||||||
|
|
||||||
return this.db
|
return this.db
|
||||||
@@ -552,6 +667,9 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
.select((eb) => eb.fn.countAll().filterWhere('type', '=', AssetType.VIDEO).as(AssetType.VIDEO))
|
.select((eb) => eb.fn.countAll().filterWhere('type', '=', AssetType.VIDEO).as(AssetType.VIDEO))
|
||||||
.select((eb) => eb.fn.countAll().filterWhere('type', '=', AssetType.OTHER).as(AssetType.OTHER))
|
.select((eb) => eb.fn.countAll().filterWhere('type', '=', AssetType.OTHER).as(AssetType.OTHER))
|
||||||
.where('ownerId', '=', asUuid(ownerId))
|
.where('ownerId', '=', asUuid(ownerId))
|
||||||
|
.where('assets.fileCreatedAt', 'is not', null)
|
||||||
|
.where('assets.fileModifiedAt', 'is not', null)
|
||||||
|
.where('assets.localDateTime', 'is not', null)
|
||||||
.where('isVisible', '=', true)
|
.where('isVisible', '=', true)
|
||||||
.$if(isArchived !== undefined, (qb) => qb.where('isArchived', '=', isArchived!))
|
.$if(isArchived !== undefined, (qb) => qb.where('isArchived', '=', isArchived!))
|
||||||
.$if(isFavorite !== undefined, (qb) => qb.where('isFavorite', '=', isFavorite!))
|
.$if(isFavorite !== undefined, (qb) => qb.where('isFavorite', '=', isFavorite!))
|
||||||
@@ -584,6 +702,9 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
.$if(!!options.isTrashed, (qb) => qb.where('assets.status', '!=', AssetStatus.DELETED))
|
.$if(!!options.isTrashed, (qb) => qb.where('assets.status', '!=', AssetStatus.DELETED))
|
||||||
.where('assets.deletedAt', options.isTrashed ? 'is not' : 'is', null)
|
.where('assets.deletedAt', options.isTrashed ? 'is not' : 'is', null)
|
||||||
.where('assets.isVisible', '=', true)
|
.where('assets.isVisible', '=', true)
|
||||||
|
.where('assets.fileCreatedAt', 'is not', null)
|
||||||
|
.where('assets.fileModifiedAt', 'is not', null)
|
||||||
|
.where('assets.localDateTime', 'is not', null)
|
||||||
.$if(!!options.albumId, (qb) =>
|
.$if(!!options.albumId, (qb) =>
|
||||||
qb
|
qb
|
||||||
.innerJoin('albums_assets_assets', 'assets.id', 'albums_assets_assets.assetsId')
|
.innerJoin('albums_assets_assets', 'assets.id', 'albums_assets_assets.assetsId')
|
||||||
|
|||||||
@@ -13,9 +13,16 @@ import { Notice } from 'postgres';
|
|||||||
import { citiesFile, excludePaths, IWorker } from 'src/constants';
|
import { citiesFile, excludePaths, IWorker } from 'src/constants';
|
||||||
import { Telemetry } from 'src/decorators';
|
import { Telemetry } from 'src/decorators';
|
||||||
import { EnvDto } from 'src/dtos/env.dto';
|
import { EnvDto } from 'src/dtos/env.dto';
|
||||||
import { ImmichEnvironment, ImmichHeader, ImmichTelemetry, ImmichWorker, LogLevel } from 'src/enum';
|
import {
|
||||||
import { DatabaseConnectionParams, DatabaseExtension, VectorExtension } from 'src/interfaces/database.interface';
|
DatabaseExtension,
|
||||||
import { QueueName } from 'src/interfaces/job.interface';
|
ImmichEnvironment,
|
||||||
|
ImmichHeader,
|
||||||
|
ImmichTelemetry,
|
||||||
|
ImmichWorker,
|
||||||
|
LogLevel,
|
||||||
|
QueueName,
|
||||||
|
} from 'src/enum';
|
||||||
|
import { DatabaseConnectionParams, VectorExtension } from 'src/types';
|
||||||
import { setDifference } from 'src/utils/set';
|
import { setDifference } from 'src/utils/set';
|
||||||
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js';
|
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions.js';
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,10 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { compareSync, hash } from 'bcrypt';
|
import { compareSync, hash } from 'bcrypt';
|
||||||
import { createHash, createPublicKey, createVerify, randomBytes, randomUUID } from 'node:crypto';
|
import { createHash, createPublicKey, createVerify, randomBytes, randomUUID } from 'node:crypto';
|
||||||
import { createReadStream } from 'node:fs';
|
import { createReadStream } from 'node:fs';
|
||||||
import { ICryptoRepository } from 'src/interfaces/crypto.interface';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CryptoRepository implements ICryptoRepository {
|
export class CryptoRepository {
|
||||||
randomUUID() {
|
randomUUID(): string {
|
||||||
return randomUUID();
|
return randomUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,26 +4,18 @@ import AsyncLock from 'async-lock';
|
|||||||
import { Kysely, sql } from 'kysely';
|
import { Kysely, sql } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
import { POSTGRES_VERSION_RANGE, VECTOR_VERSION_RANGE, VECTORS_VERSION_RANGE } from 'src/constants';
|
import { EXTENSION_NAMES, POSTGRES_VERSION_RANGE, VECTOR_VERSION_RANGE, VECTORS_VERSION_RANGE } from 'src/constants';
|
||||||
import { DB } from 'src/db';
|
import { DB } from 'src/db';
|
||||||
import {
|
import { DatabaseExtension, DatabaseLock, VectorIndex } from 'src/enum';
|
||||||
DatabaseExtension,
|
|
||||||
DatabaseLock,
|
|
||||||
EXTENSION_NAMES,
|
|
||||||
ExtensionVersion,
|
|
||||||
IDatabaseRepository,
|
|
||||||
VectorExtension,
|
|
||||||
VectorIndex,
|
|
||||||
VectorUpdateResult,
|
|
||||||
} from 'src/interfaces/database.interface';
|
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
|
import { ExtensionVersion, VectorExtension, VectorUpdateResult } from 'src/types';
|
||||||
import { UPSERT_COLUMNS } from 'src/utils/database';
|
import { UPSERT_COLUMNS } from 'src/utils/database';
|
||||||
import { isValidInteger } from 'src/validation';
|
import { isValidInteger } from 'src/validation';
|
||||||
import { DataSource, EntityManager, EntityMetadata, QueryRunner } from 'typeorm';
|
import { DataSource, EntityManager, EntityMetadata, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DatabaseRepository implements IDatabaseRepository {
|
export class DatabaseRepository {
|
||||||
private vectorExtension: VectorExtension;
|
private vectorExtension: VectorExtension;
|
||||||
private readonly asyncLock = new AsyncLock();
|
private readonly asyncLock = new AsyncLock();
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user