Merge remote-tracking branch 'origin/main' into service_worker_appstatic

This commit is contained in:
Min Idzelis 2025-05-16 00:51:33 +00:00
commit 203b097635
325 changed files with 5463 additions and 3245 deletions

2
.github/.nvmrc vendored
View File

@ -1 +1 @@
22.14.0 22.15.0

View File

@ -35,12 +35,12 @@ jobs:
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }} should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- id: found_paths - id: found_paths
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with: with:
filters: | filters: |
mobile: mobile:
@ -61,19 +61,19 @@ jobs:
runs-on: macos-14 runs-on: macos-14
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: ${{ inputs.ref || github.sha }} ref: ${{ inputs.ref || github.sha }}
persist-credentials: false persist-credentials: false
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4 - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with: with:
distribution: 'zulu' distribution: 'zulu'
java-version: '17' java-version: '17'
cache: 'gradle' cache: 'gradle'
- name: Setup Flutter SDK - name: Setup Flutter SDK
uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2 uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2.19.0
with: with:
channel: 'stable' channel: 'stable'
flutter-version-file: ./mobile/pubspec.yaml flutter-version-file: ./mobile/pubspec.yaml
@ -104,7 +104,7 @@ jobs:
flutter build apk --release --split-per-abi --target-platform android-arm,android-arm64,android-x64 flutter build apk --release --split-per-abi --target-platform android-arm,android-arm64,android-x64
- name: Publish Android Artifact - name: Publish Android Artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: release-apk-signed name: release-apk-signed
path: mobile/build/app/outputs/flutter-apk/*.apk path: mobile/build/app/outputs/flutter-apk/*.apk

View File

@ -19,7 +19,7 @@ jobs:
actions: write actions: write
steps: steps:
- name: Check out code - name: Check out code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false

View File

@ -29,12 +29,12 @@ jobs:
working-directory: ./cli working-directory: ./cli
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
# Setup .npmrc file to publish to npm # Setup .npmrc file to publish to npm
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './cli/.nvmrc' node-version-file: './cli/.nvmrc'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'
@ -59,7 +59,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
@ -70,7 +70,7 @@ jobs:
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3 uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
if: ${{ !github.event.pull_request.head.repo.fork }} if: ${{ !github.event.pull_request.head.repo.fork }}
with: with:
registry: ghcr.io registry: ghcr.io
@ -85,7 +85,7 @@ jobs:
- name: Generate docker image tags - name: Generate docker image tags
id: metadata id: metadata
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5 uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with: with:
flavor: | flavor: |
latest=false latest=false

View File

@ -44,13 +44,13 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3 uses: github/codeql-action/init@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@ -63,7 +63,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3 uses: github/codeql-action/autobuild@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@ -76,6 +76,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh # ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3 uses: github/codeql-action/analyze@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
with: with:
category: '/language:${{matrix.language}}' category: '/language:${{matrix.language}}'

View File

@ -24,11 +24,11 @@ jobs:
should_run_ml: ${{ steps.found_paths.outputs.machine-learning == 'true' || steps.should_force.outputs.should_force == 'true' }} should_run_ml: ${{ steps.found_paths.outputs.machine-learning == 'true' || steps.should_force.outputs.should_force == 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- id: found_paths - id: found_paths
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with: with:
filters: | filters: |
server: server:
@ -60,7 +60,7 @@ jobs:
suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn'] suffix: ['', '-cuda', '-rocm', '-openvino', '-armnn', '-rknn']
steps: steps:
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3 uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
@ -89,7 +89,7 @@ jobs:
suffix: [''] suffix: ['']
steps: steps:
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3 uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}

View File

@ -21,11 +21,11 @@ jobs:
should_run: ${{ steps.found_paths.outputs.docs == 'true' || steps.should_force.outputs.should_force == 'true' }} should_run: ${{ steps.found_paths.outputs.docs == 'true' || steps.should_force.outputs.should_force == 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- id: found_paths - id: found_paths
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with: with:
filters: | filters: |
docs: docs:
@ -49,12 +49,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './docs/.nvmrc' node-version-file: './docs/.nvmrc'
@ -68,7 +68,7 @@ jobs:
run: npm run build run: npm run build
- name: Upload build output - name: Upload build output
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: docs-build-output name: docs-build-output
path: docs/build/ path: docs/build/

View File

@ -20,7 +20,7 @@ jobs:
run: echo 'The triggering workflow did not succeed' && exit 1 run: echo 'The triggering workflow did not succeed' && exit 1
- name: Get artifact - name: Get artifact
id: get-artifact id: get-artifact
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
script: | script: |
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
@ -38,7 +38,7 @@ jobs:
return { found: true, id: matchArtifact.id }; return { found: true, id: matchArtifact.id };
- name: Determine deploy parameters - name: Determine deploy parameters
id: parameters id: parameters
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env: env:
HEAD_SHA: ${{ github.event.workflow_run.head_sha }} HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
with: with:
@ -108,13 +108,13 @@ jobs:
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }} if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Load parameters - name: Load parameters
id: parameters id: parameters
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env: env:
PARAM_JSON: ${{ needs.checks.outputs.parameters }} PARAM_JSON: ${{ needs.checks.outputs.parameters }}
with: with:
@ -125,7 +125,7 @@ jobs:
core.setOutput("shouldDeploy", parameters.shouldDeploy); core.setOutput("shouldDeploy", parameters.shouldDeploy);
- name: Download artifact - name: Download artifact
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env: env:
ARTIFACT_JSON: ${{ needs.checks.outputs.artifact }} ARTIFACT_JSON: ${{ needs.checks.outputs.artifact }}
with: with:
@ -150,7 +150,7 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }} TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2 uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2.1.5
with: with:
tg_version: '0.58.12' tg_version: '0.58.12'
tofu_version: '1.7.1' tofu_version: '1.7.1'
@ -165,7 +165,7 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }} TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2 uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2.1.5
with: with:
tg_version: '0.58.12' tg_version: '0.58.12'
tofu_version: '1.7.1' tofu_version: '1.7.1'
@ -181,7 +181,8 @@ jobs:
echo "output=$CLEANED" >> $GITHUB_OUTPUT echo "output=$CLEANED" >> $GITHUB_OUTPUT
- name: Publish to Cloudflare Pages - name: Publish to Cloudflare Pages
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1 # TODO: Action is deprecated
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1.5.0
with: with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN_PAGES_UPLOAD }} apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN_PAGES_UPLOAD }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
@ -198,7 +199,7 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }} TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2 uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2.1.5
with: with:
tg_version: '0.58.12' tg_version: '0.58.12'
tofu_version: '1.7.1' tofu_version: '1.7.1'
@ -206,7 +207,7 @@ jobs:
tg_command: 'apply' tg_command: 'apply'
- name: Comment - name: Comment
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3 uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0
if: ${{ steps.parameters.outputs.event == 'pr' }} if: ${{ steps.parameters.outputs.event == 'pr' }}
with: with:
number: ${{ fromJson(needs.checks.outputs.parameters).pr_number }} number: ${{ fromJson(needs.checks.outputs.parameters).pr_number }}

View File

@ -14,7 +14,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
@ -25,7 +25,7 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }} TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2 uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2.1.5
with: with:
tg_version: '0.58.12' tg_version: '0.58.12'
tofu_version: '1.7.1' tofu_version: '1.7.1'
@ -33,7 +33,7 @@ jobs:
tg_command: 'destroy -refresh=false' tg_command: 'destroy -refresh=false'
- name: Comment - name: Comment
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3 uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3.2.0
with: with:
number: ${{ github.event.number }} number: ${{ github.event.number }}
delete: true delete: true

View File

@ -16,20 +16,20 @@ jobs:
steps: steps:
- name: Generate a token - name: Generate a token
id: generate-token id: generate-token
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2 uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
with: with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: 'Checkout' - name: 'Checkout'
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
ref: ${{ github.event.pull_request.head.ref }} ref: ${{ github.event.pull_request.head.ref }}
token: ${{ steps.generate-token.outputs.token }} token: ${{ steps.generate-token.outputs.token }}
persist-credentials: true persist-credentials: true
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './server/.nvmrc' node-version-file: './server/.nvmrc'
@ -37,13 +37,13 @@ jobs:
run: make install-all && make format-all run: make install-all && make format-all
- name: Commit and push - name: Commit and push
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9 uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
with: with:
default_author: github_actions default_author: github_actions
message: 'chore: fix formatting' message: 'chore: fix formatting'
- name: Remove label - name: Remove label
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
if: always() if: always()
with: with:
script: | script: |

View File

@ -14,7 +14,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: Require PR to have a changelog label - name: Require PR to have a changelog label
uses: mheap/github-action-required-labels@388fd6af37b34cdfe5a23b37060e763217e58b03 # v5 uses: mheap/github-action-required-labels@388fd6af37b34cdfe5a23b37060e763217e58b03 # v5.5.0
with: with:
mode: exactly mode: exactly
count: 1 count: 1

View File

@ -11,4 +11,4 @@ jobs:
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5 - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0

View File

@ -32,19 +32,19 @@ jobs:
steps: steps:
- name: Generate a token - name: Generate a token
id: generate-token id: generate-token
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2 uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
with: with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
token: ${{ steps.generate-token.outputs.token }} token: ${{ steps.generate-token.outputs.token }}
persist-credentials: true persist-credentials: true
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
- name: Bump version - name: Bump version
env: env:
@ -54,7 +54,7 @@ jobs:
- name: Commit and tag - name: Commit and tag
id: push-tag id: push-tag
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9 uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
with: with:
default_author: github_actions default_author: github_actions
message: 'chore: version ${{ env.IMMICH_VERSION }}' message: 'chore: version ${{ env.IMMICH_VERSION }}'
@ -83,24 +83,24 @@ jobs:
steps: steps:
- name: Generate a token - name: Generate a token
id: generate-token id: generate-token
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2 uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
with: with:
app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }}
private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
token: ${{ steps.generate-token.outputs.token }} token: ${{ steps.generate-token.outputs.token }}
persist-credentials: false persist-credentials: false
- name: Download APK - name: Download APK
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with: with:
name: release-apk-signed name: release-apk-signed
- name: Create draft release - name: Create draft release
uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2 uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 # v2.2.2
with: with:
draft: true draft: true
tag_name: ${{ env.IMMICH_VERSION }} tag_name: ${{ env.IMMICH_VERSION }}

View File

@ -13,7 +13,7 @@ jobs:
permissions: permissions:
pull-requests: write pull-requests: write
steps: steps:
- uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2 - uses: mshick/add-pr-comment@b8f338c590a895d50bcbfa6c5859251edc8952fc # v2.8.2
with: with:
message-id: 'preview-status' message-id: 'preview-status'
message: 'Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.cloud/' message: 'Deploying preview environment to https://pr-${{ github.event.pull_request.number }}.preview.internal.immich.cloud/'
@ -24,7 +24,7 @@ jobs:
permissions: permissions:
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with: with:
script: | script: |
github.rest.issues.removeLabel({ github.rest.issues.removeLabel({

View File

@ -16,12 +16,12 @@ jobs:
run: run:
working-directory: ./open-api/typescript-sdk working-directory: ./open-api/typescript-sdk
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
# Setup .npmrc file to publish to npm # Setup .npmrc file to publish to npm
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './open-api/typescript-sdk/.nvmrc' node-version-file: './open-api/typescript-sdk/.nvmrc'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'

View File

@ -20,11 +20,11 @@ jobs:
should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }} should_run: ${{ steps.found_paths.outputs.mobile == 'true' || steps.should_force.outputs.should_force == 'true' }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- id: found_paths - id: found_paths
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with: with:
filters: | filters: |
mobile: mobile:
@ -44,12 +44,12 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Flutter SDK - name: Setup Flutter SDK
uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2 uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2.19.0
with: with:
channel: 'stable' channel: 'stable'
flutter-version-file: ./mobile/pubspec.yaml flutter-version-file: ./mobile/pubspec.yaml
@ -67,7 +67,7 @@ jobs:
working-directory: ./mobile working-directory: ./mobile
- name: Find file changes - name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20 uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-files id: verify-changed-files
with: with:
files: | files: |
@ -105,12 +105,12 @@ jobs:
actions: read actions: read
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Install the latest version of uv - name: Install the latest version of uv
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
- name: Run zizmor 🌈 - name: Run zizmor 🌈
run: uvx zizmor --format=sarif . > results.sarif run: uvx zizmor --format=sarif . > results.sarif
@ -118,7 +118,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload SARIF file - name: Upload SARIF file
uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3 uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
with: with:
sarif_file: results.sarif sarif_file: results.sarif
category: zizmor category: zizmor

View File

@ -17,6 +17,7 @@ jobs:
permissions: permissions:
contents: read contents: read
outputs: outputs:
should_run_i18n: ${{ steps.found_paths.outputs.i18n == 'true' || steps.should_force.outputs.should_force == 'true' }}
should_run_web: ${{ steps.found_paths.outputs.web == 'true' || steps.should_force.outputs.should_force == 'true' }} should_run_web: ${{ steps.found_paths.outputs.web == 'true' || steps.should_force.outputs.should_force == 'true' }}
should_run_server: ${{ steps.found_paths.outputs.server == 'true' || steps.should_force.outputs.should_force == 'true' }} should_run_server: ${{ steps.found_paths.outputs.server == 'true' || steps.should_force.outputs.should_force == 'true' }}
should_run_cli: ${{ steps.found_paths.outputs.cli == 'true' || steps.should_force.outputs.should_force == 'true' }} should_run_cli: ${{ steps.found_paths.outputs.cli == 'true' || steps.should_force.outputs.should_force == 'true' }}
@ -28,14 +29,16 @@ jobs:
should_run_.github: ${{ steps.found_paths.outputs['.github'] == 'true' || steps.should_force.outputs.should_force == 'true' }} # redundant to have should_force but if someone changes the trigger then this won't have to be changed should_run_.github: ${{ steps.found_paths.outputs['.github'] == 'true' || steps.should_force.outputs.should_force == 'true' }} # redundant to have should_force but if someone changes the trigger then this won't have to be changed
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- id: found_paths - id: found_paths
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with: with:
filters: | filters: |
i18n:
- 'i18n/**'
web: web:
- 'web/**' - 'web/**'
- 'i18n/**' - 'i18n/**'
@ -73,12 +76,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './server/.nvmrc' node-version-file: './server/.nvmrc'
@ -114,12 +117,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './cli/.nvmrc' node-version-file: './cli/.nvmrc'
@ -159,12 +162,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './cli/.nvmrc' node-version-file: './cli/.nvmrc'
@ -197,12 +200,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './web/.nvmrc' node-version-file: './web/.nvmrc'
@ -238,12 +241,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './web/.nvmrc' node-version-file: './web/.nvmrc'
@ -262,6 +265,46 @@ jobs:
run: npm run test:cov run: npm run test:cov
if: ${{ !cancelled() }} if: ${{ !cancelled() }}
i18n-tests:
name: Test i18n
needs: pre-job
if: ${{ needs.pre-job.outputs.should_run_i18n == 'true' }}
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: './web/.nvmrc'
- name: Install dependencies
run: npm --prefix=web ci
- name: Format
run: npm --prefix=web run format:i18n
- name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-files
with:
files: |
i18n/**
- name: Verify files have not changed
if: steps.verify-changed-files.outputs.files_changed == 'true'
env:
CHANGED_FILES: ${{ steps.verify-changed-files.outputs.changed_files }}
run: |
echo "ERROR: i18n files not up to date!"
echo "Changed files: ${CHANGED_FILES}"
exit 1
e2e-tests-lint: e2e-tests-lint:
name: End-to-End Lint name: End-to-End Lint
needs: pre-job needs: pre-job
@ -275,12 +318,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './e2e/.nvmrc' node-version-file: './e2e/.nvmrc'
@ -318,12 +361,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './server/.nvmrc' node-version-file: './server/.nvmrc'
@ -350,13 +393,13 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
submodules: 'recursive' submodules: 'recursive'
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './e2e/.nvmrc' node-version-file: './e2e/.nvmrc'
@ -398,13 +441,13 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
submodules: 'recursive' submodules: 'recursive'
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './e2e/.nvmrc' node-version-file: './e2e/.nvmrc'
@ -452,12 +495,12 @@ jobs:
permissions: permissions:
contents: read contents: read
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Flutter SDK - name: Setup Flutter SDK
uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2 uses: subosito/flutter-action@e938fdf56512cc96ef2f93601a5a40bde3801046 # v2.19.0
with: with:
channel: 'stable' channel: 'stable'
flutter-version-file: ./mobile/pubspec.yaml flutter-version-file: ./mobile/pubspec.yaml
@ -476,13 +519,13 @@ jobs:
run: run:
working-directory: ./machine-learning working-directory: ./machine-learning
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
# TODO: add caching when supported (https://github.com/actions/setup-python/pull/818) # TODO: add caching when supported (https://github.com/actions/setup-python/pull/818)
# with: # with:
# python-version: 3.11 # python-version: 3.11
@ -516,12 +559,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './.github/.nvmrc' node-version-file: './.github/.nvmrc'
@ -538,7 +581,7 @@ jobs:
permissions: permissions:
contents: read contents: read
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
@ -557,12 +600,12 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './server/.nvmrc' node-version-file: './server/.nvmrc'
@ -576,7 +619,7 @@ jobs:
run: make open-api run: make open-api
- name: Find file changes - name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20 uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-files id: verify-changed-files
with: with:
files: | files: |
@ -618,12 +661,12 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - name: Setup Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with: with:
node-version-file: './server/.nvmrc' node-version-file: './server/.nvmrc'
@ -644,7 +687,7 @@ jobs:
run: npm run migrations:generate src/TestMigration run: npm run migrations:generate src/TestMigration
- name: Find file changes - name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20 uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-files id: verify-changed-files
with: with:
files: | files: |
@ -665,7 +708,7 @@ jobs:
DB_URL: postgres://postgres:postgres@localhost:5432/immich DB_URL: postgres://postgres:postgres@localhost:5432/immich
- name: Find file changes - name: Find file changes
uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20 uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20.0.4
id: verify-changed-sql-files id: verify-changed-sql-files
with: with:
files: | files: |

View File

@ -15,11 +15,11 @@ jobs:
should_run: ${{ steps.found_paths.outputs.i18n == 'true' && github.head_ref != 'chore/translations'}} should_run: ${{ steps.found_paths.outputs.i18n == 'true' && github.head_ref != 'chore/translations'}}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with: with:
persist-credentials: false persist-credentials: false
- id: found_paths - id: found_paths
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3 uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
with: with:
filters: | filters: |
i18n: i18n:
@ -38,7 +38,7 @@ jobs:
exit 1 exit 1
fi fi
- name: Find Pull Request - name: Find Pull Request
uses: juliangruber/find-pull-request-action@48b6133aa6c826f267ebd33aa2d29470f9d9e7d0 # v1 uses: juliangruber/find-pull-request-action@48b6133aa6c826f267ebd33aa2d29470f9d9e7d0 # v1.9.0
id: find-pr id: find-pr
with: with:
branch: chore/translations branch: chore/translations

View File

@ -1 +1 @@
22.14.0 22.15.0

236
cli/package-lock.json generated
View File

@ -27,7 +27,7 @@
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/micromatch": "^4.0.9", "@types/micromatch": "^4.0.9",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/node": "^22.14.1", "@types/node": "^22.15.16",
"@vitest/coverage-v8": "^3.0.0", "@vitest/coverage-v8": "^3.0.0",
"byte-size": "^9.0.0", "byte-size": "^9.0.0",
"cli-progress": "^3.12.0", "cli-progress": "^3.12.0",
@ -61,7 +61,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.14.1", "@types/node": "^22.15.16",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
}, },
@ -580,9 +580,9 @@
} }
}, },
"node_modules/@eslint-community/eslint-utils": { "node_modules/@eslint-community/eslint-utils": {
"version": "4.6.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.0.tgz", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
"integrity": "sha512-WhCn7Z7TauhBtmzhvKpoQs0Wwb/kBcy4CwpuI0/eEIr2Lx2auxmulAzLr91wVZJaz47iUZdkXOK7WlAfxGKCnA==", "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1372,9 +1372,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.14.1", "version": "22.15.17",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",
"integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", "integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1389,21 +1389,21 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.0.tgz",
"integrity": "sha512-oUlH4h1ABavI4F0Xnl8/fOtML/eu8nI2A1nYd+f+55XI0BLu+RIqKoCiZKNo6DtqZBEQm5aNKA20G3Z5w3R6GQ==", "integrity": "sha512-/jU9ettcntkBFmWUzzGgsClEi2ZFiikMX5eEQsmxIAWMOn4H3D4rvHssstmAHGVvrYnaMqdWWWg0b5M6IN/MTQ==",
"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.31.1", "@typescript-eslint/scope-manager": "8.32.0",
"@typescript-eslint/type-utils": "8.31.1", "@typescript-eslint/type-utils": "8.32.0",
"@typescript-eslint/utils": "8.31.1", "@typescript-eslint/utils": "8.32.0",
"@typescript-eslint/visitor-keys": "8.31.1", "@typescript-eslint/visitor-keys": "8.32.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.1" "ts-api-utils": "^2.1.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1419,16 +1419,16 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.0.tgz",
"integrity": "sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q==", "integrity": "sha512-B2MdzyWxCE2+SqiZHAjPphft+/2x2FlO9YBx7eKE1BCb+rqBlQdhtAEhzIEdozHd55DXPmxBdpMygFJjfjjA9A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.31.1", "@typescript-eslint/scope-manager": "8.32.0",
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"@typescript-eslint/typescript-estree": "8.31.1", "@typescript-eslint/typescript-estree": "8.32.0",
"@typescript-eslint/visitor-keys": "8.31.1", "@typescript-eslint/visitor-keys": "8.32.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -1444,14 +1444,14 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.0.tgz",
"integrity": "sha512-BMNLOElPxrtNQMIsFHE+3P0Yf1z0dJqV9zLdDxN/xLlWMlXK/ApEsVEKzpizg9oal8bAT5Sc7+ocal7AC1HCVw==", "integrity": "sha512-jc/4IxGNedXkmG4mx4nJTILb6TMjL66D41vyeaPWvDUmeYQzF3lKtN15WsAeTr65ce4mPxwopPSo1yUUAWw0hQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"@typescript-eslint/visitor-keys": "8.31.1" "@typescript-eslint/visitor-keys": "8.32.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1462,16 +1462,16 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.0.tgz",
"integrity": "sha512-fNaT/m9n0+dpSp8G/iOQ05GoHYXbxw81x+yvr7TArTuZuCA6VVKbqWYVZrV5dVagpDTtj/O8k5HBEE/p/HM5LA==", "integrity": "sha512-t2vouuYQKEKSLtJaa5bB4jHeha2HJczQ6E5IXPDPgIty9EqcJxpr1QHQ86YyIPwDwxvUmLfP2YADQ5ZY4qddZg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "8.31.1", "@typescript-eslint/typescript-estree": "8.32.0",
"@typescript-eslint/utils": "8.31.1", "@typescript-eslint/utils": "8.32.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^2.0.1" "ts-api-utils": "^2.1.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1486,9 +1486,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.0.tgz",
"integrity": "sha512-SfepaEFUDQYRoA70DD9GtytljBePSj17qPxFHA/h3eg6lPTqGJ5mWOtbXCk1YrVU1cTJRd14nhaXWFu0l2troQ==", "integrity": "sha512-O5Id6tGadAZEMThM6L9HmVf5hQUXNSxLVKeGJYWNhhVseps/0LddMkp7//VDkzwJ69lPL0UmZdcZwggj9akJaA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -1500,20 +1500,20 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.0.tgz",
"integrity": "sha512-kaA0ueLe2v7KunYOyWYtlf/QhhZb7+qh4Yw6Ni5kgukMIG+iP773tjgBiLWIXYumWCwEq3nLW+TUywEp8uEeag==", "integrity": "sha512-pU9VD7anSCOIoBFnhTGfOzlVFQIA1XXiQpH/CezqOBaDppRwTglJzCC6fUQGpfwey4T183NKhF1/mfatYmjRqQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"@typescript-eslint/visitor-keys": "8.31.1", "@typescript-eslint/visitor-keys": "8.32.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.1" "ts-api-utils": "^2.1.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1553,16 +1553,16 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.0.tgz",
"integrity": "sha512-2DSI4SNfF5T4oRveQ4nUrSjUqjMND0nLq9rEkz0gfGr3tg0S5KB6DhwR+WZPCjzkZl3cH+4x2ce3EsL50FubjQ==", "integrity": "sha512-8S9hXau6nQ/sYVtC3D6ISIDoJzS1NsCK+gluVhLN2YkBPX+/1wkwyUiDKnxRh15579WoOIyVWnoyIf3yGI9REw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.31.1", "@typescript-eslint/scope-manager": "8.32.0",
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"@typescript-eslint/typescript-estree": "8.31.1" "@typescript-eslint/typescript-estree": "8.32.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1577,13 +1577,13 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.0.tgz",
"integrity": "sha512-I+/rgqOVBn6f0o7NDTmAPWWC6NuqhV174lfYvAm9fUaWeiefLdux9/YI3/nLugEn9L8fcSi0XmpKi/r5u0nmpw==", "integrity": "sha512-1rYQTCLFFzOI5Nl0c8LUpJT8HxpwVRn9E4CkMsYfuN6ctmQqExjSTzzSk0Tz2apmXy7WU6/6fyaZVVA/thPN+w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"eslint-visitor-keys": "^4.2.0" "eslint-visitor-keys": "^4.2.0"
}, },
"engines": { "engines": {
@ -1595,9 +1595,9 @@
} }
}, },
"node_modules/@vitest/coverage-v8": { "node_modules/@vitest/coverage-v8": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.3.tgz",
"integrity": "sha512-XDdaDOeaTMAMYW7N63AqoK32sYUWbXnTkC6tEbVcu3RlU1bB9of32T+PGf8KZvxqLNqeXhafDFqCkwpf2+dyaQ==", "integrity": "sha512-cj76U5gXCl3g88KSnf80kof6+6w+K4BjOflCl7t6yRJPDuCrHtVu0SgNYOUARJOL5TI8RScDbm5x4s1/P9bvpw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1618,8 +1618,8 @@
"url": "https://opencollective.com/vitest" "url": "https://opencollective.com/vitest"
}, },
"peerDependencies": { "peerDependencies": {
"@vitest/browser": "3.1.2", "@vitest/browser": "3.1.3",
"vitest": "3.1.2" "vitest": "3.1.3"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@vitest/browser": { "@vitest/browser": {
@ -1628,14 +1628,14 @@
} }
}, },
"node_modules/@vitest/expect": { "node_modules/@vitest/expect": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.3.tgz",
"integrity": "sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==", "integrity": "sha512-7FTQQuuLKmN1Ig/h+h/GO+44Q1IlglPlR2es4ab7Yvfx+Uk5xsv+Ykk+MEt/M2Yn/xGmzaLKxGw2lgy2bwuYqg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/spy": "3.1.2", "@vitest/spy": "3.1.3",
"@vitest/utils": "3.1.2", "@vitest/utils": "3.1.3",
"chai": "^5.2.0", "chai": "^5.2.0",
"tinyrainbow": "^2.0.0" "tinyrainbow": "^2.0.0"
}, },
@ -1644,13 +1644,13 @@
} }
}, },
"node_modules/@vitest/mocker": { "node_modules/@vitest/mocker": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.3.tgz",
"integrity": "sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==", "integrity": "sha512-PJbLjonJK82uCWHjzgBJZuR7zmAOrSvKk1QBxrennDIgtH4uK0TB1PvYmc0XBCigxxtiAVPfWtAdy4lpz8SQGQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/spy": "3.1.2", "@vitest/spy": "3.1.3",
"estree-walker": "^3.0.3", "estree-walker": "^3.0.3",
"magic-string": "^0.30.17" "magic-string": "^0.30.17"
}, },
@ -1671,9 +1671,9 @@
} }
}, },
"node_modules/@vitest/pretty-format": { "node_modules/@vitest/pretty-format": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.3.tgz",
"integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", "integrity": "sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1684,13 +1684,13 @@
} }
}, },
"node_modules/@vitest/runner": { "node_modules/@vitest/runner": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.3.tgz",
"integrity": "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==", "integrity": "sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/utils": "3.1.2", "@vitest/utils": "3.1.3",
"pathe": "^2.0.3" "pathe": "^2.0.3"
}, },
"funding": { "funding": {
@ -1698,13 +1698,13 @@
} }
}, },
"node_modules/@vitest/snapshot": { "node_modules/@vitest/snapshot": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.3.tgz",
"integrity": "sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==", "integrity": "sha512-XVa5OPNTYUsyqG9skuUkFzAeFnEzDp8hQu7kZ0N25B1+6KjGm4hWLtURyBbsIAOekfWQ7Wuz/N/XXzgYO3deWQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/pretty-format": "3.1.2", "@vitest/pretty-format": "3.1.3",
"magic-string": "^0.30.17", "magic-string": "^0.30.17",
"pathe": "^2.0.3" "pathe": "^2.0.3"
}, },
@ -1713,9 +1713,9 @@
} }
}, },
"node_modules/@vitest/spy": { "node_modules/@vitest/spy": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.3.tgz",
"integrity": "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==", "integrity": "sha512-x6w+ctOEmEXdWaa6TO4ilb7l9DxPR5bwEb6hILKuxfU1NqWT2mpJD9NJN7t3OTfxmVlOMrvtoFJGdgyzZ605lQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1726,13 +1726,13 @@
} }
}, },
"node_modules/@vitest/utils": { "node_modules/@vitest/utils": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.3.tgz",
"integrity": "sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==", "integrity": "sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/pretty-format": "3.1.2", "@vitest/pretty-format": "3.1.3",
"loupe": "^3.1.3", "loupe": "^3.1.3",
"tinyrainbow": "^2.0.0" "tinyrainbow": "^2.0.0"
}, },
@ -2541,9 +2541,9 @@
} }
}, },
"node_modules/eslint-config-prettier": { "node_modules/eslint-config-prettier": {
"version": "10.1.2", "version": "10.1.3",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.2.tgz", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.3.tgz",
"integrity": "sha512-Epgp/EofAUeEpIdZkW60MHKvPyru1ruQJxPL+WIycnaPApuseK0Zpkrh/FwL9oIpQvIhJwV7ptOy0DWUjTlCiA==", "integrity": "sha512-vDo4d9yQE+cS2tdIT4J02H/16veRvkHgiLDRpej+WL67oCfbOb97itZXn8wMPJ/GsiEBVjrjs//AVNw2Cp1EcA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
@ -2554,9 +2554,9 @@
} }
}, },
"node_modules/eslint-plugin-prettier": { "node_modules/eslint-plugin-prettier": {
"version": "5.3.1", "version": "5.4.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.3.1.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.0.tgz",
"integrity": "sha512-vad9VWgEm9xaVXRNmb4aeOt0PWDc61IAdzghkbYQ2wavgax148iKoX1rNJcgkBGCipzLzOnHYVgL7xudM9yccQ==", "integrity": "sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -3158,9 +3158,9 @@
} }
}, },
"node_modules/globals": { "node_modules/globals": {
"version": "16.0.0", "version": "16.1.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz", "resolved": "https://registry.npmjs.org/globals/-/globals-16.1.0.tgz",
"integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==", "integrity": "sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -5095,15 +5095,15 @@
} }
}, },
"node_modules/typescript-eslint": { "node_modules/typescript-eslint": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.31.1.tgz", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.32.0.tgz",
"integrity": "sha512-j6DsEotD/fH39qKzXTQRwYYWlt7D+0HmfpOK+DVhwJOFLcdmn92hq3mBb7HlKJHbjjI/gTOqEcc9d6JfpFf/VA==", "integrity": "sha512-UMq2kxdXCzinFFPsXc9o2ozIpYCCOiEC46MG3yEh5Vipq6BO27otTtEBZA1fQ66DulEUgE97ucQ/3YY66CPg0A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/eslint-plugin": "8.31.1", "@typescript-eslint/eslint-plugin": "8.32.0",
"@typescript-eslint/parser": "8.31.1", "@typescript-eslint/parser": "8.32.0",
"@typescript-eslint/utils": "8.31.1" "@typescript-eslint/utils": "8.32.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5285,15 +5285,15 @@
} }
}, },
"node_modules/vite-node": { "node_modules/vite-node": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.2.tgz", "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.3.tgz",
"integrity": "sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA==", "integrity": "sha512-uHV4plJ2IxCl4u1up1FQRrqclylKAogbtBfOTwcuJ28xFi+89PZ57BRh+naIRvH70HPwxy5QHYzg1OrEaC7AbA==",
"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.7.0",
"pathe": "^2.0.3", "pathe": "^2.0.3",
"vite": "^5.0.0 || ^6.0.0" "vite": "^5.0.0 || ^6.0.0"
}, },
@ -5356,19 +5356,19 @@
} }
}, },
"node_modules/vitest": { "node_modules/vitest": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.2.tgz", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.3.tgz",
"integrity": "sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ==", "integrity": "sha512-188iM4hAHQ0km23TN/adso1q5hhwKqUpv+Sd6p5sOuh6FhQnRNW3IsiIpvxqahtBabsJ2SLZgmGSpcYK4wQYJw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/expect": "3.1.2", "@vitest/expect": "3.1.3",
"@vitest/mocker": "3.1.2", "@vitest/mocker": "3.1.3",
"@vitest/pretty-format": "^3.1.2", "@vitest/pretty-format": "^3.1.3",
"@vitest/runner": "3.1.2", "@vitest/runner": "3.1.3",
"@vitest/snapshot": "3.1.2", "@vitest/snapshot": "3.1.3",
"@vitest/spy": "3.1.2", "@vitest/spy": "3.1.3",
"@vitest/utils": "3.1.2", "@vitest/utils": "3.1.3",
"chai": "^5.2.0", "chai": "^5.2.0",
"debug": "^4.4.0", "debug": "^4.4.0",
"expect-type": "^1.2.1", "expect-type": "^1.2.1",
@ -5381,7 +5381,7 @@
"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.1.2", "vite-node": "3.1.3",
"why-is-node-running": "^2.3.0" "why-is-node-running": "^2.3.0"
}, },
"bin": { "bin": {
@ -5397,8 +5397,8 @@
"@edge-runtime/vm": "*", "@edge-runtime/vm": "*",
"@types/debug": "^4.1.12", "@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.1.2", "@vitest/browser": "3.1.3",
"@vitest/ui": "3.1.2", "@vitest/ui": "3.1.3",
"happy-dom": "*", "happy-dom": "*",
"jsdom": "*" "jsdom": "*"
}, },

View File

@ -21,7 +21,7 @@
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/micromatch": "^4.0.9", "@types/micromatch": "^4.0.9",
"@types/mock-fs": "^4.13.1", "@types/mock-fs": "^4.13.1",
"@types/node": "^22.14.1", "@types/node": "^22.15.16",
"@vitest/coverage-v8": "^3.0.0", "@vitest/coverage-v8": "^3.0.0",
"byte-size": "^9.0.0", "byte-size": "^9.0.0",
"cli-progress": "^3.12.0", "cli-progress": "^3.12.0",
@ -69,6 +69,6 @@
"micromatch": "^4.0.8" "micromatch": "^4.0.8"
}, },
"volta": { "volta": {
"node": "22.14.0" "node": "22.15.0"
} }
} }

View File

@ -116,7 +116,7 @@ services:
redis: redis:
container_name: immich_redis container_name: immich_redis
image: docker.io/valkey/valkey:8-bookworm@sha256:4a9f847af90037d59b34cd4d4ad14c6e055f46540cf4ff757aaafb266060fa28 image: docker.io/valkey/valkey:8-bookworm@sha256:ff21bc0f8194dc9c105b769aeabf9585fea6a8ed649c0781caeac5cb3c247884
healthcheck: healthcheck:
test: redis-cli ping || exit 1 test: redis-cli ping || exit 1

View File

@ -56,7 +56,7 @@ services:
redis: redis:
container_name: immich_redis container_name: immich_redis
image: docker.io/valkey/valkey:8-bookworm@sha256:4a9f847af90037d59b34cd4d4ad14c6e055f46540cf4ff757aaafb266060fa28 image: docker.io/valkey/valkey:8-bookworm@sha256:ff21bc0f8194dc9c105b769aeabf9585fea6a8ed649c0781caeac5cb3c247884
healthcheck: healthcheck:
test: redis-cli ping || exit 1 test: redis-cli ping || exit 1
restart: always restart: always

View File

@ -49,7 +49,7 @@ services:
redis: redis:
container_name: immich_redis container_name: immich_redis
image: docker.io/valkey/valkey:8-bookworm@sha256:4a9f847af90037d59b34cd4d4ad14c6e055f46540cf4ff757aaafb266060fa28 image: docker.io/valkey/valkey:8-bookworm@sha256:ff21bc0f8194dc9c105b769aeabf9585fea6a8ed649c0781caeac5cb3c247884
healthcheck: healthcheck:
test: redis-cli ping || exit 1 test: redis-cli ping || exit 1
restart: always restart: always

View File

@ -1 +1 @@
22.14.0 22.15.0

View File

@ -121,6 +121,6 @@ Once this is done, you can continue to step 3 of "Basic Setup".
[hw-file]: https://github.com/immich-app/immich/releases/latest/download/hwaccel.transcoding.yml [hw-file]: https://github.com/immich-app/immich/releases/latest/download/hwaccel.transcoding.yml
[nvct]: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html [nvct]: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html
[jellyfin-lp]: https://jellyfin.org/docs/general/administration/hardware-acceleration/intel/#configure-and-verify-lp-mode-on-linux [jellyfin-lp]: https://jellyfin.org/docs/general/post-install/transcoding/hardware-acceleration/intel#low-power-encoding
[jellyfin-kernel-bug]: https://jellyfin.org/docs/general/administration/hardware-acceleration/intel/#known-issues-and-limitations [jellyfin-kernel-bug]: https://jellyfin.org/docs/general/post-install/transcoding/hardware-acceleration/intel#known-issues-and-limitations-on-linux
[libmali-rockchip]: https://github.com/tsukumijima/libmali-rockchip/releases [libmali-rockchip]: https://github.com/tsukumijima/libmali-rockchip/releases

View File

@ -57,6 +57,6 @@
"node": ">=20" "node": ">=20"
}, },
"volta": { "volta": {
"node": "22.14.0" "node": "22.15.0"
} }
} }

View File

@ -1 +1 @@
22.14.0 22.15.0

624
e2e/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -25,9 +25,9 @@
"@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.14.1", "@types/node": "^22.15.16",
"@types/oidc-provider": "^8.5.1", "@types/oidc-provider": "^8.5.1",
"@types/pg": "^8.11.0", "@types/pg": "^8.15.1",
"@types/pngjs": "^6.0.4", "@types/pngjs": "^6.0.4",
"@types/supertest": "^6.0.2", "@types/supertest": "^6.0.2",
"@vitest/coverage-v8": "^3.0.0", "@vitest/coverage-v8": "^3.0.0",
@ -52,6 +52,6 @@
"vitest": "^3.0.0" "vitest": "^3.0.0"
}, },
"volta": { "volta": {
"node": "22.14.0" "node": "22.15.0"
} }
} }

View File

@ -202,7 +202,6 @@ describe('/asset', () => {
{ {
name: 'Marie Curie', name: 'Marie Curie',
birthDate: null, birthDate: null,
thumbnailPath: '',
isHidden: false, isHidden: false,
faces: [ faces: [
{ {
@ -219,7 +218,6 @@ describe('/asset', () => {
{ {
name: 'Pierre Curie', name: 'Pierre Curie',
birthDate: null, birthDate: null,
thumbnailPath: '',
isHidden: false, isHidden: false,
faces: [ faces: [
{ {

View File

@ -1,17 +1,4 @@
{ {
"user_pin_code_settings": "PIN Code",
"user_pin_code_settings_description": "Manage your PIN code",
"current_pin_code": "Current PIN code",
"new_pin_code": "New PIN code",
"setup_pin_code": "Setup a PIN code",
"confirm_new_pin_code": "Confirm new PIN code",
"change_pin_code": "Change PIN code",
"unable_to_change_pin_code": "Unable to change PIN code",
"unable_to_setup_pin_code": "Unable to setup PIN code",
"pin_code_changed_successfully": "Successfully changed PIN code",
"pin_code_setup_successfully": "Successfully setup a PIN code",
"pin_code_reset_successfully": "Successfully reset PIN code",
"reset_pin_code": "Reset PIN code",
"about": "About", "about": "About",
"account": "Account", "account": "Account",
"account_settings": "Account Settings", "account_settings": "Account Settings",
@ -39,6 +26,7 @@
"add_to_album": "Add to album", "add_to_album": "Add to album",
"add_to_album_bottom_sheet_added": "Added to {album}", "add_to_album_bottom_sheet_added": "Added to {album}",
"add_to_album_bottom_sheet_already_exists": "Already in {album}", "add_to_album_bottom_sheet_already_exists": "Already in {album}",
"add_to_locked_folder": "Add to Locked Folder",
"add_to_shared_album": "Add to shared album", "add_to_shared_album": "Add to shared album",
"add_url": "Add URL", "add_url": "Add URL",
"added_to_archive": "Added to archive", "added_to_archive": "Added to archive",
@ -362,6 +350,7 @@
"user_delete_delay_settings_description": "Number of days after removal to permanently delete a user's account and assets. The user deletion job runs at midnight to check for users that are ready for deletion. Changes to this setting will be evaluated at the next execution.", "user_delete_delay_settings_description": "Number of days after removal to permanently delete a user's account and assets. The user deletion job runs at midnight to check for users that are ready for deletion. Changes to this setting will be evaluated at the next execution.",
"user_delete_immediately": "<b>{user}</b>'s account and assets will be queued for permanent deletion <b>immediately</b>.", "user_delete_immediately": "<b>{user}</b>'s account and assets will be queued for permanent deletion <b>immediately</b>.",
"user_delete_immediately_checkbox": "Queue user and assets for immediate deletion", "user_delete_immediately_checkbox": "Queue user and assets for immediate deletion",
"user_details": "User Details",
"user_management": "User Management", "user_management": "User Management",
"user_password_has_been_reset": "The user's password has been reset:", "user_password_has_been_reset": "The user's password has been reset:",
"user_password_reset_description": "Please provide the temporary password to the user and inform them they will need to change the password at their next login.", "user_password_reset_description": "Please provide the temporary password to the user and inform them they will need to change the password at their next login.",
@ -624,6 +613,7 @@
"change_password_form_new_password": "New Password", "change_password_form_new_password": "New Password",
"change_password_form_password_mismatch": "Passwords do not match", "change_password_form_password_mismatch": "Passwords do not match",
"change_password_form_reenter_new_password": "Re-enter New Password", "change_password_form_reenter_new_password": "Re-enter New Password",
"change_pin_code": "Change PIN code",
"change_your_password": "Change your password", "change_your_password": "Change your password",
"changed_visibility_successfully": "Changed visibility successfully", "changed_visibility_successfully": "Changed visibility successfully",
"check_all": "Check All", "check_all": "Check All",
@ -664,6 +654,7 @@
"confirm_delete_face": "Are you sure you want to delete {name} face from the asset?", "confirm_delete_face": "Are you sure you want to delete {name} face from the asset?",
"confirm_delete_shared_link": "Are you sure you want to delete this shared link?", "confirm_delete_shared_link": "Are you sure you want to delete this shared link?",
"confirm_keep_this_delete_others": "All other assets in the stack will be deleted except for this asset. Are you sure you want to continue?", "confirm_keep_this_delete_others": "All other assets in the stack will be deleted except for this asset. Are you sure you want to continue?",
"confirm_new_pin_code": "Confirm new PIN code",
"confirm_password": "Confirm password", "confirm_password": "Confirm password",
"contain": "Contain", "contain": "Contain",
"context": "Context", "context": "Context",
@ -706,9 +697,11 @@
"create_tag_description": "Create a new tag. For nested tags, please enter the full path of the tag including forward slashes.", "create_tag_description": "Create a new tag. For nested tags, please enter the full path of the tag including forward slashes.",
"create_user": "Create user", "create_user": "Create user",
"created": "Created", "created": "Created",
"created_at": "Created",
"crop": "Crop", "crop": "Crop",
"curated_object_page_title": "Things", "curated_object_page_title": "Things",
"current_device": "Current device", "current_device": "Current device",
"current_pin_code": "Current PIN code",
"current_server_address": "Current server address", "current_server_address": "Current server address",
"custom_locale": "Custom Locale", "custom_locale": "Custom Locale",
"custom_locale_description": "Format dates and numbers based on the language and the region", "custom_locale_description": "Format dates and numbers based on the language and the region",
@ -821,6 +814,7 @@
"editor_crop_tool_h2_aspect_ratios": "Aspect ratios", "editor_crop_tool_h2_aspect_ratios": "Aspect ratios",
"editor_crop_tool_h2_rotation": "Rotation", "editor_crop_tool_h2_rotation": "Rotation",
"email": "Email", "email": "Email",
"email_notifications": "Email notifications",
"empty_folder": "This folder is empty", "empty_folder": "This folder is empty",
"empty_trash": "Empty trash", "empty_trash": "Empty trash",
"empty_trash_confirmation": "Are you sure you want to empty the trash? This will remove all the assets in trash permanently from Immich.\nYou cannot undo this action!", "empty_trash_confirmation": "Are you sure you want to empty the trash? This will remove all the assets in trash permanently from Immich.\nYou cannot undo this action!",
@ -829,6 +823,8 @@
"end_date": "End date", "end_date": "End date",
"enqueued": "Enqueued", "enqueued": "Enqueued",
"enter_wifi_name": "Enter Wi-Fi name", "enter_wifi_name": "Enter Wi-Fi name",
"enter_your_pin_code": "Enter your PIN code",
"enter_your_pin_code_subtitle": "Enter your PIN code to access the locked folder",
"error": "Error", "error": "Error",
"error_change_sort_album": "Failed to change album sort order", "error_change_sort_album": "Failed to change album sort order",
"error_delete_face": "Error deleting face from asset", "error_delete_face": "Error deleting face from asset",
@ -923,6 +919,7 @@
"unable_to_log_out_all_devices": "Unable to log out all devices", "unable_to_log_out_all_devices": "Unable to log out all devices",
"unable_to_log_out_device": "Unable to log out device", "unable_to_log_out_device": "Unable to log out device",
"unable_to_login_with_oauth": "Unable to login with OAuth", "unable_to_login_with_oauth": "Unable to login with OAuth",
"unable_to_move_to_locked_folder": "Unable to move to locked folder",
"unable_to_play_video": "Unable to play video", "unable_to_play_video": "Unable to play video",
"unable_to_reassign_assets_existing_person": "Unable to reassign assets to {name, select, null {an existing person} other {{name}}}", "unable_to_reassign_assets_existing_person": "Unable to reassign assets to {name, select, null {an existing person} other {{name}}}",
"unable_to_reassign_assets_new_person": "Unable to reassign assets to a new person", "unable_to_reassign_assets_new_person": "Unable to reassign assets to a new person",
@ -1063,6 +1060,7 @@
"home_page_upload_err_limit": "Can only upload a maximum of 30 assets at a time, skipping", "home_page_upload_err_limit": "Can only upload a maximum of 30 assets at a time, skipping",
"host": "Host", "host": "Host",
"hour": "Hour", "hour": "Hour",
"id": "ID",
"ignore_icloud_photos": "Ignore iCloud photos", "ignore_icloud_photos": "Ignore iCloud photos",
"ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server", "ignore_icloud_photos_description": "Photos that are stored on iCloud will not be uploaded to the Immich server",
"image": "Image", "image": "Image",
@ -1144,6 +1142,8 @@
"location_picker_latitude_hint": "Enter your latitude here", "location_picker_latitude_hint": "Enter your latitude here",
"location_picker_longitude_error": "Enter a valid longitude", "location_picker_longitude_error": "Enter a valid longitude",
"location_picker_longitude_hint": "Enter your longitude here", "location_picker_longitude_hint": "Enter your longitude here",
"lock": "Lock",
"locked_folder": "Locked Folder",
"log_out": "Log out", "log_out": "Log out",
"log_out_all_devices": "Log Out All Devices", "log_out_all_devices": "Log Out All Devices",
"logged_out_all_devices": "Logged out all devices", "logged_out_all_devices": "Logged out all devices",
@ -1212,8 +1212,8 @@
"map_settings_only_show_favorites": "Show Favorite Only", "map_settings_only_show_favorites": "Show Favorite Only",
"map_settings_theme_settings": "Map Theme", "map_settings_theme_settings": "Map Theme",
"map_zoom_to_see_photos": "Zoom out to see photos", "map_zoom_to_see_photos": "Zoom out to see photos",
"mark_as_read": "Mark as read",
"mark_all_as_read": "Mark all as read", "mark_all_as_read": "Mark all as read",
"mark_as_read": "Mark as read",
"marked_all_as_read": "Marked all as read", "marked_all_as_read": "Marked all as read",
"matches": "Matches", "matches": "Matches",
"media_type": "Media type", "media_type": "Media type",
@ -1241,6 +1241,10 @@
"month": "Month", "month": "Month",
"monthly_title_text_date_format": "MMMM y", "monthly_title_text_date_format": "MMMM y",
"more": "More", "more": "More",
"move": "Move",
"move_off_locked_folder": "Move out of Locked Folder",
"move_to_locked_folder": "Move to Locked Folder",
"move_to_locked_folder_confirmation": "These photos and video will be removed from all albums, and only viewable from the Locked Folder",
"moved_to_archive": "Moved {count, plural, one {# asset} other {# assets}} to archive", "moved_to_archive": "Moved {count, plural, one {# asset} other {# assets}} to archive",
"moved_to_library": "Moved {count, plural, one {# asset} other {# assets}} to library", "moved_to_library": "Moved {count, plural, one {# asset} other {# assets}} to library",
"moved_to_trash": "Moved to trash", "moved_to_trash": "Moved to trash",
@ -1257,6 +1261,8 @@
"new_api_key": "New API Key", "new_api_key": "New API Key",
"new_password": "New password", "new_password": "New password",
"new_person": "New person", "new_person": "New person",
"new_pin_code": "New PIN code",
"new_pin_code_subtitle": "This is your first time accessing the locked folder. Create a PIN code to securely access this page",
"new_user_created": "New user created", "new_user_created": "New user created",
"new_version_available": "NEW VERSION AVAILABLE", "new_version_available": "NEW VERSION AVAILABLE",
"newest_first": "Newest first", "newest_first": "Newest first",
@ -1274,17 +1280,19 @@
"no_explore_results_message": "Upload more photos to explore your collection.", "no_explore_results_message": "Upload more photos to explore your collection.",
"no_favorites_message": "Add favorites to quickly find your best pictures and videos", "no_favorites_message": "Add favorites to quickly find your best pictures and videos",
"no_libraries_message": "Create an external library to view your photos and videos", "no_libraries_message": "Create an external library to view your photos and videos",
"no_locked_photos_message": "Photos and videos in Locked Folder are hidden and won't show up as you browser your library.",
"no_name": "No Name", "no_name": "No Name",
"no_notifications": "No notifications",
"no_people_found": "No matching people found", "no_people_found": "No matching people found",
"no_places": "No places", "no_places": "No places",
"no_results": "No results", "no_results": "No results",
"no_results_description": "Try a synonym or more general keyword", "no_results_description": "Try a synonym or more general keyword",
"no_notifications": "No notifications",
"no_shared_albums_message": "Create an album to share photos and videos with people in your network", "no_shared_albums_message": "Create an album to share photos and videos with people in your network",
"not_in_any_album": "Not in any album", "not_in_any_album": "Not in any album",
"not_selected": "Not selected", "not_selected": "Not selected",
"note_apply_storage_label_to_previously_uploaded assets": "Note: To apply the Storage Label to previously uploaded assets, run the", "note_apply_storage_label_to_previously_uploaded assets": "Note: To apply the Storage Label to previously uploaded assets, run the",
"notes": "Notes", "notes": "Notes",
"nothing_here_yet": "Nothing here yet",
"notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.", "notification_permission_dialog_content": "To enable notifications, go to Settings and select allow.",
"notification_permission_list_tile_content": "Grant permission to enable notifications.", "notification_permission_list_tile_content": "Grant permission to enable notifications.",
"notification_permission_list_tile_enable_button": "Enable Notifications", "notification_permission_list_tile_enable_button": "Enable Notifications",
@ -1377,6 +1385,10 @@
"photos_count": "{count, plural, one {{count, number} Photo} other {{count, number} Photos}}", "photos_count": "{count, plural, one {{count, number} Photo} other {{count, number} Photos}}",
"photos_from_previous_years": "Photos from previous years", "photos_from_previous_years": "Photos from previous years",
"pick_a_location": "Pick a location", "pick_a_location": "Pick a location",
"pin_code_changed_successfully": "Successfully changed PIN code",
"pin_code_reset_successfully": "Successfully reset PIN code",
"pin_code_setup_successfully": "Successfully setup a PIN code",
"pin_verification": "PIN code verification",
"place": "Place", "place": "Place",
"places": "Places", "places": "Places",
"places_count": "{count, plural, one {{count, number} Place} other {{count, number} Places}}", "places_count": "{count, plural, one {{count, number} Place} other {{count, number} Places}}",
@ -1394,6 +1406,7 @@
"previous_or_next_photo": "Previous or next photo", "previous_or_next_photo": "Previous or next photo",
"primary": "Primary", "primary": "Primary",
"privacy": "Privacy", "privacy": "Privacy",
"profile": "Profile",
"profile_drawer_app_logs": "Logs", "profile_drawer_app_logs": "Logs",
"profile_drawer_client_out_of_date_major": "Mobile App is out of date. Please update to the latest major version.", "profile_drawer_client_out_of_date_major": "Mobile App is out of date. Please update to the latest major version.",
"profile_drawer_client_out_of_date_minor": "Mobile App is out of date. Please update to the latest minor version.", "profile_drawer_client_out_of_date_minor": "Mobile App is out of date. Please update to the latest minor version.",
@ -1473,6 +1486,8 @@
"remove_deleted_assets": "Remove Deleted Assets", "remove_deleted_assets": "Remove Deleted Assets",
"remove_from_album": "Remove from album", "remove_from_album": "Remove from album",
"remove_from_favorites": "Remove from favorites", "remove_from_favorites": "Remove from favorites",
"remove_from_locked_folder": "Remove from Locked Folder",
"remove_from_locked_folder_confirmation": "Are you sure you want to move these photos and videos out of Locked Folder? They will be visible in your library",
"remove_from_shared_link": "Remove from shared link", "remove_from_shared_link": "Remove from shared link",
"remove_memory": "Remove memory", "remove_memory": "Remove memory",
"remove_photo_from_memory": "Remove photo from this memory", "remove_photo_from_memory": "Remove photo from this memory",
@ -1496,6 +1511,7 @@
"reset": "Reset", "reset": "Reset",
"reset_password": "Reset password", "reset_password": "Reset password",
"reset_people_visibility": "Reset people visibility", "reset_people_visibility": "Reset people visibility",
"reset_pin_code": "Reset PIN code",
"reset_to_default": "Reset to default", "reset_to_default": "Reset to default",
"resolve_duplicates": "Resolve duplicates", "resolve_duplicates": "Resolve duplicates",
"resolved_all_duplicates": "Resolved all duplicates", "resolved_all_duplicates": "Resolved all duplicates",
@ -1636,6 +1652,7 @@
"settings": "Settings", "settings": "Settings",
"settings_require_restart": "Please restart Immich to apply this setting", "settings_require_restart": "Please restart Immich to apply this setting",
"settings_saved": "Settings saved", "settings_saved": "Settings saved",
"setup_pin_code": "Setup a PIN code",
"share": "Share", "share": "Share",
"share_add_photos": "Add photos", "share_add_photos": "Add photos",
"share_assets_selected": "{count} selected", "share_assets_selected": "{count} selected",
@ -1752,6 +1769,7 @@
"stop_sharing_photos_with_user": "Stop sharing your photos with this user", "stop_sharing_photos_with_user": "Stop sharing your photos with this user",
"storage": "Storage space", "storage": "Storage space",
"storage_label": "Storage label", "storage_label": "Storage label",
"storage_quota": "Storage Quota",
"storage_usage": "{used} of {available} used", "storage_usage": "{used} of {available} used",
"submit": "Submit", "submit": "Submit",
"suggestions": "Suggestions", "suggestions": "Suggestions",
@ -1820,6 +1838,8 @@
"trash_page_title": "Trash ({count})", "trash_page_title": "Trash ({count})",
"trashed_items_will_be_permanently_deleted_after": "Trashed items will be permanently deleted after {days, plural, one {# day} other {# days}}.", "trashed_items_will_be_permanently_deleted_after": "Trashed items will be permanently deleted after {days, plural, one {# day} other {# days}}.",
"type": "Type", "type": "Type",
"unable_to_change_pin_code": "Unable to change PIN code",
"unable_to_setup_pin_code": "Unable to setup PIN code",
"unarchive": "Unarchive", "unarchive": "Unarchive",
"unarchived_count": "{count, plural, other {Unarchived #}}", "unarchived_count": "{count, plural, other {Unarchived #}}",
"unfavorite": "Unfavorite", "unfavorite": "Unfavorite",
@ -1843,6 +1863,7 @@
"untracked_files": "Untracked files", "untracked_files": "Untracked files",
"untracked_files_decription": "These files are not tracked by the application. They can be the results of failed moves, interrupted uploads, or left behind due to a bug", "untracked_files_decription": "These files are not tracked by the application. They can be the results of failed moves, interrupted uploads, or left behind due to a bug",
"up_next": "Up next", "up_next": "Up next",
"updated_at": "Updated",
"updated_password": "Updated password", "updated_password": "Updated password",
"upload": "Upload", "upload": "Upload",
"upload_concurrency": "Upload concurrency", "upload_concurrency": "Upload concurrency",
@ -1862,8 +1883,11 @@
"use_current_connection": "use current connection", "use_current_connection": "use current connection",
"use_custom_date_range": "Use custom date range instead", "use_custom_date_range": "Use custom date range instead",
"user": "User", "user": "User",
"user_has_been_deleted": "This user has been deleted.",
"user_id": "User ID", "user_id": "User ID",
"user_liked": "{user} liked {type, select, photo {this photo} video {this video} asset {this asset} other {it}}", "user_liked": "{user} liked {type, select, photo {this photo} video {this video} asset {this asset} other {it}}",
"user_pin_code_settings": "PIN Code",
"user_pin_code_settings_description": "Manage your PIN code",
"user_purchase_settings": "Purchase", "user_purchase_settings": "Purchase",
"user_purchase_settings_description": "Manage your purchase", "user_purchase_settings_description": "Manage your purchase",
"user_role_set": "Set {user} as {role}", "user_role_set": "Set {user} as {role}",
@ -1913,6 +1937,7 @@
"welcome": "Welcome", "welcome": "Welcome",
"welcome_to_immich": "Welcome to Immich", "welcome_to_immich": "Welcome to Immich",
"wifi_name": "Wi-Fi Name", "wifi_name": "Wi-Fi Name",
"wrong_pin_code": "Wrong PIN code",
"year": "Year", "year": "Year",
"years_ago": "{years, plural, one {# year} other {# years}} ago", "years_ago": "{years, plural, one {# year} other {# years}} ago",
"yes": "Yes", "yes": "Yes",

View File

@ -819,6 +819,21 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload-time = "2022-09-25T15:39:59.68Z" }, { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload-time = "2022-09-25T15:39:59.68Z" },
] ]
[[package]]
name = "hf-xet"
version = "1.1.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/3a/09/e2fc5ccd6f9828efbd9135d5aab70895fa6891752ce84c57026c48f3f33d/hf_xet-1.1.1.tar.gz", hash = "sha256:3e75d6e04c38c80115b640c025d68c3dc14d62f8b244011dfe547363674a1e87", size = 277864, upload-time = "2025-05-12T21:34:25.002Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/97/f5/81194ea8e4a585d7d4d0f2ad1ca16e05a4b0c5a385bb2610a8e6da1d2c3d/hf_xet-1.1.1-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e39a8513f0854656116c837d387d9a41e9d78430b1a181442f04c223cbc4e8f8", size = 5274857, upload-time = "2025-05-12T21:34:18.32Z" },
{ url = "https://files.pythonhosted.org/packages/55/3c/36342b3fa247f2580821a4b183d38f36fb20e911a8307df625790e734359/hf_xet-1.1.1-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:c60cd67be384cb9e592fa6dfd29a10fddffa1feb2f3b31f53e980630d1ca0fd6", size = 5079657, upload-time = "2025-05-12T21:34:16.912Z" },
{ url = "https://files.pythonhosted.org/packages/b0/c1/4f770cc7be79287905e13765d4a7e1949dce3483f90867f532ff56e7126b/hf_xet-1.1.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5efc6cf15930d9b0cef25c0444e00c2f55d9e09f856f26ed8c809fd5cd1aa044", size = 25506200, upload-time = "2025-05-12T21:34:14.725Z" },
{ url = "https://files.pythonhosted.org/packages/94/69/1ec612f8e9e2ca27563adfca926cfb41bbe988e30d4cd6fc1e0c019e5570/hf_xet-1.1.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:504bbc8341edc2aa4b3c20c1fdda818554ab34e4175730f42e2a90436cbbe706", size = 24469080, upload-time = "2025-05-12T21:34:11.974Z" },
{ url = "https://files.pythonhosted.org/packages/8d/96/9201773a0ebb982aa5936f19bdd04d404bc5d74e23f30bce6e857757998b/hf_xet-1.1.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:87d030157a21016c2cddf757a5fd6f1f364d86afef6e190e63a37dd4dc6f6c98", size = 25641374, upload-time = "2025-05-12T21:34:20.131Z" },
{ url = "https://files.pythonhosted.org/packages/ba/14/10a4cf526070e774bdc7ce68202dc27a15751ddc22c6b47a5ecb6d8ea4ad/hf_xet-1.1.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6e9b640f0f002b3bea36739b30cf3133b3175c27a342b39315be9a9bdb0cec5b", size = 25425434, upload-time = "2025-05-12T21:34:22.97Z" },
{ url = "https://files.pythonhosted.org/packages/bd/25/7015a82b3b165747ba85b0383e5d5278d268f3a30460f6d55849903cf272/hf_xet-1.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:215a4e95009a0b9795ca3cf33db4e8d1248139593d7e1185661cd19b062d2b82", size = 4391897, upload-time = "2025-05-12T21:34:26.469Z" },
]
[[package]] [[package]]
name = "httpcore" name = "httpcore"
version = "1.0.2" version = "1.0.2"
@ -885,20 +900,21 @@ wheels = [
[[package]] [[package]]
name = "huggingface-hub" name = "huggingface-hub"
version = "0.30.2" version = "0.31.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "filelock" }, { name = "filelock" },
{ name = "fsspec" }, { name = "fsspec" },
{ name = "hf-xet", marker = "platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" },
{ name = "packaging" }, { name = "packaging" },
{ name = "pyyaml" }, { name = "pyyaml" },
{ name = "requests" }, { name = "requests" },
{ name = "tqdm" }, { name = "tqdm" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/df/22/8eb91736b1dcb83d879bd49050a09df29a57cc5cd9f38e48a4b1c45ee890/huggingface_hub-0.30.2.tar.gz", hash = "sha256:9a7897c5b6fd9dad3168a794a8998d6378210f5b9688d0dfc180b1a228dc2466", size = 400868, upload-time = "2025-04-08T08:32:45.26Z" } sdist = { url = "https://files.pythonhosted.org/packages/25/eb/9268c1205d19388659d5dc664f012177b752c0eef194a9159acc7227780f/huggingface_hub-0.31.1.tar.gz", hash = "sha256:492bb5f545337aa9e2f59b75ef4c5f535a371e8958a6ce90af056387e67f1180", size = 403036, upload-time = "2025-05-07T15:25:19.695Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/93/27/1fb384a841e9661faad1c31cbfa62864f59632e876df5d795234da51c395/huggingface_hub-0.30.2-py3-none-any.whl", hash = "sha256:68ff05969927058cfa41df4f2155d4bb48f5f54f719dd0390103eefa9b191e28", size = 481433, upload-time = "2025-04-08T08:32:43.305Z" }, { url = "https://files.pythonhosted.org/packages/3a/bf/6002da17ec1c7a47bedeb216812929665927c70b6e7500b3c7bf36f01bdd/huggingface_hub-0.31.1-py3-none-any.whl", hash = "sha256:43f73124819b48b42d140cbc0d7a2e6bd15b2853b1b9d728d4d55ad1750cac5b", size = 484265, upload-time = "2025-05-07T15:25:17.921Z" },
] ]
[[package]] [[package]]
@ -1209,7 +1225,7 @@ wheels = [
[[package]] [[package]]
name = "locust" name = "locust"
version = "2.36.2" version = "2.37.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "configargparse" }, { name = "configargparse" },
@ -1229,14 +1245,14 @@ dependencies = [
{ name = "typing-extensions", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" },
{ name = "werkzeug" }, { name = "werkzeug" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/6d/90/55d4fbc8911e5e6ec4072caaca9e8b7b2b11279435c0d1330c9966b0c898/locust-2.36.2.tar.gz", hash = "sha256:604aff7535f5a83b7f666d32373b2dc74ad260c7c3d1dc274f4c82844be72eb6", size = 2251110, upload-time = "2025-04-25T14:03:35.919Z" } sdist = { url = "https://files.pythonhosted.org/packages/6a/8f/e358f3e3850a4057c05f635d94e27a2fe739301fae5f2ece230a6a8ea282/locust-2.37.1.tar.gz", hash = "sha256:97951b319cb08c8853ef76d4732359f04617d27be41c1bf91469b9a528b652e0", size = 2251378, upload-time = "2025-05-07T18:36:49.932Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/ab/f5/99dab104be69122eee3513dcdc6e0b32d59ca1f4cfd8715470c5f3aa7643/locust-2.36.2-py3-none-any.whl", hash = "sha256:74239f493f44035b25a87a0665deadf41d213b3dcd45774398e511dec15e26eb", size = 2267937, upload-time = "2025-04-25T14:03:33.671Z" }, { url = "https://files.pythonhosted.org/packages/12/10/bbfab1fd9f5fd5c7d377b9d595f5db663b2a720283949efc0135b8022758/locust-2.37.1-py3-none-any.whl", hash = "sha256:9a19a942feb0e58bf638f563b72f019dc19ddf622bee4d28c2c46a2baa8499c3", size = 2268091, upload-time = "2025-05-07T18:36:47.428Z" },
] ]
[[package]] [[package]]
name = "locust-cloud" name = "locust-cloud"
version = "1.20.7" version = "1.21.3"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "configargparse" }, { name = "configargparse" },
@ -1245,9 +1261,9 @@ dependencies = [
{ name = "python-socketio", extra = ["client"] }, { name = "python-socketio", extra = ["client"] },
{ name = "tomli", marker = "python_full_version < '3.11'" }, { name = "tomli", marker = "python_full_version < '3.11'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/94/47/1ec2478f3d4e526fb8d667b01a75b22093b2e66aea665b5369dd656ceec9/locust_cloud-1.20.7.tar.gz", hash = "sha256:24c16b767adffab51b97f489bcf142e16e2439354fb4296ecbb3e87ad20e220a", size = 448622, upload-time = "2025-04-28T11:01:49.381Z" } sdist = { url = "https://files.pythonhosted.org/packages/0f/07/94de2ed7cd7d2686f0348970808d03a070fd9264acacc4ed4c71711e2164/locust_cloud-1.21.3.tar.gz", hash = "sha256:7155fd0b64037d3031d002f56a1d3c83663dd825c0ff7af6709b5c3381c78507", size = 449927, upload-time = "2025-05-08T08:08:26.118Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/8c/07/62b5b174c77d4281235405f1ffd439f12a877e434e007a24a5299c461e39/locust_cloud-1.20.7-py3-none-any.whl", hash = "sha256:f38214e77993d0ee87114dafa857e1689789ed4bfe4ae57c2b9dc754674f08bc", size = 406619, upload-time = "2025-04-28T11:01:43.135Z" }, { url = "https://files.pythonhosted.org/packages/27/a8/d02decd8cf38d949793c8da21d4d3806281668147d0b2cedd558c51f48db/locust_cloud-1.21.3-py3-none-any.whl", hash = "sha256:fda78be76230b32927b9893667240d49d05d74b7db99bf916e1017e1a2a31c30", size = 407164, upload-time = "2025-05-08T08:08:24.232Z" },
] ]
[[package]] [[package]]
@ -1516,7 +1532,7 @@ wheels = [
[[package]] [[package]]
name = "onnxruntime" name = "onnxruntime"
version = "1.20.1" version = "1.22.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "coloredlogs" }, { name = "coloredlogs" },
@ -1527,27 +1543,24 @@ dependencies = [
{ name = "sympy" }, { name = "sympy" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/4e/28/99f903b0eb1cd6f3faa0e343217d9fb9f47b84bca98bd9859884631336ee/onnxruntime-1.20.1-cp310-cp310-macosx_13_0_universal2.whl", hash = "sha256:e50ba5ff7fed4f7d9253a6baf801ca2883cc08491f9d32d78a80da57256a5439", size = 30996314, upload-time = "2024-11-21T00:48:31.43Z" }, { url = "https://files.pythonhosted.org/packages/67/3c/c99b21646a782b89c33cffd96fdee02a81bc43f0cb651de84d58ec11e30e/onnxruntime-1.22.0-cp310-cp310-macosx_13_0_universal2.whl", hash = "sha256:85d8826cc8054e4d6bf07f779dc742a363c39094015bdad6a08b3c18cfe0ba8c", size = 34273493, upload-time = "2025-05-09T20:25:55.66Z" },
{ url = "https://files.pythonhosted.org/packages/6d/c6/c4c0860bee2fde6037bdd9dcd12d323f6e38cf00fcc9a5065b394337fc55/onnxruntime-1.20.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b2908b50101a19e99c4d4e97ebb9905561daf61829403061c1adc1b588bc0de", size = 11954010, upload-time = "2024-11-21T00:48:35.254Z" }, { url = "https://files.pythonhosted.org/packages/54/ab/fd9a3b5285008c060618be92e475337fcfbf8689787953d37273f7b52ab0/onnxruntime-1.22.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:468c9502a12f6f49ec335c2febd22fdceecc1e4cc96dfc27e419ba237dff5aff", size = 14445346, upload-time = "2025-05-09T20:25:41.322Z" },
{ url = "https://files.pythonhosted.org/packages/63/47/3dc0b075ab539f16b3d8b09df6b504f51836086ee709690a6278d791737d/onnxruntime-1.20.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d82daaec24045a2e87598b8ac2b417b1cce623244e80e663882e9fe1aae86410", size = 13330452, upload-time = "2024-11-21T00:48:40.02Z" }, { url = "https://files.pythonhosted.org/packages/1f/ca/a5625644bc079e04e3076a5ac1fb954d1e90309b8eb987a4f800732ffee6/onnxruntime-1.22.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:681fe356d853630a898ee05f01ddb95728c9a168c9460e8361d0a240c9b7cb97", size = 16392959, upload-time = "2025-05-09T20:26:09.047Z" },
{ url = "https://files.pythonhosted.org/packages/27/ef/80fab86289ecc01a734b7ddf115dfb93d8b2e004bd1e1977e12881c72b12/onnxruntime-1.20.1-cp310-cp310-win32.whl", hash = "sha256:4c4b251a725a3b8cf2aab284f7d940c26094ecd9d442f07dd81ab5470e99b83f", size = 9813849, upload-time = "2024-11-21T00:48:43.569Z" }, { url = "https://files.pythonhosted.org/packages/6d/6b/8267490476e8d4dd1883632c7e46a4634384c7ff1c35ae44edc8ab0bb7a9/onnxruntime-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:20bca6495d06925631e201f2b257cc37086752e8fe7b6c83a67c6509f4759bc9", size = 12689974, upload-time = "2025-05-12T21:26:09.704Z" },
{ url = "https://files.pythonhosted.org/packages/a9/e6/33ab10066c9875a29d55e66ae97c3bf91b9b9b987179455d67c32261a49c/onnxruntime-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:d3b616bb53a77a9463707bb313637223380fc327f5064c9a782e8ec69c22e6a2", size = 11329702, upload-time = "2024-11-21T00:48:46.599Z" }, { url = "https://files.pythonhosted.org/packages/7a/08/c008711d1b92ff1272f4fea0fbee57723171f161d42e5c680625535280af/onnxruntime-1.22.0-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:8d6725c5b9a681d8fe72f2960c191a96c256367887d076b08466f52b4e0991df", size = 34282151, upload-time = "2025-05-09T20:25:59.246Z" },
{ url = "https://files.pythonhosted.org/packages/95/8d/2634e2959b34aa8a0037989f4229e9abcfa484e9c228f99633b3241768a6/onnxruntime-1.20.1-cp311-cp311-macosx_13_0_universal2.whl", hash = "sha256:06bfbf02ca9ab5f28946e0f912a562a5f005301d0c419283dc57b3ed7969bb7b", size = 30998725, upload-time = "2024-11-21T00:48:51.013Z" }, { url = "https://files.pythonhosted.org/packages/3e/8b/22989f6b59bc4ad1324f07a945c80b9ab825f0a581ad7a6064b93716d9b7/onnxruntime-1.22.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fef17d665a917866d1f68f09edc98223b9a27e6cb167dec69da4c66484ad12fd", size = 14446302, upload-time = "2025-05-09T20:25:44.299Z" },
{ url = "https://files.pythonhosted.org/packages/a5/da/c44bf9bd66cd6d9018a921f053f28d819445c4d84b4dd4777271b0fe52a2/onnxruntime-1.20.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f6243e34d74423bdd1edf0ae9596dd61023b260f546ee17d701723915f06a9f7", size = 11955227, upload-time = "2024-11-21T00:48:54.556Z" }, { url = "https://files.pythonhosted.org/packages/7a/d5/aa83d084d05bc8f6cf8b74b499c77431ffd6b7075c761ec48ec0c161a47f/onnxruntime-1.22.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b978aa63a9a22095479c38371a9b359d4c15173cbb164eaad5f2cd27d666aa65", size = 16393496, upload-time = "2025-05-09T20:26:11.588Z" },
{ url = "https://files.pythonhosted.org/packages/11/ac/4120dfb74c8e45cce1c664fc7f7ce010edd587ba67ac41489f7432eb9381/onnxruntime-1.20.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5eec64c0269dcdb8d9a9a53dc4d64f87b9e0c19801d9321246a53b7eb5a7d1bc", size = 13331703, upload-time = "2024-11-21T00:48:57.97Z" }, { url = "https://files.pythonhosted.org/packages/89/a5/1c6c10322201566015183b52ef011dfa932f5dd1b278de8d75c3b948411d/onnxruntime-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:03d3ef7fb11adf154149d6e767e21057e0e577b947dd3f66190b212528e1db31", size = 12691517, upload-time = "2025-05-12T21:26:13.354Z" },
{ url = "https://files.pythonhosted.org/packages/12/f1/cefacac137f7bb7bfba57c50c478150fcd3c54aca72762ac2c05ce0532c1/onnxruntime-1.20.1-cp311-cp311-win32.whl", hash = "sha256:a19bc6e8c70e2485a1725b3d517a2319603acc14c1f1a017dda0afe6d4665b41", size = 9813977, upload-time = "2024-11-21T00:49:00.519Z" }, { url = "https://files.pythonhosted.org/packages/4d/de/9162872c6e502e9ac8c99a98a8738b2fab408123d11de55022ac4f92562a/onnxruntime-1.22.0-cp312-cp312-macosx_13_0_universal2.whl", hash = "sha256:f3c0380f53c1e72a41b3f4d6af2ccc01df2c17844072233442c3a7e74851ab97", size = 34298046, upload-time = "2025-05-09T20:26:02.399Z" },
{ url = "https://files.pythonhosted.org/packages/2c/2d/2d4d202c0bcfb3a4cc2b171abb9328672d7f91d7af9ea52572722c6d8d96/onnxruntime-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:8508887eb1c5f9537a4071768723ec7c30c28eb2518a00d0adcd32c89dea3221", size = 11329895, upload-time = "2024-11-21T00:49:03.845Z" }, { url = "https://files.pythonhosted.org/packages/03/79/36f910cd9fc96b444b0e728bba14607016079786adf032dae61f7c63b4aa/onnxruntime-1.22.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8601128eaef79b636152aea76ae6981b7c9fc81a618f584c15d78d42b310f1c", size = 14443220, upload-time = "2025-05-09T20:25:47.078Z" },
{ url = "https://files.pythonhosted.org/packages/e5/39/9335e0874f68f7d27103cbffc0e235e32e26759202df6085716375c078bb/onnxruntime-1.20.1-cp312-cp312-macosx_13_0_universal2.whl", hash = "sha256:22b0655e2bf4f2161d52706e31f517a0e54939dc393e92577df51808a7edc8c9", size = 31007580, upload-time = "2024-11-21T00:49:07.029Z" }, { url = "https://files.pythonhosted.org/packages/8c/60/16d219b8868cc8e8e51a68519873bdb9f5f24af080b62e917a13fff9989b/onnxruntime-1.22.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6964a975731afc19dc3418fad8d4e08c48920144ff590149429a5ebe0d15fb3c", size = 16406377, upload-time = "2025-05-09T20:26:14.478Z" },
{ url = "https://files.pythonhosted.org/packages/c5/9d/a42a84e10f1744dd27c6f2f9280cc3fb98f869dd19b7cd042e391ee2ab61/onnxruntime-1.20.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f56e898815963d6dc4ee1c35fc6c36506466eff6d16f3cb9848cea4e8c8172", size = 11952833, upload-time = "2024-11-21T00:49:10.563Z" }, { url = "https://files.pythonhosted.org/packages/36/b4/3f1c71ce1d3d21078a6a74c5483bfa2b07e41a8d2b8fb1e9993e6a26d8d3/onnxruntime-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0d534a43d1264d1273c2d4f00a5a588fa98d21117a3345b7104fa0bbcaadb9a", size = 12692233, upload-time = "2025-05-12T21:26:16.963Z" },
{ url = "https://files.pythonhosted.org/packages/47/42/2f71f5680834688a9c81becbe5c5bb996fd33eaed5c66ae0606c3b1d6a02/onnxruntime-1.20.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bb71a814f66517a65628c9e4a2bb530a6edd2cd5d87ffa0af0f6f773a027d99e", size = 13333903, upload-time = "2024-11-21T00:49:12.984Z" }, { url = "https://files.pythonhosted.org/packages/a9/65/5cb5018d5b0b7cba820d2c4a1d1b02d40df538d49138ba36a509457e4df6/onnxruntime-1.22.0-cp313-cp313-macosx_13_0_universal2.whl", hash = "sha256:fe7c051236aae16d8e2e9ffbfc1e115a0cc2450e873a9c4cb75c0cc96c1dae07", size = 34298715, upload-time = "2025-05-09T20:26:05.634Z" },
{ url = "https://files.pythonhosted.org/packages/c8/f1/aabfdf91d013320aa2fc46cf43c88ca0182860ff15df872b4552254a9680/onnxruntime-1.20.1-cp312-cp312-win32.whl", hash = "sha256:bd386cc9ee5f686ee8a75ba74037750aca55183085bf1941da8efcfe12d5b120", size = 9814562, upload-time = "2024-11-21T00:49:15.453Z" }, { url = "https://files.pythonhosted.org/packages/e1/89/1dfe1b368831d1256b90b95cb8d11da8ab769febd5c8833ec85ec1f79d21/onnxruntime-1.22.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a6bbed10bc5e770c04d422893d3045b81acbbadc9fb759a2cd1ca00993da919", size = 14443266, upload-time = "2025-05-09T20:25:49.479Z" },
{ url = "https://files.pythonhosted.org/packages/dd/80/76979e0b744307d488c79e41051117634b956612cc731f1028eb17ee7294/onnxruntime-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:19c2d843eb074f385e8bbb753a40df780511061a63f9def1b216bf53860223fb", size = 11331482, upload-time = "2024-11-21T00:49:19.412Z" }, { url = "https://files.pythonhosted.org/packages/1e/70/342514ade3a33ad9dd505dcee96ff1f0e7be6d0e6e9c911fe0f1505abf42/onnxruntime-1.22.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9fe45ee3e756300fccfd8d61b91129a121d3d80e9d38e01f03ff1295badc32b8", size = 16406707, upload-time = "2025-05-09T20:26:17.454Z" },
{ url = "https://files.pythonhosted.org/packages/f7/71/c5d980ac4189589267a06f758bd6c5667d07e55656bed6c6c0580733ad07/onnxruntime-1.20.1-cp313-cp313-macosx_13_0_universal2.whl", hash = "sha256:cc01437a32d0042b606f462245c8bbae269e5442797f6213e36ce61d5abdd8cc", size = 31007574, upload-time = "2024-11-21T00:49:23.225Z" }, { url = "https://files.pythonhosted.org/packages/3e/89/2f64e250945fa87140fb917ba377d6d0e9122e029c8512f389a9b7f953f4/onnxruntime-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:5a31d84ef82b4b05d794a4ce8ba37b0d9deb768fd580e36e17b39e0b4840253b", size = 12691777, upload-time = "2025-05-12T21:26:20.19Z" },
{ url = "https://files.pythonhosted.org/packages/81/0d/13bbd9489be2a6944f4a940084bfe388f1100472f38c07080a46fbd4ab96/onnxruntime-1.20.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb44b08e017a648924dbe91b82d89b0c105b1adcfe31e90d1dc06b8677ad37be", size = 11951459, upload-time = "2024-11-21T00:49:26.269Z" }, { url = "https://files.pythonhosted.org/packages/9f/48/d61d5f1ed098161edd88c56cbac49207d7b7b149e613d2cd7e33176c63b3/onnxruntime-1.22.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a2ac5bd9205d831541db4e508e586e764a74f14efdd3f89af7fd20e1bf4a1ed", size = 14454003, upload-time = "2025-05-09T20:25:52.287Z" },
{ url = "https://files.pythonhosted.org/packages/c0/ea/4454ae122874fd52bbb8a961262de81c5f932edeb1b72217f594c700d6ef/onnxruntime-1.20.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bda6aebdf7917c1d811f21d41633df00c58aff2bef2f598f69289c1f1dabc4b3", size = 13331620, upload-time = "2024-11-21T00:49:28.875Z" }, { url = "https://files.pythonhosted.org/packages/c3/16/873b955beda7bada5b0d798d3a601b2ff210e44ad5169f6d405b93892103/onnxruntime-1.22.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64845709f9e8a2809e8e009bc4c8f73b788cee9c6619b7d9930344eae4c9cd36", size = 16427482, upload-time = "2025-05-09T20:26:20.376Z" },
{ url = "https://files.pythonhosted.org/packages/d8/e0/50db43188ca1c945decaa8fc2a024c33446d31afed40149897d4f9de505f/onnxruntime-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:d30367df7e70f1d9fc5a6a68106f5961686d39b54d3221f760085524e8d38e16", size = 11331758, upload-time = "2024-11-21T00:49:31.417Z" },
{ url = "https://files.pythonhosted.org/packages/d8/55/3821c5fd60b52a6c82a00bba18531793c93c4addfe64fbf061e235c5617a/onnxruntime-1.20.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9158465745423b2b5d97ed25aa7740c7d38d2993ee2e5c3bfacb0c4145c49d8", size = 11950342, upload-time = "2024-11-21T00:49:34.164Z" },
{ url = "https://files.pythonhosted.org/packages/14/56/fd990ca222cef4f9f4a9400567b9a15b220dee2eafffb16b2adbc55c8281/onnxruntime-1.20.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0df6f2df83d61f46e842dbcde610ede27218947c33e994545a22333491e72a3b", size = 13337040, upload-time = "2024-11-21T00:49:37.271Z" },
] ]
[[package]] [[package]]
@ -2216,7 +2229,7 @@ wheels = [
[[package]] [[package]]
name = "rknn-toolkit-lite2" name = "rknn-toolkit-lite2"
version = "2.3.0" version = "2.3.2"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "numpy" }, { name = "numpy" },
@ -2224,9 +2237,9 @@ dependencies = [
{ name = "ruamel-yaml" }, { name = "ruamel-yaml" },
] ]
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/ed/77/6af374a4a8cd2aee762a1fb8a3050dcf3f129134bbdc4bb6bed755c4325b/rknn_toolkit_lite2-2.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b6733689bd09a262bcb6ba4744e690dd4b37ebeac4ed427cf45242c4b4ce9a4", size = 559372, upload-time = "2024-11-11T03:51:20.599Z" }, { url = "https://files.pythonhosted.org/packages/ab/db/76b40afe343f8a8c5222300da425e0dace30ce639a94776468b1d157311b/rknn_toolkit_lite2-2.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:821e80c95e6838308c133915660b1a6ae78bb8d079b2cbbd46a02dae61192d33", size = 559386, upload-time = "2025-04-09T09:39:54.414Z" },
{ url = "https://files.pythonhosted.org/packages/9b/0c/76ff1eb09d09ce4394a6959d2343a321d28dd9e604348ffdafceafdc344c/rknn_toolkit_lite2-2.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3e4fefe355dc34a155680e4bcb9e4abb37ebc271f045ec9e0a4a3a018bc5beb", size = 569149, upload-time = "2024-11-11T03:51:22.838Z" }, { url = "https://files.pythonhosted.org/packages/c1/3d/e80e1742420f62cb628d40a8bf547d6f7c9dbe4e13dcb7b7e7c0b5620e74/rknn_toolkit_lite2-2.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bda74f1179e15fccb8726054a24898982522784b65bb340b20146955d254e800", size = 569160, upload-time = "2025-04-09T09:39:56.149Z" },
{ url = "https://files.pythonhosted.org/packages/0d/6e/8679562028051b02312212defc6e8c07248953f10dd7ad506e941b575bf3/rknn_toolkit_lite2-2.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37394371d1561f470c553f39869d7c35ff93405dffe3d0d72babf297a2b0aee9", size = 527457, upload-time = "2024-11-11T03:51:25.456Z" }, { url = "https://files.pythonhosted.org/packages/ff/db/64c756f3f06b219e92ff4f0fd4e000870ee49f214d505ff01c8b0275e26d/rknn_toolkit_lite2-2.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1e4ec691fed900c0e6fde5e7d8eeba17f806aa45092b63b361ee775e2c1b50e", size = 527458, upload-time = "2025-04-09T09:39:58.881Z" },
] ]
[[package]] [[package]]

View File

@ -29,6 +29,7 @@ dynamic upgradeDto(dynamic value, String targetType) {
case 'UserResponseDto': case 'UserResponseDto':
if (value is Map) { if (value is Map) {
addDefault(value, 'profileChangedAt', DateTime.now().toIso8601String()); addDefault(value, 'profileChangedAt', DateTime.now().toIso8601String());
addDefault(value, 'visibility', AssetVisibility.timeline);
} }
break; break;
case 'UserAdminResponseDto': case 'UserAdminResponseDto':

View File

@ -111,11 +111,13 @@ Class | Method | HTTP request | Description
*AuthenticationApi* | [**changePassword**](doc//AuthenticationApi.md#changepassword) | **POST** /auth/change-password | *AuthenticationApi* | [**changePassword**](doc//AuthenticationApi.md#changepassword) | **POST** /auth/change-password |
*AuthenticationApi* | [**changePinCode**](doc//AuthenticationApi.md#changepincode) | **PUT** /auth/pin-code | *AuthenticationApi* | [**changePinCode**](doc//AuthenticationApi.md#changepincode) | **PUT** /auth/pin-code |
*AuthenticationApi* | [**getAuthStatus**](doc//AuthenticationApi.md#getauthstatus) | **GET** /auth/status | *AuthenticationApi* | [**getAuthStatus**](doc//AuthenticationApi.md#getauthstatus) | **GET** /auth/status |
*AuthenticationApi* | [**lockAuthSession**](doc//AuthenticationApi.md#lockauthsession) | **POST** /auth/session/lock |
*AuthenticationApi* | [**login**](doc//AuthenticationApi.md#login) | **POST** /auth/login | *AuthenticationApi* | [**login**](doc//AuthenticationApi.md#login) | **POST** /auth/login |
*AuthenticationApi* | [**logout**](doc//AuthenticationApi.md#logout) | **POST** /auth/logout | *AuthenticationApi* | [**logout**](doc//AuthenticationApi.md#logout) | **POST** /auth/logout |
*AuthenticationApi* | [**resetPinCode**](doc//AuthenticationApi.md#resetpincode) | **DELETE** /auth/pin-code | *AuthenticationApi* | [**resetPinCode**](doc//AuthenticationApi.md#resetpincode) | **DELETE** /auth/pin-code |
*AuthenticationApi* | [**setupPinCode**](doc//AuthenticationApi.md#setuppincode) | **POST** /auth/pin-code | *AuthenticationApi* | [**setupPinCode**](doc//AuthenticationApi.md#setuppincode) | **POST** /auth/pin-code |
*AuthenticationApi* | [**signUpAdmin**](doc//AuthenticationApi.md#signupadmin) | **POST** /auth/admin-sign-up | *AuthenticationApi* | [**signUpAdmin**](doc//AuthenticationApi.md#signupadmin) | **POST** /auth/admin-sign-up |
*AuthenticationApi* | [**unlockAuthSession**](doc//AuthenticationApi.md#unlockauthsession) | **POST** /auth/session/unlock |
*AuthenticationApi* | [**validateAccessToken**](doc//AuthenticationApi.md#validateaccesstoken) | **POST** /auth/validateToken | *AuthenticationApi* | [**validateAccessToken**](doc//AuthenticationApi.md#validateaccesstoken) | **POST** /auth/validateToken |
*DeprecatedApi* | [**getRandom**](doc//DeprecatedApi.md#getrandom) | **GET** /assets/random | *DeprecatedApi* | [**getRandom**](doc//DeprecatedApi.md#getrandom) | **GET** /assets/random |
*DownloadApi* | [**downloadArchive**](doc//DownloadApi.md#downloadarchive) | **POST** /download/archive | *DownloadApi* | [**downloadArchive**](doc//DownloadApi.md#downloadarchive) | **POST** /download/archive |
@ -193,9 +195,11 @@ Class | Method | HTTP request | Description
*ServerApi* | [**getVersionHistory**](doc//ServerApi.md#getversionhistory) | **GET** /server/version-history | *ServerApi* | [**getVersionHistory**](doc//ServerApi.md#getversionhistory) | **GET** /server/version-history |
*ServerApi* | [**pingServer**](doc//ServerApi.md#pingserver) | **GET** /server/ping | *ServerApi* | [**pingServer**](doc//ServerApi.md#pingserver) | **GET** /server/ping |
*ServerApi* | [**setServerLicense**](doc//ServerApi.md#setserverlicense) | **PUT** /server/license | *ServerApi* | [**setServerLicense**](doc//ServerApi.md#setserverlicense) | **PUT** /server/license |
*SessionsApi* | [**createSession**](doc//SessionsApi.md#createsession) | **POST** /sessions |
*SessionsApi* | [**deleteAllSessions**](doc//SessionsApi.md#deleteallsessions) | **DELETE** /sessions | *SessionsApi* | [**deleteAllSessions**](doc//SessionsApi.md#deleteallsessions) | **DELETE** /sessions |
*SessionsApi* | [**deleteSession**](doc//SessionsApi.md#deletesession) | **DELETE** /sessions/{id} | *SessionsApi* | [**deleteSession**](doc//SessionsApi.md#deletesession) | **DELETE** /sessions/{id} |
*SessionsApi* | [**getSessions**](doc//SessionsApi.md#getsessions) | **GET** /sessions | *SessionsApi* | [**getSessions**](doc//SessionsApi.md#getsessions) | **GET** /sessions |
*SessionsApi* | [**lockSession**](doc//SessionsApi.md#locksession) | **POST** /sessions/{id}/lock |
*SharedLinksApi* | [**addSharedLinkAssets**](doc//SharedLinksApi.md#addsharedlinkassets) | **PUT** /shared-links/{id}/assets | *SharedLinksApi* | [**addSharedLinkAssets**](doc//SharedLinksApi.md#addsharedlinkassets) | **PUT** /shared-links/{id}/assets |
*SharedLinksApi* | [**createSharedLink**](doc//SharedLinksApi.md#createsharedlink) | **POST** /shared-links | *SharedLinksApi* | [**createSharedLink**](doc//SharedLinksApi.md#createsharedlink) | **POST** /shared-links |
*SharedLinksApi* | [**getAllSharedLinks**](doc//SharedLinksApi.md#getallsharedlinks) | **GET** /shared-links | *SharedLinksApi* | [**getAllSharedLinks**](doc//SharedLinksApi.md#getallsharedlinks) | **GET** /shared-links |
@ -253,6 +257,7 @@ Class | Method | HTTP request | Description
*UsersAdminApi* | [**deleteUserAdmin**](doc//UsersAdminApi.md#deleteuseradmin) | **DELETE** /admin/users/{id} | *UsersAdminApi* | [**deleteUserAdmin**](doc//UsersAdminApi.md#deleteuseradmin) | **DELETE** /admin/users/{id} |
*UsersAdminApi* | [**getUserAdmin**](doc//UsersAdminApi.md#getuseradmin) | **GET** /admin/users/{id} | *UsersAdminApi* | [**getUserAdmin**](doc//UsersAdminApi.md#getuseradmin) | **GET** /admin/users/{id} |
*UsersAdminApi* | [**getUserPreferencesAdmin**](doc//UsersAdminApi.md#getuserpreferencesadmin) | **GET** /admin/users/{id}/preferences | *UsersAdminApi* | [**getUserPreferencesAdmin**](doc//UsersAdminApi.md#getuserpreferencesadmin) | **GET** /admin/users/{id}/preferences |
*UsersAdminApi* | [**getUserStatisticsAdmin**](doc//UsersAdminApi.md#getuserstatisticsadmin) | **GET** /admin/users/{id}/statistics |
*UsersAdminApi* | [**restoreUserAdmin**](doc//UsersAdminApi.md#restoreuseradmin) | **POST** /admin/users/{id}/restore | *UsersAdminApi* | [**restoreUserAdmin**](doc//UsersAdminApi.md#restoreuseradmin) | **POST** /admin/users/{id}/restore |
*UsersAdminApi* | [**searchUsersAdmin**](doc//UsersAdminApi.md#searchusersadmin) | **GET** /admin/users | *UsersAdminApi* | [**searchUsersAdmin**](doc//UsersAdminApi.md#searchusersadmin) | **GET** /admin/users |
*UsersAdminApi* | [**updateUserAdmin**](doc//UsersAdminApi.md#updateuseradmin) | **PUT** /admin/users/{id} | *UsersAdminApi* | [**updateUserAdmin**](doc//UsersAdminApi.md#updateuseradmin) | **PUT** /admin/users/{id} |
@ -389,6 +394,7 @@ Class | Method | HTTP request | Description
- [PersonUpdateDto](doc//PersonUpdateDto.md) - [PersonUpdateDto](doc//PersonUpdateDto.md)
- [PersonWithFacesResponseDto](doc//PersonWithFacesResponseDto.md) - [PersonWithFacesResponseDto](doc//PersonWithFacesResponseDto.md)
- [PinCodeChangeDto](doc//PinCodeChangeDto.md) - [PinCodeChangeDto](doc//PinCodeChangeDto.md)
- [PinCodeResetDto](doc//PinCodeResetDto.md)
- [PinCodeSetupDto](doc//PinCodeSetupDto.md) - [PinCodeSetupDto](doc//PinCodeSetupDto.md)
- [PlacesResponseDto](doc//PlacesResponseDto.md) - [PlacesResponseDto](doc//PlacesResponseDto.md)
- [PurchaseResponse](doc//PurchaseResponse.md) - [PurchaseResponse](doc//PurchaseResponse.md)
@ -418,7 +424,10 @@ Class | Method | HTTP request | Description
- [ServerThemeDto](doc//ServerThemeDto.md) - [ServerThemeDto](doc//ServerThemeDto.md)
- [ServerVersionHistoryResponseDto](doc//ServerVersionHistoryResponseDto.md) - [ServerVersionHistoryResponseDto](doc//ServerVersionHistoryResponseDto.md)
- [ServerVersionResponseDto](doc//ServerVersionResponseDto.md) - [ServerVersionResponseDto](doc//ServerVersionResponseDto.md)
- [SessionCreateDto](doc//SessionCreateDto.md)
- [SessionCreateResponseDto](doc//SessionCreateResponseDto.md)
- [SessionResponseDto](doc//SessionResponseDto.md) - [SessionResponseDto](doc//SessionResponseDto.md)
- [SessionUnlockDto](doc//SessionUnlockDto.md)
- [SharedLinkCreateDto](doc//SharedLinkCreateDto.md) - [SharedLinkCreateDto](doc//SharedLinkCreateDto.md)
- [SharedLinkEditDto](doc//SharedLinkEditDto.md) - [SharedLinkEditDto](doc//SharedLinkEditDto.md)
- [SharedLinkResponseDto](doc//SharedLinkResponseDto.md) - [SharedLinkResponseDto](doc//SharedLinkResponseDto.md)

View File

@ -189,6 +189,7 @@ part 'model/person_statistics_response_dto.dart';
part 'model/person_update_dto.dart'; part 'model/person_update_dto.dart';
part 'model/person_with_faces_response_dto.dart'; part 'model/person_with_faces_response_dto.dart';
part 'model/pin_code_change_dto.dart'; part 'model/pin_code_change_dto.dart';
part 'model/pin_code_reset_dto.dart';
part 'model/pin_code_setup_dto.dart'; part 'model/pin_code_setup_dto.dart';
part 'model/places_response_dto.dart'; part 'model/places_response_dto.dart';
part 'model/purchase_response.dart'; part 'model/purchase_response.dart';
@ -218,7 +219,10 @@ part 'model/server_storage_response_dto.dart';
part 'model/server_theme_dto.dart'; part 'model/server_theme_dto.dart';
part 'model/server_version_history_response_dto.dart'; part 'model/server_version_history_response_dto.dart';
part 'model/server_version_response_dto.dart'; part 'model/server_version_response_dto.dart';
part 'model/session_create_dto.dart';
part 'model/session_create_response_dto.dart';
part 'model/session_response_dto.dart'; part 'model/session_response_dto.dart';
part 'model/session_unlock_dto.dart';
part 'model/shared_link_create_dto.dart'; part 'model/shared_link_create_dto.dart';
part 'model/shared_link_edit_dto.dart'; part 'model/shared_link_edit_dto.dart';
part 'model/shared_link_response_dto.dart'; part 'model/shared_link_response_dto.dart';

View File

@ -143,6 +143,39 @@ class AuthenticationApi {
return null; return null;
} }
/// Performs an HTTP 'POST /auth/session/lock' operation and returns the [Response].
Future<Response> lockAuthSessionWithHttpInfo() async {
// ignore: prefer_const_declarations
final apiPath = r'/auth/session/lock';
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>[];
return apiClient.invokeAPI(
apiPath,
'POST',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
Future<void> lockAuthSession() async {
final response = await lockAuthSessionWithHttpInfo();
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
}
}
/// Performs an HTTP 'POST /auth/login' operation and returns the [Response]. /// Performs an HTTP 'POST /auth/login' operation and returns the [Response].
/// Parameters: /// Parameters:
/// ///
@ -234,13 +267,13 @@ class AuthenticationApi {
/// Performs an HTTP 'DELETE /auth/pin-code' operation and returns the [Response]. /// Performs an HTTP 'DELETE /auth/pin-code' operation and returns the [Response].
/// Parameters: /// Parameters:
/// ///
/// * [PinCodeChangeDto] pinCodeChangeDto (required): /// * [PinCodeResetDto] pinCodeResetDto (required):
Future<Response> resetPinCodeWithHttpInfo(PinCodeChangeDto pinCodeChangeDto,) async { Future<Response> resetPinCodeWithHttpInfo(PinCodeResetDto pinCodeResetDto,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/auth/pin-code'; final apiPath = r'/auth/pin-code';
// ignore: prefer_final_locals // ignore: prefer_final_locals
Object? postBody = pinCodeChangeDto; Object? postBody = pinCodeResetDto;
final queryParams = <QueryParam>[]; final queryParams = <QueryParam>[];
final headerParams = <String, String>{}; final headerParams = <String, String>{};
@ -262,9 +295,9 @@ class AuthenticationApi {
/// Parameters: /// Parameters:
/// ///
/// * [PinCodeChangeDto] pinCodeChangeDto (required): /// * [PinCodeResetDto] pinCodeResetDto (required):
Future<void> resetPinCode(PinCodeChangeDto pinCodeChangeDto,) async { Future<void> resetPinCode(PinCodeResetDto pinCodeResetDto,) async {
final response = await resetPinCodeWithHttpInfo(pinCodeChangeDto,); final response = await resetPinCodeWithHttpInfo(pinCodeResetDto,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response)); throw ApiException(response.statusCode, await _decodeBodyBytes(response));
} }
@ -356,6 +389,45 @@ class AuthenticationApi {
return null; return null;
} }
/// Performs an HTTP 'POST /auth/session/unlock' operation and returns the [Response].
/// Parameters:
///
/// * [SessionUnlockDto] sessionUnlockDto (required):
Future<Response> unlockAuthSessionWithHttpInfo(SessionUnlockDto sessionUnlockDto,) async {
// ignore: prefer_const_declarations
final apiPath = r'/auth/session/unlock';
// ignore: prefer_final_locals
Object? postBody = sessionUnlockDto;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>['application/json'];
return apiClient.invokeAPI(
apiPath,
'POST',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [SessionUnlockDto] sessionUnlockDto (required):
Future<void> unlockAuthSession(SessionUnlockDto sessionUnlockDto,) async {
final response = await unlockAuthSessionWithHttpInfo(sessionUnlockDto,);
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
}
}
/// Performs an HTTP 'POST /auth/validateToken' operation and returns the [Response]. /// Performs an HTTP 'POST /auth/validateToken' operation and returns the [Response].
Future<Response> validateAccessTokenWithHttpInfo() async { Future<Response> validateAccessTokenWithHttpInfo() async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations

View File

@ -16,6 +16,53 @@ class SessionsApi {
final ApiClient apiClient; final ApiClient apiClient;
/// Performs an HTTP 'POST /sessions' operation and returns the [Response].
/// Parameters:
///
/// * [SessionCreateDto] sessionCreateDto (required):
Future<Response> createSessionWithHttpInfo(SessionCreateDto sessionCreateDto,) async {
// ignore: prefer_const_declarations
final apiPath = r'/sessions';
// ignore: prefer_final_locals
Object? postBody = sessionCreateDto;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>['application/json'];
return apiClient.invokeAPI(
apiPath,
'POST',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [SessionCreateDto] sessionCreateDto (required):
Future<SessionCreateResponseDto?> createSession(SessionCreateDto sessionCreateDto,) async {
final response = await createSessionWithHttpInfo(sessionCreateDto,);
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'SessionCreateResponseDto',) as SessionCreateResponseDto;
}
return null;
}
/// Performs an HTTP 'DELETE /sessions' operation and returns the [Response]. /// Performs an HTTP 'DELETE /sessions' operation and returns the [Response].
Future<Response> deleteAllSessionsWithHttpInfo() async { Future<Response> deleteAllSessionsWithHttpInfo() async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
@ -132,4 +179,44 @@ class SessionsApi {
} }
return null; return null;
} }
/// Performs an HTTP 'POST /sessions/{id}/lock' operation and returns the [Response].
/// Parameters:
///
/// * [String] id (required):
Future<Response> lockSessionWithHttpInfo(String id,) async {
// ignore: prefer_const_declarations
final apiPath = r'/sessions/{id}/lock'
.replaceAll('{id}', id);
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>[];
return apiClient.invokeAPI(
apiPath,
'POST',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [String] id (required):
Future<void> lockSession(String id,) async {
final response = await lockSessionWithHttpInfo(id,);
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
}
}
} }

View File

@ -211,6 +211,76 @@ class UsersAdminApi {
return null; return null;
} }
/// Performs an HTTP 'GET /admin/users/{id}/statistics' operation and returns the [Response].
/// Parameters:
///
/// * [String] id (required):
///
/// * [bool] isFavorite:
///
/// * [bool] isTrashed:
///
/// * [AssetVisibility] visibility:
Future<Response> getUserStatisticsAdminWithHttpInfo(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async {
// ignore: prefer_const_declarations
final apiPath = r'/admin/users/{id}/statistics'
.replaceAll('{id}', id);
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
if (isFavorite != null) {
queryParams.addAll(_queryParams('', 'isFavorite', isFavorite));
}
if (isTrashed != null) {
queryParams.addAll(_queryParams('', 'isTrashed', isTrashed));
}
if (visibility != null) {
queryParams.addAll(_queryParams('', 'visibility', visibility));
}
const contentTypes = <String>[];
return apiClient.invokeAPI(
apiPath,
'GET',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [String] id (required):
///
/// * [bool] isFavorite:
///
/// * [bool] isTrashed:
///
/// * [AssetVisibility] visibility:
Future<AssetStatsResponseDto?> getUserStatisticsAdmin(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async {
final response = await getUserStatisticsAdminWithHttpInfo(id, isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, );
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'AssetStatsResponseDto',) as AssetStatsResponseDto;
}
return null;
}
/// Performs an HTTP 'POST /admin/users/{id}/restore' operation and returns the [Response]. /// Performs an HTTP 'POST /admin/users/{id}/restore' operation and returns the [Response].
/// Parameters: /// Parameters:
/// ///
@ -262,8 +332,10 @@ class UsersAdminApi {
/// Performs an HTTP 'GET /admin/users' operation and returns the [Response]. /// Performs an HTTP 'GET /admin/users' operation and returns the [Response].
/// Parameters: /// Parameters:
/// ///
/// * [String] id:
///
/// * [bool] withDeleted: /// * [bool] withDeleted:
Future<Response> searchUsersAdminWithHttpInfo({ bool? withDeleted, }) async { Future<Response> searchUsersAdminWithHttpInfo({ String? id, bool? withDeleted, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/admin/users'; final apiPath = r'/admin/users';
@ -274,6 +346,9 @@ class UsersAdminApi {
final headerParams = <String, String>{}; final headerParams = <String, String>{};
final formParams = <String, String>{}; final formParams = <String, String>{};
if (id != null) {
queryParams.addAll(_queryParams('', 'id', id));
}
if (withDeleted != null) { if (withDeleted != null) {
queryParams.addAll(_queryParams('', 'withDeleted', withDeleted)); queryParams.addAll(_queryParams('', 'withDeleted', withDeleted));
} }
@ -294,9 +369,11 @@ class UsersAdminApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id:
///
/// * [bool] withDeleted: /// * [bool] withDeleted:
Future<List<UserAdminResponseDto>?> searchUsersAdmin({ bool? withDeleted, }) async { Future<List<UserAdminResponseDto>?> searchUsersAdmin({ String? id, bool? withDeleted, }) async {
final response = await searchUsersAdminWithHttpInfo( withDeleted: withDeleted, ); final response = await searchUsersAdminWithHttpInfo( id: id, withDeleted: withDeleted, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response)); throw ApiException(response.statusCode, await _decodeBodyBytes(response));
} }

View File

@ -434,6 +434,8 @@ class ApiClient {
return PersonWithFacesResponseDto.fromJson(value); return PersonWithFacesResponseDto.fromJson(value);
case 'PinCodeChangeDto': case 'PinCodeChangeDto':
return PinCodeChangeDto.fromJson(value); return PinCodeChangeDto.fromJson(value);
case 'PinCodeResetDto':
return PinCodeResetDto.fromJson(value);
case 'PinCodeSetupDto': case 'PinCodeSetupDto':
return PinCodeSetupDto.fromJson(value); return PinCodeSetupDto.fromJson(value);
case 'PlacesResponseDto': case 'PlacesResponseDto':
@ -492,8 +494,14 @@ class ApiClient {
return ServerVersionHistoryResponseDto.fromJson(value); return ServerVersionHistoryResponseDto.fromJson(value);
case 'ServerVersionResponseDto': case 'ServerVersionResponseDto':
return ServerVersionResponseDto.fromJson(value); return ServerVersionResponseDto.fromJson(value);
case 'SessionCreateDto':
return SessionCreateDto.fromJson(value);
case 'SessionCreateResponseDto':
return SessionCreateResponseDto.fromJson(value);
case 'SessionResponseDto': case 'SessionResponseDto':
return SessionResponseDto.fromJson(value); return SessionResponseDto.fromJson(value);
case 'SessionUnlockDto':
return SessionUnlockDto.fromJson(value);
case 'SharedLinkCreateDto': case 'SharedLinkCreateDto':
return SharedLinkCreateDto.fromJson(value); return SharedLinkCreateDto.fromJson(value);
case 'SharedLinkEditDto': case 'SharedLinkEditDto':

View File

@ -43,6 +43,7 @@ class AssetResponseDto {
required this.type, required this.type,
this.unassignedFaces = const [], this.unassignedFaces = const [],
required this.updatedAt, required this.updatedAt,
required this.visibility,
}); });
/// base64 encoded sha1 hash /// base64 encoded sha1 hash
@ -132,6 +133,8 @@ class AssetResponseDto {
DateTime updatedAt; DateTime updatedAt;
AssetResponseDtoVisibilityEnum visibility;
@override @override
bool operator ==(Object other) => identical(this, other) || other is AssetResponseDto && bool operator ==(Object other) => identical(this, other) || other is AssetResponseDto &&
other.checksum == checksum && other.checksum == checksum &&
@ -163,7 +166,8 @@ class AssetResponseDto {
other.thumbhash == thumbhash && other.thumbhash == thumbhash &&
other.type == type && other.type == type &&
_deepEquality.equals(other.unassignedFaces, unassignedFaces) && _deepEquality.equals(other.unassignedFaces, unassignedFaces) &&
other.updatedAt == updatedAt; other.updatedAt == updatedAt &&
other.visibility == visibility;
@override @override
int get hashCode => int get hashCode =>
@ -197,10 +201,11 @@ class AssetResponseDto {
(thumbhash == null ? 0 : thumbhash!.hashCode) + (thumbhash == null ? 0 : thumbhash!.hashCode) +
(type.hashCode) + (type.hashCode) +
(unassignedFaces.hashCode) + (unassignedFaces.hashCode) +
(updatedAt.hashCode); (updatedAt.hashCode) +
(visibility.hashCode);
@override @override
String toString() => 'AssetResponseDto[checksum=$checksum, deviceAssetId=$deviceAssetId, deviceId=$deviceId, duplicateId=$duplicateId, duration=$duration, exifInfo=$exifInfo, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, hasMetadata=$hasMetadata, id=$id, isArchived=$isArchived, isFavorite=$isFavorite, isOffline=$isOffline, isTrashed=$isTrashed, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, originalMimeType=$originalMimeType, originalPath=$originalPath, owner=$owner, ownerId=$ownerId, people=$people, resized=$resized, stack=$stack, tags=$tags, thumbhash=$thumbhash, type=$type, unassignedFaces=$unassignedFaces, updatedAt=$updatedAt]'; String toString() => 'AssetResponseDto[checksum=$checksum, deviceAssetId=$deviceAssetId, deviceId=$deviceId, duplicateId=$duplicateId, duration=$duration, exifInfo=$exifInfo, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, hasMetadata=$hasMetadata, id=$id, isArchived=$isArchived, isFavorite=$isFavorite, isOffline=$isOffline, isTrashed=$isTrashed, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, originalMimeType=$originalMimeType, originalPath=$originalPath, owner=$owner, ownerId=$ownerId, people=$people, resized=$resized, stack=$stack, tags=$tags, thumbhash=$thumbhash, type=$type, unassignedFaces=$unassignedFaces, updatedAt=$updatedAt, visibility=$visibility]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -270,6 +275,7 @@ class AssetResponseDto {
json[r'type'] = this.type; json[r'type'] = this.type;
json[r'unassignedFaces'] = this.unassignedFaces; json[r'unassignedFaces'] = this.unassignedFaces;
json[r'updatedAt'] = this.updatedAt.toUtc().toIso8601String(); json[r'updatedAt'] = this.updatedAt.toUtc().toIso8601String();
json[r'visibility'] = this.visibility;
return json; return json;
} }
@ -312,6 +318,7 @@ class AssetResponseDto {
type: AssetTypeEnum.fromJson(json[r'type'])!, type: AssetTypeEnum.fromJson(json[r'type'])!,
unassignedFaces: AssetFaceWithoutPersonResponseDto.listFromJson(json[r'unassignedFaces']), unassignedFaces: AssetFaceWithoutPersonResponseDto.listFromJson(json[r'unassignedFaces']),
updatedAt: mapDateTime(json, r'updatedAt', r'')!, updatedAt: mapDateTime(json, r'updatedAt', r'')!,
visibility: AssetResponseDtoVisibilityEnum.fromJson(json[r'visibility'])!,
); );
} }
return null; return null;
@ -378,6 +385,87 @@ class AssetResponseDto {
'thumbhash', 'thumbhash',
'type', 'type',
'updatedAt', 'updatedAt',
'visibility',
}; };
} }
class AssetResponseDtoVisibilityEnum {
/// Instantiate a new enum with the provided [value].
const AssetResponseDtoVisibilityEnum._(this.value);
/// The underlying value of this enum member.
final String value;
@override
String toString() => value;
String toJson() => value;
static const archive = AssetResponseDtoVisibilityEnum._(r'archive');
static const timeline = AssetResponseDtoVisibilityEnum._(r'timeline');
static const hidden = AssetResponseDtoVisibilityEnum._(r'hidden');
static const locked = AssetResponseDtoVisibilityEnum._(r'locked');
/// List of all possible values in this [enum][AssetResponseDtoVisibilityEnum].
static const values = <AssetResponseDtoVisibilityEnum>[
archive,
timeline,
hidden,
locked,
];
static AssetResponseDtoVisibilityEnum? fromJson(dynamic value) => AssetResponseDtoVisibilityEnumTypeTransformer().decode(value);
static List<AssetResponseDtoVisibilityEnum> listFromJson(dynamic json, {bool growable = false,}) {
final result = <AssetResponseDtoVisibilityEnum>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = AssetResponseDtoVisibilityEnum.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
}
/// Transformation class that can [encode] an instance of [AssetResponseDtoVisibilityEnum] to String,
/// and [decode] dynamic data back to [AssetResponseDtoVisibilityEnum].
class AssetResponseDtoVisibilityEnumTypeTransformer {
factory AssetResponseDtoVisibilityEnumTypeTransformer() => _instance ??= const AssetResponseDtoVisibilityEnumTypeTransformer._();
const AssetResponseDtoVisibilityEnumTypeTransformer._();
String encode(AssetResponseDtoVisibilityEnum data) => data.value;
/// Decodes a [dynamic value][data] to a AssetResponseDtoVisibilityEnum.
///
/// 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.
AssetResponseDtoVisibilityEnum? decode(dynamic data, {bool allowNull = true}) {
if (data != null) {
switch (data) {
case r'archive': return AssetResponseDtoVisibilityEnum.archive;
case r'timeline': return AssetResponseDtoVisibilityEnum.timeline;
case r'hidden': return AssetResponseDtoVisibilityEnum.hidden;
case r'locked': return AssetResponseDtoVisibilityEnum.locked;
default:
if (!allowNull) {
throw ArgumentError('Unknown enum value to decode: $data');
}
}
}
return null;
}
/// Singleton [AssetResponseDtoVisibilityEnumTypeTransformer] instance.
static AssetResponseDtoVisibilityEnumTypeTransformer? _instance;
}

View File

@ -26,12 +26,14 @@ class AssetVisibility {
static const archive = AssetVisibility._(r'archive'); static const archive = AssetVisibility._(r'archive');
static const timeline = AssetVisibility._(r'timeline'); static const timeline = AssetVisibility._(r'timeline');
static const hidden = AssetVisibility._(r'hidden'); static const hidden = AssetVisibility._(r'hidden');
static const locked = AssetVisibility._(r'locked');
/// List of all possible values in this [enum][AssetVisibility]. /// List of all possible values in this [enum][AssetVisibility].
static const values = <AssetVisibility>[ static const values = <AssetVisibility>[
archive, archive,
timeline, timeline,
hidden, hidden,
locked,
]; ];
static AssetVisibility? fromJson(dynamic value) => AssetVisibilityTypeTransformer().decode(value); static AssetVisibility? fromJson(dynamic value) => AssetVisibilityTypeTransformer().decode(value);
@ -73,6 +75,7 @@ class AssetVisibilityTypeTransformer {
case r'archive': return AssetVisibility.archive; case r'archive': return AssetVisibility.archive;
case r'timeline': return AssetVisibility.timeline; case r'timeline': return AssetVisibility.timeline;
case r'hidden': return AssetVisibility.hidden; case r'hidden': return AssetVisibility.hidden;
case r'locked': return AssetVisibility.locked;
default: default:
if (!allowNull) { if (!allowNull) {
throw ArgumentError('Unknown enum value to decode: $data'); throw ArgumentError('Unknown enum value to decode: $data');

View File

@ -13,32 +13,70 @@ part of openapi.api;
class AuthStatusResponseDto { class AuthStatusResponseDto {
/// Returns a new [AuthStatusResponseDto] instance. /// Returns a new [AuthStatusResponseDto] instance.
AuthStatusResponseDto({ AuthStatusResponseDto({
this.expiresAt,
required this.isElevated,
required this.password, required this.password,
required this.pinCode, required this.pinCode,
this.pinExpiresAt,
}); });
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? expiresAt;
bool isElevated;
bool password; bool password;
bool pinCode; bool pinCode;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? pinExpiresAt;
@override @override
bool operator ==(Object other) => identical(this, other) || other is AuthStatusResponseDto && bool operator ==(Object other) => identical(this, other) || other is AuthStatusResponseDto &&
other.expiresAt == expiresAt &&
other.isElevated == isElevated &&
other.password == password && other.password == password &&
other.pinCode == pinCode; other.pinCode == pinCode &&
other.pinExpiresAt == pinExpiresAt;
@override @override
int get hashCode => int get hashCode =>
// ignore: unnecessary_parenthesis // ignore: unnecessary_parenthesis
(expiresAt == null ? 0 : expiresAt!.hashCode) +
(isElevated.hashCode) +
(password.hashCode) + (password.hashCode) +
(pinCode.hashCode); (pinCode.hashCode) +
(pinExpiresAt == null ? 0 : pinExpiresAt!.hashCode);
@override @override
String toString() => 'AuthStatusResponseDto[password=$password, pinCode=$pinCode]'; String toString() => 'AuthStatusResponseDto[expiresAt=$expiresAt, isElevated=$isElevated, password=$password, pinCode=$pinCode, pinExpiresAt=$pinExpiresAt]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
if (this.expiresAt != null) {
json[r'expiresAt'] = this.expiresAt;
} else {
// json[r'expiresAt'] = null;
}
json[r'isElevated'] = this.isElevated;
json[r'password'] = this.password; json[r'password'] = this.password;
json[r'pinCode'] = this.pinCode; json[r'pinCode'] = this.pinCode;
if (this.pinExpiresAt != null) {
json[r'pinExpiresAt'] = this.pinExpiresAt;
} else {
// json[r'pinExpiresAt'] = null;
}
return json; return json;
} }
@ -51,8 +89,11 @@ class AuthStatusResponseDto {
final json = value.cast<String, dynamic>(); final json = value.cast<String, dynamic>();
return AuthStatusResponseDto( return AuthStatusResponseDto(
expiresAt: mapValueOfType<String>(json, r'expiresAt'),
isElevated: mapValueOfType<bool>(json, r'isElevated')!,
password: mapValueOfType<bool>(json, r'password')!, password: mapValueOfType<bool>(json, r'password')!,
pinCode: mapValueOfType<bool>(json, r'pinCode')!, pinCode: mapValueOfType<bool>(json, r'pinCode')!,
pinExpiresAt: mapValueOfType<String>(json, r'pinExpiresAt'),
); );
} }
return null; return null;
@ -100,6 +141,7 @@ class AuthStatusResponseDto {
/// The list of required keys that must be present in a JSON. /// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{ static const requiredKeys = <String>{
'isElevated',
'password', 'password',
'pinCode', 'pinCode',
}; };

View File

@ -81,9 +81,11 @@ class Permission {
static const personPeriodStatistics = Permission._(r'person.statistics'); static const personPeriodStatistics = Permission._(r'person.statistics');
static const personPeriodMerge = Permission._(r'person.merge'); static const personPeriodMerge = Permission._(r'person.merge');
static const personPeriodReassign = Permission._(r'person.reassign'); static const personPeriodReassign = Permission._(r'person.reassign');
static const sessionPeriodCreate = Permission._(r'session.create');
static const sessionPeriodRead = Permission._(r'session.read'); static const sessionPeriodRead = Permission._(r'session.read');
static const sessionPeriodUpdate = Permission._(r'session.update'); static const sessionPeriodUpdate = Permission._(r'session.update');
static const sessionPeriodDelete = Permission._(r'session.delete'); static const sessionPeriodDelete = Permission._(r'session.delete');
static const sessionPeriodLock = Permission._(r'session.lock');
static const sharedLinkPeriodCreate = Permission._(r'sharedLink.create'); static const sharedLinkPeriodCreate = Permission._(r'sharedLink.create');
static const sharedLinkPeriodRead = Permission._(r'sharedLink.read'); static const sharedLinkPeriodRead = Permission._(r'sharedLink.read');
static const sharedLinkPeriodUpdate = Permission._(r'sharedLink.update'); static const sharedLinkPeriodUpdate = Permission._(r'sharedLink.update');
@ -166,9 +168,11 @@ class Permission {
personPeriodStatistics, personPeriodStatistics,
personPeriodMerge, personPeriodMerge,
personPeriodReassign, personPeriodReassign,
sessionPeriodCreate,
sessionPeriodRead, sessionPeriodRead,
sessionPeriodUpdate, sessionPeriodUpdate,
sessionPeriodDelete, sessionPeriodDelete,
sessionPeriodLock,
sharedLinkPeriodCreate, sharedLinkPeriodCreate,
sharedLinkPeriodRead, sharedLinkPeriodRead,
sharedLinkPeriodUpdate, sharedLinkPeriodUpdate,
@ -286,9 +290,11 @@ class PermissionTypeTransformer {
case r'person.statistics': return Permission.personPeriodStatistics; case r'person.statistics': return Permission.personPeriodStatistics;
case r'person.merge': return Permission.personPeriodMerge; case r'person.merge': return Permission.personPeriodMerge;
case r'person.reassign': return Permission.personPeriodReassign; case r'person.reassign': return Permission.personPeriodReassign;
case r'session.create': return Permission.sessionPeriodCreate;
case r'session.read': return Permission.sessionPeriodRead; case r'session.read': return Permission.sessionPeriodRead;
case r'session.update': return Permission.sessionPeriodUpdate; case r'session.update': return Permission.sessionPeriodUpdate;
case r'session.delete': return Permission.sessionPeriodDelete; case r'session.delete': return Permission.sessionPeriodDelete;
case r'session.lock': return Permission.sessionPeriodLock;
case r'sharedLink.create': return Permission.sharedLinkPeriodCreate; case r'sharedLink.create': return Permission.sharedLinkPeriodCreate;
case r'sharedLink.read': return Permission.sharedLinkPeriodRead; case r'sharedLink.read': return Permission.sharedLinkPeriodRead;
case r'sharedLink.update': return Permission.sharedLinkPeriodUpdate; case r'sharedLink.update': return Permission.sharedLinkPeriodUpdate;

View File

@ -0,0 +1,125 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.18
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class PinCodeResetDto {
/// Returns a new [PinCodeResetDto] instance.
PinCodeResetDto({
this.password,
this.pinCode,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? password;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? pinCode;
@override
bool operator ==(Object other) => identical(this, other) || other is PinCodeResetDto &&
other.password == password &&
other.pinCode == pinCode;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(password == null ? 0 : password!.hashCode) +
(pinCode == null ? 0 : pinCode!.hashCode);
@override
String toString() => 'PinCodeResetDto[password=$password, pinCode=$pinCode]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.password != null) {
json[r'password'] = this.password;
} else {
// json[r'password'] = null;
}
if (this.pinCode != null) {
json[r'pinCode'] = this.pinCode;
} else {
// json[r'pinCode'] = null;
}
return json;
}
/// Returns a new [PinCodeResetDto] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static PinCodeResetDto? fromJson(dynamic value) {
upgradeDto(value, "PinCodeResetDto");
if (value is Map) {
final json = value.cast<String, dynamic>();
return PinCodeResetDto(
password: mapValueOfType<String>(json, r'password'),
pinCode: mapValueOfType<String>(json, r'pinCode'),
);
}
return null;
}
static List<PinCodeResetDto> listFromJson(dynamic json, {bool growable = false,}) {
final result = <PinCodeResetDto>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = PinCodeResetDto.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, PinCodeResetDto> mapFromJson(dynamic json) {
final map = <String, PinCodeResetDto>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PinCodeResetDto.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of PinCodeResetDto-objects as value to a dart map
static Map<String, List<PinCodeResetDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
final map = <String, List<PinCodeResetDto>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = PinCodeResetDto.listFromJson(entry.value, growable: growable,);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{
};
}

View File

@ -0,0 +1,145 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.18
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class SessionCreateDto {
/// Returns a new [SessionCreateDto] instance.
SessionCreateDto({
this.deviceOS,
this.deviceType,
this.duration,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? deviceOS;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? deviceType;
/// session duration, in seconds
///
/// Minimum value: 1
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
num? duration;
@override
bool operator ==(Object other) => identical(this, other) || other is SessionCreateDto &&
other.deviceOS == deviceOS &&
other.deviceType == deviceType &&
other.duration == duration;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(deviceOS == null ? 0 : deviceOS!.hashCode) +
(deviceType == null ? 0 : deviceType!.hashCode) +
(duration == null ? 0 : duration!.hashCode);
@override
String toString() => 'SessionCreateDto[deviceOS=$deviceOS, deviceType=$deviceType, duration=$duration]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.deviceOS != null) {
json[r'deviceOS'] = this.deviceOS;
} else {
// json[r'deviceOS'] = null;
}
if (this.deviceType != null) {
json[r'deviceType'] = this.deviceType;
} else {
// json[r'deviceType'] = null;
}
if (this.duration != null) {
json[r'duration'] = this.duration;
} else {
// json[r'duration'] = null;
}
return json;
}
/// Returns a new [SessionCreateDto] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static SessionCreateDto? fromJson(dynamic value) {
upgradeDto(value, "SessionCreateDto");
if (value is Map) {
final json = value.cast<String, dynamic>();
return SessionCreateDto(
deviceOS: mapValueOfType<String>(json, r'deviceOS'),
deviceType: mapValueOfType<String>(json, r'deviceType'),
duration: num.parse('${json[r'duration']}'),
);
}
return null;
}
static List<SessionCreateDto> listFromJson(dynamic json, {bool growable = false,}) {
final result = <SessionCreateDto>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = SessionCreateDto.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, SessionCreateDto> mapFromJson(dynamic json) {
final map = <String, SessionCreateDto>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = SessionCreateDto.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of SessionCreateDto-objects as value to a dart map
static Map<String, List<SessionCreateDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
final map = <String, List<SessionCreateDto>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = SessionCreateDto.listFromJson(entry.value, growable: growable,);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{
};
}

View File

@ -0,0 +1,164 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.18
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class SessionCreateResponseDto {
/// Returns a new [SessionCreateResponseDto] instance.
SessionCreateResponseDto({
required this.createdAt,
required this.current,
required this.deviceOS,
required this.deviceType,
this.expiresAt,
required this.id,
required this.token,
required this.updatedAt,
});
String createdAt;
bool current;
String deviceOS;
String deviceType;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? expiresAt;
String id;
String token;
String updatedAt;
@override
bool operator ==(Object other) => identical(this, other) || other is SessionCreateResponseDto &&
other.createdAt == createdAt &&
other.current == current &&
other.deviceOS == deviceOS &&
other.deviceType == deviceType &&
other.expiresAt == expiresAt &&
other.id == id &&
other.token == token &&
other.updatedAt == updatedAt;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(createdAt.hashCode) +
(current.hashCode) +
(deviceOS.hashCode) +
(deviceType.hashCode) +
(expiresAt == null ? 0 : expiresAt!.hashCode) +
(id.hashCode) +
(token.hashCode) +
(updatedAt.hashCode);
@override
String toString() => 'SessionCreateResponseDto[createdAt=$createdAt, current=$current, deviceOS=$deviceOS, deviceType=$deviceType, expiresAt=$expiresAt, id=$id, token=$token, updatedAt=$updatedAt]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json[r'createdAt'] = this.createdAt;
json[r'current'] = this.current;
json[r'deviceOS'] = this.deviceOS;
json[r'deviceType'] = this.deviceType;
if (this.expiresAt != null) {
json[r'expiresAt'] = this.expiresAt;
} else {
// json[r'expiresAt'] = null;
}
json[r'id'] = this.id;
json[r'token'] = this.token;
json[r'updatedAt'] = this.updatedAt;
return json;
}
/// Returns a new [SessionCreateResponseDto] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static SessionCreateResponseDto? fromJson(dynamic value) {
upgradeDto(value, "SessionCreateResponseDto");
if (value is Map) {
final json = value.cast<String, dynamic>();
return SessionCreateResponseDto(
createdAt: mapValueOfType<String>(json, r'createdAt')!,
current: mapValueOfType<bool>(json, r'current')!,
deviceOS: mapValueOfType<String>(json, r'deviceOS')!,
deviceType: mapValueOfType<String>(json, r'deviceType')!,
expiresAt: mapValueOfType<String>(json, r'expiresAt'),
id: mapValueOfType<String>(json, r'id')!,
token: mapValueOfType<String>(json, r'token')!,
updatedAt: mapValueOfType<String>(json, r'updatedAt')!,
);
}
return null;
}
static List<SessionCreateResponseDto> listFromJson(dynamic json, {bool growable = false,}) {
final result = <SessionCreateResponseDto>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = SessionCreateResponseDto.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, SessionCreateResponseDto> mapFromJson(dynamic json) {
final map = <String, SessionCreateResponseDto>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = SessionCreateResponseDto.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of SessionCreateResponseDto-objects as value to a dart map
static Map<String, List<SessionCreateResponseDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
final map = <String, List<SessionCreateResponseDto>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = SessionCreateResponseDto.listFromJson(entry.value, growable: growable,);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{
'createdAt',
'current',
'deviceOS',
'deviceType',
'id',
'token',
'updatedAt',
};
}

View File

@ -17,6 +17,7 @@ class SessionResponseDto {
required this.current, required this.current,
required this.deviceOS, required this.deviceOS,
required this.deviceType, required this.deviceType,
this.expiresAt,
required this.id, required this.id,
required this.updatedAt, required this.updatedAt,
}); });
@ -29,6 +30,14 @@ class SessionResponseDto {
String deviceType; String deviceType;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? expiresAt;
String id; String id;
String updatedAt; String updatedAt;
@ -39,6 +48,7 @@ class SessionResponseDto {
other.current == current && other.current == current &&
other.deviceOS == deviceOS && other.deviceOS == deviceOS &&
other.deviceType == deviceType && other.deviceType == deviceType &&
other.expiresAt == expiresAt &&
other.id == id && other.id == id &&
other.updatedAt == updatedAt; other.updatedAt == updatedAt;
@ -49,11 +59,12 @@ class SessionResponseDto {
(current.hashCode) + (current.hashCode) +
(deviceOS.hashCode) + (deviceOS.hashCode) +
(deviceType.hashCode) + (deviceType.hashCode) +
(expiresAt == null ? 0 : expiresAt!.hashCode) +
(id.hashCode) + (id.hashCode) +
(updatedAt.hashCode); (updatedAt.hashCode);
@override @override
String toString() => 'SessionResponseDto[createdAt=$createdAt, current=$current, deviceOS=$deviceOS, deviceType=$deviceType, id=$id, updatedAt=$updatedAt]'; String toString() => 'SessionResponseDto[createdAt=$createdAt, current=$current, deviceOS=$deviceOS, deviceType=$deviceType, expiresAt=$expiresAt, id=$id, updatedAt=$updatedAt]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -61,6 +72,11 @@ class SessionResponseDto {
json[r'current'] = this.current; json[r'current'] = this.current;
json[r'deviceOS'] = this.deviceOS; json[r'deviceOS'] = this.deviceOS;
json[r'deviceType'] = this.deviceType; json[r'deviceType'] = this.deviceType;
if (this.expiresAt != null) {
json[r'expiresAt'] = this.expiresAt;
} else {
// json[r'expiresAt'] = null;
}
json[r'id'] = this.id; json[r'id'] = this.id;
json[r'updatedAt'] = this.updatedAt; json[r'updatedAt'] = this.updatedAt;
return json; return json;
@ -79,6 +95,7 @@ class SessionResponseDto {
current: mapValueOfType<bool>(json, r'current')!, current: mapValueOfType<bool>(json, r'current')!,
deviceOS: mapValueOfType<String>(json, r'deviceOS')!, deviceOS: mapValueOfType<String>(json, r'deviceOS')!,
deviceType: mapValueOfType<String>(json, r'deviceType')!, deviceType: mapValueOfType<String>(json, r'deviceType')!,
expiresAt: mapValueOfType<String>(json, r'expiresAt'),
id: mapValueOfType<String>(json, r'id')!, id: mapValueOfType<String>(json, r'id')!,
updatedAt: mapValueOfType<String>(json, r'updatedAt')!, updatedAt: mapValueOfType<String>(json, r'updatedAt')!,
); );

View File

@ -0,0 +1,125 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.18
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class SessionUnlockDto {
/// Returns a new [SessionUnlockDto] instance.
SessionUnlockDto({
this.password,
this.pinCode,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? password;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? pinCode;
@override
bool operator ==(Object other) => identical(this, other) || other is SessionUnlockDto &&
other.password == password &&
other.pinCode == pinCode;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(password == null ? 0 : password!.hashCode) +
(pinCode == null ? 0 : pinCode!.hashCode);
@override
String toString() => 'SessionUnlockDto[password=$password, pinCode=$pinCode]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.password != null) {
json[r'password'] = this.password;
} else {
// json[r'password'] = null;
}
if (this.pinCode != null) {
json[r'pinCode'] = this.pinCode;
} else {
// json[r'pinCode'] = null;
}
return json;
}
/// Returns a new [SessionUnlockDto] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static SessionUnlockDto? fromJson(dynamic value) {
upgradeDto(value, "SessionUnlockDto");
if (value is Map) {
final json = value.cast<String, dynamic>();
return SessionUnlockDto(
password: mapValueOfType<String>(json, r'password'),
pinCode: mapValueOfType<String>(json, r'pinCode'),
);
}
return null;
}
static List<SessionUnlockDto> listFromJson(dynamic json, {bool growable = false,}) {
final result = <SessionUnlockDto>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = SessionUnlockDto.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, SessionUnlockDto> mapFromJson(dynamic json) {
final map = <String, SessionUnlockDto>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = SessionUnlockDto.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of SessionUnlockDto-objects as value to a dart map
static Map<String, List<SessionUnlockDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
final map = <String, List<SessionUnlockDto>>{};
if (json is Map && json.isNotEmpty) {
// ignore: parameter_assignments
json = json.cast<String, dynamic>();
for (final entry in json.entries) {
map[entry.key] = SessionUnlockDto.listFromJson(entry.value, growable: growable,);
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{
};
}

View File

@ -293,12 +293,14 @@ class SyncAssetV1VisibilityEnum {
static const archive = SyncAssetV1VisibilityEnum._(r'archive'); static const archive = SyncAssetV1VisibilityEnum._(r'archive');
static const timeline = SyncAssetV1VisibilityEnum._(r'timeline'); static const timeline = SyncAssetV1VisibilityEnum._(r'timeline');
static const hidden = SyncAssetV1VisibilityEnum._(r'hidden'); static const hidden = SyncAssetV1VisibilityEnum._(r'hidden');
static const locked = SyncAssetV1VisibilityEnum._(r'locked');
/// List of all possible values in this [enum][SyncAssetV1VisibilityEnum]. /// List of all possible values in this [enum][SyncAssetV1VisibilityEnum].
static const values = <SyncAssetV1VisibilityEnum>[ static const values = <SyncAssetV1VisibilityEnum>[
archive, archive,
timeline, timeline,
hidden, hidden,
locked,
]; ];
static SyncAssetV1VisibilityEnum? fromJson(dynamic value) => SyncAssetV1VisibilityEnumTypeTransformer().decode(value); static SyncAssetV1VisibilityEnum? fromJson(dynamic value) => SyncAssetV1VisibilityEnumTypeTransformer().decode(value);
@ -340,6 +342,7 @@ class SyncAssetV1VisibilityEnumTypeTransformer {
case r'archive': return SyncAssetV1VisibilityEnum.archive; case r'archive': return SyncAssetV1VisibilityEnum.archive;
case r'timeline': return SyncAssetV1VisibilityEnum.timeline; case r'timeline': return SyncAssetV1VisibilityEnum.timeline;
case r'hidden': return SyncAssetV1VisibilityEnum.hidden; case r'hidden': return SyncAssetV1VisibilityEnum.hidden;
case r'locked': return SyncAssetV1VisibilityEnum.locked;
default: default:
if (!allowNull) { if (!allowNull) {
throw ArgumentError('Unknown enum value to decode: $data'); throw ArgumentError('Unknown enum value to decode: $data');

View File

@ -345,6 +345,15 @@
"get": { "get": {
"operationId": "searchUsersAdmin", "operationId": "searchUsersAdmin",
"parameters": [ "parameters": [
{
"name": "id",
"required": false,
"in": "query",
"schema": {
"format": "uuid",
"type": "string"
}
},
{ {
"name": "withDeleted", "name": "withDeleted",
"required": false, "required": false,
@ -701,6 +710,72 @@
] ]
} }
}, },
"/admin/users/{id}/statistics": {
"get": {
"operationId": "getUserStatisticsAdmin",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"type": "string"
}
},
{
"name": "isFavorite",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "isTrashed",
"required": false,
"in": "query",
"schema": {
"type": "boolean"
}
},
{
"name": "visibility",
"required": false,
"in": "query",
"schema": {
"$ref": "#/components/schemas/AssetVisibility"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AssetStatsResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Users (admin)"
]
}
},
"/albums": { "/albums": {
"get": { "get": {
"operationId": "getAllAlbums", "operationId": "getAllAlbums",
@ -2302,7 +2377,7 @@
"content": { "content": {
"application/json": { "application/json": {
"schema": { "schema": {
"$ref": "#/components/schemas/PinCodeChangeDto" "$ref": "#/components/schemas/PinCodeResetDto"
} }
} }
}, },
@ -2395,6 +2470,66 @@
] ]
} }
}, },
"/auth/session/lock": {
"post": {
"operationId": "lockAuthSession",
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Authentication"
]
}
},
"/auth/session/unlock": {
"post": {
"operationId": "unlockAuthSession",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SessionUnlockDto"
}
}
},
"required": true
},
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Authentication"
]
}
},
"/auth/status": { "/auth/status": {
"get": { "get": {
"operationId": "getAuthStatus", "operationId": "getAuthStatus",
@ -5508,6 +5643,46 @@
"tags": [ "tags": [
"Sessions" "Sessions"
] ]
},
"post": {
"operationId": "createSession",
"parameters": [],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SessionCreateDto"
}
}
},
"required": true
},
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SessionCreateResponseDto"
}
}
},
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Sessions"
]
} }
}, },
"/sessions/{id}": { "/sessions/{id}": {
@ -5545,6 +5720,41 @@
] ]
} }
}, },
"/sessions/{id}/lock": {
"post": {
"operationId": "lockSession",
"parameters": [
{
"name": "id",
"required": true,
"in": "path",
"schema": {
"format": "uuid",
"type": "string"
}
}
],
"responses": {
"204": {
"description": ""
}
},
"security": [
{
"bearer": []
},
{
"cookie": []
},
{
"api_key": []
}
],
"tags": [
"Sessions"
]
}
},
"/shared-links": { "/shared-links": {
"get": { "get": {
"operationId": "getAllSharedLinks", "operationId": "getAllSharedLinks",
@ -9075,6 +9285,15 @@
"updatedAt": { "updatedAt": {
"format": "date-time", "format": "date-time",
"type": "string" "type": "string"
},
"visibility": {
"enum": [
"archive",
"timeline",
"hidden",
"locked"
],
"type": "string"
} }
}, },
"required": [ "required": [
@ -9096,7 +9315,8 @@
"ownerId", "ownerId",
"thumbhash", "thumbhash",
"type", "type",
"updatedAt" "updatedAt",
"visibility"
], ],
"type": "object" "type": "object"
}, },
@ -9151,7 +9371,8 @@
"enum": [ "enum": [
"archive", "archive",
"timeline", "timeline",
"hidden" "hidden",
"locked"
], ],
"type": "string" "type": "string"
}, },
@ -9166,14 +9387,24 @@
}, },
"AuthStatusResponseDto": { "AuthStatusResponseDto": {
"properties": { "properties": {
"expiresAt": {
"type": "string"
},
"isElevated": {
"type": "boolean"
},
"password": { "password": {
"type": "boolean" "type": "boolean"
}, },
"pinCode": { "pinCode": {
"type": "boolean" "type": "boolean"
},
"pinExpiresAt": {
"type": "string"
} }
}, },
"required": [ "required": [
"isElevated",
"password", "password",
"pinCode" "pinCode"
], ],
@ -10927,9 +11158,11 @@
"person.statistics", "person.statistics",
"person.merge", "person.merge",
"person.reassign", "person.reassign",
"session.create",
"session.read", "session.read",
"session.update", "session.update",
"session.delete", "session.delete",
"session.lock",
"sharedLink.create", "sharedLink.create",
"sharedLink.read", "sharedLink.read",
"sharedLink.update", "sharedLink.update",
@ -11131,6 +11364,18 @@
], ],
"type": "object" "type": "object"
}, },
"PinCodeResetDto": {
"properties": {
"password": {
"type": "string"
},
"pinCode": {
"example": "123456",
"type": "string"
}
},
"type": "object"
},
"PinCodeSetupDto": { "PinCodeSetupDto": {
"properties": { "properties": {
"pinCode": { "pinCode": {
@ -11913,6 +12158,60 @@
], ],
"type": "object" "type": "object"
}, },
"SessionCreateDto": {
"properties": {
"deviceOS": {
"type": "string"
},
"deviceType": {
"type": "string"
},
"duration": {
"description": "session duration, in seconds",
"minimum": 1,
"type": "number"
}
},
"type": "object"
},
"SessionCreateResponseDto": {
"properties": {
"createdAt": {
"type": "string"
},
"current": {
"type": "boolean"
},
"deviceOS": {
"type": "string"
},
"deviceType": {
"type": "string"
},
"expiresAt": {
"type": "string"
},
"id": {
"type": "string"
},
"token": {
"type": "string"
},
"updatedAt": {
"type": "string"
}
},
"required": [
"createdAt",
"current",
"deviceOS",
"deviceType",
"id",
"token",
"updatedAt"
],
"type": "object"
},
"SessionResponseDto": { "SessionResponseDto": {
"properties": { "properties": {
"createdAt": { "createdAt": {
@ -11927,6 +12226,9 @@
"deviceType": { "deviceType": {
"type": "string" "type": "string"
}, },
"expiresAt": {
"type": "string"
},
"id": { "id": {
"type": "string" "type": "string"
}, },
@ -11944,6 +12246,18 @@
], ],
"type": "object" "type": "object"
}, },
"SessionUnlockDto": {
"properties": {
"password": {
"type": "string"
},
"pinCode": {
"example": "123456",
"type": "string"
}
},
"type": "object"
},
"SharedLinkCreateDto": { "SharedLinkCreateDto": {
"properties": { "properties": {
"albumId": { "albumId": {
@ -12589,7 +12903,8 @@
"enum": [ "enum": [
"archive", "archive",
"timeline", "timeline",
"hidden" "hidden",
"locked"
], ],
"type": "string" "type": "string"
} }

View File

@ -1 +1 @@
22.14.0 22.15.0

View File

@ -12,7 +12,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.14.1", "@types/node": "^22.15.16",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
}, },
@ -23,9 +23,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.14.1", "version": "22.15.17",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",
"integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", "integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {

View File

@ -19,7 +19,7 @@
"@oazapfts/runtime": "^1.0.2" "@oazapfts/runtime": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.14.1", "@types/node": "^22.15.16",
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"repository": { "repository": {
@ -28,6 +28,6 @@
"directory": "open-api/typescript-sdk" "directory": "open-api/typescript-sdk"
}, },
"volta": { "volta": {
"node": "22.14.0" "node": "22.15.0"
} }
} }

View File

@ -224,6 +224,11 @@ export type UserPreferencesUpdateDto = {
sharedLinks?: SharedLinksUpdate; sharedLinks?: SharedLinksUpdate;
tags?: TagsUpdate; tags?: TagsUpdate;
}; };
export type AssetStatsResponseDto = {
images: number;
total: number;
videos: number;
};
export type AlbumUserResponseDto = { export type AlbumUserResponseDto = {
role: AlbumUserRole; role: AlbumUserRole;
user: UserResponseDto; user: UserResponseDto;
@ -324,6 +329,7 @@ export type AssetResponseDto = {
"type": AssetTypeEnum; "type": AssetTypeEnum;
unassignedFaces?: AssetFaceWithoutPersonResponseDto[]; unassignedFaces?: AssetFaceWithoutPersonResponseDto[];
updatedAt: string; updatedAt: string;
visibility: Visibility;
}; };
export type AlbumResponseDto = { export type AlbumResponseDto = {
albumName: string; albumName: string;
@ -462,11 +468,6 @@ export type AssetJobsDto = {
assetIds: string[]; assetIds: string[];
name: AssetJobName; name: AssetJobName;
}; };
export type AssetStatsResponseDto = {
images: number;
total: number;
videos: number;
};
export type UpdateAssetDto = { export type UpdateAssetDto = {
dateTimeOriginal?: string; dateTimeOriginal?: string;
description?: string; description?: string;
@ -511,17 +512,28 @@ export type LogoutResponseDto = {
redirectUri: string; redirectUri: string;
successful: boolean; successful: boolean;
}; };
export type PinCodeChangeDto = { export type PinCodeResetDto = {
newPinCode: string;
password?: string; password?: string;
pinCode?: string; pinCode?: string;
}; };
export type PinCodeSetupDto = { export type PinCodeSetupDto = {
pinCode: string; pinCode: string;
}; };
export type PinCodeChangeDto = {
newPinCode: string;
password?: string;
pinCode?: string;
};
export type SessionUnlockDto = {
password?: string;
pinCode?: string;
};
export type AuthStatusResponseDto = { export type AuthStatusResponseDto = {
expiresAt?: string;
isElevated: boolean;
password: boolean; password: boolean;
pinCode: boolean; pinCode: boolean;
pinExpiresAt?: string;
}; };
export type ValidateAccessTokenResponseDto = { export type ValidateAccessTokenResponseDto = {
authStatus: boolean; authStatus: boolean;
@ -1073,9 +1085,26 @@ export type SessionResponseDto = {
current: boolean; current: boolean;
deviceOS: string; deviceOS: string;
deviceType: string; deviceType: string;
expiresAt?: string;
id: string; id: string;
updatedAt: string; updatedAt: string;
}; };
export type SessionCreateDto = {
deviceOS?: string;
deviceType?: string;
/** session duration, in seconds */
duration?: number;
};
export type SessionCreateResponseDto = {
createdAt: string;
current: boolean;
deviceOS: string;
deviceType: string;
expiresAt?: string;
id: string;
token: string;
updatedAt: string;
};
export type SharedLinkResponseDto = { export type SharedLinkResponseDto = {
album?: AlbumResponseDto; album?: AlbumResponseDto;
allowDownload: boolean; allowDownload: boolean;
@ -1502,13 +1531,15 @@ export function sendTestEmailAdmin({ systemConfigSmtpDto }: {
body: systemConfigSmtpDto body: systemConfigSmtpDto
}))); })));
} }
export function searchUsersAdmin({ withDeleted }: { export function searchUsersAdmin({ id, withDeleted }: {
id?: string;
withDeleted?: boolean; withDeleted?: boolean;
}, opts?: Oazapfts.RequestOpts) { }, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{ return oazapfts.ok(oazapfts.fetchJson<{
status: 200; status: 200;
data: UserAdminResponseDto[]; data: UserAdminResponseDto[];
}>(`/admin/users${QS.query(QS.explode({ }>(`/admin/users${QS.query(QS.explode({
id,
withDeleted withDeleted
}))}`, { }))}`, {
...opts ...opts
@ -1596,6 +1627,23 @@ export function restoreUserAdmin({ id }: {
method: "POST" method: "POST"
})); }));
} }
export function getUserStatisticsAdmin({ id, isFavorite, isTrashed, visibility }: {
id: string;
isFavorite?: boolean;
isTrashed?: boolean;
visibility?: AssetVisibility;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 200;
data: AssetStatsResponseDto;
}>(`/admin/users/${encodeURIComponent(id)}/statistics${QS.query(QS.explode({
isFavorite,
isTrashed,
visibility
}))}`, {
...opts
}));
}
export function getAllAlbums({ assetId, shared }: { export function getAllAlbums({ assetId, shared }: {
assetId?: string; assetId?: string;
shared?: boolean; shared?: boolean;
@ -2030,13 +2078,13 @@ export function logout(opts?: Oazapfts.RequestOpts) {
method: "POST" method: "POST"
})); }));
} }
export function resetPinCode({ pinCodeChangeDto }: { export function resetPinCode({ pinCodeResetDto }: {
pinCodeChangeDto: PinCodeChangeDto; pinCodeResetDto: PinCodeResetDto;
}, opts?: Oazapfts.RequestOpts) { }, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText("/auth/pin-code", oazapfts.json({ return oazapfts.ok(oazapfts.fetchText("/auth/pin-code", oazapfts.json({
...opts, ...opts,
method: "DELETE", method: "DELETE",
body: pinCodeChangeDto body: pinCodeResetDto
}))); })));
} }
export function setupPinCode({ pinCodeSetupDto }: { export function setupPinCode({ pinCodeSetupDto }: {
@ -2057,6 +2105,21 @@ export function changePinCode({ pinCodeChangeDto }: {
body: pinCodeChangeDto body: pinCodeChangeDto
}))); })));
} }
export function lockAuthSession(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText("/auth/session/lock", {
...opts,
method: "POST"
}));
}
export function unlockAuthSession({ sessionUnlockDto }: {
sessionUnlockDto: SessionUnlockDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText("/auth/session/unlock", oazapfts.json({
...opts,
method: "POST",
body: sessionUnlockDto
})));
}
export function getAuthStatus(opts?: Oazapfts.RequestOpts) { export function getAuthStatus(opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{ return oazapfts.ok(oazapfts.fetchJson<{
status: 200; status: 200;
@ -2887,6 +2950,18 @@ export function getSessions(opts?: Oazapfts.RequestOpts) {
...opts ...opts
})); }));
} }
export function createSession({ sessionCreateDto }: {
sessionCreateDto: SessionCreateDto;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchJson<{
status: 201;
data: SessionCreateResponseDto;
}>("/sessions", oazapfts.json({
...opts,
method: "POST",
body: sessionCreateDto
})));
}
export function deleteSession({ id }: { export function deleteSession({ id }: {
id: string; id: string;
}, opts?: Oazapfts.RequestOpts) { }, opts?: Oazapfts.RequestOpts) {
@ -2895,6 +2970,14 @@ export function deleteSession({ id }: {
method: "DELETE" method: "DELETE"
})); }));
} }
export function lockSession({ id }: {
id: string;
}, opts?: Oazapfts.RequestOpts) {
return oazapfts.ok(oazapfts.fetchText(`/sessions/${encodeURIComponent(id)}/lock`, {
...opts,
method: "POST"
}));
}
export function getAllSharedLinks({ albumId }: { export function getAllSharedLinks({ albumId }: {
albumId?: string; albumId?: string;
}, opts?: Oazapfts.RequestOpts) { }, opts?: Oazapfts.RequestOpts) {
@ -3552,6 +3635,12 @@ export enum UserStatus {
Removing = "removing", Removing = "removing",
Deleted = "deleted" Deleted = "deleted"
} }
export enum AssetVisibility {
Archive = "archive",
Timeline = "timeline",
Hidden = "hidden",
Locked = "locked"
}
export enum AlbumUserRole { export enum AlbumUserRole {
Editor = "editor", Editor = "editor",
Viewer = "viewer" Viewer = "viewer"
@ -3567,6 +3656,12 @@ export enum AssetTypeEnum {
Audio = "AUDIO", Audio = "AUDIO",
Other = "OTHER" Other = "OTHER"
} }
export enum Visibility {
Archive = "archive",
Timeline = "timeline",
Hidden = "hidden",
Locked = "locked"
}
export enum AssetOrder { export enum AssetOrder {
Asc = "asc", Asc = "asc",
Desc = "desc" Desc = "desc"
@ -3636,9 +3731,11 @@ export enum Permission {
PersonStatistics = "person.statistics", PersonStatistics = "person.statistics",
PersonMerge = "person.merge", PersonMerge = "person.merge",
PersonReassign = "person.reassign", PersonReassign = "person.reassign",
SessionCreate = "session.create",
SessionRead = "session.read", SessionRead = "session.read",
SessionUpdate = "session.update", SessionUpdate = "session.update",
SessionDelete = "session.delete", SessionDelete = "session.delete",
SessionLock = "session.lock",
SharedLinkCreate = "sharedLink.create", SharedLinkCreate = "sharedLink.create",
SharedLinkRead = "sharedLink.read", SharedLinkRead = "sharedLink.read",
SharedLinkUpdate = "sharedLink.update", SharedLinkUpdate = "sharedLink.update",
@ -3661,11 +3758,6 @@ export enum Permission {
AdminUserUpdate = "admin.user.update", AdminUserUpdate = "admin.user.update",
AdminUserDelete = "admin.user.delete" AdminUserDelete = "admin.user.delete"
} }
export enum AssetVisibility {
Archive = "archive",
Timeline = "timeline",
Hidden = "hidden"
}
export enum AssetMediaStatus { export enum AssetMediaStatus {
Created = "created", Created = "created",
Replaced = "replaced", Replaced = "replaced",

View File

@ -1 +1 @@
22.14.0 22.15.0

View File

@ -1,5 +1,5 @@
# dev build # dev build
FROM ghcr.io/immich-app/base-server-dev:202504081114@sha256:250ab051cb0bdefdaf7d4069f3de9eada4c0288360ba1143a0e607a202b305b1 AS dev FROM ghcr.io/immich-app/base-server-dev:202505131114@sha256:cf4507bbbf307e9b6d8ee9418993321f2b85867da8ce14d0a20ccaf9574cb995 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
@ -43,7 +43,7 @@ RUN npm run build
# prod build # prod build
FROM ghcr.io/immich-app/base-server-prod:202504081114@sha256:8353bcbdb4e6579300adfa0d8b5892abefa42ebfc99740050cbfb38ab83a0605 FROM ghcr.io/immich-app/base-server-prod:202505061115@sha256:9971d3a089787f0bd01f4682141d3665bcf5efb3e101a88e394ffd25bee4eedb
WORKDIR /usr/src/app WORKDIR /usr/src/app
ENV NODE_ENV=production \ ENV NODE_ENV=production \

322
server/package-lock.json generated
View File

@ -92,9 +92,9 @@
"@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.14.1", "@types/node": "^22.15.16",
"@types/nodemailer": "^6.4.14", "@types/nodemailer": "^6.4.14",
"@types/picomatch": "^3.0.0", "@types/picomatch": "^4.0.0",
"@types/pngjs": "^6.0.5", "@types/pngjs": "^6.0.5",
"@types/react": "^19.0.0", "@types/react": "^19.0.0",
"@types/sanitize-html": "^2.13.0", "@types/sanitize-html": "^2.13.0",
@ -621,18 +621,18 @@
} }
}, },
"node_modules/@babel/helper-string-parser": { "node_modules/@babel/helper-string-parser": {
"version": "7.25.9", "version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@babel/helper-validator-identifier": { "node_modules/@babel/helper-validator-identifier": {
"version": "7.25.9", "version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@ -661,12 +661,12 @@
} }
}, },
"node_modules/@babel/parser": { "node_modules/@babel/parser": {
"version": "7.27.0", "version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz",
"integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/types": "^7.27.0" "@babel/types": "^7.27.1"
}, },
"bin": { "bin": {
"parser": "bin/babel-parser.js" "parser": "bin/babel-parser.js"
@ -717,13 +717,13 @@
} }
}, },
"node_modules/@babel/types": { "node_modules/@babel/types": {
"version": "7.27.0", "version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz",
"integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-string-parser": "^7.25.9", "@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.25.9" "@babel/helper-validator-identifier": "^7.27.1"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@ -899,9 +899,9 @@
} }
}, },
"node_modules/@eslint-community/eslint-utils": { "node_modules/@eslint-community/eslint-utils": {
"version": "4.6.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.0.tgz", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
"integrity": "sha512-WhCn7Z7TauhBtmzhvKpoQs0Wwb/kBcy4CwpuI0/eEIr2Lx2auxmulAzLr91wVZJaz47iUZdkXOK7WlAfxGKCnA==", "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -2630,9 +2630,9 @@
} }
}, },
"node_modules/@nestjs/swagger": { "node_modules/@nestjs/swagger": {
"version": "11.1.6", "version": "11.2.0",
"resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-11.1.6.tgz", "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-11.2.0.tgz",
"integrity": "sha512-W5OyhLqUHg8CDy4GC5LBYOyGIq3dxhKNliBZ7xf2Q95+oDzptb3LGp8vwwf1ItEjyGdxM+USDStQPg2oAcxEgw==", "integrity": "sha512-5wolt8GmpNcrQv34tIPUtPoV1EeFbCetm40Ij3+M0FNNnf2RJ3FyWfuQvI8SBlcJyfaounYVTKzKHreFXsUyOg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@microsoft/tsdoc": "0.15.1", "@microsoft/tsdoc": "0.15.1",
@ -5439,9 +5439,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.14.1", "version": "22.15.17",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",
"integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", "integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.21.0" "undici-types": "~6.21.0"
@ -5495,9 +5495,9 @@
} }
}, },
"node_modules/@types/picomatch": { "node_modules/@types/picomatch": {
"version": "3.0.2", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-3.0.2.tgz", "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-4.0.0.tgz",
"integrity": "sha512-n0i8TD3UDB7paoMMxA3Y65vUncFJXjcUf7lQY7YyKGl6031FNjfsLs6pdLFCy2GNFxItPJG8GvvpbZc2skH7WA==", "integrity": "sha512-J1Bng+wlyEERWSgJQU1Pi0HObCLVcr994xT/M+1wcl/yNRTGBupsCxthgkdYG+GCOMaQH7iSVUY3LJVBBqG7MQ==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -5526,9 +5526,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "19.1.2", "version": "19.1.3",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.2.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.3.tgz",
"integrity": "sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==", "integrity": "sha512-dLWQ+Z0CkIvK1J8+wrDPwGxEYFA4RAyHoZPxHVGspYmFVnwGSNT24cGIhFJrtfRnWVuW8X7NO52gCXmhkVUWGQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -5546,9 +5546,9 @@
} }
}, },
"node_modules/@types/sanitize-html": { "node_modules/@types/sanitize-html": {
"version": "2.15.0", "version": "2.16.0",
"resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.15.0.tgz", "resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-2.16.0.tgz",
"integrity": "sha512-71Z6PbYsVKfp4i6Jvr37s5ql6if1Q/iJQT80NbaSi7uGaG8CqBMXP0pk/EsURAOuGdk5IJCd/vnzKrR7S3Txsw==", "integrity": "sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -5685,21 +5685,21 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.0.tgz",
"integrity": "sha512-oUlH4h1ABavI4F0Xnl8/fOtML/eu8nI2A1nYd+f+55XI0BLu+RIqKoCiZKNo6DtqZBEQm5aNKA20G3Z5w3R6GQ==", "integrity": "sha512-/jU9ettcntkBFmWUzzGgsClEi2ZFiikMX5eEQsmxIAWMOn4H3D4rvHssstmAHGVvrYnaMqdWWWg0b5M6IN/MTQ==",
"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.31.1", "@typescript-eslint/scope-manager": "8.32.0",
"@typescript-eslint/type-utils": "8.31.1", "@typescript-eslint/type-utils": "8.32.0",
"@typescript-eslint/utils": "8.31.1", "@typescript-eslint/utils": "8.32.0",
"@typescript-eslint/visitor-keys": "8.31.1", "@typescript-eslint/visitor-keys": "8.32.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.1" "ts-api-utils": "^2.1.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5715,16 +5715,16 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.0.tgz",
"integrity": "sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q==", "integrity": "sha512-B2MdzyWxCE2+SqiZHAjPphft+/2x2FlO9YBx7eKE1BCb+rqBlQdhtAEhzIEdozHd55DXPmxBdpMygFJjfjjA9A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.31.1", "@typescript-eslint/scope-manager": "8.32.0",
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"@typescript-eslint/typescript-estree": "8.31.1", "@typescript-eslint/typescript-estree": "8.32.0",
"@typescript-eslint/visitor-keys": "8.31.1", "@typescript-eslint/visitor-keys": "8.32.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -5740,14 +5740,14 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.0.tgz",
"integrity": "sha512-BMNLOElPxrtNQMIsFHE+3P0Yf1z0dJqV9zLdDxN/xLlWMlXK/ApEsVEKzpizg9oal8bAT5Sc7+ocal7AC1HCVw==", "integrity": "sha512-jc/4IxGNedXkmG4mx4nJTILb6TMjL66D41vyeaPWvDUmeYQzF3lKtN15WsAeTr65ce4mPxwopPSo1yUUAWw0hQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"@typescript-eslint/visitor-keys": "8.31.1" "@typescript-eslint/visitor-keys": "8.32.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5758,16 +5758,16 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.0.tgz",
"integrity": "sha512-fNaT/m9n0+dpSp8G/iOQ05GoHYXbxw81x+yvr7TArTuZuCA6VVKbqWYVZrV5dVagpDTtj/O8k5HBEE/p/HM5LA==", "integrity": "sha512-t2vouuYQKEKSLtJaa5bB4jHeha2HJczQ6E5IXPDPgIty9EqcJxpr1QHQ86YyIPwDwxvUmLfP2YADQ5ZY4qddZg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "8.31.1", "@typescript-eslint/typescript-estree": "8.32.0",
"@typescript-eslint/utils": "8.31.1", "@typescript-eslint/utils": "8.32.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^2.0.1" "ts-api-utils": "^2.1.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5782,9 +5782,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.0.tgz",
"integrity": "sha512-SfepaEFUDQYRoA70DD9GtytljBePSj17qPxFHA/h3eg6lPTqGJ5mWOtbXCk1YrVU1cTJRd14nhaXWFu0l2troQ==", "integrity": "sha512-O5Id6tGadAZEMThM6L9HmVf5hQUXNSxLVKeGJYWNhhVseps/0LddMkp7//VDkzwJ69lPL0UmZdcZwggj9akJaA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -5796,20 +5796,20 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.0.tgz",
"integrity": "sha512-kaA0ueLe2v7KunYOyWYtlf/QhhZb7+qh4Yw6Ni5kgukMIG+iP773tjgBiLWIXYumWCwEq3nLW+TUywEp8uEeag==", "integrity": "sha512-pU9VD7anSCOIoBFnhTGfOzlVFQIA1XXiQpH/CezqOBaDppRwTglJzCC6fUQGpfwey4T183NKhF1/mfatYmjRqQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"@typescript-eslint/visitor-keys": "8.31.1", "@typescript-eslint/visitor-keys": "8.32.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.1" "ts-api-utils": "^2.1.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5849,16 +5849,16 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.0.tgz",
"integrity": "sha512-2DSI4SNfF5T4oRveQ4nUrSjUqjMND0nLq9rEkz0gfGr3tg0S5KB6DhwR+WZPCjzkZl3cH+4x2ce3EsL50FubjQ==", "integrity": "sha512-8S9hXau6nQ/sYVtC3D6ISIDoJzS1NsCK+gluVhLN2YkBPX+/1wkwyUiDKnxRh15579WoOIyVWnoyIf3yGI9REw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.31.1", "@typescript-eslint/scope-manager": "8.32.0",
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"@typescript-eslint/typescript-estree": "8.31.1" "@typescript-eslint/typescript-estree": "8.32.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5873,13 +5873,13 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.0.tgz",
"integrity": "sha512-I+/rgqOVBn6f0o7NDTmAPWWC6NuqhV174lfYvAm9fUaWeiefLdux9/YI3/nLugEn9L8fcSi0XmpKi/r5u0nmpw==", "integrity": "sha512-1rYQTCLFFzOI5Nl0c8LUpJT8HxpwVRn9E4CkMsYfuN6ctmQqExjSTzzSk0Tz2apmXy7WU6/6fyaZVVA/thPN+w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.31.1", "@typescript-eslint/types": "8.32.0",
"eslint-visitor-keys": "^4.2.0" "eslint-visitor-keys": "^4.2.0"
}, },
"engines": { "engines": {
@ -5891,9 +5891,9 @@
} }
}, },
"node_modules/@vitest/coverage-v8": { "node_modules/@vitest/coverage-v8": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.3.tgz",
"integrity": "sha512-XDdaDOeaTMAMYW7N63AqoK32sYUWbXnTkC6tEbVcu3RlU1bB9of32T+PGf8KZvxqLNqeXhafDFqCkwpf2+dyaQ==", "integrity": "sha512-cj76U5gXCl3g88KSnf80kof6+6w+K4BjOflCl7t6yRJPDuCrHtVu0SgNYOUARJOL5TI8RScDbm5x4s1/P9bvpw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -5914,8 +5914,8 @@
"url": "https://opencollective.com/vitest" "url": "https://opencollective.com/vitest"
}, },
"peerDependencies": { "peerDependencies": {
"@vitest/browser": "3.1.2", "@vitest/browser": "3.1.3",
"vitest": "3.1.2" "vitest": "3.1.3"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@vitest/browser": { "@vitest/browser": {
@ -5924,14 +5924,14 @@
} }
}, },
"node_modules/@vitest/expect": { "node_modules/@vitest/expect": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.3.tgz",
"integrity": "sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==", "integrity": "sha512-7FTQQuuLKmN1Ig/h+h/GO+44Q1IlglPlR2es4ab7Yvfx+Uk5xsv+Ykk+MEt/M2Yn/xGmzaLKxGw2lgy2bwuYqg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/spy": "3.1.2", "@vitest/spy": "3.1.3",
"@vitest/utils": "3.1.2", "@vitest/utils": "3.1.3",
"chai": "^5.2.0", "chai": "^5.2.0",
"tinyrainbow": "^2.0.0" "tinyrainbow": "^2.0.0"
}, },
@ -5940,13 +5940,13 @@
} }
}, },
"node_modules/@vitest/mocker": { "node_modules/@vitest/mocker": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.3.tgz",
"integrity": "sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==", "integrity": "sha512-PJbLjonJK82uCWHjzgBJZuR7zmAOrSvKk1QBxrennDIgtH4uK0TB1PvYmc0XBCigxxtiAVPfWtAdy4lpz8SQGQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/spy": "3.1.2", "@vitest/spy": "3.1.3",
"estree-walker": "^3.0.3", "estree-walker": "^3.0.3",
"magic-string": "^0.30.17" "magic-string": "^0.30.17"
}, },
@ -5977,9 +5977,9 @@
} }
}, },
"node_modules/@vitest/pretty-format": { "node_modules/@vitest/pretty-format": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.3.tgz",
"integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", "integrity": "sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -5990,13 +5990,13 @@
} }
}, },
"node_modules/@vitest/runner": { "node_modules/@vitest/runner": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.3.tgz",
"integrity": "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==", "integrity": "sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/utils": "3.1.2", "@vitest/utils": "3.1.3",
"pathe": "^2.0.3" "pathe": "^2.0.3"
}, },
"funding": { "funding": {
@ -6004,13 +6004,13 @@
} }
}, },
"node_modules/@vitest/snapshot": { "node_modules/@vitest/snapshot": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.3.tgz",
"integrity": "sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==", "integrity": "sha512-XVa5OPNTYUsyqG9skuUkFzAeFnEzDp8hQu7kZ0N25B1+6KjGm4hWLtURyBbsIAOekfWQ7Wuz/N/XXzgYO3deWQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/pretty-format": "3.1.2", "@vitest/pretty-format": "3.1.3",
"magic-string": "^0.30.17", "magic-string": "^0.30.17",
"pathe": "^2.0.3" "pathe": "^2.0.3"
}, },
@ -6019,9 +6019,9 @@
} }
}, },
"node_modules/@vitest/spy": { "node_modules/@vitest/spy": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.3.tgz",
"integrity": "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==", "integrity": "sha512-x6w+ctOEmEXdWaa6TO4ilb7l9DxPR5bwEb6hILKuxfU1NqWT2mpJD9NJN7t3OTfxmVlOMrvtoFJGdgyzZ605lQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -6032,13 +6032,13 @@
} }
}, },
"node_modules/@vitest/utils": { "node_modules/@vitest/utils": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.2.tgz", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.3.tgz",
"integrity": "sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==", "integrity": "sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/pretty-format": "3.1.2", "@vitest/pretty-format": "3.1.3",
"loupe": "^3.1.3", "loupe": "^3.1.3",
"tinyrainbow": "^2.0.0" "tinyrainbow": "^2.0.0"
}, },
@ -7044,9 +7044,9 @@
} }
}, },
"node_modules/bullmq": { "node_modules/bullmq": {
"version": "5.52.1", "version": "5.52.2",
"resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.52.1.tgz", "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.52.2.tgz",
"integrity": "sha512-u7CSV9wID3MBEX2DNubEErbAlrADgm8abUBAi6h8rQTnuTkhhgMs2iD7uhqplK8lIgUOkBIW3sDJWaMSInH47A==", "integrity": "sha512-fK/dKIv8ymyys4K+zeNEPA+yuYWzRPmBWUmwIMz8DvYekadl8VG19yUx94Na0n0cLAi+spdn3a/+ufkYK7CBUg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"cron-parser": "^4.9.0", "cron-parser": "^4.9.0",
@ -8797,9 +8797,9 @@
} }
}, },
"node_modules/es-module-lexer": { "node_modules/es-module-lexer": {
"version": "1.6.0", "version": "1.7.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
"integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -8960,9 +8960,9 @@
} }
}, },
"node_modules/eslint-config-prettier": { "node_modules/eslint-config-prettier": {
"version": "10.1.2", "version": "10.1.3",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.2.tgz", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.3.tgz",
"integrity": "sha512-Epgp/EofAUeEpIdZkW60MHKvPyru1ruQJxPL+WIycnaPApuseK0Zpkrh/FwL9oIpQvIhJwV7ptOy0DWUjTlCiA==", "integrity": "sha512-vDo4d9yQE+cS2tdIT4J02H/16veRvkHgiLDRpej+WL67oCfbOb97itZXn8wMPJ/GsiEBVjrjs//AVNw2Cp1EcA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
@ -8973,9 +8973,9 @@
} }
}, },
"node_modules/eslint-plugin-prettier": { "node_modules/eslint-plugin-prettier": {
"version": "5.3.1", "version": "5.4.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.3.1.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.0.tgz",
"integrity": "sha512-vad9VWgEm9xaVXRNmb4aeOt0PWDc61IAdzghkbYQ2wavgax148iKoX1rNJcgkBGCipzLzOnHYVgL7xudM9yccQ==", "integrity": "sha512-BvQOvUhkVQM1i63iMETK9Hjud9QhqBnbtT1Zc642p9ynzBuCe5pybkOnvqZIBypXmMlsGcnU4HZ8sCTPfpAexA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -10162,9 +10162,9 @@
} }
}, },
"node_modules/globals": { "node_modules/globals": {
"version": "16.0.0", "version": "16.1.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz", "resolved": "https://registry.npmjs.org/globals/-/globals-16.1.0.tgz",
"integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==", "integrity": "sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -12737,9 +12737,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/oauth4webapi": { "node_modules/oauth4webapi": {
"version": "3.5.0", "version": "3.5.1",
"resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.5.0.tgz", "resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.5.1.tgz",
"integrity": "sha512-DF3mLWNuxPkxJkHmWxbSFz4aE5CjWOsm465VBfBdWzmzX4Mg3vF8icxK+iKqfdWrIumBJ2TaoNQWx+SQc2bsPQ==", "integrity": "sha512-txg/jZQwcbaF7PMJgY7aoxc9QuCxHVFMiEkDIJ60DwDz3PbtXPQnrzo+3X4IRYGChIwWLabRBRpf1k9hO9+xrQ==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/panva" "url": "https://github.com/sponsors/panva"
@ -12848,13 +12848,13 @@
} }
}, },
"node_modules/openid-client": { "node_modules/openid-client": {
"version": "6.4.2", "version": "6.5.0",
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.4.2.tgz", "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.5.0.tgz",
"integrity": "sha512-4zBRTsKNRTyKxV5cFzl+LtamsYx/FsWhejjax+qgMkFNGtLj1gMtng2iSoJqqWUT0FHU3IUhO53aeBePg7Sp/g==", "integrity": "sha512-fAfYaTnOYE2kQCqEJGX9KDObW2aw7IQy4jWpU/+3D3WoCFLbix5Hg6qIPQ6Js9r7f8jDUmsnnguRNCSw4wU/IQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"jose": "^6.0.10", "jose": "^6.0.10",
"oauth4webapi": "^3.4.1" "oauth4webapi": "^3.5.1"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/panva" "url": "https://github.com/sponsors/panva"
@ -16800,9 +16800,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/typeorm": { "node_modules/typeorm": {
"version": "0.3.22", "version": "0.3.23",
"resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.22.tgz", "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.23.tgz",
"integrity": "sha512-P/Tsz3UpJ9+K0oryC0twK5PO27zejLYYwMsE8SISfZc1lVHX+ajigiOyWsKbuXpEFMjD9z7UjLzY3+ElVOMMDA==", "integrity": "sha512-CJUZWW7O5zZG0TA7bRpntJx97AvvQwsoSa1UgYlzTOtmkwODrqIyxP9wtzHpBssEKie5chnLiCVyxKNeYo65wQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@sqltools/formatter": "^1.2.5", "@sqltools/formatter": "^1.2.5",
@ -17031,15 +17031,15 @@
} }
}, },
"node_modules/typescript-eslint": { "node_modules/typescript-eslint": {
"version": "8.31.1", "version": "8.32.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.31.1.tgz", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.32.0.tgz",
"integrity": "sha512-j6DsEotD/fH39qKzXTQRwYYWlt7D+0HmfpOK+DVhwJOFLcdmn92hq3mBb7HlKJHbjjI/gTOqEcc9d6JfpFf/VA==", "integrity": "sha512-UMq2kxdXCzinFFPsXc9o2ozIpYCCOiEC46MG3yEh5Vipq6BO27otTtEBZA1fQ66DulEUgE97ucQ/3YY66CPg0A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/eslint-plugin": "8.31.1", "@typescript-eslint/eslint-plugin": "8.32.0",
"@typescript-eslint/parser": "8.31.1", "@typescript-eslint/parser": "8.32.0",
"@typescript-eslint/utils": "8.31.1" "@typescript-eslint/utils": "8.32.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -17447,15 +17447,15 @@
} }
}, },
"node_modules/vite-node": { "node_modules/vite-node": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.2.tgz", "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.3.tgz",
"integrity": "sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA==", "integrity": "sha512-uHV4plJ2IxCl4u1up1FQRrqclylKAogbtBfOTwcuJ28xFi+89PZ57BRh+naIRvH70HPwxy5QHYzg1OrEaC7AbA==",
"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.7.0",
"pathe": "^2.0.3", "pathe": "^2.0.3",
"vite": "^5.0.0 || ^6.0.0" "vite": "^5.0.0 || ^6.0.0"
}, },
@ -17577,19 +17577,19 @@
} }
}, },
"node_modules/vitest": { "node_modules/vitest": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.2.tgz", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.3.tgz",
"integrity": "sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ==", "integrity": "sha512-188iM4hAHQ0km23TN/adso1q5hhwKqUpv+Sd6p5sOuh6FhQnRNW3IsiIpvxqahtBabsJ2SLZgmGSpcYK4wQYJw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/expect": "3.1.2", "@vitest/expect": "3.1.3",
"@vitest/mocker": "3.1.2", "@vitest/mocker": "3.1.3",
"@vitest/pretty-format": "^3.1.2", "@vitest/pretty-format": "^3.1.3",
"@vitest/runner": "3.1.2", "@vitest/runner": "3.1.3",
"@vitest/snapshot": "3.1.2", "@vitest/snapshot": "3.1.3",
"@vitest/spy": "3.1.2", "@vitest/spy": "3.1.3",
"@vitest/utils": "3.1.2", "@vitest/utils": "3.1.3",
"chai": "^5.2.0", "chai": "^5.2.0",
"debug": "^4.4.0", "debug": "^4.4.0",
"expect-type": "^1.2.1", "expect-type": "^1.2.1",
@ -17602,7 +17602,7 @@
"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.1.2", "vite-node": "3.1.3",
"why-is-node-running": "^2.3.0" "why-is-node-running": "^2.3.0"
}, },
"bin": { "bin": {
@ -17618,8 +17618,8 @@
"@edge-runtime/vm": "*", "@edge-runtime/vm": "*",
"@types/debug": "^4.1.12", "@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.1.2", "@vitest/browser": "3.1.3",
"@vitest/ui": "3.1.2", "@vitest/ui": "3.1.3",
"happy-dom": "*", "happy-dom": "*",
"jsdom": "*" "jsdom": "*"
}, },

View File

@ -117,9 +117,9 @@
"@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.14.1", "@types/node": "^22.15.16",
"@types/nodemailer": "^6.4.14", "@types/nodemailer": "^6.4.14",
"@types/picomatch": "^3.0.0", "@types/picomatch": "^4.0.0",
"@types/pngjs": "^6.0.5", "@types/pngjs": "^6.0.5",
"@types/react": "^19.0.0", "@types/react": "^19.0.0",
"@types/sanitize-html": "^2.13.0", "@types/sanitize-html": "^2.13.0",
@ -154,7 +154,7 @@
"vitest": "^3.0.0" "vitest": "^3.0.0"
}, },
"volta": { "volta": {
"node": "22.14.0" "node": "22.15.0"
}, },
"overrides": { "overrides": {
"sharp": "^0.34.0" "sharp": "^0.34.0"

View File

@ -9,7 +9,9 @@ import {
LoginResponseDto, LoginResponseDto,
LogoutResponseDto, LogoutResponseDto,
PinCodeChangeDto, PinCodeChangeDto,
PinCodeResetDto,
PinCodeSetupDto, PinCodeSetupDto,
SessionUnlockDto,
SignUpDto, SignUpDto,
ValidateAccessTokenResponseDto, ValidateAccessTokenResponseDto,
} from 'src/dtos/auth.dto'; } from 'src/dtos/auth.dto';
@ -98,7 +100,21 @@ export class AuthController {
@Delete('pin-code') @Delete('pin-code')
@Authenticated() @Authenticated()
async resetPinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeChangeDto): Promise<void> { async resetPinCode(@Auth() auth: AuthDto, @Body() dto: PinCodeResetDto): Promise<void> {
return this.service.resetPinCode(auth, dto); return this.service.resetPinCode(auth, dto);
} }
@Post('session/unlock')
@HttpCode(HttpStatus.OK)
@Authenticated()
async unlockAuthSession(@Auth() auth: AuthDto, @Body() dto: SessionUnlockDto): Promise<void> {
return this.service.unlockSession(auth, dto);
}
@Post('session/lock')
@HttpCode(HttpStatus.OK)
@Authenticated()
async lockAuthSession(@Auth() auth: AuthDto): Promise<void> {
return this.service.lockSession(auth);
}
} }

View File

@ -66,7 +66,7 @@ describe(SearchController.name, () => {
.send({ visibility: 'immich' }); .send({ visibility: 'immich' });
expect(status).toBe(400); expect(status).toBe(400);
expect(body).toEqual( expect(body).toEqual(
errorDto.badRequest(['visibility must be one of the following values: archive, timeline, hidden']), errorDto.badRequest(['visibility must be one of the following values: archive, timeline, hidden, locked']),
); );
}); });

View File

@ -1,7 +1,7 @@
import { Controller, Delete, Get, HttpCode, HttpStatus, Param } from '@nestjs/common'; import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger'; import { ApiTags } from '@nestjs/swagger';
import { AuthDto } from 'src/dtos/auth.dto'; import { AuthDto } from 'src/dtos/auth.dto';
import { SessionResponseDto } from 'src/dtos/session.dto'; import { SessionCreateDto, SessionCreateResponseDto, SessionResponseDto } from 'src/dtos/session.dto';
import { Permission } from 'src/enum'; import { Permission } from 'src/enum';
import { Auth, Authenticated } from 'src/middleware/auth.guard'; import { Auth, Authenticated } from 'src/middleware/auth.guard';
import { SessionService } from 'src/services/session.service'; import { SessionService } from 'src/services/session.service';
@ -12,6 +12,12 @@ import { UUIDParamDto } from 'src/validation';
export class SessionController { export class SessionController {
constructor(private service: SessionService) {} constructor(private service: SessionService) {}
@Post()
@Authenticated({ permission: Permission.SESSION_CREATE })
createSession(@Auth() auth: AuthDto, @Body() dto: SessionCreateDto): Promise<SessionCreateResponseDto> {
return this.service.create(auth, dto);
}
@Get() @Get()
@Authenticated({ permission: Permission.SESSION_READ }) @Authenticated({ permission: Permission.SESSION_READ })
getSessions(@Auth() auth: AuthDto): Promise<SessionResponseDto[]> { getSessions(@Auth() auth: AuthDto): Promise<SessionResponseDto[]> {
@ -31,4 +37,11 @@ export class SessionController {
deleteSession(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> { deleteSession(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
return this.service.delete(auth, id); return this.service.delete(auth, id);
} }
@Post(':id/lock')
@Authenticated({ permission: Permission.SESSION_LOCK })
@HttpCode(HttpStatus.NO_CONTENT)
lockSession(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
return this.service.lock(auth, id);
}
} }

View File

@ -1,5 +1,6 @@
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common'; import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger'; import { ApiTags } from '@nestjs/swagger';
import { AssetStatsDto, AssetStatsResponseDto } from 'src/dtos/asset.dto';
import { AuthDto } from 'src/dtos/auth.dto'; import { AuthDto } from 'src/dtos/auth.dto';
import { UserPreferencesResponseDto, UserPreferencesUpdateDto } from 'src/dtos/user-preferences.dto'; import { UserPreferencesResponseDto, UserPreferencesUpdateDto } from 'src/dtos/user-preferences.dto';
import { import {
@ -57,6 +58,16 @@ export class UserAdminController {
return this.service.delete(auth, id, dto); return this.service.delete(auth, id, dto);
} }
@Get(':id/statistics')
@Authenticated({ permission: Permission.ADMIN_USER_READ, admin: true })
getUserStatisticsAdmin(
@Auth() auth: AuthDto,
@Param() { id }: UUIDParamDto,
@Query() dto: AssetStatsDto,
): Promise<AssetStatsResponseDto> {
return this.service.getStatistics(auth, id, dto);
}
@Get(':id/preferences') @Get(':id/preferences')
@Authenticated({ permission: Permission.ADMIN_USER_READ, admin: true }) @Authenticated({ permission: Permission.ADMIN_USER_READ, admin: true })
getUserPreferencesAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserPreferencesResponseDto> { getUserPreferencesAdmin(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<UserPreferencesResponseDto> {

View File

@ -200,6 +200,7 @@ export type Album = Selectable<Albums> & {
export type AuthSession = { export type AuthSession = {
id: string; id: string;
hasElevatedPermission: boolean;
}; };
export type Partner = { export type Partner = {
@ -231,8 +232,10 @@ export type Session = {
id: string; id: string;
createdAt: Date; createdAt: Date;
updatedAt: Date; updatedAt: Date;
expiresAt: Date | null;
deviceOS: string; deviceOS: string;
deviceType: string; deviceType: string;
pinExpiresAt: Date | null;
}; };
export type Exif = Omit<Selectable<DatabaseExif>, 'updatedAt' | 'updateId'>; export type Exif = Omit<Selectable<DatabaseExif>, 'updatedAt' | 'updateId'>;
@ -306,7 +309,7 @@ export const columns = {
'users.quotaSizeInBytes', 'users.quotaSizeInBytes',
], ],
authApiKey: ['api_keys.id', 'api_keys.permissions'], authApiKey: ['api_keys.id', 'api_keys.permissions'],
authSession: ['sessions.id', 'sessions.updatedAt'], authSession: ['sessions.id', 'sessions.updatedAt', 'sessions.pinExpiresAt'],
authSharedLink: [ authSharedLink: [
'shared_links.id', 'shared_links.id',
'shared_links.userId', 'shared_links.userId',

3
server/src/db.d.ts vendored
View File

@ -343,10 +343,13 @@ export interface Sessions {
deviceOS: Generated<string>; deviceOS: Generated<string>;
deviceType: Generated<string>; deviceType: Generated<string>;
id: Generated<string>; id: Generated<string>;
parentId: string | null;
expiresAt: Date | null;
token: string; token: string;
updatedAt: Generated<Timestamp>; updatedAt: Generated<Timestamp>;
updateId: Generated<string>; updateId: Generated<string>;
userId: string; userId: string;
pinExpiresAt: Timestamp | null;
} }
export interface SessionSyncCheckpoints { export interface SessionSyncCheckpoints {

View File

@ -43,6 +43,7 @@ export class AssetResponseDto extends SanitizedAssetResponseDto {
isArchived!: boolean; isArchived!: boolean;
isTrashed!: boolean; isTrashed!: boolean;
isOffline!: boolean; isOffline!: boolean;
visibility!: AssetVisibility;
exifInfo?: ExifResponseDto; exifInfo?: ExifResponseDto;
tags?: TagResponseDto[]; tags?: TagResponseDto[];
people?: PersonWithFacesResponseDto[]; people?: PersonWithFacesResponseDto[];
@ -184,6 +185,7 @@ export function mapAsset(entity: MapAsset, options: AssetMapOptions = {}): Asset
isFavorite: options.auth?.user.id === entity.ownerId ? entity.isFavorite : false, isFavorite: options.auth?.user.id === entity.ownerId ? entity.isFavorite : false,
isArchived: entity.visibility === AssetVisibility.ARCHIVE, isArchived: entity.visibility === AssetVisibility.ARCHIVE,
isTrashed: !!entity.deletedAt, isTrashed: !!entity.deletedAt,
visibility: entity.visibility,
duration: entity.duration ?? '0:00:00.00000', duration: entity.duration ?? '0:00:00.00000',
exifInfo: entity.exifInfo ? mapExif(entity.exifInfo) : undefined, exifInfo: entity.exifInfo ? mapExif(entity.exifInfo) : undefined,
livePhotoVideoId: entity.livePhotoVideoId, livePhotoVideoId: entity.livePhotoVideoId,

View File

@ -93,6 +93,8 @@ export class PinCodeResetDto {
password?: string; password?: string;
} }
export class SessionUnlockDto extends PinCodeResetDto {}
export class PinCodeChangeDto extends PinCodeResetDto { export class PinCodeChangeDto extends PinCodeResetDto {
@PinCode() @PinCode()
newPinCode!: string; newPinCode!: string;
@ -138,4 +140,7 @@ export class OAuthAuthorizeResponseDto {
export class AuthStatusResponseDto { export class AuthStatusResponseDto {
pinCode!: boolean; pinCode!: boolean;
password!: boolean; password!: boolean;
isElevated!: boolean;
expiresAt?: string;
pinExpiresAt?: string;
} }

View File

@ -1,18 +1,44 @@
import { IsInt, IsPositive, IsString } from 'class-validator';
import { Session } from 'src/database'; import { Session } from 'src/database';
import { Optional } from 'src/validation';
export class SessionCreateDto {
/**
* session duration, in seconds
*/
@IsInt()
@IsPositive()
@Optional()
duration?: number;
@IsString()
@Optional()
deviceType?: string;
@IsString()
@Optional()
deviceOS?: string;
}
export class SessionResponseDto { export class SessionResponseDto {
id!: string; id!: string;
createdAt!: string; createdAt!: string;
updatedAt!: string; updatedAt!: string;
expiresAt?: string;
current!: boolean; current!: boolean;
deviceType!: string; deviceType!: string;
deviceOS!: string; deviceOS!: string;
} }
export class SessionCreateResponseDto extends SessionResponseDto {
token!: string;
}
export const mapSession = (entity: Session, currentId?: string): SessionResponseDto => ({ export const mapSession = (entity: Session, 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(),
expiresAt: entity.expiresAt?.toISOString(),
current: currentId === entity.id, current: currentId === entity.id,
deviceOS: entity.deviceOS, deviceOS: entity.deviceOS,
deviceType: entity.deviceType, deviceType: entity.deviceType,

View File

@ -4,7 +4,7 @@ import { IsBoolean, IsEmail, IsEnum, IsNotEmpty, IsNumber, IsString, Min } from
import { User, UserAdmin } from 'src/database'; import { User, UserAdmin } from 'src/database';
import { UserAvatarColor, UserMetadataKey, UserStatus } from 'src/enum'; import { UserAvatarColor, UserMetadataKey, UserStatus } from 'src/enum';
import { UserMetadataItem } from 'src/types'; import { UserMetadataItem } from 'src/types';
import { Optional, PinCode, ValidateBoolean, toEmail, toSanitized } from 'src/validation'; import { Optional, PinCode, ValidateBoolean, ValidateUUID, toEmail, toSanitized } from 'src/validation';
export class UserUpdateMeDto { export class UserUpdateMeDto {
@Optional() @Optional()
@ -67,6 +67,9 @@ export const mapUser = (entity: User | UserAdmin): UserResponseDto => {
export class UserAdminSearchDto { export class UserAdminSearchDto {
@ValidateBoolean({ optional: true }) @ValidateBoolean({ optional: true })
withDeleted?: boolean; withDeleted?: boolean;
@ValidateUUID({ optional: true })
id?: string;
} }
export class UserAdminCreateDto { export class UserAdminCreateDto {

View File

@ -144,9 +144,11 @@ export enum Permission {
PERSON_MERGE = 'person.merge', PERSON_MERGE = 'person.merge',
PERSON_REASSIGN = 'person.reassign', PERSON_REASSIGN = 'person.reassign',
SESSION_CREATE = 'session.create',
SESSION_READ = 'session.read', SESSION_READ = 'session.read',
SESSION_UPDATE = 'session.update', SESSION_UPDATE = 'session.update',
SESSION_DELETE = 'session.delete', SESSION_DELETE = 'session.delete',
SESSION_LOCK = 'session.lock',
SHARED_LINK_CREATE = 'sharedLink.create', SHARED_LINK_CREATE = 'sharedLink.create',
SHARED_LINK_READ = 'sharedLink.read', SHARED_LINK_READ = 'sharedLink.read',
@ -627,4 +629,5 @@ export enum AssetVisibility {
* Video part of the LivePhotos and MotionPhotos * Video part of the LivePhotos and MotionPhotos
*/ */
HIDDEN = 'hidden', HIDDEN = 'hidden',
LOCKED = 'locked',
} }

View File

@ -98,6 +98,7 @@ from
where where
"assets"."id" in ($1) "assets"."id" in ($1)
and "assets"."ownerId" = $2 and "assets"."ownerId" = $2
and "assets"."visibility" != $3
-- AccessRepository.asset.checkPartnerAccess -- AccessRepository.asset.checkPartnerAccess
select select
@ -198,6 +199,15 @@ where
"partners"."sharedById" in ($1) "partners"."sharedById" in ($1)
and "partners"."sharedWithId" = $2 and "partners"."sharedWithId" = $2
-- AccessRepository.session.checkOwnerAccess
select
"sessions"."id"
from
"sessions"
where
"sessions"."id" in ($1)
and "sessions"."userId" = $2
-- AccessRepository.stack.checkOwnerAccess -- AccessRepository.stack.checkOwnerAccess
select select
"stacks"."id" "stacks"."id"

View File

@ -392,6 +392,11 @@ where
order by order by
"albums"."createdAt" desc "albums"."createdAt" desc
-- AlbumRepository.removeAssetsFromAll
delete from "albums_assets_assets"
where
"albums_assets_assets"."assetsId" in ($1)
-- AlbumRepository.getAssetIds -- AlbumRepository.getAssetIds
select select
* *

View File

@ -432,3 +432,34 @@ where
and "assets"."updatedAt" > $3 and "assets"."updatedAt" > $3
limit limit
$4 $4
-- AssetRepository.detectOfflineExternalAssets
update "assets"
set
"isOffline" = $1,
"deletedAt" = $2
where
"isOffline" = $3
and "isExternal" = $4
and "libraryId" = $5::uuid
and (
not "originalPath" like $6
or "originalPath" like $7
)
-- AssetRepository.filterNewExternalAssetPaths
select
"path"
from
unnest(array[$1]::text[]) as "path"
where
not exists (
select
"originalPath"
from
"assets"
where
"assets"."originalPath" = "path"
and "libraryId" = $2::uuid
and "isExternal" = $3
)

View File

@ -14,8 +14,3 @@ order by
"audit"."entityId" desc, "audit"."entityId" desc,
"audit"."entityType" desc, "audit"."entityType" desc,
"audit"."createdAt" desc "audit"."createdAt" desc
-- AuditRepository.removeBefore
delete from "audit"
where
"createdAt" < $1

View File

@ -1,11 +1,5 @@
-- NOTE: This file is auto generated by ./sql-generator -- NOTE: This file is auto generated by ./sql-generator
-- MemoryRepository.cleanup
delete from "memories"
where
"createdAt" < $1
and "isSaved" = $2
-- MemoryRepository.search -- MemoryRepository.search
select select
"memories".*, "memories".*,

View File

@ -16,19 +16,6 @@ where
returning returning
* *
-- MoveRepository.cleanMoveHistory
delete from "move_history"
where
"move_history"."entityId" not in (
select
"id"
from
"assets"
where
"assets"."id" = "move_history"."entityId"
)
and "move_history"."pathType" = 'original'
-- MoveRepository.cleanMoveHistorySingle -- MoveRepository.cleanMoveHistorySingle
delete from "move_history" delete from "move_history"
where where

View File

@ -1,23 +1,5 @@
-- NOTE: This file is auto generated by ./sql-generator -- NOTE: This file is auto generated by ./sql-generator
-- NotificationRepository.cleanup
delete from "notifications"
where
(
(
"deletedAt" is not null
and "deletedAt" < $1
)
or (
"readAt" > $2
and "createdAt" < $3
)
or (
"readAt" = $4
and "createdAt" < $5
)
)
-- NotificationRepository.search -- NotificationRepository.search
select select
"id", "id",

View File

@ -100,50 +100,6 @@ where
"sharedWithId" = $1 "sharedWithId" = $1
and "sharedById" = $2 and "sharedById" = $2
-- PartnerRepository.create
insert into
"partners" ("sharedWithId", "sharedById")
values
($1, $2)
returning
*,
(
select
to_json(obj)
from
(
select
"id",
"name",
"email",
"avatarColor",
"profileImagePath",
"profileChangedAt"
from
"users" as "sharedBy"
where
"sharedBy"."id" = "partners"."sharedById"
) as obj
) as "sharedBy",
(
select
to_json(obj)
from
(
select
"id",
"name",
"email",
"avatarColor",
"profileImagePath",
"profileChangedAt"
from
"users" as "sharedWith"
where
"sharedWith"."id" = "partners"."sharedWithId"
) as obj
) as "sharedWith"
-- PartnerRepository.update -- PartnerRepository.update
update "partners" update "partners"
set set

View File

@ -7,34 +7,10 @@ set
where where
"asset_faces"."personId" = $2 "asset_faces"."personId" = $2
-- PersonRepository.unassignFaces
update "asset_faces"
set
"personId" = $1
where
"asset_faces"."sourceType" = $2
VACUUM
ANALYZE asset_faces,
face_search,
person
REINDEX TABLE asset_faces
REINDEX TABLE person
-- PersonRepository.delete -- PersonRepository.delete
delete from "person" delete from "person"
where where
"person"."id" in $1 "person"."id" in ($1)
-- PersonRepository.deleteFaces
delete from "asset_faces"
where
"asset_faces"."sourceType" = $1
VACUUM
ANALYZE asset_faces,
face_search,
person
REINDEX TABLE asset_faces
REINDEX TABLE person
-- PersonRepository.getAllWithoutFaces -- PersonRepository.getAllWithoutFaces
select select
@ -145,18 +121,24 @@ select
"asset_faces"."imageHeight" as "oldHeight", "asset_faces"."imageHeight" as "oldHeight",
"assets"."type", "assets"."type",
"assets"."originalPath", "assets"."originalPath",
"asset_files"."path" as "previewPath", "exif"."orientation" as "exifOrientation",
"exif"."orientation" as "exifOrientation" (
select
"asset_files"."path"
from
"asset_files"
where
"asset_files"."assetId" = "assets"."id"
and "asset_files"."type" = 'preview'
) as "previewPath"
from from
"person" "person"
inner join "asset_faces" on "asset_faces"."id" = "person"."faceAssetId" inner join "asset_faces" on "asset_faces"."id" = "person"."faceAssetId"
inner join "assets" on "asset_faces"."assetId" = "assets"."id" inner join "assets" on "asset_faces"."assetId" = "assets"."id"
left join "exif" on "exif"."assetId" = "assets"."id" left join "exif" on "exif"."assetId" = "assets"."id"
left join "asset_files" on "asset_files"."assetId" = "assets"."id"
where where
"person"."id" = $1 "person"."id" = $1
and "asset_faces"."deletedAt" is null and "asset_faces"."deletedAt" is null
and "asset_files"."type" = $2
-- PersonRepository.reassignFace -- PersonRepository.reassignFace
update "asset_faces" update "asset_faces"
@ -222,21 +204,6 @@ where
"person"."ownerId" = $3 "person"."ownerId" = $3
and "asset_faces"."deletedAt" is null and "asset_faces"."deletedAt" is null
-- PersonRepository.refreshFaces
with
"added_embeddings" as (
insert into
"face_search" ("faceId", "embedding")
values
($1, $2)
)
select
from
(
select
1
) as "dummy"
-- PersonRepository.getFacesByIds -- PersonRepository.getFacesByIds
select select
"asset_faces".*, "asset_faces".*,

View File

@ -1,17 +1,20 @@
-- NOTE: This file is auto generated by ./sql-generator -- NOTE: This file is auto generated by ./sql-generator
-- SessionRepository.search -- SessionRepository.get
select select
* "id",
"expiresAt",
"pinExpiresAt"
from from
"sessions" "sessions"
where where
"sessions"."updatedAt" <= $1 "id" = $1
-- SessionRepository.getByToken -- SessionRepository.getByToken
select select
"sessions"."id", "sessions"."id",
"sessions"."updatedAt", "sessions"."updatedAt",
"sessions"."pinExpiresAt",
( (
select select
to_json(obj) to_json(obj)
@ -35,6 +38,10 @@ from
"sessions" "sessions"
where where
"sessions"."token" = $1 "sessions"."token" = $1
and (
"sessions"."expiresAt" is null
or "sessions"."expiresAt" > $2
)
-- SessionRepository.getByUserId -- SessionRepository.getByUserId
select select
@ -45,6 +52,10 @@ from
and "users"."deletedAt" is null and "users"."deletedAt" is null
where where
"sessions"."userId" = $1 "sessions"."userId" = $1
and (
"sessions"."expiresAt" is null
or "sessions"."expiresAt" > $2
)
order by order by
"sessions"."updatedAt" desc, "sessions"."updatedAt" desc,
"sessions"."createdAt" desc "sessions"."createdAt" desc
@ -53,3 +64,10 @@ order by
delete from "sessions" delete from "sessions"
where where
"id" = $1::uuid "id" = $1::uuid
-- SessionRepository.lockAll
update "sessions"
set
"pinExpiresAt" = $1
where
"userId" = $2

View File

@ -8,15 +8,6 @@ from
where where
"key" = $1 "key" = $1
-- SystemMetadataRepository.set
insert into
"system_metadata" ("key", "value")
values
($1, $2)
on conflict ("key") do update
set
"value" = $3
-- SystemMetadataRepository.delete -- SystemMetadataRepository.delete
delete from "system_metadata" delete from "system_metadata"
where where

View File

@ -58,7 +58,7 @@ from
where where
"userId" = $1 "userId" = $1
order by order by
"value" asc "value"
-- TagRepository.create -- TagRepository.create
insert into insert into
@ -94,6 +94,15 @@ where
"tagsId" = $1 "tagsId" = $1
and "assetsId" in ($2) and "assetsId" in ($2)
-- TagRepository.upsertAssetIds
insert into
"tag_asset" ("assetId", "tagsIds")
values
($1, $2)
on conflict do nothing
returning
*
-- TagRepository.replaceAssetTags -- TagRepository.replaceAssetTags
begin begin
delete from "tag_asset" delete from "tag_asset"
@ -107,17 +116,3 @@ on conflict do nothing
returning returning
* *
rollback rollback
-- TagRepository.deleteEmptyTags
begin
select
"tags"."id",
count("assets"."id") as "count"
from
"assets"
inner join "tag_asset" on "tag_asset"."assetsId" = "assets"."id"
inner join "tags_closure" on "tags_closure"."id_descendant" = "tag_asset"."tagsId"
inner join "tags" on "tags"."id" = "tags_closure"."id_descendant"
group by
"tags"."id"
commit

View File

@ -15,11 +15,3 @@ from
"version_history" "version_history"
order by order by
"createdAt" desc "createdAt" desc
-- VersionHistoryRepository.create
insert into
"version_history" ("version")
values
($1)
returning
*

View File

@ -168,7 +168,7 @@ class AssetAccess {
@GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] }) @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] })
@ChunkedSet({ paramIndex: 1 }) @ChunkedSet({ paramIndex: 1 })
async checkOwnerAccess(userId: string, assetIds: Set<string>) { async checkOwnerAccess(userId: string, assetIds: Set<string>, hasElevatedPermission: boolean | undefined) {
if (assetIds.size === 0) { if (assetIds.size === 0) {
return new Set<string>(); return new Set<string>();
} }
@ -178,6 +178,7 @@ class AssetAccess {
.select('assets.id') .select('assets.id')
.where('assets.id', 'in', [...assetIds]) .where('assets.id', 'in', [...assetIds])
.where('assets.ownerId', '=', userId) .where('assets.ownerId', '=', userId)
.$if(!hasElevatedPermission, (eb) => eb.where('assets.visibility', '!=', AssetVisibility.LOCKED))
.execute() .execute()
.then((assets) => new Set(assets.map((asset) => asset.id))); .then((assets) => new Set(assets.map((asset) => asset.id)));
} }
@ -305,6 +306,25 @@ class NotificationAccess {
} }
} }
class SessionAccess {
constructor(private db: Kysely<DB>) {}
@GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID_SET] })
@ChunkedSet({ paramIndex: 1 })
async checkOwnerAccess(userId: string, sessionIds: Set<string>) {
if (sessionIds.size === 0) {
return new Set<string>();
}
return this.db
.selectFrom('sessions')
.select('sessions.id')
.where('sessions.id', 'in', [...sessionIds])
.where('sessions.userId', '=', userId)
.execute()
.then((sessions) => new Set(sessions.map((session) => session.id)));
}
}
class StackAccess { class StackAccess {
constructor(private db: Kysely<DB>) {} constructor(private db: Kysely<DB>) {}
@ -455,6 +475,7 @@ export class AccessRepository {
notification: NotificationAccess; notification: NotificationAccess;
person: PersonAccess; person: PersonAccess;
partner: PartnerAccess; partner: PartnerAccess;
session: SessionAccess;
stack: StackAccess; stack: StackAccess;
tag: TagAccess; tag: TagAccess;
timeline: TimelineAccess; timeline: TimelineAccess;
@ -468,6 +489,7 @@ export class AccessRepository {
this.notification = new NotificationAccess(db); this.notification = new NotificationAccess(db);
this.person = new PersonAccess(db); this.person = new PersonAccess(db);
this.partner = new PartnerAccess(db); this.partner = new PartnerAccess(db);
this.session = new SessionAccess(db);
this.stack = new StackAccess(db); this.stack = new StackAccess(db);
this.tag = new TagAccess(db); this.tag = new TagAccess(db);
this.timeline = new TimelineAccess(db); this.timeline = new TimelineAccess(db);

View File

@ -220,8 +220,10 @@ export class AlbumRepository {
await this.db.deleteFrom('albums').where('ownerId', '=', userId).execute(); await this.db.deleteFrom('albums').where('ownerId', '=', userId).execute();
} }
async removeAsset(assetId: string): Promise<void> { @GenerateSql({ params: [[DummyValue.UUID]] })
await this.db.deleteFrom('albums_assets_assets').where('albums_assets_assets.assetsId', '=', assetId).execute(); @Chunked()
async removeAssetsFromAll(assetIds: string[]): Promise<void> {
await this.db.deleteFrom('albums_assets_assets').where('albums_assets_assets.assetsId', 'in', assetIds).execute();
} }
@Chunked({ paramIndex: 1 }) @Chunked({ paramIndex: 1 })

View File

@ -817,9 +817,7 @@ export class AssetRepository {
.execute(); .execute();
} }
@GenerateSql({ @GenerateSql({ params: [DummyValue.UUID, [DummyValue.STRING], [DummyValue.STRING]] })
params: [{ libraryId: DummyValue.UUID, importPaths: [DummyValue.STRING], exclusionPatterns: [DummyValue.STRING] }],
})
async detectOfflineExternalAssets( async detectOfflineExternalAssets(
libraryId: string, libraryId: string,
importPaths: string[], importPaths: string[],
@ -846,9 +844,7 @@ export class AssetRepository {
.executeTakeFirstOrThrow(); .executeTakeFirstOrThrow();
} }
@GenerateSql({ @GenerateSql({ params: [DummyValue.UUID, [DummyValue.STRING]] })
params: [{ libraryId: DummyValue.UUID, paths: [DummyValue.STRING] }],
})
async filterNewExternalAssetPaths(libraryId: string, paths: string[]): Promise<string[]> { async filterNewExternalAssetPaths(libraryId: string, paths: string[]): Promise<string[]> {
const result = await this.db const result = await this.db
.selectFrom(unnest(paths).as('path')) .selectFrom(unnest(paths).as('path'))

View File

@ -38,7 +38,6 @@ export class AuditRepository {
return records.map(({ entityId }) => entityId); return records.map(({ entityId }) => entityId);
} }
@GenerateSql({ params: [DummyValue.DATE] })
async removeBefore(before: Date): Promise<void> { async removeBefore(before: Date): Promise<void> {
await this.db.deleteFrom('audit').where('createdAt', '<', before).execute(); await this.db.deleteFrom('audit').where('createdAt', '<', before).execute();
} }

View File

@ -54,7 +54,7 @@ export class CryptoRepository {
}); });
} }
newPassword(bytes: number) { randomBytesAsText(bytes: number) {
return randomBytes(bytes).toString('base64').replaceAll(/\W/g, ''); return randomBytes(bytes).toString('base64').replaceAll(/\W/g, '');
} }
} }

View File

@ -12,7 +12,6 @@ import { IBulkAsset } from 'src/types';
export class MemoryRepository implements IBulkAsset { export class MemoryRepository implements IBulkAsset {
constructor(@InjectKysely() private db: Kysely<DB>) {} constructor(@InjectKysely() private db: Kysely<DB>) {}
@GenerateSql({ params: [DummyValue.UUID] })
cleanup() { cleanup() {
return this.db return this.db
.deleteFrom('memories') .deleteFrom('memories')

View File

@ -37,7 +37,6 @@ export class MoveRepository {
return this.db.deleteFrom('move_history').where('id', '=', id).returningAll().executeTakeFirstOrThrow(); return this.db.deleteFrom('move_history').where('id', '=', id).returningAll().executeTakeFirstOrThrow();
} }
@GenerateSql()
async cleanMoveHistory(): Promise<void> { async cleanMoveHistory(): Promise<void> {
await this.db await this.db
.deleteFrom('move_history') .deleteFrom('move_history')
@ -52,7 +51,7 @@ export class MoveRepository {
.execute(); .execute();
} }
@GenerateSql() @GenerateSql({ params: [DummyValue.UUID] })
async cleanMoveHistorySingle(assetId: string): Promise<void> { async cleanMoveHistorySingle(assetId: string): Promise<void> {
await this.db await this.db
.deleteFrom('move_history') .deleteFrom('move_history')

View File

@ -9,7 +9,6 @@ import { NotificationSearchDto } from 'src/dtos/notification.dto';
export class NotificationRepository { export class NotificationRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {} constructor(@InjectKysely() private db: Kysely<DB>) {}
@GenerateSql({ params: [DummyValue.UUID] })
cleanup() { cleanup() {
return this.db return this.db
.deleteFrom('notifications') .deleteFrom('notifications')

View File

@ -47,7 +47,6 @@ export class PartnerRepository {
.executeTakeFirst(); .executeTakeFirst();
} }
@GenerateSql({ params: [{ sharedWithId: DummyValue.UUID, sharedById: DummyValue.UUID }] })
create(values: Insertable<Partners>) { create(values: Insertable<Partners>) {
return this.db return this.db
.insertInto('partners') .insertInto('partners')

View File

@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { ExpressionBuilder, Insertable, Kysely, NotNull, Selectable, sql, Updateable } from 'kysely'; import { ExpressionBuilder, Insertable, Kysely, Selectable, sql, Updateable } from 'kysely';
import { jsonObjectFrom } from 'kysely/helpers/postgres'; import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely'; import { InjectKysely } from 'nestjs-kysely';
import { AssetFaces, DB, FaceSearch, Person } from 'src/db'; import { AssetFaces, DB, FaceSearch, Person } from 'src/db';
@ -98,18 +98,15 @@ export class PersonRepository {
return Number(result.numChangedRows ?? 0); return Number(result.numChangedRows ?? 0);
} }
@GenerateSql({ params: [{ sourceType: SourceType.EXIF }] })
async unassignFaces({ sourceType }: UnassignFacesOptions): Promise<void> { async unassignFaces({ sourceType }: UnassignFacesOptions): Promise<void> {
await this.db await this.db
.updateTable('asset_faces') .updateTable('asset_faces')
.set({ personId: null }) .set({ personId: null })
.where('asset_faces.sourceType', '=', sourceType) .where('asset_faces.sourceType', '=', sourceType)
.execute(); .execute();
await this.vacuum({ reindexVectors: false });
} }
@GenerateSql({ params: [DummyValue.UUID] }) @GenerateSql({ params: [[DummyValue.UUID]] })
async delete(ids: string[]): Promise<void> { async delete(ids: string[]): Promise<void> {
if (ids.length === 0) { if (ids.length === 0) {
return; return;
@ -118,11 +115,8 @@ export class PersonRepository {
await this.db.deleteFrom('person').where('person.id', 'in', ids).execute(); await this.db.deleteFrom('person').where('person.id', 'in', ids).execute();
} }
@GenerateSql({ params: [{ sourceType: SourceType.EXIF }] })
async deleteFaces({ sourceType }: DeleteFacesOptions): Promise<void> { async deleteFaces({ sourceType }: DeleteFacesOptions): Promise<void> {
await this.db.deleteFrom('asset_faces').where('asset_faces.sourceType', '=', sourceType).execute(); await this.db.deleteFrom('asset_faces').where('asset_faces.sourceType', '=', sourceType).execute();
await this.vacuum({ reindexVectors: sourceType === SourceType.MACHINE_LEARNING });
} }
getAllFaces(options: GetAllFacesOptions = {}) { getAllFaces(options: GetAllFacesOptions = {}) {
@ -265,7 +259,6 @@ export class PersonRepository {
.innerJoin('asset_faces', 'asset_faces.id', 'person.faceAssetId') .innerJoin('asset_faces', 'asset_faces.id', 'person.faceAssetId')
.innerJoin('assets', 'asset_faces.assetId', 'assets.id') .innerJoin('assets', 'asset_faces.assetId', 'assets.id')
.leftJoin('exif', 'exif.assetId', 'assets.id') .leftJoin('exif', 'exif.assetId', 'assets.id')
.leftJoin('asset_files', 'asset_files.assetId', 'assets.id')
.select([ .select([
'person.ownerId', 'person.ownerId',
'asset_faces.boundingBoxX1 as x1', 'asset_faces.boundingBoxX1 as x1',
@ -276,13 +269,18 @@ export class PersonRepository {
'asset_faces.imageHeight as oldHeight', 'asset_faces.imageHeight as oldHeight',
'assets.type', 'assets.type',
'assets.originalPath', 'assets.originalPath',
'asset_files.path as previewPath',
'exif.orientation as exifOrientation', 'exif.orientation as exifOrientation',
]) ])
.select((eb) =>
eb
.selectFrom('asset_files')
.select('asset_files.path')
.whereRef('asset_files.assetId', '=', 'assets.id')
.where('asset_files.type', '=', sql.lit(AssetFileType.PREVIEW))
.as('previewPath'),
)
.where('person.id', '=', id) .where('person.id', '=', id)
.where('asset_faces.deletedAt', 'is', null) .where('asset_faces.deletedAt', 'is', null)
.where('asset_files.type', '=', AssetFileType.PREVIEW)
.$narrowType<{ exifImageWidth: NotNull; exifImageHeight: NotNull }>()
.executeTakeFirst(); .executeTakeFirst();
} }
@ -400,7 +398,6 @@ export class PersonRepository {
return results.map(({ id }) => id); return results.map(({ id }) => id);
} }
@GenerateSql({ params: [[], [], [{ faceId: DummyValue.UUID, embedding: DummyValue.VECTOR }]] })
async refreshFaces( async refreshFaces(
facesToAdd: (Insertable<AssetFaces> & { assetId: string })[], facesToAdd: (Insertable<AssetFaces> & { assetId: string })[],
faceIdsToRemove: string[], faceIdsToRemove: string[],
@ -519,7 +516,7 @@ export class PersonRepository {
await this.db.updateTable('asset_faces').set({ deletedAt: new Date() }).where('asset_faces.id', '=', id).execute(); await this.db.updateTable('asset_faces').set({ deletedAt: new Date() }).where('asset_faces.id', '=', id).execute();
} }
private async vacuum({ reindexVectors }: { reindexVectors: boolean }): Promise<void> { async vacuum({ reindexVectors }: { reindexVectors: boolean }): Promise<void> {
await sql`VACUUM ANALYZE asset_faces, face_search, person`.execute(this.db); await sql`VACUUM ANALYZE asset_faces, face_search, person`.execute(this.db);
await sql`REINDEX TABLE asset_faces`.execute(this.db); await sql`REINDEX TABLE asset_faces`.execute(this.db);
await sql`REINDEX TABLE person`.execute(this.db); await sql`REINDEX TABLE person`.execute(this.db);

View File

@ -1,6 +1,7 @@
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 { jsonObjectFrom } from 'kysely/helpers/postgres';
import { DateTime } from 'luxon';
import { InjectKysely } from 'nestjs-kysely'; import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database'; import { columns } from 'src/database';
import { DB, Sessions } from 'src/db'; import { DB, Sessions } from 'src/db';
@ -13,13 +14,26 @@ export type SessionSearchOptions = { updatedBefore: Date };
export class SessionRepository { export class SessionRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {} constructor(@InjectKysely() private db: Kysely<DB>) {}
@GenerateSql({ params: [{ updatedBefore: DummyValue.DATE }] }) cleanup() {
search(options: SessionSearchOptions) { return this.db
.deleteFrom('sessions')
.where((eb) =>
eb.or([
eb('updatedAt', '<=', DateTime.now().minus({ days: 90 }).toJSDate()),
eb.and([eb('expiresAt', 'is not', null), eb('expiresAt', '<=', DateTime.now().toJSDate())]),
]),
)
.returning(['id', 'deviceOS', 'deviceType'])
.execute();
}
@GenerateSql({ params: [DummyValue.UUID] })
get(id: string) {
return this.db return this.db
.selectFrom('sessions') .selectFrom('sessions')
.selectAll() .select(['id', 'expiresAt', 'pinExpiresAt'])
.where('sessions.updatedAt', '<=', options.updatedBefore) .where('id', '=', id)
.execute(); .executeTakeFirst();
} }
@GenerateSql({ params: [DummyValue.STRING] }) @GenerateSql({ params: [DummyValue.STRING] })
@ -37,6 +51,9 @@ export class SessionRepository {
).as('user'), ).as('user'),
]) ])
.where('sessions.token', '=', token) .where('sessions.token', '=', token)
.where((eb) =>
eb.or([eb('sessions.expiresAt', 'is', null), eb('sessions.expiresAt', '>', DateTime.now().toJSDate())]),
)
.executeTakeFirst(); .executeTakeFirst();
} }
@ -47,6 +64,9 @@ export class SessionRepository {
.innerJoin('users', (join) => join.onRef('users.id', '=', 'sessions.userId').on('users.deletedAt', 'is', null)) .innerJoin('users', (join) => join.onRef('users.id', '=', 'sessions.userId').on('users.deletedAt', 'is', null))
.selectAll('sessions') .selectAll('sessions')
.where('sessions.userId', '=', userId) .where('sessions.userId', '=', userId)
.where((eb) =>
eb.or([eb('sessions.expiresAt', 'is', null), eb('sessions.expiresAt', '>', DateTime.now().toJSDate())]),
)
.orderBy('sessions.updatedAt', 'desc') .orderBy('sessions.updatedAt', 'desc')
.orderBy('sessions.createdAt', 'desc') .orderBy('sessions.createdAt', 'desc')
.execute(); .execute();
@ -69,4 +89,9 @@ export class SessionRepository {
async delete(id: string) { async delete(id: string) {
await this.db.deleteFrom('sessions').where('id', '=', asUuid(id)).execute(); await this.db.deleteFrom('sessions').where('id', '=', asUuid(id)).execute();
} }
@GenerateSql({ params: [DummyValue.UUID] })
async lockAll(userId: string) {
await this.db.updateTable('sessions').set({ pinExpiresAt: null }).where('userId', '=', userId).execute();
}
} }

View File

@ -26,7 +26,6 @@ export class SystemMetadataRepository {
return metadata.value as SystemMetadata[T]; return metadata.value as SystemMetadata[T];
} }
@GenerateSql({ params: ['metadata_key', { foo: 'bar' }] })
async set<T extends keyof SystemMetadata>(key: T, value: SystemMetadata[T]): Promise<void> { async set<T extends keyof SystemMetadata>(key: T, value: SystemMetadata[T]): Promise<void> {
await this.db await this.db
.insertInto('system_metadata') .insertInto('system_metadata')

View File

@ -68,7 +68,7 @@ export class TagRepository {
@GenerateSql({ params: [DummyValue.UUID] }) @GenerateSql({ params: [DummyValue.UUID] })
getAll(userId: string) { getAll(userId: string) {
return this.db.selectFrom('tags').select(columns.tag).where('userId', '=', userId).orderBy('value asc').execute(); return this.db.selectFrom('tags').select(columns.tag).where('userId', '=', userId).orderBy('value').execute();
} }
@GenerateSql({ params: [{ userId: DummyValue.UUID, color: DummyValue.STRING, value: DummyValue.STRING }] }) @GenerateSql({ params: [{ userId: DummyValue.UUID, color: DummyValue.STRING, value: DummyValue.STRING }] })
@ -126,7 +126,7 @@ export class TagRepository {
await this.db.deleteFrom('tag_asset').where('tagsId', '=', tagId).where('assetsId', 'in', assetIds).execute(); await this.db.deleteFrom('tag_asset').where('tagsId', '=', tagId).where('assetsId', 'in', assetIds).execute();
} }
@GenerateSql({ params: [{ assetId: DummyValue.UUID, tagsIds: [DummyValue.UUID] }] }) @GenerateSql({ params: [[{ assetId: DummyValue.UUID, tagsIds: [DummyValue.UUID] }]] })
@Chunked() @Chunked()
upsertAssetIds(items: Insertable<TagAsset>[]) { upsertAssetIds(items: Insertable<TagAsset>[]) {
if (items.length === 0) { if (items.length === 0) {
@ -160,7 +160,6 @@ export class TagRepository {
}); });
} }
@GenerateSql()
async deleteEmptyTags() { async deleteEmptyTags() {
// TODO rewrite as a single statement // TODO rewrite as a single statement
await this.db.transaction().execute(async (tx) => { await this.db.transaction().execute(async (tx) => {

View File

@ -14,6 +14,7 @@ import { asUuid } from 'src/utils/database';
type Upsert = Insertable<DbUserMetadata>; type Upsert = Insertable<DbUserMetadata>;
export interface UserListFilter { export interface UserListFilter {
id?: string;
withDeleted?: boolean; withDeleted?: boolean;
} }
@ -141,12 +142,13 @@ export class UserRepository {
{ name: 'with deleted', params: [{ withDeleted: true }] }, { name: 'with deleted', params: [{ withDeleted: true }] },
{ name: 'without deleted', params: [{ withDeleted: false }] }, { name: 'without deleted', params: [{ withDeleted: false }] },
) )
getList({ withDeleted }: UserListFilter = {}) { getList({ id, withDeleted }: UserListFilter = {}) {
return this.db return this.db
.selectFrom('users') .selectFrom('users')
.select(columns.userAdmin) .select(columns.userAdmin)
.select(withMetadata) .select(withMetadata)
.$if(!withDeleted, (eb) => eb.where('users.deletedAt', 'is', null)) .$if(!withDeleted, (eb) => eb.where('users.deletedAt', 'is', null))
.$if(!!id, (eb) => eb.where('users.id', '=', id!))
.orderBy('createdAt', 'desc') .orderBy('createdAt', 'desc')
.execute(); .execute();
} }

View File

@ -18,7 +18,6 @@ export class VersionHistoryRepository {
return this.db.selectFrom('version_history').selectAll().orderBy('createdAt', 'desc').executeTakeFirst(); return this.db.selectFrom('version_history').selectAll().orderBy('createdAt', 'desc').executeTakeFirst();
} }
@GenerateSql({ params: [{ version: 'v1.123.0' }] })
create(version: Insertable<VersionHistory>) { create(version: Insertable<VersionHistory>) {
return this.db.insertInto('version_history').values(version).returningAll().executeTakeFirstOrThrow(); return this.db.insertInto('version_history').values(version).returningAll().executeTakeFirstOrThrow();
} }

View File

@ -0,0 +1,9 @@
import { Kysely, sql } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> {
await sql`ALTER TYPE "asset_visibility_enum" ADD VALUE IF NOT EXISTS 'locked';`.execute(db);
}
export async function down(): Promise<void> {
// noop
}

View File

@ -0,0 +1,9 @@
import { Kysely, sql } from 'kysely';
export async function up(db: Kysely<any>): Promise<void> {
await sql`ALTER TABLE "sessions" ADD "pinExpiresAt" timestamp with time zone;`.execute(db);
}
export async function down(db: Kysely<any>): Promise<void> {
await sql`ALTER TABLE "sessions" DROP COLUMN "pinExpiresAt";`.execute(db);
}

Some files were not shown because too many files have changed in this diff Show More